test.py
changeset 6200 2bf2700b6e67
parent 6127 b5bc10de166d
child 6201 9918fb8a08c2
equal deleted inserted replaced
6194:5f8e99c4c456 6200:2bf2700b6e67
   154     ("wireless/wifi-wired-bridging", "True", "True"),
   154     ("wireless/wifi-wired-bridging", "True", "True"),
   155 
   155 
   156     ("wimax/wimax-simple", "True", "True"),
   156     ("wimax/wimax-simple", "True", "True"),
   157     ("wimax/wimax-ipv4", "True", "True"),
   157     ("wimax/wimax-ipv4", "True", "True"),
   158     ("wimax/wimax-multicast", "True", "True"),
   158     ("wimax/wimax-multicast", "True", "True"),
       
   159 ]
       
   160 
       
   161 #
       
   162 # A list of python examples to run as smoke tests just to ensure that they 
       
   163 # runnable over time.  Also a condition under which to run the example (from
       
   164 # the waf configuration)
       
   165 #
       
   166 # XXX Should this not be read from a configuration file somewhere and not
       
   167 # hardcoded.
       
   168 #
       
   169 python_tests = [
       
   170     ("csma/csma-bridge.py", "True"),
       
   171 
       
   172     ("flowmon/wifi-olsr-flowmon.py", "True"),
       
   173 
       
   174     ("routing/simple-routing-ping6.py", "True"),
       
   175 
       
   176     ("tap/tap-csma-virtual-machine.py", "True"),
       
   177     ("tap/tap-wifi-virtual-machine.py", "True"),
       
   178 
       
   179     ("tutorial/first.py", "True"),
       
   180 
       
   181     ("wireless/wifi-ap.py", "True"),
       
   182     ("wireless/mixed-wireless.py", "True"),
   159 ]
   183 ]
   160 
   184 
   161 #
   185 #
   162 # The test suites are going to want to output status.  They are running
   186 # The test suites are going to want to output status.  They are running
   163 # concurrently.  This means that unless we are careful, the output of
   187 # concurrently.  This means that unless we are careful, the output of
   671 #
   695 #
   672 # Now, when you run valgrind the error will be suppressed.
   696 # Now, when you run valgrind the error will be suppressed.
   673 #
   697 #
   674 VALGRIND_SUPPRESSIONS_FILE = "testpy.supp"
   698 VALGRIND_SUPPRESSIONS_FILE = "testpy.supp"
   675 
   699 
   676 def run_job_synchronously(shell_command, directory, valgrind):
   700 def run_job_synchronously(shell_command, directory, valgrind, is_python):
   677     (base, build) = os.path.split (NS3_BUILDDIR)
   701     (base, build) = os.path.split (NS3_BUILDDIR)
   678     suppressions_path = os.path.join (base, VALGRIND_SUPPRESSIONS_FILE)
   702     suppressions_path = os.path.join (base, VALGRIND_SUPPRESSIONS_FILE)
   679     path_cmd = os.path.join (NS3_BUILDDIR, NS3_ACTIVE_VARIANT, shell_command)
   703 
       
   704     if is_python:
       
   705         path_cmd = "python " + os.path.join (base, shell_command)
       
   706     else:
       
   707         path_cmd = os.path.join (NS3_BUILDDIR, NS3_ACTIVE_VARIANT, shell_command)
       
   708 
   680     if valgrind:
   709     if valgrind:
   681         cmd = "valgrind --suppressions=%s --leak-check=full --show-reachable=yes --error-exitcode=2 %s" % (suppressions_path, 
   710         cmd = "valgrind --suppressions=%s --leak-check=full --show-reachable=yes --error-exitcode=2 %s" % (suppressions_path, 
   682             path_cmd)
   711             path_cmd)
   683     else:
   712     else:
   684         cmd = path_cmd
   713         cmd = path_cmd
   718 class Job:
   747 class Job:
   719     def __init__(self):
   748     def __init__(self):
   720         self.is_break = False
   749         self.is_break = False
   721         self.is_skip = False
   750         self.is_skip = False
   722         self.is_example = False
   751         self.is_example = False
       
   752         self.is_pyexample = False
   723         self.shell_command = ""
   753         self.shell_command = ""
   724         self.display_name = ""
   754         self.display_name = ""
   725         self.basedir = ""
   755         self.basedir = ""
   726         self.tempdir = ""
   756         self.tempdir = ""
   727         self.cwd = ""
   757         self.cwd = ""
   752     #
   782     #
   753     def set_is_example(self, is_example):
   783     def set_is_example(self, is_example):
   754         self.is_example = is_example
   784         self.is_example = is_example
   755 
   785 
   756     #
   786     #
       
   787     # Examples are treated differently than standard test suites.  This is
       
   788     # mostly because they are completely unaware that they are being run as 
       
   789     # tests.  So we have to do some special case processing to make them look
       
   790     # like tests.
       
   791     #
       
   792     def set_is_pyexample(self, is_pyexample):
       
   793         self.is_pyexample = is_pyexample
       
   794 
       
   795     #
   757     # This is the shell command that will be executed in the job.  For example,
   796     # This is the shell command that will be executed in the job.  For example,
   758     #
   797     #
   759     #  "utils/test-runner --suite=some-test-suite"
   798     #  "utils/test-runner --suite=some-test-suite"
   760     #
   799     #
   761     def set_shell_command(self, shell_command):
   800     def set_shell_command(self, shell_command):
   865             #
   904             #
   866             else:
   905             else:
   867                 if options.verbose:
   906                 if options.verbose:
   868                     print "Launch %s" % job.shell_command
   907                     print "Launch %s" % job.shell_command
   869 
   908 
   870                 if job.is_example:
   909                 if job.is_example or job.is_pyexample:
   871                     #
   910                     #
   872                     # If we have an example, the shell command is all we need to
   911                     # If we have an example, the shell command is all we need to
   873                     # know.  It will be something like "examples/udp-echo"
   912                     # know.  It will be something like "examples/udp-echo" or 
       
   913                     # "examples/mixed-wireless.py"
   874                     #
   914                     #
   875                     (job.returncode, standard_out, standard_err, et) = run_job_synchronously(job.shell_command, 
   915                     (job.returncode, standard_out, standard_err, et) = run_job_synchronously(job.shell_command, 
   876                         job.cwd, options.valgrind)
   916                         job.cwd, options.valgrind, job.is_pyexample)
   877                 else:
   917                 else:
   878                     #
   918                     #
   879                     # If we're a test suite, we need to provide a little more info
   919                     # If we're a test suite, we need to provide a little more info
   880                     # to the test runner, specifically the base directory and temp
   920                     # to the test runner, specifically the base directory and temp
   881                     # file name
   921                     # file name
   882                     #
   922                     #
   883                     (job.returncode, standard_out, standard_err, et) = run_job_synchronously(job.shell_command + 
   923                     (job.returncode, standard_out, standard_err, et) = run_job_synchronously(job.shell_command + 
   884                         " --basedir=%s --tempdir=%s --out=%s" % (job.basedir, job.tempdir, job.tmp_file_name), 
   924                         " --basedir=%s --tempdir=%s --out=%s" % (job.basedir, job.tempdir, job.tmp_file_name), 
   885                         job.cwd, options.valgrind)
   925                         job.cwd, options.valgrind, False)
   886 
   926 
   887                 job.set_elapsed_time(et)
   927                 job.set_elapsed_time(et)
   888 
   928 
   889                 if options.verbose:
   929                 if options.verbose:
   890                     print "returncode = %d" % job.returncode
   930                     print "returncode = %d" % job.returncode
   972     # up a bunch of threads and running tests.  Let's detect these cases and 
  1012     # up a bunch of threads and running tests.  Let's detect these cases and 
   973     # handle them without doing all of the hard work.
  1013     # handle them without doing all of the hard work.
   974     #
  1014     #
   975     if options.kinds:
  1015     if options.kinds:
   976         path_cmd = os.path.join("utils", "test-runner --kinds")
  1016         path_cmd = os.path.join("utils", "test-runner --kinds")
   977         (rc, standard_out, standard_err, et) = run_job_synchronously(path_cmd, os.getcwd(), False)
  1017         (rc, standard_out, standard_err, et) = run_job_synchronously(path_cmd, os.getcwd(), False, False)
   978         print standard_out
  1018         print standard_out
   979 
  1019 
   980     if options.list:
  1020     if options.list:
   981         path_cmd = os.path.join("utils", "test-runner --list")
  1021         path_cmd = os.path.join("utils", "test-runner --list")
   982         (rc, standard_out, standard_err, et) = run_job_synchronously(path_cmd, os.getcwd(), False)
  1022         (rc, standard_out, standard_err, et) = run_job_synchronously(path_cmd, os.getcwd(), False, False)
   983         print standard_out
  1023         print standard_out
   984 
  1024 
   985     if options.kinds or options.list:
  1025     if options.kinds or options.list:
   986         return
  1026         return
   987 
  1027 
  1026     f.write('<TestResults>\n')
  1066     f.write('<TestResults>\n')
  1027     f.close()
  1067     f.close()
  1028 
  1068 
  1029     #
  1069     #
  1030     # We need to figure out what test suites to execute.  We are either given one 
  1070     # We need to figure out what test suites to execute.  We are either given one 
  1031     # suite or example explicitly via the --suite or --example option, or we
  1071     # suite or example explicitly via the --suite or --example/--pyexample option,
  1032     # need to call into the test runner and ask it to list all of the available
  1072     # or we need to call into the test runner and ask it to list all of the available
  1033     # test suites.  Further, we need to provide the constraint information if it
  1073     # test suites.  Further, we need to provide the constraint information if it
  1034     # has been given to us.
  1074     # has been given to us.
  1035     # 
  1075     # 
  1036     # This translates into allowing the following options with respect to the 
  1076     # This translates into allowing the following options with respect to the 
  1037     # suites
  1077     # suites
  1038     #
  1078     #
  1039     #  ./test,py:                                           run all of the suites and examples
  1079     #  ./test,py:                                           run all of the suites and examples
  1040     #  ./test.py --constrain=core:                          run all of the suites of all kinds
  1080     #  ./test.py --constrain=core:                          run all of the suites of all kinds
  1041     #  ./test.py --constrain=unit:                          run all unit suites
  1081     #  ./test.py --constrain=unit:                          run all unit suites
  1042     #  ./test,py --suite=some-test-suite:                   run a single suite
  1082     #  ./test,py --suite=some-test-suite:                   run a single suite
  1043     #  ./test,py --example=udp-echo:                        run no test suites
  1083     #  ./test,py --example=udp/udp-echo:                    run no test suites
       
  1084     #  ./test,py --pyexample=wireless/mixed-wireless.py:    run no test suites
  1044     #  ./test,py --suite=some-suite --example=some-example: run the single suite
  1085     #  ./test,py --suite=some-suite --example=some-example: run the single suite
  1045     #
  1086     #
  1046     # We can also use the --constrain option to provide an ordering of test 
  1087     # We can also use the --constrain option to provide an ordering of test 
  1047     # execution quite easily.
  1088     # execution quite easily.
  1048     #
  1089     #
  1049     if len(options.suite):
  1090     if len(options.suite):
  1050         suites = options.suite + "\n"
  1091         suites = options.suite + "\n"
  1051     elif len(options.example) == 0:
  1092     elif len(options.example) == 0 and len(options.pyexample) == 0:
  1052         if len(options.constrain):
  1093         if len(options.constrain):
  1053             path_cmd = os.path.join("utils", "test-runner --list --constrain=%s" % options.constrain)
  1094             path_cmd = os.path.join("utils", "test-runner --list --constrain=%s" % options.constrain)
  1054             (rc, suites, standard_err, et) = run_job_synchronously(path_cmd, os.getcwd(), False)
  1095             (rc, suites, standard_err, et) = run_job_synchronously(path_cmd, os.getcwd(), False, False)
  1055         else:
  1096         else:
  1056             path_cmd = os.path.join("utils", "test-runner --list")
  1097             path_cmd = os.path.join("utils", "test-runner --list")
  1057             (rc, suites, standard_err, et) = run_job_synchronously(path_cmd, os.getcwd(), False)
  1098             (rc, suites, standard_err, et) = run_job_synchronously(path_cmd, os.getcwd(), False, False)
  1058     else:
  1099     else:
  1059         suites = ""
  1100         suites = ""
  1060 
  1101 
  1061     #
  1102     #
  1062     # suite_list will either a single test suite name that the user has 
  1103     # suite_list will either a single test suite name that the user has 
  1122     for test in suite_list:
  1163     for test in suite_list:
  1123         test = test.strip()
  1164         test = test.strip()
  1124         if len(test):
  1165         if len(test):
  1125             job = Job()
  1166             job = Job()
  1126             job.set_is_example(False)
  1167             job.set_is_example(False)
       
  1168             job.set_is_pyexample(False)
  1127             job.set_display_name(test)
  1169             job.set_display_name(test)
  1128             job.set_tmp_file_name(os.path.join(testpy_output_dir, "%s.xml" % test))
  1170             job.set_tmp_file_name(os.path.join(testpy_output_dir, "%s.xml" % test))
  1129             job.set_cwd(os.getcwd())
  1171             job.set_cwd(os.getcwd())
  1130             job.set_basedir(os.getcwd())
  1172             job.set_basedir(os.getcwd())
  1131             job.set_tempdir(testpy_output_dir)
  1173             job.set_tempdir(testpy_output_dir)
  1179     # suites
  1221     # suites
  1180     #
  1222     #
  1181     #  ./test,py:                                           run all of the examples
  1223     #  ./test,py:                                           run all of the examples
  1182     #  ./test.py --constrain=unit                           run no examples
  1224     #  ./test.py --constrain=unit                           run no examples
  1183     #  ./test.py --constrain=example                        run all of the examples
  1225     #  ./test.py --constrain=example                        run all of the examples
  1184     #  ./test,py --suite=some-test-suite:                   run no examples
  1226     #  ./test.py --suite=some-test-suite:                   run no examples
  1185     #  ./test,py --example=some-example:                    run the single example
  1227     #  ./test.py --example=some-example:                    run the single example
  1186     #  ./test,py --suite=some-suite --example=some-example: run the single example
  1228     #  ./test.py --suite=some-suite --example=some-example: run the single example
  1187     #
  1229     #
  1188     # XXX could use constrain to separate out examples used for performance 
  1230     # XXX could use constrain to separate out examples used for performance 
  1189     # testing
  1231     # testing
  1190     #
  1232     #
  1191     if len(options.suite) == 0 and len(options.example) == 0:
  1233     if len(options.suite) == 0 and len(options.example) == 0 and len(options.pyexample) == 0:
  1192         if len(options.constrain) == 0 or options.constrain == "example":
  1234         if len(options.constrain) == 0 or options.constrain == "example":
  1193             if ENABLE_EXAMPLES:
  1235             if ENABLE_EXAMPLES:
  1194                 for test, do_run, do_valgrind_run in example_tests:
  1236                 for test, do_run, do_valgrind_run in example_tests:
  1195                     if eval(do_run):
  1237                     if eval(do_run):
  1196                         job = Job()
  1238                         job = Job()
  1197                         job.set_is_example(True)
  1239                         job.set_is_example(True)
       
  1240                         job.set_is_pyexample(False)
  1198                         job.set_display_name(test)
  1241                         job.set_display_name(test)
  1199                         job.set_tmp_file_name("")
  1242                         job.set_tmp_file_name("")
  1200                         job.set_cwd(testpy_output_dir)
  1243                         job.set_cwd(testpy_output_dir)
  1201                         job.set_basedir(os.getcwd())
  1244                         job.set_basedir(os.getcwd())
  1202                         job.set_tempdir(testpy_output_dir)
  1245                         job.set_tempdir(testpy_output_dir)
  1217         # If you tell me to run an example, I will try and run the example
  1260         # If you tell me to run an example, I will try and run the example
  1218         # irrespective of any condition.
  1261         # irrespective of any condition.
  1219         #
  1262         #
  1220         job = Job()
  1263         job = Job()
  1221         job.set_is_example(True)
  1264         job.set_is_example(True)
       
  1265         job.set_is_pyexample(False)
  1222         job.set_display_name(options.example)
  1266         job.set_display_name(options.example)
  1223         job.set_tmp_file_name("")
  1267         job.set_tmp_file_name("")
  1224         job.set_cwd(testpy_output_dir)
  1268         job.set_cwd(testpy_output_dir)
  1225         job.set_basedir(os.getcwd())
  1269         job.set_basedir(os.getcwd())
  1226         job.set_tempdir(testpy_output_dir)
  1270         job.set_tempdir(testpy_output_dir)
  1227         job.set_shell_command("examples/%s" % options.example)
  1271         job.set_shell_command("examples/%s" % options.example)
  1228         
  1272         
  1229         if options.verbose:
  1273         if options.verbose:
  1230             print "Queue %s" % test
  1274             print "Queue %s" % options.example
       
  1275 
       
  1276         input_queue.put(job)
       
  1277         jobs = jobs + 1
       
  1278         total_tests = total_tests + 1
       
  1279 
       
  1280     #
       
  1281     # Run some Python examples as smoke tests.  We have a list of all of
       
  1282     # the example programs it makes sense to try and run.  Each example will
       
  1283     # have a condition associated with it that must evaluate to true for us
       
  1284     # to try and execute it.  This is used to determine if the example has
       
  1285     # a dependency that is not satisfied.
       
  1286     #
       
  1287     # We don't care at all how the trace files come out, so we just write them 
       
  1288     # to a single temporary directory.
       
  1289     #
       
  1290     # We need to figure out what python examples to execute.  We are either 
       
  1291     # given one pyexample explicitly via the --pyexample option, or we
       
  1292     # need to walk the list of python examples
       
  1293     #
       
  1294     # This translates into allowing the following options with respect to the 
       
  1295     # suites
       
  1296     #
       
  1297     #  ./test.py --constrain=pyexample           run all of the python examples
       
  1298     #  ./test.py --pyexample=some-example.py:    run the single python example
       
  1299     #
       
  1300     if len(options.suite) == 0 and len(options.example) == 0 and len(options.pyexample) == 0:
       
  1301         if len(options.constrain) == 0 or options.constrain == "pyexample":
       
  1302             if ENABLE_EXAMPLES:
       
  1303                 for test, do_run in python_tests:
       
  1304                     if eval(do_run):
       
  1305                         job = Job()
       
  1306                         job.set_is_example(False)
       
  1307                         job.set_is_pyexample(True)
       
  1308                         job.set_display_name(test)
       
  1309                         job.set_tmp_file_name("")
       
  1310                         job.set_cwd(testpy_output_dir)
       
  1311                         job.set_basedir(os.getcwd())
       
  1312                         job.set_tempdir(testpy_output_dir)
       
  1313                         job.set_shell_command("examples/%s" % test)
       
  1314 
       
  1315                         if options.valgrind and not eval(do_valgrind_run):
       
  1316                             job.set_is_skip (True)
       
  1317 
       
  1318                         if options.verbose:
       
  1319                             print "Queue %s" % test
       
  1320 
       
  1321                         input_queue.put(job)
       
  1322                         jobs = jobs + 1
       
  1323                         total_tests = total_tests + 1
       
  1324 
       
  1325     elif len(options.pyexample):
       
  1326         #
       
  1327         # If you tell me to run a python example, I will try and run the example
       
  1328         # irrespective of any condition.
       
  1329         #
       
  1330         job = Job()
       
  1331         job.set_is_pyexample(True)
       
  1332         job.set_display_name(options.pyexample)
       
  1333         job.set_tmp_file_name("")
       
  1334         job.set_cwd(testpy_output_dir)
       
  1335         job.set_basedir(os.getcwd())
       
  1336         job.set_tempdir(testpy_output_dir)
       
  1337         job.set_shell_command("examples/%s" % options.pyexample)
       
  1338         
       
  1339         if options.verbose:
       
  1340             print "Queue %s" % options.pyexample
  1231 
  1341 
  1232         input_queue.put(job)
  1342         input_queue.put(job)
  1233         jobs = jobs + 1
  1343         jobs = jobs + 1
  1234         total_tests = total_tests + 1
  1344         total_tests = total_tests + 1
  1235 
  1345 
  1261         if job.is_break:
  1371         if job.is_break:
  1262             continue
  1372             continue
  1263 
  1373 
  1264         if job.is_example:
  1374         if job.is_example:
  1265             kind = "Example"
  1375             kind = "Example"
       
  1376         elif job.is_pyexample:
       
  1377             kind = "PythonExample"
  1266         else:
  1378         else:
  1267             kind = "TestSuite"
  1379             kind = "TestSuite"
  1268 
  1380 
  1269         if job.is_skip:
  1381         if job.is_skip:
  1270             status = "SKIP"
  1382             status = "SKIP"
  1283                 crashed_tests = crashed_tests + 1
  1395                 crashed_tests = crashed_tests + 1
  1284                 status = "CRASH"
  1396                 status = "CRASH"
  1285 
  1397 
  1286         print "%s: %s %s" % (status, kind, job.display_name)
  1398         print "%s: %s %s" % (status, kind, job.display_name)
  1287 
  1399 
  1288         if job.is_example == True:
  1400         if job.is_example or job.is_pyexample:
  1289             #
  1401             #
  1290             # Examples are the odd man out here.  They are written without any
  1402             # Examples are the odd man out here.  They are written without any
  1291             # knowledge that they are going to be run as a test, so we need to 
  1403             # knowledge that they are going to be run as a test, so we need to 
  1292             # cook up some kind of output for them.  We're writing an xml file,
  1404             # cook up some kind of output for them.  We're writing an xml file,
  1293             # so we do some simple XML that says we ran the example.
  1405             # so we do some simple XML that says we ran the example.
  1466                       help="report multiple failures from test suites and test cases")
  1578                       help="report multiple failures from test suites and test cases")
  1467 
  1579 
  1468     parser.add_option("-n", "--nowaf", action="store_true", dest="nowaf", default=False,
  1580     parser.add_option("-n", "--nowaf", action="store_true", dest="nowaf", default=False,
  1469                       help="do not run waf before starting testing")
  1581                       help="do not run waf before starting testing")
  1470 
  1582 
       
  1583     parser.add_option("-p", "--pyexample", action="store", type="string", dest="pyexample", default="",
       
  1584                       metavar="PYEXAMPLE",
       
  1585                       help="specify a single python example to run")
       
  1586 
       
  1587     parser.add_option("-r", "--retain", action="store_true", dest="retain", default=False,
       
  1588                       help="retain all temporary files (which are normally deleted)")
       
  1589 
  1471     parser.add_option("-s", "--suite", action="store", type="string", dest="suite", default="",
  1590     parser.add_option("-s", "--suite", action="store", type="string", dest="suite", default="",
  1472                       metavar="TEST-SUITE",
  1591                       metavar="TEST-SUITE",
  1473                       help="specify a single test suite to run")
  1592                       help="specify a single test suite to run")
  1474 
  1593 
       
  1594     parser.add_option("-t", "--text", action="store", type="string", dest="text", default="",
       
  1595                       metavar="TEXT-FILE",
       
  1596                       help="write detailed test results into TEXT-FILE.txt")
       
  1597 
  1475     parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False,
  1598     parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False,
  1476                       help="print progress and informational messages")
  1599                       help="print progress and informational messages")
  1477 
  1600 
  1478     parser.add_option("-w", "--web", "--html", action="store", type="string", dest="html", default="",
  1601     parser.add_option("-w", "--web", "--html", action="store", type="string", dest="html", default="",
  1479                       metavar="HTML-FILE",
  1602                       metavar="HTML-FILE",
  1480                       help="write detailed test results into HTML-FILE.html")
  1603                       help="write detailed test results into HTML-FILE.html")
  1481 
       
  1482     parser.add_option("-r", "--retain", action="store_true", dest="retain", default=False,
       
  1483                       help="retain all temporary files (which are normally deleted)")
       
  1484 
       
  1485     parser.add_option("-t", "--text", action="store", type="string", dest="text", default="",
       
  1486                       metavar="TEXT-FILE",
       
  1487                       help="write detailed test results into TEXT-FILE.txt")
       
  1488 
  1604 
  1489     parser.add_option("-x", "--xml", action="store", type="string", dest="xml", default="",
  1605     parser.add_option("-x", "--xml", action="store", type="string", dest="xml", default="",
  1490                       metavar="XML-FILE",
  1606                       metavar="XML-FILE",
  1491                       help="write detailed test results into XML-FILE.xml")
  1607                       help="write detailed test results into XML-FILE.xml")
  1492 
  1608