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 |
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 |
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 |
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 |