22Test suite for the ns3 wrapper script 
   32from functools 
import partial
 
   35ns3_path = os.path.dirname(os.path.abspath(os.sep.join([__file__, 
"../../"])))
 
   36ns3_lock_filename = os.path.join(ns3_path, 
".lock-ns3_%s_build" % sys.platform)
 
   37ns3_script = os.sep.join([ns3_path, 
"ns3"])
 
   38ns3rc_script = os.sep.join([ns3_path, 
".ns3rc"])
 
   39usual_outdir = os.sep.join([ns3_path, 
"build"])
 
   40usual_lib_outdir = os.sep.join([usual_outdir, 
"lib"])
 
   46num_threads = 
max(1, os.cpu_count() - 1)
 
   47cmake_build_project_command = 
"cmake --build . -j".format(ns3_path=ns3_path)
 
   48cmake_build_target_command = partial(
"cmake --build . -j {jobs} --target {target}".format,
 
   51win32 = sys.platform == 
"win32" 
   52platform_makefiles = 
"MinGW Makefiles" if win32 
else "Unix Makefiles" 
   53ext = 
".exe" if win32 
else "" 
   56def run_ns3(args, env=None, generator=platform_makefiles):
 
   58    Runs the ns3 wrapper script with arguments
 
   59    @param args: string containing arguments that will get split before calling ns3
 
   60    @param env: environment variables dictionary
 
   61    @param generator: CMake generator
 
   62    @return tuple containing (error code, stdout 
and stderr)
 
   65        possible_leftovers = [
"contrib/borked", 
"contrib/calibre"]
 
   66        for leftover 
in possible_leftovers:
 
   67            if os.path.exists(leftover):
 
   68                shutil.rmtree(leftover, ignore_errors=
True)
 
   70        args = args.format(generator=generator)
 
   75    return run_program(ns3_script, args, python=
True, env=env)
 
   79def run_program(program, args, python=False, cwd=ns3_path, env=None):
 
   81    Runs a program with the given arguments 
and returns a tuple containing (error code, stdout 
and stderr)
 
   82    @param program: program to execute (
or python script)
 
   83    @param args: string containing arguments that will get split before calling the program
 
   84    @param python: flag indicating whether the program 
is a python script
 
   85    @param cwd: the working directory used that will be the root folder 
for the execution
 
   86    @param env: environment variables dictionary
 
   87    @return tuple containing (error code, stdout 
and stderr)
 
   90        raise Exception(
"args should be a string")
 
   94        arguments = [sys.executable, program]
 
   99        arguments.extend(re.findall(
"(?:\".*?\"|\S)+", args))  
 
  101    for i 
in range(len(arguments)):
 
  102        arguments[i] = arguments[i].replace(
"\"", 
"")
 
  105    current_env = os.environ.copy()
 
  109        current_env.update(env)
 
  112    ret = subprocess.run(
 
  114        stdin=subprocess.DEVNULL,
 
  115        stdout=subprocess.PIPE,
 
  116        stderr=subprocess.PIPE,
 
  121    return ret.returncode, ret.stdout.decode(sys.stdout.encoding), ret.stderr.decode(sys.stderr.encoding)
 
  126    Extracts the programs list from .lock-ns3
 
  127    @return list of programs.
 
  130    with open(ns3_lock_filename) 
as f:
 
  131        exec(f.read(), globals(), values)
 
  133    programs_list = values[
"ns3_runnable_programs"]
 
  137        programs_list = 
list(map(
lambda x: x + ext, programs_list))
 
  143    Gets a list of built libraries 
  144    @param lib_outdir: path containing libraries
 
  145    @return list of built libraries.
 
  147    libraries = glob.glob(lib_outdir + '/*', recursive=
True)
 
  148    return list(filter(
lambda x: 
"scratch-nested-subdir-lib" not in x, libraries))
 
  153    Gets a list of header files 
  154    @param outdir: path containing headers
 
  155    @return list of headers.
 
  157    return glob.glob(outdir + 
'/**/*.h', recursive=
True)
 
  162    Read interesting entries from the .lock-ns3 file
 
  163    @param entry: entry to read 
from .lock-ns3
 
  164    @return value of the requested entry.
 
  167    with open(ns3_lock_filename) 
as f:
 
  168        exec(f.read(), globals(), values)
 
  169    return values.get(entry, 
None)
 
  174    Check if tests are enabled 
in the .lock-ns3
 
  182    Check if tests are enabled 
in the .lock-ns3
 
  183    @return list of enabled modules (prefixed 
with 'ns3-').
 
  190    Python-on-whales wrapper for Docker-based ns-3 tests
 
  193    def __init__(self, currentTestCase: unittest.TestCase, containerName: str = 
"ubuntu:latest"):
 
  195        Create and start container 
with containerName 
in the current ns-3 directory
 
  196        @param self: the current DockerContainerManager instance
 
  197        @param currentTestCase: the test case instance creating the DockerContainerManager
 
  198        @param containerName: name of the container image to be used
 
  200        global DockerException
 
  202            from python_on_whales 
import docker
 
  203            from python_on_whales.exceptions 
import DockerException
 
  204        except ModuleNotFoundError:
 
  206            DockerException = 
None   
  207            currentTestCase.skipTest(
"python-on-whales was not found")
 
  210        with open(os.path.expanduser(
"~/.bashrc"), 
"r") 
as f:
 
  211            docker_settings = re.findall(
"(DOCKER_.*=.*)", f.read())
 
  212            for setting 
in docker_settings:
 
  213                key, value = setting.split(
"=")
 
  214                os.environ[key] = value
 
  215            del docker_settings, setting, key, value
 
  220                                    interactive=
True, detach=
True,
 
  222                                    volumes=[(ns3_path, 
"/ns-3-dev")]
 
  226        def split_exec(docker_container, cmd):
 
  227            return docker_container._execute(cmd.split(), workdir=
"/ns-3-dev")
 
  234        Return the managed container when entiring the block "with DockerContainerManager() as container" 
  235        @param self: the current DockerContainerManager instance
 
  236        @return container managed by DockerContainerManager.
 
  242        Clean up the managed container at the end of the block "with DockerContainerManager() as container" 
  243        @param self: the current DockerContainerManager instance
 
  244        @param exc_type: unused parameter
 
  245        @param exc_val: unused parameter
 
  246        @param exc_tb: unused parameter
 
  255    ns-3 tests related to checking if source files were left behind, 
not being used by CMake
 
  259    directory_and_files = {} 
  263        Scan all C++ source files and add them to a list based on their path
 
  266        for root, dirs, files 
in os.walk(ns3_path):
 
  267            if "gitlab-ci-local" in root:
 
  270                if name.endswith(
".cc"):
 
  271                    path = os.path.join(root, name)
 
  272                    directory = os.path.dirname(path)
 
  279        Test if all example source files are being used 
in their respective CMakeLists.txt
 
  282        unused_sources = set() 
  285            if os.sep + 
"examples" not in example_directory:
 
  289            with open(os.path.join(example_directory, 
"CMakeLists.txt"), 
"r") 
as f:
 
  290                cmake_contents = f.read()
 
  295                if os.path.basename(file).replace(
".cc", 
"") 
not in cmake_contents:
 
  296                    unused_sources.add(file)
 
  298        self.assertListEqual([], 
list(unused_sources))
 
  302        Test if all module source files are being used 
in their respective CMakeLists.txt
 
  305        unused_sources = set() 
  308            is_not_module = 
not (
"src" in directory 
or "contrib" in directory)
 
  309            is_example = os.sep + 
"examples" in directory
 
  310            is_bindings = os.sep + 
"bindings" in directory
 
  312            if is_not_module 
or is_bindings 
or is_example:
 
  317            cmake_path = os.path.join(directory, 
"CMakeLists.txt")
 
  318            while not os.path.exists(cmake_path):
 
  319                parent_directory = os.path.dirname(os.path.dirname(cmake_path))
 
  320                cmake_path = os.path.join(parent_directory, os.path.basename(cmake_path))
 
  323            with open(cmake_path, 
"r") 
as f:
 
  324                cmake_contents = f.read()
 
  328                if os.path.basename(file) 
not in cmake_contents:
 
  329                    unused_sources.add(file)
 
  332        exceptions = [
"win32-system-wall-clock-ms.cc",  
 
  334        for exception 
in exceptions:
 
  335            for unused_source 
in unused_sources:
 
  336                if os.path.basename(unused_source) == exception:
 
  337                    unused_sources.remove(unused_source)
 
  340        self.assertListEqual([], 
list(unused_sources))
 
  344        Test if all utils source files are being used 
in their respective CMakeLists.txt
 
  347        unused_sources = set() 
  350            is_module = 
"src" in directory 
or "contrib" in directory
 
  351            if os.sep + 
"utils" not in directory 
or is_module:
 
  356            cmake_path = os.path.join(directory, 
"CMakeLists.txt")
 
  357            while not os.path.exists(cmake_path):
 
  358                parent_directory = os.path.dirname(os.path.dirname(cmake_path))
 
  359                cmake_path = os.path.join(parent_directory, os.path.basename(cmake_path))
 
  362            with open(cmake_path, 
"r") 
as f:
 
  363                cmake_contents = f.read()
 
  367                if os.path.basename(file) 
not in cmake_contents:
 
  368                    unused_sources.add(file)
 
  370        self.assertListEqual([], 
list(unused_sources))
 
  375    ns-3 tests related to dependencies 
  380        Checks if headers 
from different modules (src/A, contrib/B) that are included by
 
  381        the current module (src/C) source files correspond to the list of linked modules
 
  383        LIBRARIES_TO_LINK A (missing B)
 
  387        headers_to_modules = {} 
  388        module_paths = glob.glob(ns3_path + "/src/*/") + glob.glob(ns3_path + 
"/contrib/*/")
 
  390        for path 
in module_paths:
 
  392            cmake_path = os.path.join(path, 
"CMakeLists.txt")
 
  393            with open(cmake_path, 
"r") 
as f:
 
  394                cmake_contents = f.readlines()
 
  396            module_name = os.path.relpath(path, ns3_path)
 
  397            module_name_nodir = module_name.replace(
"src/", 
"").replace(
"contrib/", 
"")
 
  398            modules[module_name_nodir] = {
"sources": set(),
 
  401                                          "included_headers": set(),
 
  402                                          "included_libraries": set(),
 
  406            for line 
in cmake_contents:
 
  407                base_name = os.path.basename(line[:-1])
 
  408                if not os.path.exists(os.path.join(path, line.strip())):
 
  413                    modules[module_name_nodir][
"headers"].add(base_name)
 
  414                    modules[module_name_nodir][
"sources"].add(base_name)
 
  417                    headers_to_modules[base_name] = module_name_nodir
 
  421                    modules[module_name_nodir][
"sources"].add(base_name)
 
  423                if ".cc" in line 
or ".h" in line:
 
  425                    source_file = os.path.join(ns3_path, module_name, line.strip())
 
  426                    with open(source_file, 
"r", encoding=
"utf-8") 
as f:
 
  427                        source_contents = f.read()
 
  428                    modules[module_name_nodir][
"included_headers"].update(map(
lambda x: x.replace(
"ns3/", 
""),
 
  429                                                                              re.findall(
"#include.*[\"|<](.*)[\"|>]",
 
  436            modules[module_name_nodir][
"libraries"].update(re.findall(
"\\${lib(.*)}", 
"".join(cmake_contents)))
 
  439        all_project_headers = set(headers_to_modules.keys())
 
  442        print(file=sys.stderr)
 
  443        for module 
in sorted(modules):
 
  444            external_headers = modules[module][
"included_headers"].difference(all_project_headers)
 
  445            project_headers_included = modules[module][
"included_headers"].difference(external_headers)
 
  446            modules[module][
"included_libraries"] = set(
 
  447                [headers_to_modules[x] 
for x 
in project_headers_included]).difference(
 
  450            diff = modules[module][
"included_libraries"].difference(modules[module][
"libraries"])
 
  452                print(
"Module %s includes modules that are not linked: %s" % (module, 
", ".join(
list(diff))),
 
  459        self.assertTrue(
True)
 
  464    ns-3 tests to check if the source code, whitespaces 
and CMake formatting
 
  465    are according to the coding style
 
  475        Import GitRepo and load the original diff state of the repository before the tests
 
  478        if not NS3StyleTestCase.starting_diff:
 
  480            if shutil.which(
"git") 
is None:
 
  481                self.skipTest(
"Git is not available")
 
  487                self.skipTest(
"GitPython is not available")
 
  490                repo = Repo(ns3_path)  
 
  491            except git.exc.InvalidGitRepositoryError:  
 
  492                self.skipTest(
"ns-3 directory does not contain a .git directory")
 
  494            hcommit = repo.head.commit  
 
  495            NS3StyleTestCase.starting_diff = hcommit.diff(
None)
 
  496            NS3StyleTestCase.repo = repo
 
  498        if NS3StyleTestCase.starting_diff 
is None:
 
  499            self.skipTest(
"Unmet dependencies")
 
  503        Check if there 
is any difference between tracked file after
 
  504        applying cmake-format
 
  508        for required_program 
in [
"cmake", 
"cmake-format"]:
 
  509            if shutil.which(required_program) 
is None:
 
  510                self.skipTest(
"%s was not found" % required_program)
 
  513        return_code, stdout, stderr = 
run_ns3(
"configure")
 
  514        self.assertEqual(return_code, 0)
 
  517        return_code, stdout, stderr = 
run_ns3(
"build cmake-format")
 
  518        self.assertEqual(return_code, 0)
 
  521        return_code, stdout, stderr = 
run_ns3(
"clean")
 
  522        self.assertEqual(return_code, 0)
 
  525        new_diff = NS3StyleTestCase.repo.head.commit.diff(
None)
 
  526        self.assertEqual(NS3StyleTestCase.starting_diff, new_diff)
 
  531    ns3 tests related to generic options 
  536        Clean configuration/build artifacts before common commands 
  545        Test not passing any arguments to
 
  548        return_code, stdout, stderr = run_ns3("")
 
  549        self.assertEqual(return_code, 1)
 
  550        self.assertIn(
"You need to configure ns-3 first: try ./ns3 configure", stdout)
 
  554        Test only passing --quiet argument to ns3 
  557        return_code, stdout, stderr = run_ns3("--quiet")
 
  558        self.assertEqual(return_code, 1)
 
  559        self.assertIn(
"You need to configure ns-3 first: try ./ns3 configure", stdout)
 
  563        Test only passing 'show config' argument to ns3
 
  566        return_code, stdout, stderr = run_ns3("show config")
 
  567        self.assertEqual(return_code, 1)
 
  568        self.assertIn(
"You need to configure ns-3 first: try ./ns3 configure", stdout)
 
  572        Test only passing 'show profile' argument to ns3
 
  575        return_code, stdout, stderr = run_ns3("show profile")
 
  576        self.assertEqual(return_code, 1)
 
  577        self.assertIn(
"You need to configure ns-3 first: try ./ns3 configure", stdout)
 
  581        Test only passing 'show version' argument to ns3
 
  584        return_code, stdout, stderr = run_ns3("show version")
 
  585        self.assertEqual(return_code, 1)
 
  586        self.assertIn(
"You need to configure ns-3 first: try ./ns3 configure", stdout)
 
  591    ns3 tests related to build profiles 
  596        Clean configuration/build artifacts before testing configuration settings 
  608        return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" -d debug --enable-verbose")
 
  609        self.assertEqual(return_code, 0)
 
  610        self.assertIn(
"Build profile                 : debug", stdout)
 
  611        self.assertIn(
"Build files have been written to", stdout)
 
  614        return_code, stdout, stderr = 
run_ns3(
"build core")
 
  615        self.assertEqual(return_code, 0)
 
  616        self.assertIn(
"Built target libcore", stdout)
 
  619        self.assertGreater(len(libraries), 0)
 
  620        self.assertIn(
"core-debug", libraries[0])
 
  624        Test the release build 
  627        return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" -d release")
 
  628        self.assertEqual(return_code, 0)
 
  629        self.assertIn(
"Build profile                 : release", stdout)
 
  630        self.assertIn(
"Build files have been written to", stdout)
 
  634        Test the optimized build 
  637        return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" -d optimized --enable-verbose")
 
  638        self.assertEqual(return_code, 0)
 
  639        self.assertIn(
"Build profile                 : optimized", stdout)
 
  640        self.assertIn(
"Build files have been written to", stdout)
 
  643        return_code, stdout, stderr = 
run_ns3(
"build core")
 
  644        self.assertEqual(return_code, 0)
 
  645        self.assertIn(
"Built target libcore", stdout)
 
  648        self.assertGreater(len(libraries), 0)
 
  649        self.assertIn(
"core-optimized", libraries[0])
 
  653        Test a build type with a typo
 
  656        return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" -d Optimized")
 
  657        self.assertEqual(return_code, 2)
 
  658        self.assertIn(
"invalid choice: 'Optimized'", stderr)
 
  662        Test a build type with another typo
 
  665        return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" -d OPTIMIZED")
 
  666        self.assertEqual(return_code, 2)
 
  667        self.assertIn(
"invalid choice: 'OPTIMIZED'", stderr)
 
  671        Replace settings set by default (e.g. ASSERT/LOGs enabled in debug builds 
and disabled 
in default ones)
 
  674        return_code, _, _ = run_ns3("clean")
 
  675        self.assertEqual(return_code, 0)
 
  677        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --dry-run -d debug")
 
  678        self.assertEqual(return_code, 0)
 
  680            "-DCMAKE_BUILD_TYPE=debug -DNS3_ASSERT=ON -DNS3_LOG=ON -DNS3_WARNINGS_AS_ERRORS=ON -DNS3_NATIVE_OPTIMIZATIONS=OFF",
 
  683        return_code, stdout, stderr = 
run_ns3(
 
  684            "configure -G \"{generator}\" --dry-run -d debug --disable-asserts --disable-logs --disable-werror")
 
  685        self.assertEqual(return_code, 0)
 
  687            "-DCMAKE_BUILD_TYPE=debug -DNS3_NATIVE_OPTIMIZATIONS=OFF -DNS3_ASSERT=OFF -DNS3_LOG=OFF -DNS3_WARNINGS_AS_ERRORS=OFF",
 
  690        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --dry-run")
 
  691        self.assertEqual(return_code, 0)
 
  693            "-DCMAKE_BUILD_TYPE=default -DNS3_ASSERT=ON -DNS3_LOG=ON -DNS3_WARNINGS_AS_ERRORS=OFF -DNS3_NATIVE_OPTIMIZATIONS=OFF",
 
  696        return_code, stdout, stderr = 
run_ns3(
 
  697            "configure -G \"{generator}\" --dry-run --enable-asserts --enable-logs --enable-werror")
 
  698        self.assertEqual(return_code, 0)
 
  700            "-DCMAKE_BUILD_TYPE=default -DNS3_ASSERT=ON -DNS3_LOG=ON -DNS3_NATIVE_OPTIMIZATIONS=OFF -DNS3_ASSERT=ON -DNS3_LOG=ON -DNS3_WARNINGS_AS_ERRORS=ON",
 
  706    Generic test case with basic function inherited by more complex tests.
 
  711        Check if configuration 
for release mode worked normally
 
  712        @param return_code: 
return code 
from CMake
 
  713        @param stdout: output 
from CMake.
 
  716        self.assertEqual(return_code, 0) 
  717        self.assertIn("Build profile                 : release", stdout)
 
  718        self.assertIn(
"Build files have been written to", stdout)
 
  722        Clean configuration/build artifacts before testing configuration and build settings
 
  723        After configuring the build 
as release,
 
  724        check 
if configuration worked 
and check expected output files.
 
  729        if os.path.exists(ns3rc_script):
 
  730            os.remove(ns3rc_script)
 
  734        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" -d release --enable-verbose")
 
  738        self.assertTrue(os.path.exists(ns3_lock_filename))
 
  743        self.assertTrue(os.path.exists(ns3_lock_filename))
 
  750    Test ns3 configuration options 
  755        Reuse cleaning/release configuration from NS3BaseTestCase 
if flag 
is cleaned
 
  762        Test enabling and disabling examples
 
  765        return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --enable-examples")
 
  774        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --disable-examples")
 
  784        Test enabling and disabling tests
 
  788        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --enable-tests")
 
  792        return_code, stdout, stderr = 
run_ns3(
"build core-test")
 
  795        self.assertEqual(return_code, 0)
 
  796        self.assertIn(
"Built target libcore-test", stdout)
 
  799        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --disable-tests")
 
  803        return_code, stdout, stderr = 
run_ns3(
"build core-test")
 
  806        self.assertEqual(return_code, 1)
 
  807        self.assertIn(
"Target to build does not exist: core-test", stdout)
 
  811        Test enabling specific modules 
  815        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --enable-modules='network;wifi'")
 
  821        self.assertIn(
"ns3-network", enabled_modules)
 
  822        self.assertIn(
"ns3-wifi", enabled_modules)
 
  825        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --enable-modules='core'")
 
  830        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --enable-modules=''")
 
  838        Test disabling specific modules 
  842        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --disable-modules='lte;wimax'")
 
  847        self.assertLess(len(enabled_modules), len(self.
ns3_modules))
 
  848        self.assertNotIn(
"ns3-lte", enabled_modules)
 
  849        self.assertNotIn(
"ns3-wimax", enabled_modules)
 
  852        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --disable-modules=''")
 
  860        Test enabling comma-separated (waf-style) examples 
  864        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --enable-modules='network,wifi'")
 
  870        self.assertIn(
"ns3-network", enabled_modules)
 
  871        self.assertIn(
"ns3-wifi", enabled_modules)
 
  874        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --enable-modules=''")
 
  882        Test disabling comma-separated (waf-style) examples 
  886        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --disable-modules='lte,mpi'")
 
  891        self.assertLess(len(enabled_modules), len(self.
ns3_modules))
 
  892        self.assertNotIn(
"ns3-lte", enabled_modules)
 
  893        self.assertNotIn(
"ns3-mpi", enabled_modules)
 
  896        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --disable-modules=''")
 
  904        Test loading settings from the ns3rc config file
 
  910            ns3rc_python_template = 
"# ! /usr/bin/env python\ 
  912                                 # A list of the modules that will be enabled when ns-3 is run.\ 
  913                                 # Modules that depend on the listed modules will be enabled also.\ 
  915                                 # All modules can be enabled by choosing 'all_modules'.\ 
  916                                 modules_enabled = [{modules}]\ 
  918                                 # Set this equal to true if you want examples to be run.\ 
  919                                 examples_enabled = {examples}\ 
  921                                 # Set this equal to true if you want tests to be run.\ 
  922                                 tests_enabled = {tests}\ 
  926            ns3rc_cmake_template = 
"set(ns3rc_tests_enabled {tests})\ 
  927                                    \nset(ns3rc_examples_enabled {examples})\ 
  928                                    \nset(ns3rc_enabled_modules {modules})\ 
  933                "python": ns3rc_python_template,
 
  934                "cmake": ns3rc_cmake_template
 
  937            def __init__(self, type_ns3rc):
 
  940            def format(self, **args):
 
  942                if self.
type == 
"cmake":
 
  943                    args[
"modules"] = args[
"modules"].replace(
"'", 
"").replace(
"\"", 
"").replace(
",", 
" ")
 
  944                    args[
"examples"] = 
"ON" if args[
"examples"] == 
"True" else "OFF" 
  945                    args[
"tests"] = 
"ON" if args[
"tests"] == 
"True" else "OFF" 
  947                formatted_string = ns3rc_str.ns3rc_templates[self.
type].format(**args)
 
  950                return formatted_string
 
  954                return ns3rc_str.ns3rc_templates.keys()
 
  956        for ns3rc_type 
in ns3rc_str.types():
 
  958            ns3rc_template = ns3rc_str(ns3rc_type)
 
  961            with open(ns3rc_script, 
"w") 
as f:
 
  962                f.write(ns3rc_template.format(modules=
"'lte'", examples=
"False", tests=
"True"))
 
  965            return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\"")
 
  971            self.assertIn(
"ns3-lte", enabled_modules)
 
  976            with open(ns3rc_script, 
"w") 
as f:
 
  977                f.write(ns3rc_template.format(modules=
"'wifi'", examples=
"True", tests=
"False"))
 
  980            return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\"")
 
  986            self.assertIn(
"ns3-wifi", enabled_modules)
 
  991            with open(ns3rc_script, 
"w") 
as f:
 
  992                f.write(ns3rc_template.format(modules=
"'core','network'", examples=
"True", tests=
"False"))
 
  995            return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\"")
 
 1001            self.assertIn(
"ns3-core", enabled_modules)
 
 1002            self.assertIn(
"ns3-network", enabled_modules)
 
 1008            with open(ns3rc_script, 
"w") 
as f:
 
 1009                if ns3rc_type == 
"python":
 
 1010                    f.write(ns3rc_template.format(modules=
"""'core', #comment 
 1014                    'network', 
'internet',
'wimax'""", examples="True", tests="True")) 
 1016                    f.write(ns3rc_template.format(modules=
"'core', 'lte', 'network', 'internet', 'wimax'",
 
 1021            return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\"")
 
 1027            self.assertIn(
"ns3-core", enabled_modules)
 
 1028            self.assertIn(
"ns3-internet", enabled_modules)
 
 1029            self.assertIn(
"ns3-lte", enabled_modules)
 
 1030            self.assertIn(
"ns3-wimax", enabled_modules)
 
 1035            os.remove(ns3rc_script)
 
 1038            return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\"")
 
 1048        Test dry-run (printing commands to be executed instead of running them) 
 1054        for positional_command 
in [
"configure", 
"build", 
"clean"]:
 
 1055            return_code, stdout, stderr = 
run_ns3(
"--dry-run %s" % positional_command)
 
 1056            return_code1, stdout1, stderr1 = 
run_ns3(
"%s --dry-run" % positional_command)
 
 1058            self.assertEqual(return_code, return_code1)
 
 1059            self.assertEqual(stdout, stdout1)
 
 1060            self.assertEqual(stderr, stderr1)
 
 1065        run_ns3(
"configure -G \"{generator}\" -d release --enable-verbose")
 
 1066        run_ns3(
"build scratch-simulator")
 
 1069        return_code0, stdout0, stderr0 = 
run_ns3(
"--dry-run run scratch-simulator")
 
 1070        return_code1, stdout1, stderr1 = 
run_ns3(
"run scratch-simulator")
 
 1071        return_code2, stdout2, stderr2 = 
run_ns3(
"--dry-run run scratch-simulator --no-build")
 
 1072        return_code3, stdout3, stderr3 = 
run_ns3(
"run scratch-simulator --no-build")
 
 1075        self.assertEqual(sum([return_code0, return_code1, return_code2, return_code3]), 0)
 
 1076        self.assertEqual([stderr0, stderr1, stderr2, stderr3], [
""] * 4)
 
 1080            if "scratch-simulator" in program 
and "subdir" not in program:
 
 1081                scratch_path = program
 
 1087        self.assertIn(scratch_path, stdout0)
 
 1091        self.assertIn(
"Built target", stdout1)
 
 1092        self.assertNotIn(scratch_path, stdout1)
 
 1095        self.assertIn(
"The following commands would be executed:", stdout2)
 
 1096        self.assertIn(scratch_path, stdout2)
 
 1099        self.assertNotIn(
"Finished executing the following commands:", stdout3)
 
 1100        self.assertNotIn(scratch_path, stdout3)
 
 1104        Test if ns3 
is propagating back the 
return code 
from the executables called 
with the run command
 
 1108        return_code, _, _ = 
run_ns3(
"clean")
 
 1109        self.assertEqual(return_code, 0)
 
 1111        return_code, _, _ = 
run_ns3(
"configure -G \"{generator}\" --enable-examples --enable-tests")
 
 1112        self.assertEqual(return_code, 0)
 
 1115        return_code, stdout, stderr = 
run_ns3(
"build command-line-example test-runner")
 
 1116        self.assertEqual(return_code, 0)
 
 1119        return_code, stdout, stderr = 
run_ns3(
"run \"test-runner --test-name=command-line\" --no-build")
 
 1120        self.assertEqual(return_code, 0)
 
 1123        return_code, stdout, stderr = 
run_ns3(
"run \"test-runner --test-name=command-line\" --no-build",
 
 1124                                              env={
"NS_COMMANDLINE_INTROSPECTION": 
".."}
 
 1126        self.assertNotEqual(return_code, 0)
 
 1129        sigsegv_example = os.path.join(ns3_path, 
"scratch", 
"sigsegv.cc")
 
 1130        with open(sigsegv_example, 
"w") 
as f:
 
 1132                    int main (int argc, char *argv[]) 
 1134                      char *s = "hello world"; *s = 
'H';
 
 1138        return_code, stdout, stderr = run_ns3("run sigsegv")
 
 1140            self.assertEqual(return_code, 4294967295)  
 
 1141            self.assertIn(
"sigsegv-default.exe' returned non-zero exit status", stdout)
 
 1143            self.assertEqual(return_code, 245)
 
 1144            self.assertIn(
"sigsegv-default' died with <Signals.SIGSEGV: 11>", stdout)
 
 1147        abort_example = os.path.join(ns3_path, 
"scratch", 
"abort.cc")
 
 1148        with open(abort_example, 
"w") 
as f:
 
 1152                    using namespace ns3;
 
 1153                    int main (int argc, char *argv[])
 
 1159        return_code, stdout, stderr = run_ns3("run abort")
 
 1161            self.assertEqual(return_code, 3)
 
 1162            self.assertIn(
"abort-default.exe' returned non-zero exit status", stdout)
 
 1164            self.assertEqual(return_code, 250)
 
 1165            self.assertIn(
"abort-default' died with <Signals.SIGABRT: 6>", stdout)
 
 1167        os.remove(sigsegv_example)
 
 1168        os.remove(abort_example)
 
 1172        Test passing 'show config' argument to ns3 to get the configuration table
 
 1175        return_code, stdout, stderr = run_ns3("show config")
 
 1176        self.assertEqual(return_code, 0)
 
 1177        self.assertIn(
"Summary of ns-3 settings", stdout)
 
 1181        Test passing 'show profile' argument to ns3 to get the build profile
 
 1184        return_code, stdout, stderr = run_ns3("show profile")
 
 1185        self.assertEqual(return_code, 0)
 
 1186        self.assertIn(
"Build profile: release", stdout)
 
 1190        Test passing 'show version' argument to ns3 to get the build version
 
 1193        if shutil.which(
"git") 
is None:
 
 1194            self.skipTest(
"git is not available")
 
 1196        return_code, _, _ = 
run_ns3(
"configure -G \"{generator}\" --enable-build-version")
 
 1197        self.assertEqual(return_code, 0)
 
 1199        return_code, stdout, stderr = 
run_ns3(
"show version")
 
 1200        self.assertEqual(return_code, 0)
 
 1201        self.assertIn(
"ns-3 version:", stdout)
 
 1205        Test if CMake target names 
for scratches 
and ns3 shortcuts
 
 1206        are working correctly
 
 1210        test_files = ["scratch/main.cc",
 
 1212                      "scratch/subdir1/main.cc",
 
 1213                      "scratch/subdir2/main.cc"]
 
 1214        backup_files = [
"scratch/.main.cc"]  
 
 1217        for path 
in test_files + backup_files:
 
 1218            filepath = os.path.join(ns3_path, path)
 
 1219            os.makedirs(os.path.dirname(filepath), exist_ok=
True)
 
 1220            with open(filepath, 
"w") 
as f:
 
 1222                    f.write(
"int main (int argc, char *argv[]){}")
 
 1230        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\"")
 
 1231        self.assertEqual(return_code, 0)
 
 1234        for path 
in test_files + backup_files:
 
 1235            path = path.replace(
".cc", 
"")
 
 1236            return_code1, stdout1, stderr1 = 
run_program(
"cmake", 
"--build . --target %s -j %d" 
 1237                                                         % (path.replace(
"/", 
"_"), num_threads),
 
 1238                                                         cwd=os.path.join(ns3_path, 
"cmake-cache"))
 
 1239            return_code2, stdout2, stderr2 = 
run_ns3(
"build %s" % path)
 
 1240            if "main" in path 
and ".main" not in path:
 
 1241                self.assertEqual(return_code1, 0)
 
 1242                self.assertEqual(return_code2, 0)
 
 1244                self.assertEqual(return_code1, 2)
 
 1245                self.assertEqual(return_code2, 1)
 
 1248        for path 
in test_files:
 
 1249            path = path.replace(
".cc", 
"")
 
 1250            return_code, stdout, stderr = 
run_ns3(
"run %s --no-build" % path)
 
 1252                self.assertEqual(return_code, 0)
 
 1254                self.assertEqual(return_code, 1)
 
 1257        for path 
in test_files + backup_files:
 
 1258            source_absolute_path = os.path.join(ns3_path, path)
 
 1259            os.remove(source_absolute_path)
 
 1260            if "empty" in path 
or ".main" in path:
 
 1262            filename = os.path.basename(path).replace(
".cc", 
"")
 
 1263            executable_absolute_path = os.path.dirname(os.path.join(ns3_path, 
"build", path))
 
 1264            executable_name = 
list(filter(
lambda x: filename 
in x,
 
 1265                                          os.listdir(executable_absolute_path)
 
 1269            os.remove(os.path.join(executable_absolute_path, executable_name))
 
 1270            if path 
not in [
"scratch/main.cc", 
"scratch/empty.cc"]:
 
 1271                os.rmdir(os.path.dirname(source_absolute_path))
 
 1273        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\"")
 
 1274        self.assertEqual(return_code, 0)
 
 1278        Test if ns3 
is inserting additional arguments by MPICH 
and OpenMPI to run on the CI
 
 1282        if shutil.which(
"mpiexec") 
is None or win32:
 
 1283            self.skipTest(
"Mpi is not available")
 
 1285        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --enable-examples")
 
 1286        self.assertEqual(return_code, 0)
 
 1290        return_code, stdout, stderr = 
run_ns3(
"build sample-simulator")
 
 1291        self.assertEqual(return_code, 0)
 
 1294        sample_simulator_path = 
list(filter(
lambda x: 
"sample-simulator" in x, executables))[0]
 
 1296        mpi_command = 
"--dry-run run sample-simulator --command-template=\"mpiexec -np 2 %s\"" 
 1297        non_mpi_command = 
"--dry-run run sample-simulator --command-template=\"echo %s\"" 
 1300        return_code, stdout, stderr = 
run_ns3(mpi_command)
 
 1301        self.assertEqual(return_code, 0)
 
 1302        self.assertIn(
"mpiexec -np 2 %s" % sample_simulator_path, stdout)
 
 1305        return_code, stdout, stderr = 
run_ns3(mpi_command)
 
 1306        self.assertEqual(return_code, 0)
 
 1307        if os.getenv(
"USER", 
"") == 
"root":
 
 1308            if shutil.which(
"ompi_info"):
 
 1309                self.assertIn(
"mpiexec --allow-run-as-root --oversubscribe -np 2 %s" % sample_simulator_path, stdout)
 
 1311                self.assertIn(
"mpiexec --allow-run-as-root -np 2 %s" % sample_simulator_path, stdout)
 
 1313            self.assertIn(
"mpiexec -np 2 %s" % sample_simulator_path, stdout)
 
 1316        return_code, stdout, stderr = 
run_ns3(non_mpi_command)
 
 1317        self.assertEqual(return_code, 0)
 
 1318        self.assertIn(
"echo %s" % sample_simulator_path, stdout)
 
 1321        return_code, stdout, stderr = 
run_ns3(non_mpi_command)
 
 1322        self.assertEqual(return_code, 0)
 
 1323        self.assertIn(
"echo %s" % sample_simulator_path, stdout)
 
 1325        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --disable-examples")
 
 1326        self.assertEqual(return_code, 0)
 
 1330        Test if CMake 
and ns3 fail 
in the expected ways when:
 
 1331        - examples 
from modules 
or general examples fail 
if they depend on a
 
 1332        library 
with a name shorter than 4 characters 
or are disabled when
 
 1333        a library 
is nonexistent
 
 1334        - a module library passes the configuration but fails to build due to
 
 1338        os.makedirs("contrib/borked", exist_ok=
True)
 
 1339        os.makedirs(
"contrib/borked/examples", exist_ok=
True)
 
 1342        with open(
"contrib/borked/examples/CMakeLists.txt", 
"w") 
as f:
 
 1344        for invalid_or_nonexistent_library 
in [
"", 
"gsd", 
"lib", 
"libfi", 
"calibre"]:
 
 1345            with open(
"contrib/borked/CMakeLists.txt", 
"w") 
as f:
 
 1349                            SOURCE_FILES ${PROJECT_SOURCE_DIR}/build-support/empty.cc 
 1350                            LIBRARIES_TO_LINK ${libcore} %s 
 1352                        """ % invalid_or_nonexistent_library) 
 1354            return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --enable-examples")
 
 1355            if invalid_or_nonexistent_library 
in [
"", 
"gsd", 
"libfi", 
"calibre"]:
 
 1356                self.assertEqual(return_code, 0)
 
 1357            elif invalid_or_nonexistent_library 
in [
"lib"]:
 
 1358                self.assertEqual(return_code, 1)
 
 1359                self.assertIn(
"Invalid library name: %s" % invalid_or_nonexistent_library, stderr)
 
 1363            return_code, stdout, stderr = 
run_ns3(
"build borked")
 
 1364            if invalid_or_nonexistent_library 
in [
""]:
 
 1365                self.assertEqual(return_code, 0)
 
 1366            elif invalid_or_nonexistent_library 
in [
"lib"]:
 
 1367                self.assertEqual(return_code, 2)  
 
 1368                self.assertIn(
"Invalid library name: %s" % invalid_or_nonexistent_library, stderr)
 
 1369            elif invalid_or_nonexistent_library 
in [
"gsd", 
"libfi", 
"calibre"]:
 
 1370                self.assertEqual(return_code, 2)  
 
 1373                if "lld" in stdout + stderr:
 
 1374                    self.assertIn(
"unable to find library -l%s" % invalid_or_nonexistent_library, stderr)
 
 1376                    self.assertIn(
"cannot find -l%s" % invalid_or_nonexistent_library, stderr)
 
 1384        with open(
"contrib/borked/CMakeLists.txt", 
"w") 
as f:
 
 1388                        SOURCE_FILES ${PROJECT_SOURCE_DIR}/build-support/empty.cc 
 1389                        LIBRARIES_TO_LINK ${libcore} 
 1392        for invalid_or_nonexistent_library 
in [
"", 
"gsd", 
"lib", 
"libfi", 
"calibre"]:
 
 1393            with open(
"contrib/borked/examples/CMakeLists.txt", 
"w") 
as f:
 
 1397                            SOURCE_FILES ${PROJECT_SOURCE_DIR}/build-support/empty-main.cc 
 1398                            LIBRARIES_TO_LINK ${libborked} %s 
 1400                        """ % invalid_or_nonexistent_library) 
 1402            return_code, stdout, stderr = run_ns3("configure -G \"{generator}\"")
 
 1403            if invalid_or_nonexistent_library 
in [
"", 
"gsd", 
"libfi", 
"calibre"]:
 
 1404                self.assertEqual(return_code, 0)  
 
 1405            elif invalid_or_nonexistent_library 
in [
"lib"]:
 
 1406                self.assertEqual(return_code, 1)  
 
 1407                self.assertIn(
"Invalid library name: %s" % invalid_or_nonexistent_library, stderr)
 
 1411            return_code, stdout, stderr = 
run_ns3(
"build borked-example")
 
 1412            if invalid_or_nonexistent_library 
in [
""]:
 
 1413                self.assertEqual(return_code, 0)  
 
 1414            elif invalid_or_nonexistent_library 
in [
"libf"]:
 
 1415                self.assertEqual(return_code, 2)  
 
 1416                self.assertIn(
"Invalid library name: %s" % invalid_or_nonexistent_library, stderr)
 
 1417            elif invalid_or_nonexistent_library 
in [
"gsd", 
"libfi", 
"calibre"]:
 
 1418                self.assertEqual(return_code, 1)  
 
 1419                self.assertIn(
"Target to build does not exist: borked-example", stdout)
 
 1423        shutil.rmtree(
"contrib/borked", ignore_errors=
True)
 
 1427        Test if CMake can properly handle modules containing 
"lib",
 
 1428        which 
is used internally 
as a prefix 
for module libraries
 
 1432        os.makedirs("contrib/calibre", exist_ok=
True)
 
 1433        os.makedirs(
"contrib/calibre/examples", exist_ok=
True)
 
 1436        with open(
"contrib/calibre/examples/CMakeLists.txt", 
"w") 
as f:
 
 1438        with open(
"contrib/calibre/CMakeLists.txt", 
"w") 
as f:
 
 1442                    SOURCE_FILES ${PROJECT_SOURCE_DIR}/build-support/empty.cc 
 1443                    LIBRARIES_TO_LINK ${libcore} 
 1447        return_code, stdout, stderr = run_ns3("configure -G \"{generator}\"")
 
 1450        self.assertEqual(return_code, 0)
 
 1453        self.assertIn(
"calibre", stdout)
 
 1457        self.assertNotIn(
"care", stdout)
 
 1458        self.assertTrue(os.path.exists(os.path.join(ns3_path, 
"cmake-cache", 
"pkgconfig", 
"ns3-calibre.pc")))
 
 1461        return_code, stdout, stderr = 
run_ns3(
"build calibre")
 
 1462        self.assertEqual(return_code, 0)
 
 1465        shutil.rmtree(
"contrib/calibre", ignore_errors=
True)
 
 1469        Test if CMake performance tracing works 
and produces the
 
 1470        cmake_performance_trace.log file
 
 1473        return_code, stdout, stderr = run_ns3("configure --trace-performance")
 
 1474        self.assertEqual(return_code, 0)
 
 1476            self.assertIn(
"--profiling-format=google-trace --profiling-output=", stdout)
 
 1478            self.assertIn(
"--profiling-format=google-trace --profiling-output=../cmake_performance_trace.log", stdout)
 
 1479        self.assertTrue(os.path.exists(os.path.join(ns3_path, 
"cmake_performance_trace.log")))
 
 1483        Check if ENABLE_BUILD_VERSION 
and version.cache are working
 
 1491            container.execute(
"apt-get update")
 
 1492            container.execute(
"apt-get install -y python3 ninja-build cmake g++")
 
 1495            container.execute(
"./ns3 clean")
 
 1498            version_cache_file = os.path.join(ns3_path, 
"src/core/model/version.cache")
 
 1501            if os.path.exists(version_cache_file):
 
 1502                os.remove(version_cache_file)
 
 1506                container.execute(
"./ns3 configure -G Ninja --enable-build-version")
 
 1507            except DockerException:
 
 1509            self.assertFalse(os.path.exists(os.path.join(ns3_path, 
"cmake-cache", 
"build.ninja")))
 
 1512            version_cache_contents = (
"CLOSEST_TAG = '\"ns-3.0.0\"'\n" 
 1513                                      "VERSION_COMMIT_HASH = '\"0000000000\"'\n" 
 1514                                      "VERSION_DIRTY_FLAG = '0'\n" 
 1515                                      "VERSION_MAJOR = '3'\n" 
 1516                                      "VERSION_MINOR = '0'\n" 
 1517                                      "VERSION_PATCH = '0'\n" 
 1518                                      "VERSION_RELEASE_CANDIDATE = '\"\"'\n" 
 1519                                      "VERSION_TAG = '\"ns-3.0.0\"'\n" 
 1520                                      "VERSION_TAG_DISTANCE = '0'\n" 
 1521                                      "VERSION_BUILD_PROFILE = 'debug'\n" 
 1523            with open(version_cache_file, 
"w") 
as version:
 
 1524                version.write(version_cache_contents)
 
 1527            container.execute(
"./ns3 clean")
 
 1528            container.execute(
"./ns3 configure -G Ninja --enable-build-version")
 
 1529            container.execute(
"./ns3 build core")
 
 1530            self.assertTrue(os.path.exists(os.path.join(ns3_path, 
"cmake-cache", 
"build.ninja")))
 
 1533            with open(version_cache_file, 
"r") 
as version:
 
 1534                self.assertEqual(version.read(), version_cache_contents)
 
 1539            os.rename(os.path.join(ns3_path, 
".git"), os.path.join(ns3_path, 
"temp_git"))
 
 1541                container.execute(
"apt-get install -y git")
 
 1542                container.execute(
"./ns3 clean")
 
 1543                container.execute(
"./ns3 configure -G Ninja --enable-build-version")
 
 1544                container.execute(
"./ns3 build core")
 
 1545            except DockerException:
 
 1547            os.rename(os.path.join(ns3_path, 
"temp_git"), os.path.join(ns3_path, 
".git"))
 
 1548            self.assertTrue(os.path.exists(os.path.join(ns3_path, 
"cmake-cache", 
"build.ninja")))
 
 1551            container.execute(
"./ns3 clean")
 
 1552            container.execute(
"./ns3 configure -G Ninja --enable-build-version")
 
 1553            container.execute(
"./ns3 build core")
 
 1554            self.assertTrue(os.path.exists(os.path.join(ns3_path, 
"cmake-cache", 
"build.ninja")))
 
 1555            with open(version_cache_file, 
"r") 
as version:
 
 1556                self.assertNotEqual(version.read(), version_cache_contents)
 
 1559            if os.path.exists(version_cache_file):
 
 1560                os.remove(version_cache_file)
 
 1564        Test filtering in examples 
and tests 
from specific modules
 
 1568        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --enable-examples --enable-tests")
 
 1574        return_code, stdout, stderr = 
run_ns3(
 
 1575            "configure -G \"{generator}\" --filter-module-examples-and-tests='core;network'")
 
 1582        self.assertEqual(len(modules_after_filtering), len(modules_before_filtering))
 
 1584        self.assertLess(len(programs_after_filtering), len(programs_before_filtering))
 
 1587        return_code, stdout, stderr = 
run_ns3(
 
 1588            "configure -G \"{generator}\" --filter-module-examples-and-tests='core'")
 
 1597        return_code, stdout, stderr = 
run_ns3(
 
 1598            "configure -G \"{generator}\" --disable-examples --disable-tests --filter-module-examples-and-tests=''")
 
 1607        Check if fast linkers LLD 
and Mold are correctly found 
and configured
 
 1614            container.execute(
"apt-get update")
 
 1615            container.execute(
"apt-get install -y python3 ninja-build cmake g++ lld")
 
 1618            container.execute(
"./ns3 configure -G Ninja")
 
 1621            self.assertTrue(os.path.exists(os.path.join(ns3_path, 
"cmake-cache", 
"build.ninja")))
 
 1622            with open(os.path.join(ns3_path, 
"cmake-cache", 
"build.ninja"), 
"r") 
as f:
 
 1623                self.assertIn(
"-fuse-ld=lld", f.read())
 
 1627                container.execute(
"./ns3 build core")
 
 1628            except DockerException:
 
 1629                self.assertTrue(
False, 
"Build with lld failed")
 
 1632            if not os.path.exists(
"./mold-1.4.2-x86_64-linux.tar.gz"):
 
 1634                    "wget https://github.com/rui314/mold/releases/download/v1.4.2/mold-1.4.2-x86_64-linux.tar.gz")
 
 1635            container.execute(
"tar xzfC mold-1.4.2-x86_64-linux.tar.gz /usr/local --strip-components=1")
 
 1639            container.execute(
"./ns3 configure -G Ninja")
 
 1642            self.assertTrue(os.path.exists(os.path.join(ns3_path, 
"cmake-cache", 
"build.ninja")))
 
 1643            with open(os.path.join(ns3_path, 
"cmake-cache", 
"build.ninja"), 
"r") 
as f:
 
 1644                self.assertIn(
"-fuse-ld=mold", f.read())
 
 1648                container.execute(
"./ns3 build core")
 
 1649            except DockerException:
 
 1650                self.assertTrue(
False, 
"Build with mold failed")
 
 1653            os.remove(
"./mold-1.4.2-x86_64-linux.tar.gz")
 
 1656            container.execute(
"./ns3 configure -G Ninja -- -DNS3_FAST_LINKERS=OFF")
 
 1659            self.assertTrue(os.path.exists(os.path.join(ns3_path, 
"cmake-cache", 
"build.ninja")))
 
 1660            with open(os.path.join(ns3_path, 
"cmake-cache", 
"build.ninja"), 
"r") 
as f:
 
 1661                self.assertNotIn(
"-fuse-ld=mold", f.read())
 
 1665        Check if NS3_CLANG_TIMETRACE feature 
is working
 
 1666        Clang
's -ftime-trace plus ClangAnalyzer report 
 1672            container.execute(
"apt-get update")
 
 1673            container.execute(
"apt-get install -y python3 ninja-build cmake clang-10")
 
 1678                    "./ns3 configure -G Ninja --enable-modules=core --enable-examples --enable-tests -- -DCMAKE_CXX_COMPILER=/usr/bin/clang++-10 -DNS3_CLANG_TIMETRACE=ON")
 
 1679            except DockerException 
as e:
 
 1680                self.assertIn(
"could not find git for clone of ClangBuildAnalyzer", e.stderr)
 
 1682            container.execute(
"apt-get install -y git")
 
 1687                    "./ns3 configure -G Ninja --enable-modules=core --enable-examples --enable-tests -- -DCMAKE_CXX_COMPILER=/usr/bin/clang++-10 -DNS3_CLANG_TIMETRACE=ON")
 
 1688            except DockerException 
as e:
 
 1689                self.assertIn(
"could not find git for clone of ClangBuildAnalyzer", e.stderr)
 
 1692            time_trace_report_path = os.path.join(ns3_path, 
"ClangBuildAnalyzerReport.txt")
 
 1693            if os.path.exists(time_trace_report_path):
 
 1694                os.remove(time_trace_report_path)
 
 1698                container.execute(
"./ns3 build timeTraceReport")
 
 1699            except DockerException 
as e:
 
 1700                self.assertTrue(
False, 
"Failed to build the ClangAnalyzer's time trace report")
 
 1703            self.assertTrue(os.path.exists(time_trace_report_path))
 
 1707            container.execute(
"apt-get install -y g++")
 
 1708            container.execute(
"apt-get remove -y clang-10")
 
 1712                    "./ns3 configure -G Ninja --enable-modules=core --enable-examples --enable-tests -- -DNS3_CLANG_TIMETRACE=ON")
 
 1713                self.assertTrue(
False, 
"ClangTimeTrace requires Clang, but GCC just passed the checks too")
 
 1714            except DockerException 
as e:
 
 1715                self.assertIn(
"TimeTrace is a Clang feature", e.stderr)
 
 1719        Check if NS3_NINJA_TRACE feature 
is working
 
 1720        Ninja
's .ninja_log conversion to about://tracing 
 1721        json format conversion with Ninjatracing
 
 1727            container.execute(
"apt-get update")
 
 1728            container.execute(
"apt-get install -y python3 cmake clang-10")
 
 1733                    "./ns3 configure --enable-modules=core --enable-ninja-tracing -- -DCMAKE_CXX_COMPILER=/usr/bin/clang++-10")
 
 1734            except DockerException 
as e:
 
 1735                self.assertIn(
"Ninjatracing requires the Ninja generator", e.stderr)
 
 1740            container.execute(
"apt-get install -y ninja-build")
 
 1744                    "./ns3 configure -G Ninja --enable-modules=core --enable-ninja-tracing -- -DCMAKE_CXX_COMPILER=/usr/bin/clang++-10")
 
 1745            except DockerException 
as e:
 
 1746                self.assertIn(
"could not find git for clone of NinjaTracing", e.stderr)
 
 1748            container.execute(
"apt-get install -y git")
 
 1752                    "./ns3 configure -G Ninja --enable-modules=core --enable-ninja-tracing -- -DCMAKE_CXX_COMPILER=/usr/bin/clang++-10")
 
 1753            except DockerException 
as e:
 
 1754                self.assertTrue(
False, 
"Failed to configure with Ninjatracing")
 
 1757            ninja_trace_path = os.path.join(ns3_path, 
"ninja_performance_trace.json")
 
 1758            if os.path.exists(ninja_trace_path):
 
 1759                os.remove(ninja_trace_path)
 
 1762            container.execute(
"./ns3 build core")
 
 1766                container.execute(
"./ns3 build ninjaTrace")
 
 1767            except DockerException 
as e:
 
 1768                self.assertTrue(
False, 
"Failed to run Ninjatracing's tool to build the trace")
 
 1771            self.assertTrue(os.path.exists(ninja_trace_path))
 
 1772            trace_size = os.stat(ninja_trace_path).st_size
 
 1773            os.remove(ninja_trace_path)
 
 1780                    "./ns3 configure -G Ninja --enable-modules=core --enable-ninja-tracing -- -DCMAKE_CXX_COMPILER=/usr/bin/clang++-10 -DNS3_CLANG_TIMETRACE=ON")
 
 1781            except DockerException 
as e:
 
 1782                self.assertTrue(
False, 
"Failed to configure Ninjatracing with Clang's TimeTrace")
 
 1785            container.execute(
"./ns3 build core")
 
 1789                container.execute(
"./ns3 build ninjaTrace")
 
 1790            except DockerException 
as e:
 
 1791                self.assertTrue(
False, 
"Failed to run Ninjatracing's tool to build the trace")
 
 1793            self.assertTrue(os.path.exists(ninja_trace_path))
 
 1794            timetrace_size = os.stat(ninja_trace_path).st_size
 
 1795            os.remove(ninja_trace_path)
 
 1798            self.assertGreater(timetrace_size, trace_size)
 
 1802        Check if precompiled headers are being enabled correctly.
 
 1811            container.execute(
"apt-get update")
 
 1812            container.execute(
"apt-get install -y python3 cmake ccache clang-10")
 
 1814                container.execute(
"./ns3 configure -- -DCMAKE_CXX_COMPILER=/usr/bin/clang++-10")
 
 1815            except DockerException 
as e:
 
 1816                self.assertIn(
"does not support precompiled headers", e.stderr)
 
 1823            container.execute(
"apt-get update")
 
 1824            container.execute(
"apt-get install -y python3 cmake ccache g++")
 
 1826                container.execute(
"./ns3 configure")
 
 1827            except DockerException 
as e:
 
 1828                self.assertIn(
"incompatible with ccache", e.stderr)
 
 1835            container.execute(
"apt-get update")
 
 1836            container.execute(
"apt-get install -y python3 cmake ccache g++")
 
 1838                container.execute(
"./ns3 configure")
 
 1839            except DockerException 
as e:
 
 1840                self.assertTrue(
False, 
"Precompiled headers should have been enabled")
 
 1845    Tests ns3 regarding building the project 
 1850        Reuse cleaning/release configuration from NS3BaseTestCase 
if flag 
is cleaned
 
 1859        Try building the core library 
 1862        return_code, stdout, stderr = run_ns3("build core")
 
 1863        self.assertEqual(return_code, 0)
 
 1864        self.assertIn(
"Built target libcore", stdout)
 
 1868        Try building core-test library without tests enabled 
 1872        return_code, stdout, stderr = 
run_ns3(
"build core-test")
 
 1873        self.assertEqual(return_code, 1)
 
 1874        self.assertIn(
"Target to build does not exist: core-test", stdout)
 
 1878        Try building the project: 
 1881        return_code, stdout, stderr = run_ns3("build")
 
 1882        self.assertEqual(return_code, 0)
 
 1883        self.assertIn(
"Built target", stdout)
 
 1885            self.assertTrue(os.path.exists(program), program)
 
 1886        self.assertIn(cmake_build_project_command, stdout)
 
 1890        Try hiding task lines 
 1893        return_code, stdout, stderr = run_ns3("--quiet build")
 
 1894        self.assertEqual(return_code, 0)
 
 1895        self.assertIn(cmake_build_project_command, stdout)
 
 1899        Try removing an essential file to break the build
 
 1903        attribute_cc_path = os.sep.join([ns3_path, 
"src", 
"core", 
"model", 
"attribute.cc"])
 
 1904        attribute_cc_bak_path = attribute_cc_path + 
".bak" 
 1905        shutil.move(attribute_cc_path, attribute_cc_bak_path)
 
 1908        return_code, stdout, stderr = 
run_ns3(
"build")
 
 1909        self.assertNotEqual(return_code, 0)
 
 1912        shutil.move(attribute_cc_bak_path, attribute_cc_path)
 
 1915        return_code, stdout, stderr = 
run_ns3(
"build")
 
 1916        self.assertEqual(return_code, 0)
 
 1920        Test if changing the version file affects the library names
 
 1926        version_file = os.sep.join([ns3_path, 
"VERSION"])
 
 1927        with open(version_file, 
"w") 
as f:
 
 1931        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\"")
 
 1935        return_code, stdout, stderr = 
run_ns3(
"build")
 
 1936        self.assertEqual(return_code, 0)
 
 1937        self.assertIn(
"Built target", stdout)
 
 1943        for program 
in new_programs:
 
 1944            self.assertTrue(os.path.exists(program))
 
 1952        self.assertEqual(len(new_libraries), len(self.
ns3_libraries))
 
 1953        for library 
in new_libraries:
 
 1954            self.assertNotIn(
"libns3-dev", library)
 
 1955            self.assertIn(
"libns3-00", library)
 
 1956            self.assertTrue(os.path.exists(library))
 
 1959        with open(version_file, 
"w") 
as f:
 
 1964        Try setting a different output directory and if everything 
is 
 1965        in the right place 
and still working correctly
 
 1970        return_code, stdout, stderr = 
run_ns3(
"build")
 
 1971        self.assertEqual(return_code, 0)
 
 1986        absolute_path = os.sep.join([ns3_path, 
"build", 
"release"])
 
 1987        relative_path = os.sep.join([
"build", 
"release"])
 
 1988        for different_out_dir 
in [absolute_path, relative_path]:
 
 1989            return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --out=%s" % different_out_dir)
 
 1991            self.assertIn(
"Build directory               : %s" % absolute_path.replace(os.sep, 
'/'), stdout)
 
 1999            for program 
in new_programs:
 
 2000                self.assertTrue(os.path.exists(program))
 
 2005            self.assertEqual(len(new_libraries), len(self.
ns3_libraries))
 
 2006            for library 
in new_libraries:
 
 2007                self.assertTrue(os.path.exists(library))
 
 2010            shutil.rmtree(absolute_path)
 
 2013        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --out=''")
 
 2015        self.assertIn(
"Build directory               : %s" % usual_outdir.replace(os.sep, 
'/'), stdout)
 
 2023        for program 
in new_programs:
 
 2024            self.assertTrue(os.path.exists(program))
 
 2029        for library 
in libraries:
 
 2030            self.assertTrue(os.path.exists(library))
 
 2034        Tries setting a ns3 version, then installing it. 
 2035        After that, tries searching for ns-3 
with CMake
's find_package(ns3). 
 2036        Finally, tries using core library in a 3rd-party project
 
 2041        for library 
in libraries:
 
 2045        version_file = os.sep.join([ns3_path, 
"VERSION"])
 
 2046        with open(version_file, 
"w") 
as f:
 
 2050        install_prefix = os.sep.join([ns3_path, 
"build", 
"install"])
 
 2051        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --prefix=%s" % install_prefix)
 
 2063        lib64 = os.path.exists(os.sep.join([install_prefix, 
"lib64"]))
 
 2064        installed_libdir = os.sep.join([install_prefix, (
"lib64" if lib64 
else "lib")])
 
 2068        installed_libraries_list = 
";".join(installed_libraries)
 
 2069        for library 
in libraries:
 
 2070            library_name = os.path.basename(library)
 
 2071            self.assertIn(library_name, installed_libraries_list)
 
 2075        missing_headers = 
list(set([os.path.basename(x) 
for x 
in headers])
 
 2076                               - (set([os.path.basename(x) 
for x 
in installed_headers]))
 
 2078        self.assertEqual(len(missing_headers), 0)
 
 2081        test_main_file = os.sep.join([install_prefix, 
"main.cpp"])
 
 2082        with open(test_main_file, 
"w") 
as f:
 
 2085            using namespace ns3;
 
 2088                Simulator::Stop (Seconds (1.0));
 
 2090                Simulator::Destroy ();
 
 2098        for version 
in [
"", 
"3.01", 
"3.00"]:
 
 2099            ns3_import_methods = []
 
 2102            cmake_find_package_import = 
""" 
 2103                                  list(APPEND CMAKE_PREFIX_PATH ./{lib}/cmake/ns3) 
 2104                                  find_package(ns3 {version} COMPONENTS libcore) 
 2105                                  target_link_libraries(test PRIVATE ns3::libcore) 
 2106                                  """.format(lib=("lib64" if lib64 else "lib"), version=version) 
 2107            ns3_import_methods.append(cmake_find_package_import) 
 2110            pkgconfig_import = 
""" 
 2111                               list(APPEND CMAKE_PREFIX_PATH ./) 
 2112                               include(FindPkgConfig) 
 2113                               pkg_check_modules(ns3 REQUIRED IMPORTED_TARGET ns3-core{version}) 
 2114                               target_link_libraries(test PUBLIC PkgConfig::ns3) 
 2115                               """.format(lib=("lib64" if lib64 else "lib"), 
 2116                                          version="=" + version 
if version 
else "" 
 2118            if shutil.which(
"pkg-config"):
 
 2119                ns3_import_methods.append(pkgconfig_import)
 
 2122            for import_method 
in ns3_import_methods:
 
 2123                test_cmake_project = 
""" 
 2124                                     cmake_minimum_required(VERSION 3.10..3.10) 
 2125                                     project(ns3_consumer CXX) 
 2126                                     set(CMAKE_CXX_STANDARD 17) 
 2127                                     set(CMAKE_CXX_STANDARD_REQUIRED ON) 
 2128                                     add_executable(test main.cpp) 
 2131                test_cmake_project_file = os.sep.join([install_prefix, "CMakeLists.txt"])
 
 2132                with open(test_cmake_project_file, 
"w") 
as f:
 
 2133                    f.write(test_cmake_project)
 
 2136                cmake = shutil.which(
"cmake")
 
 2139                    "-DCMAKE_BUILD_TYPE=debug -G\"{generator}\" .".format(generator=platform_makefiles),
 
 2143                if version == 
"3.00":
 
 2144                    self.assertEqual(return_code, 1)
 
 2145                    if import_method == cmake_find_package_import:
 
 2146                        self.assertIn(
'Could not find a configuration file for package "ns3" that is compatible',
 
 2147                                      stderr.replace(
"\n", 
""))
 
 2148                    elif import_method == pkgconfig_import:
 
 2149                        self.assertIn(
'A required package was not found',
 
 2150                                      stderr.replace(
"\n", 
""))
 
 2152                        raise Exception(
"Unknown import type")
 
 2154                    self.assertEqual(return_code, 0)
 
 2155                    self.assertIn(
"Build files", stdout)
 
 2158                return_code, stdout, stderr = 
run_program(
"cmake", 
"--build .", cwd=install_prefix)
 
 2160                if version == 
"3.00":
 
 2161                    self.assertEqual(return_code, 2)
 
 2162                    self.assertGreater(len(stderr), 0)
 
 2164                    self.assertEqual(return_code, 0)
 
 2165                    self.assertIn(
"Built target", stdout)
 
 2169                        test_program = os.path.join(install_prefix, 
"test.exe")
 
 2170                        env_sep = 
";" if ";" in os.environ[
"PATH"] 
else ":" 
 2171                        env = {
"PATH": env_sep.join([os.environ[
"PATH"], os.path.join(install_prefix, 
"lib")])}
 
 2173                        test_program = 
"./test" 
 2175                    return_code, stdout, stderr = 
run_program(test_program, 
"", cwd=install_prefix, env=env)
 
 2176                    self.assertEqual(return_code, 0)
 
 2179        return_code, stdout, stderr = 
run_ns3(
"uninstall")
 
 2180        self.assertIn(
"Built target uninstall", stdout)
 
 2183        os.remove(version_file)
 
 2184        with open(version_file, 
"w") 
as f:
 
 2189        Tries to build scratch-simulator and subdir/scratch-simulator-subdir
 
 2193        targets = {
"scratch/scratch-simulator": 
"scratch-simulator",
 
 2194                   "scratch/scratch-simulator.cc": 
"scratch-simulator",
 
 2195                   "scratch-simulator": 
"scratch-simulator",
 
 2196                   "scratch/subdir/scratch-subdir": 
"subdir_scratch-subdir",
 
 2197                   "subdir/scratch-subdir": 
"subdir_scratch-subdir",
 
 2198                   "scratch-subdir": 
"subdir_scratch-subdir",
 
 2200        for (target_to_run, target_cmake) 
in targets.items():
 
 2202            build_line = 
"target scratch_%s" % target_cmake
 
 2203            return_code, stdout, stderr = 
run_ns3(
"build %s" % target_to_run)
 
 2204            self.assertEqual(return_code, 0)
 
 2205            self.assertIn(build_line, stdout)
 
 2208            return_code, stdout, stderr = 
run_ns3(
"run %s --verbose" % target_to_run)
 
 2209            self.assertEqual(return_code, 0)
 
 2210            self.assertIn(build_line, stdout)
 
 2211            stdout = stdout.replace(
"scratch_%s" % target_cmake, 
"")  
 
 2212            self.assertIn(target_to_run.split(
"/")[-1].replace(
".cc", 
""), stdout)
 
 2216        Test if ns3 can alert correctly 
in case a shortcut collision happens
 
 2221        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --enable-examples")
 
 2222        self.assertEqual(return_code, 0)
 
 2225        shutil.copy(
"./examples/tutorial/second.cc", 
"./scratch/second.cc")
 
 2228        return_code, stdout, stderr = 
run_ns3(
"configure -G \"{generator}\" --enable-examples")
 
 2229        self.assertEqual(return_code, 0)
 
 2232        return_code, stdout, stderr = 
run_ns3(
"build second")
 
 2233        self.assertEqual(return_code, 1)
 
 2235            'Build target "second" is ambiguous. Try one of these: "scratch/second", "examples/tutorial/second"',
 
 2236            stdout.replace(os.sep, 
'/')
 
 2240        return_code, stdout, stderr = 
run_ns3(
"build scratch/second")
 
 2241        self.assertEqual(return_code, 0)
 
 2245        return_code, stdout, stderr = 
run_ns3(
"build tutorial/second")
 
 2246        self.assertEqual(return_code, 0)
 
 2250        return_code, stdout, stderr = 
run_ns3(
"run second")
 
 2251        self.assertEqual(return_code, 1)
 
 2253            'Run target "second" is ambiguous. Try one of these: "scratch/second", "examples/tutorial/second"',
 
 2254            stdout.replace(os.sep, 
'/')
 
 2258        return_code, stdout, stderr = 
run_ns3(
"run scratch/second")
 
 2259        self.assertEqual(return_code, 0)
 
 2262        return_code, stdout, stderr = 
run_ns3(
"run tutorial/second")
 
 2263        self.assertEqual(return_code, 0)
 
 2266        os.remove(
"./scratch/second.cc")
 
 2270        Test if we can build a static ns-3 library 
and link it to static programs
 
 2275        return_code, stdout, stderr = 
run_ns3(
 
 2276            "configure -G \"{generator}\" --enable-examples --disable-gtk --enable-static")
 
 2281            self.assertEqual(return_code, 1)
 
 2282            self.assertIn(
"Static builds are unsupported on Windows", stderr)
 
 2285            self.assertEqual(return_code, 0)
 
 2288            return_code, stdout, stderr = 
run_ns3(
'build sample-simulator')
 
 2289            self.assertEqual(return_code, 0)
 
 2290            self.assertIn(
"Built target", stdout)
 
 2296        Test if we can use python bindings
 
 2301        except ModuleNotFoundError:
 
 2302            self.skipTest(
"Cppyy was not found")
 
 2305        return_code, stdout, stderr = 
run_ns3(
 
 2306            "configure -G \"{generator}\" --enable-python-bindings")
 
 2309        self.assertEqual(return_code, 0)
 
 2312        return_code, stdout, stderr = 
run_program(
"test.py", 
"", python=
True)
 
 2313        self.assertEqual(return_code, 0)
 
 2316        return_code, stdout, stderr = 
run_program(
"test.py", 
"-p mixed-wired-wireless", python=
True)
 
 2317        self.assertEqual(return_code, 0)
 
 2320        return_code, stdout, stderr = 
run_program(
"test.py", 
"-p ./examples/wireless/mixed-wired-wireless", python=
True)
 
 2321        self.assertEqual(return_code, 0)
 
 2326    Tests ns3 usage in more realistic scenarios
 
 2331        Reuse cleaning/release configuration from NS3BaseTestCase 
if flag 
is cleaned
 
 2332        Here examples, tests 
and documentation are also enabled.
 
 2339        return_code, stdout, stderr = 
run_ns3(
 
 2340            "configure -d release -G \"{generator}\" --enable-examples --enable-tests")
 
 2344        self.assertTrue(os.path.exists(ns3_lock_filename))
 
 2350        self.assertTrue(os.path.exists(ns3_lock_filename))
 
 2357        Try to build the project 
 2360        return_code, stdout, stderr = run_ns3("build")
 
 2361        self.assertEqual(return_code, 0)
 
 2362        self.assertIn(
"Built target", stdout)
 
 2364            self.assertTrue(os.path.exists(program))
 
 2367            self.assertIn(module.replace(
"ns3-", 
""), 
";".join(libraries))
 
 2368        self.assertIn(cmake_build_project_command, stdout)
 
 2372        Try to build and run test-runner
 
 2375        return_code, stdout, stderr = run_ns3('run "test-runner --list" --verbose')
 
 2376        self.assertEqual(return_code, 0)
 
 2377        self.assertIn(
"Built target test-runner", stdout)
 
 2382        Try to build and run a library
 
 2385        return_code, stdout, stderr = run_ns3("run core")  
 
 2386        self.assertEqual(return_code, 1)
 
 2387        self.assertIn(
"Couldn't find the specified program: core", stderr)
 
 2391        Try to build and run an unknown target
 
 2394        return_code, stdout, stderr = run_ns3("run nonsense")  
 
 2395        self.assertEqual(return_code, 1)
 
 2396        self.assertIn(
"Couldn't find the specified program: nonsense", stderr)
 
 2400        Try to run test-runner without building 
 2403        return_code, stdout, stderr = run_ns3('build test-runner')
 
 2404        self.assertEqual(return_code, 0)
 
 2406        return_code, stdout, stderr = 
run_ns3(
'run "test-runner --list" --no-build --verbose')
 
 2407        self.assertEqual(return_code, 0)
 
 2408        self.assertNotIn(
"Built target test-runner", stdout)
 
 2413        Test ns3 fails to run a library 
 2416        return_code, stdout, stderr = run_ns3("run core --no-build")  
 
 2417        self.assertEqual(return_code, 1)
 
 2418        self.assertIn(
"Couldn't find the specified program: core", stderr)
 
 2422        Test ns3 fails to run an unknown program 
 2425        return_code, stdout, stderr = run_ns3("run nonsense --no-build")  
 
 2426        self.assertEqual(return_code, 1)
 
 2427        self.assertIn(
"Couldn't find the specified program: nonsense", stderr)
 
 2431        Test if scratch simulator 
is executed through gdb 
and lldb
 
 2434        if shutil.which(
"gdb") 
is None:
 
 2435            self.skipTest(
"Missing gdb")
 
 2437        return_code, stdout, stderr = 
run_ns3(
"build scratch-simulator")
 
 2438        self.assertEqual(return_code, 0)
 
 2440        return_code, stdout, stderr = 
run_ns3(
"run scratch-simulator --gdb --verbose --no-build", env={
"gdb_eval": 
"1"})
 
 2441        self.assertEqual(return_code, 0)
 
 2442        self.assertIn(
"scratch-simulator", stdout)
 
 2444            self.assertIn(
"GNU gdb", stdout)
 
 2446            self.assertIn(
"No debugging symbols found", stdout)
 
 2450        Test if scratch simulator 
is executed through valgrind
 
 2453        if shutil.which(
"valgrind") 
is None:
 
 2454            self.skipTest(
"Missing valgrind")
 
 2456        return_code, stdout, stderr = 
run_ns3(
"build scratch-simulator")
 
 2457        self.assertEqual(return_code, 0)
 
 2459        return_code, stdout, stderr = 
run_ns3(
"run scratch-simulator --valgrind --verbose --no-build")
 
 2460        self.assertEqual(return_code, 0)
 
 2461        self.assertIn(
"scratch-simulator", stderr)
 
 2462        self.assertIn(
"Memcheck", stderr)
 
 2466        Test the doxygen target that does trigger a full build 
 2469        if shutil.which(
"doxygen") 
is None:
 
 2470            self.skipTest(
"Missing doxygen")
 
 2472        if shutil.which(
"bash") 
is None:
 
 2473            self.skipTest(
"Missing bash")
 
 2475        doc_folder = os.path.abspath(os.sep.join([
".", 
"doc"]))
 
 2477        doxygen_files = [
"introspected-command-line.h", 
"introspected-doxygen.h"]
 
 2478        for filename 
in doxygen_files:
 
 2479            file_path = os.sep.join([doc_folder, filename])
 
 2480            if os.path.exists(file_path):
 
 2481                os.remove(file_path)
 
 2488        return_code, stdout, stderr = 
run_ns3(
"docs doxygen")
 
 2489        self.assertEqual(return_code, 0)
 
 2491        self.assertIn(
"Built target doxygen", stdout)
 
 2495        Test the doxygen target that doesn't trigger a full build 
 2498        if shutil.which(
"doxygen") 
is None:
 
 2499            self.skipTest(
"Missing doxygen")
 
 2507        return_code, stdout, stderr = 
run_ns3(
"docs doxygen-no-build")
 
 2508        self.assertEqual(return_code, 0)
 
 2510        self.assertIn(
"Built target doxygen-no-build", stdout)
 
 2514        Test every individual target for Sphinx-based documentation
 
 2517        if shutil.which(
"sphinx-build") 
is None:
 
 2518            self.skipTest(
"Missing sphinx")
 
 2520        doc_folder = os.path.abspath(os.sep.join([
".", 
"doc"]))
 
 2523        for target 
in [
"installation", 
"contributing", 
"manual", 
"models", 
"tutorial"]:
 
 2525            doc_build_folder = os.sep.join([doc_folder, target, 
"build"])
 
 2526            doc_temp_folder = os.sep.join([doc_folder, target, 
"source-temp"])
 
 2527            if os.path.exists(doc_build_folder):
 
 2528                shutil.rmtree(doc_build_folder)
 
 2529            if os.path.exists(doc_temp_folder):
 
 2530                shutil.rmtree(doc_temp_folder)
 
 2533            return_code, stdout, stderr = 
run_ns3(
"docs %s" % target)
 
 2534            self.assertEqual(return_code, 0, target)
 
 2536            self.assertIn(
"Built target sphinx_%s" % target, stdout)
 
 2539            doc_build_folder = os.sep.join([doc_folder, target, 
"build"])
 
 2540            self.assertTrue(os.path.exists(doc_build_folder))
 
 2543            for build_type 
in [
"latex", 
"html", 
"singlehtml"]:
 
 2544                self.assertTrue(os.path.exists(os.sep.join([doc_build_folder, build_type])))
 
 2548        Test the documentation target that builds 
 2549        both doxygen and sphinx based documentation
 
 2552        if shutil.which(
"doxygen") 
is None:
 
 2553            self.skipTest(
"Missing doxygen")
 
 2554        if shutil.which(
"sphinx-build") 
is None:
 
 2555            self.skipTest(
"Missing sphinx")
 
 2557        doc_folder = os.path.abspath(os.sep.join([
".", 
"doc"]))
 
 2566        for target 
in [
"manual", 
"models", 
"tutorial"]:
 
 2567            doc_build_folder = os.sep.join([doc_folder, target, 
"build"])
 
 2568            if os.path.exists(doc_build_folder):
 
 2569                shutil.rmtree(doc_build_folder)
 
 2571        return_code, stdout, stderr = 
run_ns3(
"docs all")
 
 2572        self.assertEqual(return_code, 0)
 
 2574        self.assertIn(
"Built target sphinx", stdout)
 
 2576        self.assertIn(
"Built target doxygen", stdout)
 
 2580        Try to set ownership of scratch-simulator from current user to root,
 
 2581        and change execution permissions
 
 2586        sudo_password = os.getenv(
"SUDO_PASSWORD", 
None)
 
 2589        if sudo_password 
is None:
 
 2590            self.skipTest(
"SUDO_PASSWORD environment variable was not specified")
 
 2593        self.assertFalse(enable_sudo 
is True)
 
 2596        return_code, stdout, stderr = 
run_ns3(
'run scratch-simulator')
 
 2597        self.assertEqual(return_code, 0)
 
 2598        self.assertIn(
"Built target scratch_scratch-simulator", stdout)
 
 2600        scratch_simulator_path = 
list(filter(
lambda x: x 
if "scratch-simulator" in x 
else None,
 
 2604        prev_fstat = os.stat(scratch_simulator_path)  
 
 2607        return_code, stdout, stderr = 
run_ns3(
'run scratch-simulator --enable-sudo',
 
 2608                                              env={
"SUDO_PASSWORD": sudo_password})
 
 2609        self.assertEqual(return_code, 0)
 
 2610        self.assertIn(
"Built target scratch_scratch-simulator", stdout)
 
 2612        fstat = os.stat(scratch_simulator_path)
 
 2617        likely_fuse_mount = ((prev_fstat.st_mode & stat.S_ISUID) == (fstat.st_mode & stat.S_ISUID)) 
and \
 
 2618                            prev_fstat.st_uid == 0  
 
 2620        if win32 
or likely_fuse_mount:
 
 2621            self.skipTest(
"Windows or likely a FUSE mount")
 
 2624        self.assertEqual(fstat.st_uid, 0)  
 
 2625        self.assertEqual(fstat.st_mode & stat.S_ISUID, stat.S_ISUID)  
 
 2628        return_code, stdout, stderr = 
run_ns3(
'configure --enable-sudo')
 
 2629        self.assertEqual(return_code, 0)
 
 2633        self.assertTrue(enable_sudo)
 
 2637            if os.path.exists(executable):
 
 2638                os.remove(executable)
 
 2641        return_code, stdout, stderr = 
run_ns3(
'build', env={
"SUDO_PASSWORD": sudo_password})
 
 2642        self.assertEqual(return_code, 0)
 
 2645        self.assertIn(
"chown root", stdout)
 
 2646        self.assertIn(
"chmod u+s", stdout)
 
 2648            self.assertIn(os.path.basename(executable), stdout)
 
 2651        fstat = os.stat(scratch_simulator_path)
 
 2652        self.assertEqual(fstat.st_uid, 0)  
 
 2653        self.assertEqual(fstat.st_mode & stat.S_ISUID, stat.S_ISUID)  
 
 2657        Check if command template 
is working
 
 2662        return_code0, stdout0, stderr0 = 
run_ns3(
'run sample-simulator --command-template')
 
 2663        self.assertEqual(return_code0, 2)
 
 2664        self.assertIn(
"argument --command-template: expected one argument", stderr0)
 
 2666        return_code1, stdout1, stderr1 = 
run_ns3(
'run sample-simulator --command-template=" "')
 
 2667        return_code2, stdout2, stderr2 = 
run_ns3(
'run sample-simulator --command-template " "')
 
 2668        return_code3, stdout3, stderr3 = 
run_ns3(
'run sample-simulator --command-template "echo "')
 
 2669        self.assertEqual((return_code1, return_code2, return_code3), (1, 1, 1))
 
 2670        for stderr 
in [stderr1, stderr2, stderr3]:
 
 2671            self.assertIn(
"not all arguments converted during string formatting", stderr)
 
 2674        return_code4, stdout4, _ = 
run_ns3(
'run sample-simulator --command-template "%s --PrintVersion" --verbose')
 
 2675        return_code5, stdout5, _ = 
run_ns3(
'run sample-simulator --command-template="%s --PrintVersion" --verbose')
 
 2676        self.assertEqual((return_code4, return_code5), (0, 0))
 
 2678        self.assertIn(
"sample-simulator{ext} --PrintVersion".format(ext=ext), stdout4)
 
 2679        self.assertIn(
"sample-simulator{ext} --PrintVersion".format(ext=ext), stdout5)
 
 2683        Check if all flavors of different argument passing to
 
 2684        executable targets are working
 
 2689        return_code0, stdout0, stderr0 = 
run_ns3(
'run "sample-simulator --help" --verbose')
 
 2690        return_code1, stdout1, stderr1 = 
run_ns3(
'run sample-simulator --command-template="%s --help" --verbose')
 
 2691        return_code2, stdout2, stderr2 = 
run_ns3(
'run sample-simulator --verbose -- --help')
 
 2693        self.assertEqual((return_code0, return_code1, return_code2), (0, 0, 0))
 
 2694        self.assertIn(
"sample-simulator{ext} --help".format(ext=ext), stdout0)
 
 2695        self.assertIn(
"sample-simulator{ext} --help".format(ext=ext), stdout1)
 
 2696        self.assertIn(
"sample-simulator{ext} --help".format(ext=ext), stdout2)
 
 2699        return_code0, stdout0, stderr0 = 
run_ns3(
'run "sample-simulator --help" --no-build')
 
 2700        return_code1, stdout1, stderr1 = 
run_ns3(
'run sample-simulator --command-template="%s --help" --no-build')
 
 2701        return_code2, stdout2, stderr2 = 
run_ns3(
'run sample-simulator --no-build -- --help')
 
 2702        self.assertEqual((return_code0, return_code1, return_code2), (0, 0, 0))
 
 2703        self.assertEqual(stdout0, stdout1)
 
 2704        self.assertEqual(stdout1, stdout2)
 
 2705        self.assertEqual(stderr0, stderr1)
 
 2706        self.assertEqual(stderr1, stderr2)
 
 2709        return_code0, stdout0, stderr0 = 
run_ns3(
'run "sample-simulator --PrintGlobals" --verbose')
 
 2710        return_code1, stdout1, stderr1 = 
run_ns3(
'run "sample-simulator --PrintGroups" --verbose')
 
 2711        return_code2, stdout2, stderr2 = 
run_ns3(
'run "sample-simulator --PrintTypeIds" --verbose')
 
 2713        self.assertEqual((return_code0, return_code1, return_code2), (0, 0, 0))
 
 2714        self.assertIn(
"sample-simulator{ext} --PrintGlobals".format(ext=ext), stdout0)
 
 2715        self.assertIn(
"sample-simulator{ext} --PrintGroups".format(ext=ext), stdout1)
 
 2716        self.assertIn(
"sample-simulator{ext} --PrintTypeIds".format(ext=ext), stdout2)
 
 2719        cmd = 
'run "sample-simulator --PrintGlobals" --command-template="%s --PrintGroups" --verbose -- --PrintTypeIds' 
 2720        return_code, stdout, stderr = 
run_ns3(cmd)
 
 2721        self.assertEqual(return_code, 0)
 
 2726        self.assertIn(
"sample-simulator{ext} --PrintGroups --PrintGlobals --PrintTypeIds".format(ext=ext), stdout)
 
 2729        cmd0 = 
'run sample-simulator --command-template="%s " --PrintTypeIds' 
 2730        cmd1 = 
'run sample-simulator --PrintTypeIds' 
 2732        return_code0, stdout0, stderr0 = 
run_ns3(cmd0)
 
 2733        return_code1, stdout1, stderr1 = 
run_ns3(cmd1)
 
 2734        self.assertEqual((return_code0, return_code1), (1, 1))
 
 2735        self.assertIn(
"To forward configuration or runtime options, put them after '--'", stderr0)
 
 2736        self.assertIn(
"To forward configuration or runtime options, put them after '--'", stderr1)
 
 2740        Test if scratch simulator 
is executed through lldb
 
 2743        if shutil.which(
"lldb") 
is None:
 
 2744            self.skipTest(
"Missing lldb")
 
 2746        return_code, stdout, stderr = 
run_ns3(
"run scratch-simulator --lldb --verbose --no-build")
 
 2747        self.assertEqual(return_code, 0)
 
 2748        self.assertIn(
"scratch-simulator", stdout)
 
 2749        self.assertIn(
"(lldb) target create", stdout)
 
 2754    ns-3 tests to control the quality of the repository over time, 
 2755    by checking the state of URLs listed and more
 
 2760        Test if all urls 
in source files are alive
 
 2769            self.skipTest(
"Django URL validators are not available")
 
 2775            urllib3.disable_warnings()
 
 2778            self.skipTest(
"Requests library is not available")
 
 2780        regex = re.compile(
r'((http|https)://[^\ \n\)\"\'\}><\]\;\`\\]*)')  
 
 2783        whitelisted_urls = {
"https://gitlab.com/your-user-name/ns-3-dev",
 
 2784                            "https://www.nsnam.org/release/ns-allinone-3.31.rc1.tar.bz2",
 
 2785                            "https://www.nsnam.org/release/ns-allinone-3.X.rcX.tar.bz2",
 
 2786                            "https://www.nsnam.org/releases/ns-3-x",
 
 2787                            "https://www.nsnam.org/releases/ns-allinone-3.(x-1",
 
 2788                            "https://www.nsnam.org/releases/ns-allinone-3.x.tar.bz2",
 
 2790                            "https://cmake.org/cmake/help/latest/manual/cmake-",
 
 2791                            "http://www.ieeeghn.org/wiki/index.php/First-Hand:Digital_Television:_The_",
 
 2793                            "http://www.lysator.liu.se/~alla/dia/",
 
 2795                            "http://www.ieeeghn.org/wiki/index.php/First-Hand:Digital_Television:_The_Digital_Terrestrial_Television_Broadcasting_(DTTB",
 
 2796                            "http://en.wikipedia.org/wiki/Namespace_(computer_science",
 
 2797                            "http://en.wikipedia.org/wiki/Bonobo_(component_model",
 
 2798                            "http://msdn.microsoft.com/en-us/library/aa365247(v=vs.85",
 
 2800                            "http://www.research.att.com/info/kpv/",
 
 2801                            "http://www.research.att.com/~gsf/",
 
 2805        files_and_urls = set()
 
 2807        for topdir 
in [
"bindings", 
"doc", 
"examples", 
"src", 
"utils"]:
 
 2808            for root, dirs, files 
in os.walk(topdir):
 
 2810                if "build" in root 
or "_static" in root 
or "source-temp" in root 
or 'html' in root:
 
 2814                    if file.endswith(
".svg"):
 
 2816                    filepath = os.path.join(root, file)
 
 2819                        with open(filepath, 
"r") 
as f:
 
 2820                            matches = regex.findall(f.read())
 
 2825                            urls = 
list(map(
lambda x: x[0][:-1] 
if x[0][-1] 
in ".," else x[0], matches))
 
 2826                    except UnicodeDecodeError:
 
 2827                        skipped_files.append(filepath)
 
 2831                    for url 
in set(urls) - unique_urls - whitelisted_urls:
 
 2832                        unique_urls.add(url)
 
 2833                        files_and_urls.add((filepath, url))
 
 2836        from django.core.validators 
import URLValidator  
 
 2837        from django.core.exceptions 
import ValidationError  
 
 2838        validate_url = URLValidator()
 
 2842            'User-Agent': 
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36' 
 2846        def test_file_url(args):
 
 2847            test_filepath, test_url = args
 
 2848            dead_link_msg = 
None 
 2852                validate_url(test_url)
 
 2853            except ValidationError:
 
 2854                dead_link_msg = 
"%s: URL %s, invalid URL" % (test_filepath, test_url)
 
 2855            except Exception 
as e:
 
 2856                self.assertEqual(
False, 
True, msg=e.__str__())
 
 2858            if dead_link_msg 
is not None:
 
 2859                return dead_link_msg
 
 2867                    response = requests.get(test_url, verify=
False, headers=headers, timeout=50)
 
 2870                    if response.status_code 
in [200, 301]:
 
 2871                        dead_link_msg = 
None 
 2876                    if response.status_code 
in [302, 308, 500, 503]:
 
 2877                        if response.reason.lower() 
in [
'found',
 
 2878                                                       'moved temporarily',
 
 2879                                                       'permanent redirect',
 
 2881                                                       'service temporarily unavailable' 
 2883                            dead_link_msg = 
None 
 2887                    dead_link_msg = 
"%s: URL %s: returned code %d" % (test_filepath, test_url, response.status_code)
 
 2888                except requests.exceptions.InvalidURL:
 
 2889                    dead_link_msg = 
"%s: URL %s: invalid URL" % (test_filepath, test_url)
 
 2890                except requests.exceptions.SSLError:
 
 2891                    dead_link_msg = 
"%s: URL %s: SSL error" % (test_filepath, test_url)
 
 2892                except requests.exceptions.TooManyRedirects:
 
 2893                    dead_link_msg = 
"%s: URL %s: too many redirects" % (test_filepath, test_url)
 
 2894                except Exception 
as e:
 
 2896                        error_msg = e.args[0].reason.__str__()
 
 2897                    except AttributeError:
 
 2898                        error_msg = e.args[0]
 
 2899                    dead_link_msg = 
"%s: URL %s: failed with exception: %s" % (test_filepath, test_url, error_msg)
 
 2901            return dead_link_msg
 
 2904        from concurrent.futures 
import ThreadPoolExecutor
 
 2905        with ThreadPoolExecutor(max_workers=100) 
as executor:
 
 2906            dead_links = 
list(executor.map(test_file_url, 
list(files_and_urls)))
 
 2909        dead_links = 
list(sorted(filter(
lambda x: x 
is not None, dead_links)))
 
 2910        self.assertEqual(len(dead_links), 0, msg=
"\n".join([
"Dead links found:", *dead_links]))
 
 2914        Test if all tests can be executed without hitting major memory bugs
 
 2917        return_code, stdout, stderr = run_ns3( 
 2918            "configure --enable-tests --enable-examples --enable-sanitizers -d optimized")
 
 2919        self.assertEqual(return_code, 0)
 
 2921        test_return_code, stdout, stderr = 
run_program(
"test.py", 
"", python=
True)
 
 2922        self.assertEqual(test_return_code, 0)
 
 2926        Check if images 
in the docs are above a brightness threshold.
 
 2927        This should prevent screenshots 
with dark UI themes.
 
 2930        if shutil.which(
"convert") 
is None:
 
 2931            self.skipTest(
"Imagemagick was not found")
 
 2933        from pathlib 
import Path
 
 2936        image_extensions = [
"png", 
"jpg"]
 
 2938        for extension 
in image_extensions:
 
 2939            images += 
list(Path(
"./doc").glob(
"**/figures/*.{ext}".format(ext=extension)))
 
 2940            images += 
list(Path(
"./doc").glob(
"**/figures/**/*.{ext}".format(ext=extension)))
 
 2943        imagemagick_get_image_brightness = \
 
 2944            'convert {image} -colorspace HSI -channel b -separate +channel -scale 1x1 -format "%[fx:100*u]" info:' 
 2948        brightness_threshold = 50
 
 2949        for image 
in images:
 
 2950            brightness = subprocess.check_output(imagemagick_get_image_brightness.format(image=image).split())
 
 2951            brightness = float(brightness.decode().strip(
"'\""))
 
 2952            self.assertGreater(brightness, brightness_threshold,
 
 2953                               "Image darker than threshold (%d < %d): %s" % (brightness, brightness_threshold, image)
 
 2963    test_completeness = { 
 2964        "style": [NS3UnusedSourcesTestCase,
 
 2967        "build": [NS3CommonSettingsTestCase,
 
 2968                  NS3ConfigureBuildProfileTestCase,
 
 2969                  NS3ConfigureTestCase,
 
 2970                  NS3BuildBaseTestCase,
 
 2971                  NS3ExpectedUseTestCase,
 
 2973        "complete": [NS3UnusedSourcesTestCase,
 
 2975                     NS3CommonSettingsTestCase,
 
 2976                     NS3ConfigureBuildProfileTestCase,
 
 2977                     NS3ConfigureTestCase,
 
 2978                     NS3BuildBaseTestCase,
 
 2979                     NS3ExpectedUseTestCase,
 
 2980                     NS3QualityControlTestCase,
 
 2982        "extras": [NS3DependenciesTestCase,
 
 2988    parser = argparse.ArgumentParser(
"Test suite for the ns-3 buildsystem")
 
 2989    parser.add_argument(
"-c", 
"--completeness",
 
 2990                        choices=test_completeness.keys(),
 
 2992    parser.add_argument(
"-tn", 
"--test-name",
 
 2996    parser.add_argument(
"-rtn", 
"--resume-from-test-name",
 
 3000    parser.add_argument(
"-q", 
"--quiet",
 
 3001                        action=
"store_true",
 
 3003    args = parser.parse_args(sys.argv[1:])
 
 3005    loader = unittest.TestLoader()
 
 3006    suite = unittest.TestSuite()
 
 3009    for testCase 
in test_completeness[args.completeness]:
 
 3010        suite.addTests(loader.loadTestsFromTestCase(testCase))
 
 3015        tests = dict(map(
lambda x: (x._testMethodName, x), suite._tests))
 
 3017        tests_to_run = set(map(
lambda x: x 
if args.test_name 
in x 
else None, tests.keys()))
 
 3018        tests_to_remove = set(tests) - set(tests_to_run)
 
 3019        for test_to_remove 
in tests_to_remove:
 
 3020            suite._tests.remove(tests[test_to_remove])
 
 3023    if args.resume_from_test_name:
 
 3025        tests = dict(map(
lambda x: (x._testMethodName, x), suite._tests))
 
 3026        keys = 
list(tests.keys())
 
 3028        while args.resume_from_test_name 
not in keys[0] 
and len(tests) > 0:
 
 3029            suite._tests.remove(tests[keys[0]])
 
 3033    ns3rc_script_bak = ns3rc_script + 
".bak" 
 3034    if os.path.exists(ns3rc_script) 
and not os.path.exists(ns3rc_script_bak):
 
 3035        shutil.move(ns3rc_script, ns3rc_script_bak)
 
 3038    runner = unittest.TextTestRunner(failfast=
True, verbosity=1 
if args.quiet 
else 2)
 
 3042    if os.path.exists(ns3rc_script_bak):
 
 3043        shutil.move(ns3rc_script_bak, ns3rc_script)
 
 3046if __name__ == 
'__main__':
 
Python-on-whales wrapper for Docker-based ns-3 tests.
def __exit__(self, exc_type, exc_val, exc_tb)
Clean up the managed container at the end of the block "with DockerContainerManager() as container".
def __init__(self, unittest.TestCase currentTestCase, str containerName="ubuntu:latest")
Create and start container with containerName in the current ns-3 directory.
def __enter__(self)
Return the managed container when entiring the block "with DockerContainerManager() as container".
container
The Python-on-whales container instance.
Generic test case with basic function inherited by more complex tests.
def config_ok(self, return_code, stdout)
Check if configuration for release mode worked normally.
ns3_executables
ns3_executables holds a list of executables in .lock-ns3 # noqa
def setUp(self)
Clean configuration/build artifacts before testing configuration and build settings After configuring...
ns3_modules
ns3_modules holds a list to the modules enabled stored in .lock-ns3 # noqa
Tests ns3 regarding building the project.
def test_06_TestVersionFile(self)
Test if changing the version file affects the library names.
def test_10_AmbiguityCheck(self)
Test if ns3 can alert correctly in case a shortcut collision happens.
def test_01_BuildExistingTargets(self)
Try building the core library.
def test_12_CppyyBindings(self)
Test if we can use python bindings.
def test_08_InstallationAndUninstallation(self)
Tries setting a ns3 version, then installing it.
def test_11_StaticBuilds(self)
Test if we can build a static ns-3 library and link it to static programs.
def setUp(self)
Reuse cleaning/release configuration from NS3BaseTestCase if flag is cleaned.
def test_02_BuildNonExistingTargets(self)
Try building core-test library without tests enabled.
def test_04_BuildProjectNoTaskLines(self)
Try hiding task lines.
def test_03_BuildProject(self)
Try building the project:
def test_09_Scratches(self)
Tries to build scratch-simulator and subdir/scratch-simulator-subdir.
def test_05_BreakBuild(self)
Try removing an essential file to break the build.
ns3_executables
ns3_executables holds a list of executables in .lock-ns3 # noqa
def test_07_OutputDirectory(self)
Try setting a different output directory and if everything is in the right place and still working co...
ns3_libraries
ns3_libraries holds a list of built module libraries # noqa
ns3 tests related to generic options
def test_05_CheckVersion(self)
Test only passing 'show version' argument to ns3.
def setUp(self)
Clean configuration/build artifacts before common commands.
def test_01_NoOption(self)
Test not passing any arguments to.
def test_02_NoTaskLines(self)
Test only passing –quiet argument to ns3.
def test_03_CheckConfig(self)
Test only passing 'show config' argument to ns3.
def test_04_CheckProfile(self)
Test only passing 'show profile' argument to ns3.
ns-3 tests related to dependencies
def test_01_CheckIfIncludedHeadersMatchLinkedModules(self)
Checks if headers from different modules (src/A, contrib/B) that are included by the current module (...
Tests ns3 usage in more realistic scenarios.
def test_10_DoxygenWithBuild(self)
Test the doxygen target that does trigger a full build.
def test_02_BuildAndRunExistingExecutableTarget(self)
Try to build and run test-runner.
def test_08_RunNoBuildGdb(self)
Test if scratch simulator is executed through gdb and lldb.
def test_05_RunNoBuildExistingExecutableTarget(self)
Try to run test-runner without building.
def test_06_RunNoBuildExistingLibraryTarget(self)
Test ns3 fails to run a library.
def test_03_BuildAndRunExistingLibraryTarget(self)
Try to build and run a library.
def test_01_BuildProject(self)
Try to build the project.
ns3_modules
ns3_modules holds a list to the modules enabled stored in .lock-ns3 # noqa
def test_14_EnableSudo(self)
Try to set ownership of scratch-simulator from current user to root, and change execution permissions...
def test_16_ForwardArgumentsToRunTargets(self)
Check if all flavors of different argument passing to executable targets are working.
def test_17_RunNoBuildLldb(self)
Test if scratch simulator is executed through lldb.
def test_15_CommandTemplate(self)
Check if command template is working.
def test_04_BuildAndRunNonExistingTarget(self)
Try to build and run an unknown target.
def test_07_RunNoBuildNonExistingExecutableTarget(self)
Test ns3 fails to run an unknown program.
ns3_executables
ns3_executables holds a list of executables in .lock-ns3 # noqa
def test_09_RunNoBuildValgrind(self)
Test if scratch simulator is executed through valgrind.
def test_13_Documentation(self)
Test the documentation target that builds both doxygen and sphinx based documentation.
def setUp(self)
Reuse cleaning/release configuration from NS3BaseTestCase if flag is cleaned Here examples,...
def test_11_DoxygenWithoutBuild(self)
Test the doxygen target that doesn't trigger a full build.
def test_12_SphinxDocumentation(self)
Test every individual target for Sphinx-based documentation.
ns-3 tests to control the quality of the repository over time, by checking the state of URLs listed a...
def test_03_CheckImageBrightness(self)
Check if images in the docs are above a brightness threshold.
def test_02_MemoryCheckWithSanitizers(self)
Test if all tests can be executed without hitting major memory bugs.
def test_01_CheckForDeadLinksInSources(self)
Test if all urls in source files are alive.
ns-3 tests to check if the source code, whitespaces and CMake formatting are according to the coding ...
def test_01_CheckCMakeFormat(self)
Check if there is any difference between tracked file after applying cmake-format.
None setUp(self)
Import GitRepo and load the original diff state of the repository before the tests.
ns-3 tests related to checking if source files were left behind, not being used by CMake
dict directory_and_files
dictionary containing directories with .cc source files # noqa
def test_01_UnusedExampleSources(self)
Test if all example source files are being used in their respective CMakeLists.txt.
def setUp(self)
Scan all C++ source files and add them to a list based on their path.
def test_02_UnusedModuleSources(self)
Test if all module source files are being used in their respective CMakeLists.txt.
def test_03_UnusedUtilsSources(self)
Test if all utils source files are being used in their respective CMakeLists.txt.
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
def run_ns3(args, env=None, generator=platform_makefiles)
Runs the ns3 wrapper script with arguments.
def get_programs_list()
Extracts the programs list from .lock-ns3.
def get_libraries_list(lib_outdir=usual_lib_outdir)
Gets a list of built libraries.
def get_test_enabled()
Check if tests are enabled in the .lock-ns3.
def read_lock_entry(entry)
Read interesting entries from the .lock-ns3 file.
def get_headers_list(outdir=usual_outdir)
Gets a list of header files.
def run_program(program, args, python=False, cwd=ns3_path, env=None)
Runs a program with the given arguments and returns a tuple containing (error code,...
def get_enabled_modules()
partial cmake_build_target_command