| OLD | NEW |
| 1 #! /usr/bin/env python | 1 #! /usr/bin/env python |
| 2 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8;
-*- | 2 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8;
-*- |
| 3 # | 3 # |
| 4 # Copyright (c) 2009 University of Washington | 4 # Copyright (c) 2009 University of Washington |
| 5 # | 5 # |
| 6 # This program is free software; you can redistribute it and/or modify | 6 # This program is free software; you can redistribute it and/or modify |
| 7 # it under the terms of the GNU General Public License version 2 as | 7 # it under the terms of the GNU General Public License version 2 as |
| 8 # published by the Free Software Foundation; | 8 # published by the Free Software Foundation; |
| 9 # | 9 # |
| 10 # This program is distributed in the hope that it will be useful, | 10 # This program is distributed in the hope that it will be useful, |
| 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 # GNU General Public License for more details. | 13 # GNU General Public License for more details. |
| 14 # | 14 # |
| 15 # You should have received a copy of the GNU General Public License | 15 # You should have received a copy of the GNU General Public License |
| 16 # along with this program; if not, write to the Free Software | 16 # along with this program; if not, write to the Free Software |
| 17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 18 # | 18 # |
| 19 from __future__ import print_function | 19 from __future__ import print_function |
| 20 import os | 20 import os |
| 21 import sys | 21 import sys |
| 22 import time | 22 import time |
| 23 import optparse | 23 import argparse |
| 24 import subprocess | 24 import subprocess |
| 25 import threading | 25 import threading |
| 26 import signal | 26 import signal |
| 27 import xml.dom.minidom | |
| 28 import shutil | 27 import shutil |
| 29 import re | 28 import logging |
| 29 import csv |
| 30 import io |
| 30 | 31 |
| 31 from utils import get_list_from_file | 32 from utils import get_list_from_file |
| 32 | 33 |
| 34 log = logging.getLogger("ns3log") |
| 35 log.addHandler(logging.StreamHandler()) |
| 36 |
| 33 try: | 37 try: |
| 34 import queue | 38 import queue |
| 35 except ImportError: | 39 except ImportError: |
| 36 import Queue as queue | 40 import Queue as queue |
| 37 # | 41 # |
| 38 # XXX This should really be part of a waf command to list the configuration | 42 # XXX This should really be part of a waf command to list the configuration |
| 39 # items relative to optional ns-3 pieces. | 43 # items relative to optional ns-3 pieces. |
| 40 # | 44 # |
| 41 # A list of interesting configuration items in the waf configuration· | 45 # A list of interesting configuration items in the waf configuration· |
| 42 # cache which we may be interested in when deciding on which examples | 46 # cache which we may be interested in when deciding on which examples |
| (...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 568 # Examples, however, are a different story. In that case, we are just given | 572 # Examples, however, are a different story. In that case, we are just given |
| 569 # a list of examples that could be run. Instead of just failing, for example, | 573 # a list of examples that could be run. Instead of just failing, for example, |
| 570 # nsc-tcp-zoo if NSC is not present, we look into the waf saved configuration | 574 # nsc-tcp-zoo if NSC is not present, we look into the waf saved configuration |
| 571 # for relevant configuration items.·· | 575 # for relevant configuration items.·· |
| 572 # | 576 # |
| 573 # XXX This function pokes around in the waf internal state file. To be a | 577 # XXX This function pokes around in the waf internal state file. To be a |
| 574 # little less hacky, we should add a commmand to waf to return this info | 578 # little less hacky, we should add a commmand to waf to return this info |
| 575 # and use that result. | 579 # and use that result. |
| 576 # | 580 # |
| 577 def read_waf_config(): | 581 def read_waf_config(): |
| 578 for line in open(".lock-waf_" + sys.platform + "_build", "rt"): | 582 lock_file = ".lock-waf_" + sys.platform + "_build" |
| 583 |
| 584 for line in open(lock_file, "rt"): |
| 579 if line.startswith("top_dir ="): | 585 if line.startswith("top_dir ="): |
| 580 key, val = line.split('=') | 586 key, val = line.split('=') |
| 581 top_dir = eval(val.strip()) | 587 top_dir = eval(val.strip()) |
| 582 if line.startswith("out_dir ="): | 588 if line.startswith("out_dir ="): |
| 583 key, val = line.split('=') | 589 key, val = line.split('=') |
| 584 out_dir = eval(val.strip()) | 590 out_dir = eval(val.strip()) |
| 585 global NS3_BASEDIR | 591 global NS3_BASEDIR |
| 586 NS3_BASEDIR = top_dir | 592 NS3_BASEDIR = top_dir |
| 587 global NS3_BUILDDIR | 593 global NS3_BUILDDIR |
| 588 NS3_BUILDDIR = out_dir | 594 NS3_BUILDDIR = out_dir |
| 589 for line in open("%s/c4che/_cache.py" % out_dir).readlines(): | 595 for line in open("%s/c4che/_cache.py" % out_dir).readlines(): |
| 590 for item in interesting_config_items: | 596 for item in interesting_config_items: |
| 591 if line.startswith(item): | 597 if line.startswith(item): |
| 592 exec(line, globals()) | 598 exec(line, globals()) |
| 593 | 599 log.info("%s == %r" % (item, eval(item))) |
| 594 if options.verbose: | |
| 595 for item in interesting_config_items: | |
| 596 print("%s ==" % item, eval(item)) | |
| 597 | 600 |
| 598 # | 601 # |
| 599 # It seems pointless to fork a process to run waf to fork a process to run | 602 # It seems pointless to fork a process to run waf to fork a process to run |
| 600 # the test runner, so we just run the test runner directly. The main thing· | 603 # the test runner, so we just run the test runner directly. The main thing· |
| 601 # that waf would do for us would be to sort out the shared library path but | 604 # that waf would do for us would be to sort out the shared library path but |
| 602 # we can deal with that easily and do here. | 605 # we can deal with that easily and do here. |
| 603 # | 606 # |
| 604 # There can be many different ns-3 repositories on a system, and each has· | 607 # There can be many different ns-3 repositories on a system, and each has· |
| 605 # its own shared libraries, so ns-3 doesn't hardcode a shared library search | 608 # its own shared libraries, so ns-3 doesn't hardcode a shared library search |
| 606 # path -- it is cooked up dynamically, so we do that too. | 609 # path -- it is cooked up dynamically, so we do that too. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 622 if key == "PYTHONPATH": | 625 if key == "PYTHONPATH": |
| 623 have_PYTHONPATH = True | 626 have_PYTHONPATH = True |
| 624 | 627 |
| 625 pypath = os.environ["PYTHONPATH"] = os.path.join (NS3_BUILDDIR, "bindings",
"python") | 628 pypath = os.environ["PYTHONPATH"] = os.path.join (NS3_BUILDDIR, "bindings",
"python") |
| 626 | 629 |
| 627 if not have_PYTHONPATH: | 630 if not have_PYTHONPATH: |
| 628 os.environ["PYTHONPATH"] = pypath | 631 os.environ["PYTHONPATH"] = pypath |
| 629 else: | 632 else: |
| 630 os.environ["PYTHONPATH"] += ":" + pypath | 633 os.environ["PYTHONPATH"] += ":" + pypath |
| 631 | 634 |
| 632 if options.verbose: | 635 log.debug("os.environ[\"PYTHONPATH\"] == %s" % os.environ["PYTHONPATH"]) |
| 633 print("os.environ[\"PYTHONPATH\"] == %s" % os.environ["PYTHONPATH"]) | |
| 634 | 636 |
| 635 if sys.platform == "darwin": | 637 if sys.platform == "darwin": |
| 636 if not have_DYLD_LIBRARY_PATH: | 638 if not have_DYLD_LIBRARY_PATH: |
| 637 os.environ["DYLD_LIBRARY_PATH"] = "" | 639 os.environ["DYLD_LIBRARY_PATH"] = "" |
| 638 for path in NS3_MODULE_PATH: | 640 for path in NS3_MODULE_PATH: |
| 639 os.environ["DYLD_LIBRARY_PATH"] += ":" + path | 641 os.environ["DYLD_LIBRARY_PATH"] += ":" + path |
| 640 if options.verbose: | 642 log.debug("os.environ[\"DYLD_LIBRARY_PATH\"] == %s" % os.environ["DYLD_L
IBRARY_PATH"]) |
| 641 print("os.environ[\"DYLD_LIBRARY_PATH\"] == %s" % os.environ["DYLD_L
IBRARY_PATH"]) | |
| 642 elif sys.platform == "win32": | 643 elif sys.platform == "win32": |
| 643 if not have_PATH: | 644 if not have_PATH: |
| 644 os.environ["PATH"] = "" | 645 os.environ["PATH"] = "" |
| 645 for path in NS3_MODULE_PATH: | 646 for path in NS3_MODULE_PATH: |
| 646 os.environ["PATH"] += ';' + path | 647 os.environ["PATH"] += ';' + path |
| 647 if options.verbose: | 648 log.debug("os.environ[\"PATH\"] == %s" % os.environ["PATH"]) |
| 648 print("os.environ[\"PATH\"] == %s" % os.environ["PATH"]) | |
| 649 elif sys.platform == "cygwin": | 649 elif sys.platform == "cygwin": |
| 650 if not have_PATH: | 650 if not have_PATH: |
| 651 os.environ["PATH"] = "" | 651 os.environ["PATH"] = "" |
| 652 for path in NS3_MODULE_PATH: | 652 for path in NS3_MODULE_PATH: |
| 653 os.environ["PATH"] += ":" + path | 653 os.environ["PATH"] += ":" + path |
| 654 if options.verbose: | 654 log.debug("os.environ[\"PATH\"] == %s" % os.environ["PATH"]) |
| 655 print("os.environ[\"PATH\"] == %s" % os.environ["PATH"]) | |
| 656 else: | 655 else: |
| 657 if not have_LD_LIBRARY_PATH: | 656 if not have_LD_LIBRARY_PATH: |
| 658 os.environ["LD_LIBRARY_PATH"] = "" | 657 os.environ["LD_LIBRARY_PATH"] = "" |
| 659 for path in NS3_MODULE_PATH: | 658 for path in NS3_MODULE_PATH: |
| 660 os.environ["LD_LIBRARY_PATH"] += ":" + str(path) | 659 os.environ["LD_LIBRARY_PATH"] += ":" + str(path) |
| 661 if options.verbose: | 660 log.debug("os.environ[\"LD_LIBRARY_PATH\"] == %s" % os.environ["LD_LIBRA
RY_PATH"]) |
| 662 print("os.environ[\"LD_LIBRARY_PATH\"] == %s" % os.environ["LD_LIBRA
RY_PATH"]) | |
| 663 | 661 |
| 664 # | 662 # |
| 665 # Short note on generating suppressions: | 663 # Short note on generating suppressions: |
| 666 # | 664 # |
| 667 # See the valgrind documentation for a description of suppressions. The easiest | 665 # See the valgrind documentation for a description of suppressions. The easiest |
| 668 # way to generate a suppression expression is by using the valgrind· | 666 # way to generate a suppression expression is by using the valgrind· |
| 669 # --gen-suppressions option. To do that you have to figure out how to run the· | 667 # --gen-suppressions option. To do that you have to figure out how to run the· |
| 670 # test in question. | 668 # test in question. |
| 671 # | 669 # |
| 672 # If you do "test.py -v -g -s <suitename> then test.py will output most of what | 670 # If you do "test.py -v -g -s <suitename> then test.py will output most of what |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 path_cmd = os.path.join (build_path, shell_command) | 749 path_cmd = os.path.join (build_path, shell_command) |
| 752 else: | 750 else: |
| 753 path_cmd = os.path.join (NS3_BUILDDIR, shell_command) | 751 path_cmd = os.path.join (NS3_BUILDDIR, shell_command) |
| 754 | 752 |
| 755 if valgrind: | 753 if valgrind: |
| 756 cmd = "valgrind --suppressions=%s --leak-check=full --show-reachable=yes
--error-exitcode=2 %s" % (suppressions_path,· | 754 cmd = "valgrind --suppressions=%s --leak-check=full --show-reachable=yes
--error-exitcode=2 %s" % (suppressions_path,· |
| 757 path_cmd) | 755 path_cmd) |
| 758 else: | 756 else: |
| 759 cmd = path_cmd | 757 cmd = path_cmd |
| 760 | 758 |
| 761 if options.verbose: | 759 log.info("Synchronously execute %s" % cmd) |
| 762 print("Synchronously execute %s" % cmd) | |
| 763 | 760 |
| 764 start_time = time.time() | 761 start_time = time.time() |
| 765 proc = subprocess.Popen(cmd, shell = True, cwd = directory, stdout=subproces
s.PIPE, stderr=subprocess.PIPE) | 762 proc = subprocess.Popen(cmd, shell = True, cwd = directory, stdout=subproces
s.PIPE, stderr=subprocess.PIPE) |
| 766 stdout_results, stderr_results = proc.communicate() | 763 stdout_results, stderr_results = proc.communicate() |
| 767 elapsed_time = time.time() - start_time | 764 elapsed_time = time.time() - start_time |
| 768 | 765 |
| 769 retval = proc.returncode | 766 retval = proc.returncode |
| 770 try: | 767 try: |
| 771 stdout_results = stdout_results.decode() | 768 stdout_results = stdout_results.decode() |
| 772 except UnicodeDecodeError: | 769 except UnicodeDecodeError: |
| (...skipping 12 matching lines...) Expand all Loading... |
| 785 # errors are important. We want to detect *any* leaks, so the way to do· | 782 # errors are important. We want to detect *any* leaks, so the way to do· |
| 786 # that is to look for the presence of a valgrind leak summary section. | 783 # that is to look for the presence of a valgrind leak summary section. |
| 787 # | 784 # |
| 788 # If another error has occurred (like a test suite has failed), we don't· | 785 # If another error has occurred (like a test suite has failed), we don't· |
| 789 # want to trump that error, so only do the valgrind output scan if the· | 786 # want to trump that error, so only do the valgrind output scan if the· |
| 790 # test has otherwise passed (return code was zero). | 787 # test has otherwise passed (return code was zero). |
| 791 # | 788 # |
| 792 if valgrind and retval == 0 and "== LEAK SUMMARY:" in stderr_results: | 789 if valgrind and retval == 0 and "== LEAK SUMMARY:" in stderr_results: |
| 793 retval = 2 | 790 retval = 2 |
| 794 ···· | 791 ···· |
| 795 if options.verbose: | |
| 796 print("Return code = ", retval) | 792 print("Return code = ", retval) |
| 797 print("stderr = ", stderr_results) | 793 log.info("stderr = ", stderr_results) |
| 798 | 794 |
| 799 return (retval, stdout_results, stderr_results, elapsed_time) | 795 return (retval, stdout_results, stderr_results, elapsed_time) |
| 800 | 796 |
| 801 # | 797 # |
| 802 # This class defines a unit of testing work. It will typically refer to | 798 # This class defines a unit of testing work. It will typically refer to |
| 803 # a test suite to run using the test-runner, or an example to run directly. | 799 # a test suite to run using the test-runner, or an example to run directly. |
| 804 # | 800 # |
| 805 class Job: | 801 class Job: |
| 806 def __init__(self): | 802 def __init__(self): |
| 807 self.is_break = False | 803 self.is_break = False |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 954 if thread_exit == True: | 950 if thread_exit == True: |
| 955 job.set_is_break(True) | 951 job.set_is_break(True) |
| 956 self.output_queue.put(job) | 952 self.output_queue.put(job) |
| 957 continue | 953 continue |
| 958 | 954 |
| 959 # | 955 # |
| 960 # If we are actually supposed to skip this job, do so. Note that | 956 # If we are actually supposed to skip this job, do so. Note that |
| 961 # if is_skip is true, returncode is undefined. | 957 # if is_skip is true, returncode is undefined. |
| 962 # | 958 # |
| 963 if job.is_skip: | 959 if job.is_skip: |
| 964 if options.verbose: | 960 log.info("Skip %s" % job.shell_command) |
| 965 print("Skip %s" % job.shell_command) | |
| 966 self.output_queue.put(job) | 961 self.output_queue.put(job) |
| 967 continue | 962 continue |
| 968 | 963 |
| 969 # | 964 # |
| 970 # Otherwise go about the business of running tests as normal. | 965 # Otherwise go about the business of running tests as normal. |
| 971 # | 966 # |
| 972 else: | 967 else: |
| 973 if options.verbose: | 968 log.info("Launch %s" % job.shell_command) |
| 974 print("Launch %s" % job.shell_command) | |
| 975 | 969 |
| 976 if job.is_example or job.is_pyexample: | 970 if job.is_example or job.is_pyexample: |
| 977 # | 971 # |
| 978 # If we have an example, the shell command is all we need to | 972 # If we have an example, the shell command is all we need to |
| 979 # know. It will be something like "examples/udp/udp-echo" o
r· | 973 # know. It will be something like "examples/udp/udp-echo" o
r· |
| 980 # "examples/wireless/mixed-wireless.py" | 974 # "examples/wireless/mixed-wireless.py" |
| 981 # | 975 # |
| 982 (job.returncode, standard_out, standard_err, et) = run_job_s
ynchronously(job.shell_command,· | 976 (job.returncode, standard_out, standard_err, et) = run_job_s
ynchronously(job.shell_command,· |
| 983 job.cwd, options.valgrind, job.is_pyexample, job.build_p
ath) | 977 job.cwd, options.valgrind, job.is_pyexample, job.build_p
ath) |
| 984 else: | 978 else: |
| 985 # | 979 # |
| 986 # If we're a test suite, we need to provide a little more in
fo | 980 # If we're a test suite, we need to provide a little more in
fo |
| 987 # to the test runner, specifically the base directory and te
mp | 981 # to the test runner, specifically the base directory and te
mp |
| 988 # file name | 982 # file name |
| 989 # | 983 # |
| 990 if options.update_data: | 984 if options.update_data: |
| 991 update_data = '--update-data' | 985 update_data = '--update-data' |
| 992 else: | 986 else: |
| 993 update_data = '' | 987 update_data = '' |
| 994 (job.returncode, standard_out, standard_err, et) = run_job_s
ynchronously(job.shell_command +· | 988 (job.returncode, standard_out, standard_err, et) = run_job_s
ynchronously(job.shell_command +· |
| 995 " --xml --tempdir=%s --out=%s %s" % (job.tempdir, job.tm
p_file_name, update_data),· | 989 " --xml --tempdir=%s --out=%s %s" % (job.tempdir, job.tm
p_file_name, update_data),· |
| 996 job.cwd, options.valgrind, False) | 990 job.cwd, options.valgrind, False) |
| 997 | 991 |
| 998 job.set_elapsed_time(et) | 992 job.set_elapsed_time(et) |
| 999 | 993 |
| 1000 if options.verbose: | 994 log.info("returncode = %d" % job.returncode) |
| 1001 print("returncode = %d" % job.returncode) | 995 log.info("---------- begin standard out ----------") |
| 1002 print("---------- begin standard out ----------") | 996 log.info(standard_out) |
| 1003 print(standard_out) | 997 log.info("---------- begin standard err ----------") |
| 1004 print("---------- begin standard err ----------") | 998 log.info(standard_err) |
| 1005 print(standard_err) | 999 log.info("---------- end standard err ----------") |
| 1006 print("---------- end standard err ----------") | |
| 1007 | 1000 |
| 1008 self.output_queue.put(job) | 1001 self.output_queue.put(job) |
| 1009 | 1002 |
| 1003 def list_tests(test_runner_name, constrain=None): |
| 1004 """ |
| 1005 Return a dict |
| 1006 """ |
| 1007 path_cmd = os.path.join("utils", test_runner_name) |
| 1008 path_cmd += " --print-test-name-list --print-test-types {constraint}".format
( |
| 1009 constraint= "--test-type=%s" % constrain if constrain else "" |
| 1010 ) |
| 1011 (rc, standard_out, standard_err, et) = run_job_synchronously(path_cmd, os.ge
tcwd(), False, False) |
| 1012 if rc != 0: |
| 1013 # This is usually a sign that ns-3 crashed or exited uncleanly |
| 1014 print('test.py error: test-runner return code returned {}'.format(rc)) |
| 1015 print('To debug, try running {}\n'.format('\'./waf --run \"test-runner -
-list\"\'')) |
| 1016 return |
| 1017 |
| 1018 if isinstance(standard_out, bytes): |
| 1019 standard_out = standard_out.decode() |
| 1020 |
| 1021 reader = csv.DictReader(io.StringIO(standard_out), fieldnames=["kind", "name
"], delimiter=' ', skipinitialspace=True) |
| 1022 |
| 1023 return dict((row['name'], row['kind']) for row in reader) |
| 1010 # | 1024 # |
| 1011 # This is the main function that does the work of interacting with the | 1025 # This is the main function that does the work of interacting with the |
| 1012 # test-runner itself. | 1026 # test-runner itself. |
| 1013 # | 1027 # |
| 1014 def run_tests(): | 1028 def run_tests(unknown_args): |
| 1029 |
| 1030 if options.debug: |
| 1031 log.setLevel(logging.DEBUG) |
| 1015 # | 1032 # |
| 1016 # Pull some interesting configuration information out of waf, primarily | 1033 # Pull some interesting configuration information out of waf, primarily |
| 1017 # so we can know where executables can be found, but also to tell us what | 1034 # so we can know where executables can be found, but also to tell us what |
| 1018 # pieces of the system have been built. This will tell us what examples· | 1035 # pieces of the system have been built. This will tell us what examples· |
| 1019 # are runnable. | 1036 # are runnable. |
| 1020 # | 1037 # |
| 1021 read_waf_config() | 1038 read_waf_config() |
| 1022 | 1039 |
| 1023 # | 1040 # |
| 1024 # Set the proper suffix. | 1041 # Set the proper suffix. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1053 # file, we can only ask waf to build what we know will be necessary. | 1070 # file, we can only ask waf to build what we know will be necessary. |
| 1054 # For example, if the user only wants to run BVT tests, we only have | 1071 # For example, if the user only wants to run BVT tests, we only have |
| 1055 # to build the test-runner and can ignore all of the examples. | 1072 # to build the test-runner and can ignore all of the examples. |
| 1056 # | 1073 # |
| 1057 # If the user only wants to run a single example, then we can just build | 1074 # If the user only wants to run a single example, then we can just build |
| 1058 # that example. | 1075 # that example. |
| 1059 # | 1076 # |
| 1060 # If there is no constraint, then we have to build everything since the | 1077 # If there is no constraint, then we have to build everything since the |
| 1061 # user wants to run everything. | 1078 # user wants to run everything. |
| 1062 # | 1079 # |
| 1063 if options.kinds or options.list or (len(options.constrain) and options.
constrain in core_kinds): | 1080 if options.kinds or options.list or (options.constrain and options.const
rain in core_kinds): |
| 1064 if sys.platform == "win32": | 1081 if sys.platform == "win32": |
| 1065 waf_cmd = sys.executable + " waf --target=test-runner" | 1082 waf_cmd = sys.executable + " waf --target=test-runner" |
| 1066 else: | 1083 else: |
| 1067 waf_cmd = sys.executable + " waf --target=test-runner" | 1084 waf_cmd = sys.executable + " waf --target=test-runner" |
| 1068 elif len(options.example): | 1085 elif len(options.example): |
| 1069 if sys.platform == "win32": #Modify for windows | 1086 if sys.platform == "win32": #Modify for windows |
| 1070 waf_cmd = sys.executable + " waf --target=%s" % os.path.basename
(options.example) | 1087 waf_cmd = sys.executable + " waf --target=%s" % os.path.basename
(options.example) |
| 1071 else: | 1088 else: |
| 1072 waf_cmd = sys.executable + " waf --target=%s" % os.path.basename
(options.example) | 1089 waf_cmd = sys.executable + " waf --target=%s" % os.path.basename
(options.example) |
| 1073 | 1090 |
| 1074 else: | 1091 else: |
| 1075 if sys.platform == "win32": #Modify for windows | 1092 if sys.platform == "win32": #Modify for windows |
| 1076 waf_cmd = sys.executable + " waf" | 1093 waf_cmd = sys.executable + " waf" |
| 1077 else: | 1094 else: |
| 1078 waf_cmd = sys.executable + " waf" | 1095 waf_cmd = sys.executable + " waf" |
| 1079 | 1096 |
| 1080 if options.verbose: | 1097 log.info("Building: %s" % waf_cmd) |
| 1081 print("Building: %s" % waf_cmd) | |
| 1082 | 1098 |
| 1083 proc = subprocess.Popen(waf_cmd, shell = True) | 1099 proc = subprocess.Popen(waf_cmd, shell = True) |
| 1084 proc.communicate() | 1100 proc.communicate() |
| 1085 if proc.returncode: | 1101 if proc.returncode: |
| 1086 print("Waf died. Not running tests", file=sys.stderr) | 1102 print("Waf died. Not running tests", file=sys.stderr) |
| 1087 return proc.returncode | 1103 return proc.returncode |
| 1088 | 1104 |
| 1089 | 1105 |
| 1090 # | 1106 # |
| 1091 # Dynamically set up paths. | 1107 # Dynamically set up paths. |
| 1092 # | 1108 # |
| 1093 make_paths() | 1109 make_paths() |
| 1094 | 1110 |
| 1095 # | 1111 # |
| 1096 # Get the information from the build status file. | 1112 # Get the information from the build status file. |
| 1097 # | 1113 # |
| 1098 build_status_file = os.path.join (NS3_BUILDDIR, 'build-status.py') | 1114 build_status_file = os.path.join (NS3_BUILDDIR, 'build-status.py') |
| 1099 if os.path.exists(build_status_file): | 1115 if os.path.exists(build_status_file): |
| 1100 ns3_runnable_programs = get_list_from_file(build_status_file, "ns3_runna
ble_programs") | 1116 ns3_runnable_programs = get_list_from_file(build_status_file, "ns3_runna
ble_programs") |
| 1101 ns3_runnable_scripts = get_list_from_file(build_status_file, "ns3_runnab
le_scripts") | 1117 ns3_runnable_scripts = get_list_from_file(build_status_file, "ns3_runnab
le_scripts") |
| 1102 else: | 1118 else: |
| 1103 print('The build status file was not found. You must do waf build befor
e running test.py.', file=sys.stderr) | 1119 print('The build status file was not found. You must do waf build before
running test.py.', file=sys.stderr) |
| 1104 sys.exit(2) | 1120 sys.exit(2) |
| 1105 | 1121 |
| 1106 # | 1122 # |
| 1107 # Make a dictionary that maps the name of a program to its path. | 1123 # Make a dictionary that maps the name of a program to its path. |
| 1108 # | 1124 # |
| 1109 ns3_runnable_programs_dictionary = {} | 1125 ns3_runnable_programs_dictionary = {} |
| 1110 for program in ns3_runnable_programs: | 1126 for program in ns3_runnable_programs: |
| 1111 # Remove any directory names from path. | 1127 # Remove any directory names from path. |
| 1112 program_name = os.path.basename(program) | 1128 program_name = os.path.basename(program) |
| 1113 ns3_runnable_programs_dictionary[program_name] = program | 1129 ns3_runnable_programs_dictionary[program_name] = program |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1163 os.environ["NS_LOG"] = "" | 1179 os.environ["NS_LOG"] = "" |
| 1164 | 1180 |
| 1165 # | 1181 # |
| 1166 # There are a couple of options that imply we can to exit before starting | 1182 # There are a couple of options that imply we can to exit before starting |
| 1167 # up a bunch of threads and running tests. Let's detect these cases and· | 1183 # up a bunch of threads and running tests. Let's detect these cases and· |
| 1168 # handle them without doing all of the hard work. | 1184 # handle them without doing all of the hard work. |
| 1169 # | 1185 # |
| 1170 if options.kinds: | 1186 if options.kinds: |
| 1171 path_cmd = os.path.join("utils", test_runner_name + " --print-test-type-
list") | 1187 path_cmd = os.path.join("utils", test_runner_name + " --print-test-type-
list") |
| 1172 (rc, standard_out, standard_err, et) = run_job_synchronously(path_cmd, o
s.getcwd(), False, False) | 1188 (rc, standard_out, standard_err, et) = run_job_synchronously(path_cmd, o
s.getcwd(), False, False) |
| 1173 print(standard_out.decode()) | 1189 print(standard_out) |
| 1174 | 1190 |
| 1175 if options.list: | 1191 if options.list: |
| 1176 if len(options.constrain): | 1192 tests = list_tests(test_runner_name, options.constrain) |
| 1177 path_cmd = os.path.join("utils", test_runner_name + " --print-test-n
ame-list --print-test-types --test-type=%s" % options.constrain) | |
| 1178 else: | |
| 1179 path_cmd = os.path.join("utils", test_runner_name + " --print-test-n
ame-list --print-test-types") | |
| 1180 (rc, standard_out, standard_err, et) = run_job_synchronously(path_cmd, o
s.getcwd(), False, False) | |
| 1181 if rc != 0: | |
| 1182 # This is usually a sign that ns-3 crashed or exited uncleanly | |
| 1183 print(('test.py error: test-runner return code returned {}'.format(
rc))) | |
| 1184 print(('To debug, try running {}\n'.format('\'./waf --run \"test-run
ner --print-test-name-list\"\''))) | |
| 1185 return | |
| 1186 if isinstance(standard_out, bytes): | |
| 1187 standard_out = standard_out.decode() | |
| 1188 list_items = standard_out.split('\n') | |
| 1189 list_items.sort() | |
| 1190 print("Test Type Test Name") | 1193 print("Test Type Test Name") |
| 1191 print("--------- ---------") | 1194 print("--------- ---------") |
| 1192 for item in list_items: | 1195 for name, desc in tests.items(): |
| 1193 if len(item.strip()): | 1196 line = "{:<12}{}".format(desc, name) |
| 1194 print(item) | 1197 print(line) |
| 1195 example_names_original.sort() | 1198 example_names_original.sort() |
| 1196 for item in example_names_original: | 1199 for item in example_names_original: |
| 1197 print("example ", item) | 1200 print("example ", item) |
| 1198 print() | 1201 print() |
| 1199 | 1202 |
| 1200 if options.kinds or options.list: | 1203 if options.kinds or options.list: |
| 1201 return | 1204 return |
| 1202 | 1205 |
| 1203 # | 1206 # |
| 1204 # We communicate results in two ways. First, a simple message relating· | 1207 # We communicate results in two ways. First, a simple message relating· |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1255 # ./test.py --constrain=core: run all of the suite
s of all kinds | 1258 # ./test.py --constrain=core: run all of the suite
s of all kinds |
| 1256 # ./test.py --constrain=unit: run all unit suites | 1259 # ./test.py --constrain=unit: run all unit suites |
| 1257 # ./test.py --suite=some-test-suite: run a single suite | 1260 # ./test.py --suite=some-test-suite: run a single suite |
| 1258 # ./test.py --example=examples/udp/udp-echo: run single example | 1261 # ./test.py --example=examples/udp/udp-echo: run single example |
| 1259 # ./test.py --pyexample=examples/wireless/mixed-wireless.py: run python ex
ample | 1262 # ./test.py --pyexample=examples/wireless/mixed-wireless.py: run python ex
ample |
| 1260 # ./test.py --suite=some-suite --example=some-example: run the single suite | 1263 # ./test.py --suite=some-suite --example=some-example: run the single suite |
| 1261 # | 1264 # |
| 1262 # We can also use the --constrain option to provide an ordering of test· | 1265 # We can also use the --constrain option to provide an ordering of test· |
| 1263 # execution quite easily. | 1266 # execution quite easily. |
| 1264 # | 1267 # |
| 1265 if len(options.suite): | 1268 available_tests = list_tests(test_runner_name) |
| 1269 suite_list = [] |
| 1270 for suite in options.suite: |
| 1266 # See if this is a valid test suite. | 1271 # See if this is a valid test suite. |
| 1267 path_cmd = os.path.join("utils", test_runner_name + " --print-test-name-
list") | 1272 if suite not in available_tests.keys(): |
| 1268 (rc, suites, standard_err, et) = run_job_synchronously(path_cmd, os.getc
wd(), False, False) | 1273 print('The test suite was not run because an unknown test suite "%s"
name was requested.' % suite, file=sys.stderr) |
| 1269 if isinstance(suites, bytes): | |
| 1270 suites = suites.decode() | |
| 1271 if options.suite in suites.split('\n'): | |
| 1272 suites = options.suite + "\n" | |
| 1273 else: | |
| 1274 print('The test suite was not run because an unknown test suite name
was requested.', file=sys.stderr) | |
| 1275 sys.exit(2) | 1274 sys.exit(2) |
| 1275 suite_list.append(suite) |
| 1276 | 1276 |
| 1277 elif len(options.example) == 0 and len(options.pyexample) == 0: | 1277 if len(options.example) == 0 and len(options.pyexample) == 0: |
| 1278 if len(options.constrain): | 1278 if options.constrain: |
| 1279 path_cmd = os.path.join("utils", test_runner_name + " --print-test-n
ame-list --test-type=%s" % options.constrain) | 1279 path_cmd = os.path.join("utils", test_runner_name + " --print-test-n
ame-list --test-type=%s" % options.constrain) |
| 1280 (rc, suites, standard_err, et) = run_job_synchronously(path_cmd, os.
getcwd(), False, False) | 1280 (rc, suites, standard_err, et) = run_job_synchronously(path_cmd, os.
getcwd(), False, False) |
| 1281 else: | 1281 else: |
| 1282 path_cmd = os.path.join("utils", test_runner_name + " --print-test-n
ame-list") | 1282 path_cmd = os.path.join("utils", test_runner_name + " --print-test-n
ame-list") |
| 1283 (rc, suites, standard_err, et) = run_job_synchronously(path_cmd, os.
getcwd(), False, False) | 1283 (rc, suites, standard_err, et) = run_job_synchronously(path_cmd, os.
getcwd(), False, False) |
| 1284 else: | |
| 1285 suites = "" | |
| 1286 | 1284 |
| 1287 # | 1285 # |
| 1288 # suite_list will either a single test suite name that the user has· | 1286 # suite_list will either a single test suite name that the user has· |
| 1289 # indicated she wants to run or a list of test suites provided by | 1287 # indicated she wants to run or a list of test suites provided by |
| 1290 # the test-runner possibly according to user provided constraints. | 1288 # the test-runner possibly according to user provided constraints. |
| 1291 # We go through the trouble of setting up the parallel execution· | 1289 # We go through the trouble of setting up the parallel execution· |
| 1292 # even in the case of a single suite to avoid having two process the | 1290 # even in the case of a single suite to avoid having two process the |
| 1293 # results in two different places. | 1291 # results in two different places. |
| 1294 # | 1292 # |
| 1295 if isinstance(suites, bytes): | |
| 1296 suites = suites.decode() | |
| 1297 suite_list = suites.split('\n') | |
| 1298 | 1293 |
| 1299 # | 1294 # |
| 1300 # Performance tests should only be run when they are requested, | 1295 # Performance tests should only be run when they are requested, |
| 1301 # i.e. they are not run by default in test.py. | 1296 # i.e. they are not run by default in test.py. |
| 1302 # | 1297 # |
| 1303 if options.constrain != 'performance': | 1298 if options.constrain != 'performance': |
| 1304 | 1299 |
| 1305 # Get a list of all of the performance tests. | 1300 # Get a list of all of the performance tests. |
| 1306 path_cmd = os.path.join("utils", test_runner_name + " --print-test-name-
list --test-type=%s" % "performance") | 1301 path_cmd = os.path.join("utils", test_runner_name + " --print-test-name-
list --test-type=%s" % "performance") |
| 1307 (rc, performance_tests, standard_err, et) = run_job_synchronously(path_c
md, os.getcwd(), False, False) | 1302 (rc, performance_tests, standard_err, et) = run_job_synchronously(path_c
md, os.getcwd(), False, False) |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1371 test = test.strip() | 1366 test = test.strip() |
| 1372 if len(test): | 1367 if len(test): |
| 1373 job = Job() | 1368 job = Job() |
| 1374 job.set_is_example(False) | 1369 job.set_is_example(False) |
| 1375 job.set_is_pyexample(False) | 1370 job.set_is_pyexample(False) |
| 1376 job.set_display_name(test) | 1371 job.set_display_name(test) |
| 1377 job.set_tmp_file_name(os.path.join(testpy_output_dir, "%s.xml" % tes
t)) | 1372 job.set_tmp_file_name(os.path.join(testpy_output_dir, "%s.xml" % tes
t)) |
| 1378 job.set_cwd(os.getcwd()) | 1373 job.set_cwd(os.getcwd()) |
| 1379 job.set_basedir(os.getcwd()) | 1374 job.set_basedir(os.getcwd()) |
| 1380 job.set_tempdir(testpy_output_dir) | 1375 job.set_tempdir(testpy_output_dir) |
| 1381 if (options.multiple): | |
| 1382 multiple = "" | |
| 1383 else: | |
| 1384 multiple = " --stop-on-failure" | |
| 1385 if (len(options.fullness)): | |
| 1386 fullness = options.fullness.upper() | |
| 1387 fullness = " --fullness=%s" % fullness | |
| 1388 else: | |
| 1389 fullness = " --fullness=QUICK" | |
| 1390 | 1376 |
| 1391 path_cmd = os.path.join("utils", test_runner_name + " --test-name=%s
%s%s" % (test, multiple, fullness)) | 1377 path_cmd = os.path.join("utils", test_runner_name) |
| 1378 path_cmd += " --test-name={name} {multiple} --fullness={fullness} {v
erbose} {args}".format( |
| 1379 name=test, |
| 1380 multiple= "" if options.multiple else " --stop-on-failure", |
| 1381 fullness=options.fullness, |
| 1382 verbose="--verbose" if options.verbose else "", |
| 1383 args= "" |
| 1384 ) |
| 1392 | 1385 |
| 1393 job.set_shell_command(path_cmd) | 1386 job.set_shell_command(path_cmd) |
| 1394 | 1387 |
| 1395 if options.valgrind and test in core_valgrind_skip_tests: | 1388 if options.valgrind and test in core_valgrind_skip_tests: |
| 1396 job.set_is_skip(True) | 1389 job.set_is_skip(True) |
| 1397 | 1390 |
| 1398 # Skip tests that will fail if NSC is missing. | 1391 # Skip tests that will fail if NSC is missing. |
| 1399 if not NSC_ENABLED and test in core_nsc_missing_skip_tests: | 1392 if not NSC_ENABLED and test in core_nsc_missing_skip_tests: |
| 1400 job.set_is_skip(True) | 1393 job.set_is_skip(True) |
| 1401 | 1394 |
| 1402 if options.verbose: | 1395 log.debug("Queue %s" % test) |
| 1403 print("Queue %s" % test) | |
| 1404 | 1396 |
| 1405 input_queue.put(job) | 1397 input_queue.put(job) |
| 1406 jobs = jobs + 1 | 1398 jobs = jobs + 1 |
| 1407 total_tests = total_tests + 1 | 1399 total_tests = total_tests + 1 |
| 1408 ···· | 1400 ···· |
| 1409 # | 1401 # |
| 1410 # We've taken care of the discovered or specified test suites. Now we | 1402 # We've taken care of the discovered or specified test suites. Now we |
| 1411 # have to deal with examples run as smoke tests. We have a list of all of | 1403 # have to deal with examples run as smoke tests. We have a list of all of |
| 1412 # the example programs it makes sense to try and run. Each example will | 1404 # the example programs it makes sense to try and run. Each example will |
| 1413 # have a condition associated with it that must evaluate to true for us | 1405 # have a condition associated with it that must evaluate to true for us |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1439 # | 1431 # |
| 1440 # ./test.py: run all of the examp
les | 1432 # ./test.py: run all of the examp
les |
| 1441 # ./test.py --constrain=unit run no examples | 1433 # ./test.py --constrain=unit run no examples |
| 1442 # ./test.py --constrain=example run all of the examp
les | 1434 # ./test.py --constrain=example run all of the examp
les |
| 1443 # ./test.py --suite=some-test-suite: run no examples | 1435 # ./test.py --suite=some-test-suite: run no examples |
| 1444 # ./test.py --example=some-example: run the single examp
le | 1436 # ./test.py --example=some-example: run the single examp
le |
| 1445 # ./test.py --suite=some-suite --example=some-example: run the single examp
le | 1437 # ./test.py --suite=some-suite --example=some-example: run the single examp
le |
| 1446 # | 1438 # |
| 1447 # | 1439 # |
| 1448 if len(options.suite) == 0 and len(options.example) == 0 and len(options.pye
xample) == 0: | 1440 if len(options.suite) == 0 and len(options.example) == 0 and len(options.pye
xample) == 0: |
| 1449 if len(options.constrain) == 0 or options.constrain == "example": | 1441 if not options.constrain or options.constrain == "example": |
| 1450 if ENABLE_EXAMPLES: | 1442 if ENABLE_EXAMPLES: |
| 1451 for name, test, do_run, do_valgrind_run in example_tests: | 1443 for name, test, do_run, do_valgrind_run in example_tests: |
| 1452 # Remove any arguments and directory names from test. | 1444 # Remove any arguments and directory names from test. |
| 1453 test_name = test.split(' ', 1)[0]· | 1445 test_name = test.split(' ', 1)[0]· |
| 1454 test_name = os.path.basename(test_name) | 1446 test_name = os.path.basename(test_name) |
| 1455 | 1447 |
| 1456 # Don't try to run this example if it isn't runnable. | 1448 # Don't try to run this example if it isn't runnable. |
| 1457 if test_name in ns3_runnable_programs_dictionary: | 1449 if test_name in ns3_runnable_programs_dictionary: |
| 1458 if eval(do_run): | 1450 if eval(do_run): |
| 1459 job = Job() | 1451 job = Job() |
| 1460 job.set_is_example(True) | 1452 job.set_is_example(True) |
| 1461 job.set_is_pyexample(False) | 1453 job.set_is_pyexample(False) |
| 1462 job.set_display_name(name) | 1454 job.set_display_name(name) |
| 1463 job.set_tmp_file_name("") | 1455 job.set_tmp_file_name("") |
| 1464 job.set_cwd(testpy_output_dir) | 1456 job.set_cwd(testpy_output_dir) |
| 1465 job.set_basedir(os.getcwd()) | 1457 job.set_basedir(os.getcwd()) |
| 1466 job.set_tempdir(testpy_output_dir) | 1458 job.set_tempdir(testpy_output_dir) |
| 1467 job.set_shell_command(test) | 1459 job.set_shell_command(test) |
| 1468 job.set_build_path(options.buildpath) | 1460 job.set_build_path(options.buildpath) |
| 1469 | 1461 |
| 1470 if options.valgrind and not eval(do_valgrind_run): | 1462 if options.valgrind and not eval(do_valgrind_run): |
| 1471 job.set_is_skip (True) | 1463 job.set_is_skip (True) |
| 1472 | 1464 |
| 1473 if options.verbose: | 1465 log.info("Queue %s" % test) |
| 1474 print("Queue %s" % test) | |
| 1475 | 1466 |
| 1476 input_queue.put(job) | 1467 input_queue.put(job) |
| 1477 jobs = jobs + 1 | 1468 jobs = jobs + 1 |
| 1478 total_tests = total_tests + 1 | 1469 total_tests = total_tests + 1 |
| 1479 | 1470 |
| 1480 elif len(options.example): | 1471 elif len(options.example): |
| 1481 # Add the proper prefix and suffix to the example name to | 1472 # Add the proper prefix and suffix to the example name to |
| 1482 # match what is done in the wscript file. | 1473 # match what is done in the wscript file. |
| 1483 example_name = "%s%s-%s%s" % (APPNAME, VERSION, options.example, BUILD_P
ROFILE_SUFFIX) | 1474 example_name = "%s%s-%s%s" % (APPNAME, VERSION, options.example, BUILD_P
ROFILE_SUFFIX) |
| 1484 | 1475 |
| 1485 # Don't try to run this example if it isn't runnable. | 1476 # Don't try to run this example if it isn't runnable. |
| 1486 if example_name not in ns3_runnable_programs_dictionary: | 1477 if example_name not in ns3_runnable_programs_dictionary: |
| 1487 print("Example %s is not runnable." % example_name) | 1478 print("Example %s is not runnable." % example_name) |
| 1488 else: | 1479 else: |
| 1489 # | 1480 # |
| 1490 # If you tell me to run an example, I will try and run the example | 1481 # If you tell me to run an example, I will try and run the example |
| 1491 # irrespective of any condition. | 1482 # irrespective of any condition. |
| 1492 # | 1483 # |
| 1493 example_path = ns3_runnable_programs_dictionary[example_name] | 1484 example_path = ns3_runnable_programs_dictionary[example_name] |
| 1494 example_path = os.path.abspath(example_path) | 1485 example_path = os.path.abspath(example_path) |
| 1486 example_path += " " + ' '.join(unknown_args) |
| 1487 |
| 1495 job = Job() | 1488 job = Job() |
| 1496 job.set_is_example(True) | 1489 job.set_is_example(True) |
| 1497 job.set_is_pyexample(False) | 1490 job.set_is_pyexample(False) |
| 1498 job.set_display_name(example_path) | 1491 job.set_display_name(example_path) |
| 1499 job.set_tmp_file_name("") | 1492 job.set_tmp_file_name("") |
| 1500 job.set_cwd(testpy_output_dir) | 1493 job.set_cwd(testpy_output_dir) |
| 1501 job.set_basedir(os.getcwd()) | 1494 job.set_basedir(os.getcwd()) |
| 1502 job.set_tempdir(testpy_output_dir) | 1495 job.set_tempdir(testpy_output_dir) |
| 1503 job.set_shell_command(example_path) | 1496 job.set_shell_command(example_path) |
| 1504 job.set_build_path(options.buildpath) | 1497 job.set_build_path(options.buildpath) |
| 1505 | 1498 |
| 1506 if options.verbose: | 1499 log.debug("Queue %s" % example_name) |
| 1507 print("Queue %s" % example_name) | |
| 1508 | 1500 |
| 1509 input_queue.put(job) | 1501 input_queue.put(job) |
| 1510 jobs = jobs + 1 | 1502 jobs = jobs + 1 |
| 1511 total_tests = total_tests + 1 | 1503 total_tests = total_tests + 1 |
| 1512 | 1504 |
| 1513 # | 1505 # |
| 1514 # Run some Python examples as smoke tests. We have a list of all of | 1506 # Run some Python examples as smoke tests. We have a list of all of |
| 1515 # the example programs it makes sense to try and run. Each example will | 1507 # the example programs it makes sense to try and run. Each example will |
| 1516 # have a condition associated with it that must evaluate to true for us | 1508 # have a condition associated with it that must evaluate to true for us |
| 1517 # to try and execute it. This is used to determine if the example has | 1509 # to try and execute it. This is used to determine if the example has |
| 1518 # a dependency that is not satisfied. | 1510 # a dependency that is not satisfied. |
| 1519 # | 1511 # |
| 1520 # We don't care at all how the trace files come out, so we just write them· | 1512 # We don't care at all how the trace files come out, so we just write them· |
| 1521 # to a single temporary directory. | 1513 # to a single temporary directory. |
| 1522 # | 1514 # |
| 1523 # We need to figure out what python examples to execute. We are either· | 1515 # We need to figure out what python examples to execute. We are either· |
| 1524 # given one pyexample explicitly via the --pyexample option, or we | 1516 # given one pyexample explicitly via the --pyexample option, or we |
| 1525 # need to walk the list of python examples | 1517 # need to walk the list of python examples |
| 1526 # | 1518 # |
| 1527 # This translates into allowing the following options with respect to the· | 1519 # This translates into allowing the following options with respect to the· |
| 1528 # suites | 1520 # suites |
| 1529 # | 1521 # |
| 1530 # ./test.py --constrain=pyexample run all of the python examples | 1522 # ./test.py --constrain=pyexample run all of the python examples |
| 1531 # ./test.py --pyexample=some-example.py: run the single python example | 1523 # ./test.py --pyexample=some-example.py: run the single python example |
| 1532 # | 1524 # |
| 1533 if len(options.suite) == 0 and len(options.example) == 0 and len(options.pye
xample) == 0: | 1525 if len(options.suite) == 0 and len(options.example) == 0 and len(options.pye
xample) == 0: |
| 1534 if len(options.constrain) == 0 or options.constrain == "pyexample": | 1526 if not options.constrain or options.constrain == "pyexample": |
| 1535 if ENABLE_EXAMPLES: | 1527 if ENABLE_EXAMPLES: |
| 1536 for test, do_run in python_tests: | 1528 for test, do_run in python_tests: |
| 1537 # Remove any arguments and directory names from test. | 1529 # Remove any arguments and directory names from test. |
| 1538 test_name = test.split(' ', 1)[0]· | 1530 test_name = test.split(' ', 1)[0]· |
| 1539 test_name = os.path.basename(test_name) | 1531 test_name = os.path.basename(test_name) |
| 1540 | 1532 |
| 1541 # Don't try to run this example if it isn't runnable. | 1533 # Don't try to run this example if it isn't runnable. |
| 1542 if test_name in ns3_runnable_scripts: | 1534 if test_name in ns3_runnable_scripts: |
| 1543 if eval(do_run): | 1535 if eval(do_run): |
| 1544 job = Job() | 1536 job = Job() |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1563 job.set_is_skip (True) | 1555 job.set_is_skip (True) |
| 1564 | 1556 |
| 1565 # | 1557 # |
| 1566 # The user can disable python bindings, so we need | 1558 # The user can disable python bindings, so we need |
| 1567 # to pay attention to that and give some feedback | 1559 # to pay attention to that and give some feedback |
| 1568 # that we're not testing them | 1560 # that we're not testing them |
| 1569 # | 1561 # |
| 1570 if not ENABLE_PYTHON_BINDINGS: | 1562 if not ENABLE_PYTHON_BINDINGS: |
| 1571 job.set_is_skip (True) | 1563 job.set_is_skip (True) |
| 1572 | 1564 |
| 1573 if options.verbose: | 1565 log.debug("Queue %s" % test) |
| 1574 print("Queue %s" % test) | |
| 1575 | 1566 |
| 1576 input_queue.put(job) | 1567 input_queue.put(job) |
| 1577 jobs = jobs + 1 | 1568 jobs = jobs + 1 |
| 1578 total_tests = total_tests + 1 | 1569 total_tests = total_tests + 1 |
| 1579 | 1570 |
| 1580 elif len(options.pyexample): | 1571 elif len(options.pyexample): |
| 1581 # Don't try to run this example if it isn't runnable. | 1572 # Don't try to run this example if it isn't runnable. |
| 1582 example_name = os.path.basename(options.pyexample) | 1573 example_name = os.path.basename(options.pyexample) |
| 1583 if example_name not in ns3_runnable_scripts: | 1574 if example_name not in ns3_runnable_scripts: |
| 1584 print("Example %s is not runnable." % example_name) | 1575 print("Example %s is not runnable." % example_name) |
| 1585 else: | 1576 else: |
| 1586 # | 1577 # |
| 1587 # If you tell me to run a python example, I will try and run the exa
mple | 1578 # If you tell me to run a python example, I will try and run the exa
mple |
| 1588 # irrespective of any condition. | 1579 # irrespective of any condition. |
| 1589 # | 1580 # |
| 1590 job = Job() | 1581 job = Job() |
| 1591 job.set_is_pyexample(True) | 1582 job.set_is_pyexample(True) |
| 1592 job.set_display_name(options.pyexample) | 1583 job.set_display_name(options.pyexample) |
| 1593 job.set_tmp_file_name("") | 1584 job.set_tmp_file_name("") |
| 1594 job.set_cwd(testpy_output_dir) | 1585 job.set_cwd(testpy_output_dir) |
| 1595 job.set_basedir(os.getcwd()) | 1586 job.set_basedir(os.getcwd()) |
| 1596 job.set_tempdir(testpy_output_dir) | 1587 job.set_tempdir(testpy_output_dir) |
| 1597 job.set_shell_command(options.pyexample) | 1588 job.set_shell_command(options.pyexample) |
| 1598 job.set_build_path("") | 1589 job.set_build_path("") |
| 1599 | 1590 |
| 1600 if options.verbose: | 1591 log.debug("Queue %s" % options.pyexample) |
| 1601 print("Queue %s" % options.pyexample) | |
| 1602 | 1592 |
| 1603 input_queue.put(job) | 1593 input_queue.put(job) |
| 1604 jobs = jobs + 1 | 1594 jobs = jobs + 1 |
| 1605 total_tests = total_tests + 1 | 1595 total_tests = total_tests + 1 |
| 1606 | 1596 |
| 1607 # | 1597 # |
| 1608 # Tell the worker threads to pack up and go home for the day. Each one | 1598 # Tell the worker threads to pack up and go home for the day. Each one |
| 1609 # will exit when they see their is_break task. | 1599 # will exit when they see their is_break task. |
| 1610 # | 1600 # |
| 1611 for i in range(processors): | 1601 for i in range(processors): |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1752 if job.returncode == 0 or job.returncode == 1 or job.returncode
== 2: | 1742 if job.returncode == 0 or job.returncode == 1 or job.returncode
== 2: |
| 1753 f_to = open(xml_results_file, 'a') | 1743 f_to = open(xml_results_file, 'a') |
| 1754 f_from = open(job.tmp_file_name) | 1744 f_from = open(job.tmp_file_name) |
| 1755 f_to.write(f_from.read()) | 1745 f_to.write(f_from.read()) |
| 1756 f_to.close() | 1746 f_to.close() |
| 1757 f_from.close() | 1747 f_from.close() |
| 1758 else: | 1748 else: |
| 1759 f = open(xml_results_file, 'a') | 1749 f = open(xml_results_file, 'a') |
| 1760 f.write("<Test>\n") | 1750 f.write("<Test>\n") |
| 1761 f.write(" <Name>%s</Name>\n" % job.display_name) | 1751 f.write(" <Name>%s</Name>\n" % job.display_name) |
| 1762 f.write(' <Result>CRASH</Suite>\n') | 1752 f.write(' <Result>CRASH</Result>\n') |
| 1763 f.write("</Test>\n") | 1753 f.write("</Test>\n") |
| 1764 f.close() | 1754 f.close() |
| 1765 | 1755 |
| 1766 if job.returncode == 2: | 1756 if job.returncode == 2: |
| 1767 f = open(xml_results_file, 'a') | 1757 f = open(xml_results_file, 'a') |
| 1768 f.write("<Test>\n") | 1758 f.write("<Test>\n") |
| 1769 f.write(" <Name>%s</Name>\n" % job.display_name) | 1759 f.write(" <Name>%s</Name>\n" % job.display_name) |
| 1770 f.write(' <Result>VALGR</Result>\n') | 1760 f.write(' <Result>VALGR</Result>\n') |
| 1771 f.write("</Test>\n") | 1761 f.write("</Test>\n") |
| 1772 f.close() | 1762 f.close() |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1854 # | 1844 # |
| 1855 if not options.retain: | 1845 if not options.retain: |
| 1856 shutil.rmtree(testpy_output_dir) | 1846 shutil.rmtree(testpy_output_dir) |
| 1857 | 1847 |
| 1858 if passed_tests + skipped_tests == total_tests: | 1848 if passed_tests + skipped_tests == total_tests: |
| 1859 return 0 # success | 1849 return 0 # success |
| 1860 else: | 1850 else: |
| 1861 return 1 # catchall for general errors | 1851 return 1 # catchall for general errors |
| 1862 | 1852 |
| 1863 def main(argv): | 1853 def main(argv): |
| 1864 parser = optparse.OptionParser() | 1854 parser = argparse.ArgumentParser(description='ns3 test helper') |
| 1865 parser.add_option("-b", "--buildpath", action="store", type="string", dest="
buildpath", default="", | 1855 parser.add_argument("-b", "--buildpath", action="store", type=str, dest="bui
ldpath", default="", |
| 1866 metavar="BUILDPATH", | 1856 metavar="BUILDPATH", |
| 1867 help="specify the path where ns-3 was built (defaults to t
he build directory for the current variant)") | 1857 help="specify the path where ns-3 was built (defaults to t
he build directory for the current variant)") |
| 1868 | 1858 |
| 1869 parser.add_option("-c", "--constrain", action="store", type="string", dest="
constrain", default="", | 1859 parser.add_argument("-c", "--constrain", action="store", choices=core_kinds
+ ["example"], dest="constrain",· |
| 1870 metavar="KIND", | 1860 metavar="KIND", |
| 1871 help="constrain the test-runner by kind of test") | 1861 help="constrain the test-runner by kind of test") |
| 1872 | 1862 |
| 1873 parser.add_option("-d", "--duration", action="store_true", dest="duration",
default=False, | 1863 parser.add_argument("-d", "--duration", action="store_true", dest="duration"
, default=False, |
| 1874 help="print the duration of each test suite and example") | 1864 help="print the duration of each test suite and example") |
| 1875 | 1865 |
| 1876 parser.add_option("-e", "--example", action="store", type="string", dest="ex
ample", default="", | 1866 parser.add_argument("-e", "--example", type=str, metavar="EXAMPLE", |
| 1877 metavar="EXAMPLE", | |
| 1878 help="specify a single example to run (no relative path is
needed)") | 1867 help="specify a single example to run (no relative path is
needed)") |
| 1879 | 1868 |
| 1880 parser.add_option("-u", "--update-data", action="store_true", dest="update_d
ata", default=False, | 1869 parser.add_argument("-u", "--update-data", action="store_true", dest="update
_data", default=False, |
| 1881 help="If examples use reference data files, get them to re
-generate them") | 1870 help="If examples use reference data files, get them to re
-generate them") |
| 1882 | 1871 |
| 1883 parser.add_option("-f", "--fullness", action="store", type="string", dest="f
ullness", default="QUICK", | 1872 parser.add_argument("-f", "--fullness", action="store", choices=["QUICK", "E
XTENSIVE", "TAKES_FOREVER"], |
| 1884 metavar="FULLNESS", | 1873 dest="fullness", default="QUICK", metavar="FULLNESS", |
| 1885 help="choose the duration of tests to run: QUICK, EXTENSIV
E, or TAKES_FOREVER, where EXTENSIVE includes QUICK and TAKES_FOREVER includes Q
UICK and EXTENSIVE (only QUICK tests are run by default)") | 1874 help="choose the duration of tests to run: QUICK, EXTENSIVE, or TAKE
S_FOREVER, where EXTENSIVE includes QUICK and TAKES_FOREVER includes QUICK and E
XTENSIVE (only QUICK tests are run by default)") |
| 1886 | 1875 |
| 1887 parser.add_option("-g", "--grind", action="store_true", dest="valgrind", def
ault=False, | 1876 parser.add_argument("-g", "--grind", action="store_true", dest="valgrind", d
efault=False, |
| 1888 help="run the test suites and examples using valgrind") | 1877 help="run the test suites and examples using valgrind") |
| 1889 | 1878 |
| 1890 parser.add_option("-k", "--kinds", action="store_true", dest="kinds", defaul
t=False, | 1879 parser.add_argument("-k", "--kinds", action="store_true", dest="kinds", defa
ult=False, |
| 1891 help="print the kinds of tests available") | 1880 help="print the kinds of tests available") |
| 1892 | 1881 |
| 1893 parser.add_option("-l", "--list", action="store_true", dest="list", default=
False, | 1882 parser.add_argument("-l", "--list", action="store_true", dest="list", defaul
t=False, |
| 1894 help="print the list of known tests") | 1883 help="print the list of known tests") |
| 1895 | 1884 |
| 1896 parser.add_option("-m", "--multiple", action="store_true", dest="multiple",
default=False, | 1885 parser.add_argument("-m", "--multiple", action="store_true", dest="multiple"
, default=False, |
| 1897 help="report multiple failures from test suites and test c
ases") | 1886 help="report multiple failures from test suites and test c
ases") |
| 1898 | 1887 |
| 1899 parser.add_option("-n", "--nowaf", action="store_true", dest="nowaf", defaul
t=False, | 1888 parser.add_argument("-n", "--nowaf", action="store_true", dest="nowaf", defa
ult=False, |
| 1900 help="do not run waf before starting testing") | 1889 help="do not run waf before starting testing") |
| 1901 | 1890 |
| 1902 parser.add_option("-p", "--pyexample", action="store", type="string", dest="
pyexample", default="", | 1891 parser.add_argument("-p", "--pyexample", action="store", type=str, dest="pye
xample", default="", |
| 1903 metavar="PYEXAMPLE", | 1892 metavar="PYEXAMPLE", |
| 1904 help="specify a single python example to run (with relativ
e path)") | 1893 help="specify a single python example to run (with relativ
e path)") |
| 1905 | 1894 |
| 1906 parser.add_option("-r", "--retain", action="store_true", dest="retain", defa
ult=False, | 1895 parser.add_argument("-r", "--retain", action="store_true", dest="retain", de
fault=False, |
| 1907 help="retain all temporary files (which are normally delet
ed)") | 1896 help="retain all temporary files (which are normally delet
ed)") |
| 1908 | 1897 |
| 1909 parser.add_option("-s", "--suite", action="store", type="string", dest="suit
e", default="", | 1898 parser.add_argument("-s", "--suite", action="append", default=[], metavar="T
EST-SUITE", |
| 1910 metavar="TEST-SUITE", | 1899 help="specify a test suite to run. Can appear several time
s") |
| 1911 help="specify a single test suite to run") | |
| 1912 | 1900 |
| 1913 parser.add_option("-t", "--text", action="store", type="string", dest="text"
, default="", | 1901 parser.add_argument("-t", "--text", action="store", type=str, default="", me
tavar="TEXT-FILE", |
| 1914 metavar="TEXT-FILE", | |
| 1915 help="write detailed test results into TEXT-FILE.txt") | 1902 help="write detailed test results into TEXT-FILE.txt") |
| 1916 | 1903 |
| 1917 parser.add_option("-v", "--verbose", action="store_true", dest="verbose", de
fault=False, | 1904 parser.add_argument("-D", "--debug", action="store_true", default=False, |
| 1918 help="print progress and informational messages") | 1905 help="print progress and informational messages") |
| 1919 | 1906 |
| 1920 parser.add_option("-w", "--web", "--html", action="store", type="string", de
st="html", default="", | 1907 parser.add_argument("-v", "--verbose", action="store_true", default=False, |
| 1908 help="print progress and informational messages") |
| 1909 |
| 1910 parser.add_argument("-w", "--web", "--html", action="store", type=str, dest=
"html", default="", |
| 1921 metavar="HTML-FILE", | 1911 metavar="HTML-FILE", |
| 1922 help="write detailed test results into HTML-FILE.html") | 1912 help="write detailed test results into HTML-FILE.html") |
| 1923 | 1913 |
| 1924 parser.add_option("-x", "--xml", action="store", type="string", dest="xml",
default="", | 1914 parser.add_argument("-x", "--xml", action="store", type=str, dest="xml", def
ault="", |
| 1925 metavar="XML-FILE", | 1915 metavar="XML-FILE", |
| 1926 help="write detailed test results into XML-FILE.xml") | 1916 help="write detailed test results into XML-FILE.xml") |
| 1927 | 1917 |
| 1928 global options | 1918 global options |
| 1929 options = parser.parse_args()[0] | 1919 options, unknown_args = parser.parse_known_args() |
| 1930 signal.signal(signal.SIGINT, sigint_hook) | 1920 signal.signal(signal.SIGINT, sigint_hook) |
| 1931 | 1921 |
| 1932 return run_tests() | 1922 return run_tests(unknown_args) |
| 1933 | 1923 |
| 1934 if __name__ == '__main__': | 1924 if __name__ == '__main__': |
| 1935 sys.exit(main(sys.argv)) | 1925 sys.exit(main(sys.argv)) |
| OLD | NEW |