#! /usr/bin/env python3 # # Copyright (c) 2014 Siddharth Santurkar # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as # published by the Free Software Foundation; # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # from __future__ import print_function import argparse import os import subprocess import sys def print_case_in_file(case_string, out): for i in range(100): print("-", end="", file=out) print(file=out) print("running test case " + case_string, end="\n\n", file=out) out.flush() def print_failed_cases(failed_cases): print("\nFailed Cases:") for case in failed_cases: print(case) def print_cmds(cmds): print("Commands to be executed:") for cmd in cmds: print(cmd.replace(sys.executable, "")) def set_workdir(): dir_files = [f for f in os.listdir(".") if os.path.exists(f)] if not "VERSION" in dir_files and not "ns3" in dir_files: if ( os.path.split(os.path.abspath("."))[1] == "tests" and os.path.split(os.path.abspath(os.pardir))[1] == "utils" ): os.chdir("../../") else: print("Error: Invalid working directory") sys.exit(1) ## TestBaseClass class class TestBaseClass: """ Generic class for testing tools based on provided commands and test cases. """ ## @var my_env # os environment ## @var mode # mode ## @var outfile # output file ## @var options # options def __init__(self, argv, desc, mode): """! Provide input argument list, description and mode of the suite being executed. @param self this object @param argv argument list @param desc description @param mode test mode """ self.my_env = os.environ set_workdir() self.my_env["LD_LIBRARY_PATH"] = os.getcwd() + "/build" self.mode = mode self.outfile = "test-port-" + self.mode + ".out" self.options = self.parseargs(argv, desc) def parseargs(self, argv, desc): """! Parses the commandline arguments @param self this object @param argv argument list @param desc description @return command line arguments """ parser = argparse.ArgumentParser(description=desc) parser.add_argument( "-f", "--file", action="store", dest="out_file", default=self.outfile, metavar="FILE", help="File to be used for storing the command specific output (Default: " + self.outfile + ")", ) parser.add_argument( "-c", action="store_true", dest="cmds", default=False, help="List out all the commands being tested", ) parser.add_argument( "-m", action="store_true", dest="mute", default=False, help="Sends only stderr output to FILE", ) parser.add_argument( "-x", "--customcmd", action="store", dest="custcmd", default=None, help="Enter a comma-separated list of commands to override the existing ones. NOT APPLICABLE FOR TEST-PY SUITE.", ) return parser.parse_args(argv) def override_cmds(self): """! Can be used by importing suite to handle custom commands @param self this object @return custom commands """ return self.options.custcmd def runtests(self, cmds): """! Execute the tests. @param self this object @param cmds test commands @return error code """ if self.options.cmds: print_cmds(cmds) return base_dir = os.sep.join( os.path.abspath(__file__).replace(os.path.pathsep, "/").split("/")[:-3] ) final_return = 0 total_tests = len(cmds) passed = 0 progress = 0.0 failed_cases = [] with open(self.options.out_file, "w", encoding="utf-8") as out: outstream = out with open(os.devnull, "w", encoding="utf-8") as sink: if self.options.mute: outstream = sink for cmd in cmds: case_string = cmd.replace(sys.executable, "") print("running test case: " + case_string) print_case_in_file(case_string, out) progress += 1 ret = subprocess.call( cmd, shell=True, env=self.my_env, stdout=outstream, stderr=out, cwd=base_dir ) if not ret: passed += 1 else: final_return = 1 failed_cases.append(case_string) print( "[ %s out of %s ] test cases passed; Progress = %.2f%% \n" % (passed, total_tests, progress * 100 / total_tests) ) if final_return != 0: print_failed_cases(failed_cases) else: print("\nAll cases passed") print("Detailed output available in " + self.options.out_file, end="\n\n") return final_return