22 Test suite for the ns3 wrapper script
32 from functools
import partial
35 ns3_path = os.path.dirname(os.path.abspath(os.sep.join([__file__,
"../../"])))
36 ns3_lock_filename = os.path.join(ns3_path,
".lock-ns3_%s_build" % sys.platform)
37 ns3_script = os.sep.join([ns3_path,
"ns3"])
38 ns3rc_script = os.sep.join([ns3_path,
".ns3rc"])
39 usual_outdir = os.sep.join([ns3_path,
"build"])
40 usual_lib_outdir = os.sep.join([usual_outdir,
"lib"])
46 cmake_build_project_command =
"cmake --build . -j".format(ns3_path=ns3_path)
47 cmake_build_target_command = partial(
"cmake --build . -j {jobs} --target {target}".format,
48 jobs=
max(1, os.cpu_count() - 1)
54 Runs the ns3 wrapper script with arguments
55 @param args: string containing arguments that will get split before calling ns3
56 @param env: environment variables dictionary
57 @return tuple containing (error code, stdout and stderr)
60 possible_leftovers = [
"contrib/borked",
"contrib/calibre"]
61 for leftover
in possible_leftovers:
62 if os.path.exists(leftover):
63 shutil.rmtree(leftover, ignore_errors=
True)
64 return run_program(ns3_script, args, python=
True, env=env)
68 def run_program(program, args, python=False, cwd=ns3_path, env=None):
70 Runs a program with the given arguments and returns a tuple containing (error code, stdout and stderr)
71 @param program: program to execute (or python script)
72 @param args: string containing arguments that will get split before calling the program
73 @param python: flag indicating whether the program is a python script
74 @param cwd: the working directory used that will be the root folder for the execution
75 @param env: environment variables dictionary
76 @return tuple containing (error code, stdout and stderr)
79 raise Exception(
"args should be a string")
83 arguments = [sys.executable, program]
88 arguments.extend(re.findall(
"(?:\".*?\"|\S)+", args))
90 for i
in range(len(arguments)):
91 arguments[i] = arguments[i].replace(
"\"",
"")
94 current_env = os.environ.copy()
98 current_env.update(env)
101 ret = subprocess.run(
103 stdin=subprocess.DEVNULL,
104 stdout=subprocess.PIPE,
105 stderr=subprocess.PIPE,
110 return ret.returncode, ret.stdout.decode(sys.stdout.encoding), ret.stderr.decode(sys.stderr.encoding)
115 Extracts the programs list from .lock-ns3
116 @return list of programs.
119 with open(ns3_lock_filename)
as f:
120 exec(f.read(), globals(), values)
121 return values[
"ns3_runnable_programs"]
126 Gets a list of built libraries
127 @param lib_outdir: path containing libraries
128 @return list of built libraries.
130 return glob.glob(lib_outdir +
'/*', recursive=
True)
135 Gets a list of header files
136 @param outdir: path containing headers
137 @return list of headers.
139 return glob.glob(outdir +
'/**/*.h', recursive=
True)
144 Read interesting entries from the .lock-ns3 file
145 @param entry: entry to read from .lock-ns3
146 @return value of the requested entry.
149 with open(ns3_lock_filename)
as f:
150 exec(f.read(), globals(), values)
151 return values.get(entry,
None)
156 Check if tests are enabled in the .lock-ns3
164 Check if tests are enabled in the .lock-ns3
165 @return list of enabled modules (prefixed with 'ns3-').
172 ns-3 tests related to checking if source files were left behind, not being used by CMake
176 directory_and_files = {}
180 Scan all C++ source files and add them to a list based on their path
183 for root, dirs, files
in os.walk(ns3_path):
184 if "gitlab-ci-local" in root:
187 if name.endswith(
".cc"):
188 path = os.path.join(root, name)
189 directory = os.path.dirname(path)
196 Test if all example source files are being used in their respective CMakeLists.txt
199 unused_sources = set()
202 if os.sep +
"examples" not in example_directory:
206 with open(os.path.join(example_directory,
"CMakeLists.txt"),
"r")
as f:
207 cmake_contents = f.read()
212 if os.path.basename(file).replace(
".cc",
"")
not in cmake_contents:
213 unused_sources.add(file)
215 self.assertListEqual([],
list(unused_sources))
219 Test if all module source files are being used in their respective CMakeLists.txt
222 unused_sources = set()
225 is_not_module =
not (
"src" in directory
or "contrib" in directory)
226 is_example = os.sep +
"examples" in directory
227 is_bindings = os.sep +
"bindings" in directory
229 if is_not_module
or is_bindings
or is_example:
234 cmake_path = os.path.join(directory,
"CMakeLists.txt")
235 while not os.path.exists(cmake_path):
236 parent_directory = os.path.dirname(os.path.dirname(cmake_path))
237 cmake_path = os.path.join(parent_directory, os.path.basename(cmake_path))
240 with open(cmake_path,
"r")
as f:
241 cmake_contents = f.read()
245 if os.path.basename(file)
not in cmake_contents:
246 unused_sources.add(file)
249 exceptions = [
"win32-system-wall-clock-ms.cc",
251 for exception
in exceptions:
252 for unused_source
in unused_sources:
253 if os.path.basename(unused_source) == exception:
254 unused_sources.remove(unused_source)
257 self.assertListEqual([],
list(unused_sources))
261 Test if all utils source files are being used in their respective CMakeLists.txt
264 unused_sources = set()
267 is_module =
"src" in directory
or "contrib" in directory
268 if os.sep +
"utils" not in directory
or is_module:
273 cmake_path = os.path.join(directory,
"CMakeLists.txt")
274 while not os.path.exists(cmake_path):
275 parent_directory = os.path.dirname(os.path.dirname(cmake_path))
276 cmake_path = os.path.join(parent_directory, os.path.basename(cmake_path))
279 with open(cmake_path,
"r")
as f:
280 cmake_contents = f.read()
284 if os.path.basename(file)
not in cmake_contents:
285 unused_sources.add(file)
287 self.assertListEqual([],
list(unused_sources))
292 ns3 tests related to generic options
297 Clean configuration/build artifacts before common commands
306 Test not passing any arguments to
309 return_code, stdout, stderr =
run_ns3(
"")
310 self.assertEqual(return_code, 1)
311 self.assertIn(
"You need to configure ns-3 first: try ./ns3 configure", stdout)
315 Test only passing --quiet argument to ns3
318 return_code, stdout, stderr =
run_ns3(
"--quiet")
319 self.assertEqual(return_code, 1)
320 self.assertIn(
"You need to configure ns-3 first: try ./ns3 configure", stdout)
324 Test only passing 'show config' argument to ns3
327 return_code, stdout, stderr =
run_ns3(
"show config")
328 self.assertEqual(return_code, 1)
329 self.assertIn(
"You need to configure ns-3 first: try ./ns3 configure", stdout)
333 Test only passing 'show profile' argument to ns3
336 return_code, stdout, stderr =
run_ns3(
"show profile")
337 self.assertEqual(return_code, 1)
338 self.assertIn(
"You need to configure ns-3 first: try ./ns3 configure", stdout)
342 Test only passing 'show version' argument to ns3
345 return_code, stdout, stderr =
run_ns3(
"show version")
346 self.assertEqual(return_code, 1)
347 self.assertIn(
"You need to configure ns-3 first: try ./ns3 configure", stdout)
352 ns3 tests related to build profiles
357 Clean configuration/build artifacts before testing configuration settings
369 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" -d debug --enable-verbose")
370 self.assertEqual(return_code, 0)
371 self.assertIn(
"Build profile : debug", stdout)
372 self.assertIn(
"Build files have been written to", stdout)
375 return_code, stdout, stderr =
run_ns3(
"build core")
376 self.assertEqual(return_code, 0)
377 self.assertIn(
"Built target libcore", stdout)
380 self.assertGreater(len(libraries), 0)
381 self.assertIn(
"core-debug", libraries[0])
385 Test the release build
388 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" -d release")
389 self.assertEqual(return_code, 0)
390 self.assertIn(
"Build profile : release", stdout)
391 self.assertIn(
"Build files have been written to", stdout)
395 Test the optimized build
398 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" -d optimized --enable-verbose")
399 self.assertEqual(return_code, 0)
400 self.assertIn(
"Build profile : optimized", stdout)
401 self.assertIn(
"Build files have been written to", stdout)
404 return_code, stdout, stderr =
run_ns3(
"build core")
405 self.assertEqual(return_code, 0)
406 self.assertIn(
"Built target libcore", stdout)
409 self.assertGreater(len(libraries), 0)
410 self.assertIn(
"core-optimized", libraries[0])
414 Test a build type with a typo
417 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" -d Optimized")
418 self.assertEqual(return_code, 2)
419 self.assertIn(
"invalid choice: 'Optimized'", stderr)
423 Test a build type with another typo
426 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" -d OPTIMIZED")
427 self.assertEqual(return_code, 2)
428 self.assertIn(
"invalid choice: 'OPTIMIZED'", stderr)
433 Generic test case with basic function inherited by more complex tests.
441 Check if configuration for release mode worked normally
442 @param return_code: return code from CMake
443 @param stdout: output from CMake.
446 self.assertEqual(return_code, 0)
447 self.assertIn(
"Build profile : release", stdout)
448 self.assertIn(
"Build files have been written to", stdout)
452 Clean configuration/build artifacts before testing configuration and build settings
453 After configuring the build as release,
454 check if configuration worked and check expected output files.
459 if os.path.exists(ns3rc_script):
460 os.remove(ns3rc_script)
463 if not NS3BaseTestCase.cleaned_once:
464 NS3BaseTestCase.cleaned_once =
True
466 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" -d release --enable-verbose")
467 self.
config_okconfig_ok(return_code, stdout)
470 self.assertTrue(os.path.exists(ns3_lock_filename))
475 self.assertTrue(os.path.exists(ns3_lock_filename))
482 Test ns3 configuration options
490 Reuse cleaning/release configuration from NS3BaseTestCase if flag is cleaned
493 if not NS3ConfigureTestCase.cleaned_once:
494 NS3ConfigureTestCase.cleaned_once =
True
495 NS3BaseTestCase.cleaned_once =
False
500 Test enabling and disabling examples
503 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --enable-examples")
506 self.
config_okconfig_ok(return_code, stdout)
512 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --disable-examples")
515 self.
config_okconfig_ok(return_code, stdout)
522 Test enabling and disabling tests
526 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --enable-tests")
527 self.
config_okconfig_ok(return_code, stdout)
530 return_code, stdout, stderr =
run_ns3(
"build core-test")
533 self.assertEqual(return_code, 0)
534 self.assertIn(
"Built target libcore-test", stdout)
537 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --disable-tests")
538 self.
config_okconfig_ok(return_code, stdout)
541 return_code, stdout, stderr =
run_ns3(
"build core-test")
544 self.assertEqual(return_code, 1)
545 self.assertIn(
"Target to build does not exist: core-test", stdout)
549 Test enabling specific modules
553 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --enable-modules='network;wifi'")
554 self.
config_okconfig_ok(return_code, stdout)
559 self.assertIn(
"ns3-network", enabled_modules)
560 self.assertIn(
"ns3-wifi", enabled_modules)
563 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --enable-modules='core'")
564 self.
config_okconfig_ok(return_code, stdout)
568 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --enable-modules=''")
569 self.
config_okconfig_ok(return_code, stdout)
576 Test disabling specific modules
580 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --disable-modules='lte;wimax'")
581 self.
config_okconfig_ok(return_code, stdout)
585 self.assertLess(len(enabled_modules), len(self.
ns3_modulesns3_modules))
586 self.assertNotIn(
"ns3-lte", enabled_modules)
587 self.assertNotIn(
"ns3-wimax", enabled_modules)
590 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --disable-modules=''")
591 self.
config_okconfig_ok(return_code, stdout)
598 Test enabling comma-separated (waf-style) examples
602 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --enable-modules='network,wifi'")
603 self.
config_okconfig_ok(return_code, stdout)
608 self.assertIn(
"ns3-network", enabled_modules)
609 self.assertIn(
"ns3-wifi", enabled_modules)
612 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --enable-modules=''")
613 self.
config_okconfig_ok(return_code, stdout)
620 Test disabling comma-separated (waf-style) examples
624 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --disable-modules='lte,mpi'")
625 self.
config_okconfig_ok(return_code, stdout)
629 self.assertLess(len(enabled_modules), len(self.
ns3_modulesns3_modules))
630 self.assertNotIn(
"ns3-lte", enabled_modules)
631 self.assertNotIn(
"ns3-mpi", enabled_modules)
634 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --disable-modules=''")
635 self.
config_okconfig_ok(return_code, stdout)
642 Test loading settings from the ns3rc config file
645 ns3rc_template =
"# ! /usr/bin/env python\
647 # A list of the modules that will be enabled when ns-3 is run.\
648 # Modules that depend on the listed modules will be enabled also.\
650 # All modules can be enabled by choosing 'all_modules'.\
651 modules_enabled = [{modules}]\
653 # Set this equal to true if you want examples to be run.\
654 examples_enabled = {examples}\
656 # Set this equal to true if you want tests to be run.\
657 tests_enabled = {tests}\
661 with open(ns3rc_script,
"w")
as f:
662 f.write(ns3rc_template.format(modules=
"'lte'", examples=
"False", tests=
"True"))
665 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\"")
666 self.
config_okconfig_ok(return_code, stdout)
671 self.assertIn(
"ns3-lte", enabled_modules)
676 with open(ns3rc_script,
"w")
as f:
677 f.write(ns3rc_template.format(modules=
"'wifi'", examples=
"True", tests=
"False"))
680 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\"")
681 self.
config_okconfig_ok(return_code, stdout)
686 self.assertIn(
"ns3-wifi", enabled_modules)
691 with open(ns3rc_script,
"w")
as f:
692 f.write(ns3rc_template.format(modules=
"'core','network'", examples=
"True", tests=
"False"))
695 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\"")
696 self.
config_okconfig_ok(return_code, stdout)
701 self.assertIn(
"ns3-core", enabled_modules)
702 self.assertIn(
"ns3-network", enabled_modules)
708 with open(ns3rc_script,
"w")
as f:
709 f.write(ns3rc_template.format(modules=
"""'core', #comment
713 'network', 'internet','wimax'""", examples=
"True", tests=
"True"))
716 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\"")
717 self.
config_okconfig_ok(return_code, stdout)
722 self.assertIn(
"ns3-core", enabled_modules)
723 self.assertIn(
"ns3-internet", enabled_modules)
724 self.assertIn(
"ns3-lte", enabled_modules)
725 self.assertIn(
"ns3-wimax", enabled_modules)
730 os.remove(ns3rc_script)
733 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\"")
734 self.
config_okconfig_ok(return_code, stdout)
743 Test dry-run (printing commands to be executed instead of running them)
749 for positional_command
in [
"configure",
"build",
"clean"]:
750 return_code, stdout, stderr =
run_ns3(
"--dry-run %s" % positional_command)
751 return_code1, stdout1, stderr1 =
run_ns3(
"%s --dry-run" % positional_command)
753 self.assertEqual(return_code, return_code1)
754 self.assertEqual(stdout, stdout1)
755 self.assertEqual(stderr, stderr1)
760 run_ns3(
"configure -G \"Unix Makefiles\" -d release --enable-verbose")
761 run_ns3(
"build scratch-simulator")
764 return_code0, stdout0, stderr0 =
run_ns3(
"--dry-run run scratch-simulator")
765 return_code1, stdout1, stderr1 =
run_ns3(
"run scratch-simulator")
766 return_code2, stdout2, stderr2 =
run_ns3(
"--dry-run run scratch-simulator --no-build")
767 return_code3, stdout3, stderr3 =
run_ns3(
"run scratch-simulator --no-build")
770 self.assertEqual(sum([return_code0, return_code1, return_code2, return_code3]), 0)
771 self.assertEqual([stderr0, stderr1, stderr2, stderr3], [
""] * 4)
775 if "scratch-simulator" in program
and "subdir" not in program:
776 scratch_path = program
782 self.assertIn(scratch_path, stdout0)
786 self.assertIn(
"Built target", stdout1)
787 self.assertNotIn(scratch_path, stdout1)
790 self.assertIn(
"The following commands would be executed:", stdout2)
791 self.assertIn(scratch_path, stdout2)
794 self.assertNotIn(
"Finished executing the following commands:", stdout3)
795 self.assertNotIn(scratch_path, stdout3)
799 Test if ns3 is propagating back the return code from the executables called with the run command
803 return_code, _, _ =
run_ns3(
"clean")
804 self.assertEqual(return_code, 0)
806 return_code, _, _ =
run_ns3(
"configure -G \"Unix Makefiles\" --enable-examples --enable-tests")
807 self.assertEqual(return_code, 0)
810 return_code, stdout, stderr =
run_ns3(
"build command-line-example test-runner")
811 self.assertEqual(return_code, 0)
814 return_code, stdout, stderr =
run_ns3(
"run \"test-runner --test-name=command-line\" --no-build")
815 self.assertEqual(return_code, 0)
818 return_code, stdout, stderr =
run_ns3(
"run \"test-runner --test-name=command-line\" --no-build",
819 env={
"NS_COMMANDLINE_INTROSPECTION":
".."}
821 self.assertNotEqual(return_code, 0)
824 sigsegv_example = os.path.join(ns3_path,
"scratch",
"sigsegv.cc")
825 with open(sigsegv_example,
"w")
as f:
827 int main (int argc, char *argv[])
829 char *s = "hello world"; *s = 'H';
833 return_code, stdout, stderr =
run_ns3(
"run sigsegv")
834 self.assertEqual(return_code, 245)
835 self.assertIn(
"sigsegv-default' died with <Signals.SIGSEGV: 11>", stdout)
838 abort_example = os.path.join(ns3_path,
"scratch",
"abort.cc")
839 with open(abort_example,
"w")
as f:
841 #include "ns3/core-module.h"
844 int main (int argc, char *argv[])
850 return_code, stdout, stderr =
run_ns3(
"run abort")
851 self.assertEqual(return_code, 250)
852 self.assertIn(
"abort-default' died with <Signals.SIGABRT: 6>", stdout)
854 os.remove(sigsegv_example)
855 os.remove(abort_example)
859 Test passing 'show config' argument to ns3 to get the configuration table
862 return_code, stdout, stderr =
run_ns3(
"show config")
863 self.assertEqual(return_code, 0)
864 self.assertIn(
"Summary of optional ns-3 features", stdout)
868 Test passing 'show profile' argument to ns3 to get the build profile
871 return_code, stdout, stderr =
run_ns3(
"show profile")
872 self.assertEqual(return_code, 0)
873 self.assertIn(
"Build profile: default", stdout)
877 Test passing 'show version' argument to ns3 to get the build version
880 if shutil.which(
"git")
is None:
881 self.skipTest(
"git is not available")
883 return_code, _, _ =
run_ns3(
"configure -G \"Unix Makefiles\" --enable-build-version")
884 self.assertEqual(return_code, 0)
886 return_code, stdout, stderr =
run_ns3(
"show version")
887 self.assertEqual(return_code, 0)
888 self.assertIn(
"ns-3 version:", stdout)
892 Test if CMake target names for scratches and ns3 shortcuts
893 are working correctly
897 test_files = [
"scratch/main.cc",
899 "scratch/subdir1/main.cc",
900 "scratch/subdir2/main.cc"]
903 for path
in test_files:
904 filepath = os.path.join(ns3_path, path)
905 os.makedirs(os.path.dirname(filepath), exist_ok=
True)
906 with open(filepath,
"w")
as f:
908 f.write(
"int main (int argc, char *argv[]){}")
916 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\"")
917 self.assertEqual(return_code, 0)
920 for path
in test_files:
921 path = path.replace(
".cc",
"")
922 return_code1, stdout1, stderr1 =
run_program(
"cmake",
"--build . --target %s"
923 % path.replace(
"/",
"_"),
924 cwd=os.path.join(ns3_path,
"cmake-cache"))
925 return_code2, stdout2, stderr2 =
run_ns3(
"build %s" % path)
927 self.assertEqual(return_code1, 0)
928 self.assertEqual(return_code2, 0)
930 self.assertEqual(return_code1, 2)
931 self.assertEqual(return_code2, 1)
934 for path
in test_files:
935 path = path.replace(
".cc",
"")
936 return_code, stdout, stderr =
run_ns3(
"run %s --no-build" % path)
938 self.assertEqual(return_code, 0)
940 self.assertEqual(return_code, 1)
943 for path
in test_files:
944 source_absolute_path = os.path.join(ns3_path, path)
945 os.remove(source_absolute_path)
948 filename = os.path.basename(path).replace(
".cc",
"")
949 executable_absolute_path = os.path.dirname(os.path.join(ns3_path,
"build", path))
950 executable_name =
list(filter(
lambda x: filename
in x,
951 os.listdir(executable_absolute_path)
955 os.remove(os.path.join(executable_absolute_path, executable_name))
956 if path
not in [
"scratch/main.cc",
"scratch/empty.cc"]:
957 os.rmdir(os.path.dirname(source_absolute_path))
959 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\"")
960 self.assertEqual(return_code, 0)
964 Test if ns3 is inserting additional arguments by MPICH and OpenMPI to run on the CI
968 if shutil.which(
"mpiexec")
is None:
969 self.skipTest(
"Mpi is not available")
972 return_code, stdout, stderr =
run_ns3(
"build sample-simulator")
973 self.assertEqual(return_code, 0)
976 sample_simulator_path =
list(filter(
lambda x:
"sample-simulator" in x, self.
ns3_executablesns3_executables))[0]
978 mpi_command =
"--dry-run run sample-simulator --command-template=\"mpiexec -np 2 %s\""
979 non_mpi_command =
"--dry-run run sample-simulator --command-template=\"echo %s\""
982 return_code, stdout, stderr =
run_ns3(mpi_command)
983 self.assertEqual(return_code, 0)
984 self.assertIn(
"mpiexec -np 2 %s" % sample_simulator_path, stdout)
987 return_code, stdout, stderr =
run_ns3(mpi_command, env={
"MPI_CI":
"1"})
988 self.assertEqual(return_code, 0)
989 if shutil.which(
"ompi_info"):
990 self.assertIn(
"mpiexec --allow-run-as-root --oversubscribe -np 2 %s" % sample_simulator_path, stdout)
992 self.assertIn(
"mpiexec --allow-run-as-root -np 2 %s" % sample_simulator_path, stdout)
995 return_code, stdout, stderr =
run_ns3(non_mpi_command)
996 self.assertEqual(return_code, 0)
997 self.assertIn(
"echo %s" % sample_simulator_path, stdout)
1000 return_code, stdout, stderr =
run_ns3(non_mpi_command, env={
"MPI_CI":
"1"})
1001 self.assertEqual(return_code, 0)
1002 self.assertIn(
"echo %s" % sample_simulator_path, stdout)
1006 Test if CMake and ns3 fail in the expected ways when:
1007 - examples from modules or general examples fail if they depend on a
1008 library with a name shorter than 4 characters or are disabled when
1009 a library is non-existant
1010 - a module library passes the configuration but fails to build due to
1014 os.makedirs(
"contrib/borked", exist_ok=
True)
1015 os.makedirs(
"contrib/borked/examples", exist_ok=
True)
1018 with open(
"contrib/borked/examples/CMakeLists.txt",
"w")
as f:
1020 for invalid_or_non_existant_library
in [
"",
"gsd",
"lib",
"libfi",
"calibre"]:
1021 with open(
"contrib/borked/CMakeLists.txt",
"w")
as f:
1025 SOURCE_FILES ${PROJECT_SOURCE_DIR}/build-support/empty.cc
1026 LIBRARIES_TO_LINK ${libcore} %s
1028 """ % invalid_or_non_existant_library)
1030 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --enable-examples")
1031 if invalid_or_non_existant_library
in [
"",
"gsd",
"libfi",
"calibre"]:
1032 self.assertEqual(return_code, 0)
1033 elif invalid_or_non_existant_library
in [
"lib"]:
1034 self.assertEqual(return_code, 1)
1035 self.assertIn(
"Invalid library name: %s" % invalid_or_non_existant_library, stderr)
1039 return_code, stdout, stderr =
run_ns3(
"build borked")
1040 if invalid_or_non_existant_library
in [
""]:
1041 self.assertEqual(return_code, 0)
1042 elif invalid_or_non_existant_library
in [
"lib"]:
1043 self.assertEqual(return_code, 2)
1044 self.assertIn(
"Invalid library name: %s" % invalid_or_non_existant_library, stderr)
1045 elif invalid_or_non_existant_library
in [
"gsd",
"libfi",
"calibre"]:
1046 self.assertEqual(return_code, 2)
1047 self.assertIn(
"cannot find -l%s" % invalid_or_non_existant_library, stderr)
1055 with open(
"contrib/borked/CMakeLists.txt",
"w")
as f:
1059 SOURCE_FILES ${PROJECT_SOURCE_DIR}/build-support/empty.cc
1060 LIBRARIES_TO_LINK ${libcore}
1063 for invalid_or_non_existant_library
in [
"",
"gsd",
"lib",
"libfi",
"calibre"]:
1064 with open(
"contrib/borked/examples/CMakeLists.txt",
"w")
as f:
1068 SOURCE_FILES ${PROJECT_SOURCE_DIR}/build-support/empty-main.cc
1069 LIBRARIES_TO_LINK ${libborked} %s
1071 """ % invalid_or_non_existant_library)
1073 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\"")
1074 if invalid_or_non_existant_library
in [
"",
"gsd",
"libfi",
"calibre"]:
1075 self.assertEqual(return_code, 0)
1076 elif invalid_or_non_existant_library
in [
"lib"]:
1077 self.assertEqual(return_code, 1)
1078 self.assertIn(
"Invalid library name: %s" % invalid_or_non_existant_library, stderr)
1082 return_code, stdout, stderr =
run_ns3(
"build borked-example")
1083 if invalid_or_non_existant_library
in [
""]:
1084 self.assertEqual(return_code, 0)
1085 elif invalid_or_non_existant_library
in [
"libf"]:
1086 self.assertEqual(return_code, 2)
1087 self.assertIn(
"Invalid library name: %s" % invalid_or_non_existant_library, stderr)
1088 elif invalid_or_non_existant_library
in [
"gsd",
"libfi",
"calibre"]:
1089 self.assertEqual(return_code, 1)
1090 self.assertIn(
"Target to build does not exist: borked-example", stdout)
1094 shutil.rmtree(
"contrib/borked", ignore_errors=
True)
1098 Test if CMake can properly handle modules containing "lib",
1099 which is used internally as a prefix for module libraries
1103 os.makedirs(
"contrib/calibre", exist_ok=
True)
1104 os.makedirs(
"contrib/calibre/examples", exist_ok=
True)
1107 with open(
"contrib/calibre/examples/CMakeLists.txt",
"w")
as f:
1109 with open(
"contrib/calibre/CMakeLists.txt",
"w")
as f:
1113 SOURCE_FILES ${PROJECT_SOURCE_DIR}/build-support/empty.cc
1114 LIBRARIES_TO_LINK ${libcore}
1118 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\"")
1121 self.assertEqual(return_code, 0)
1124 self.assertIn(
"calibre", stdout)
1128 self.assertNotIn(
"care", stdout)
1129 self.assertTrue(os.path.exists(os.path.join(ns3_path,
"cmake-cache",
"pkgconfig",
"ns3-calibre.pc")))
1132 return_code, stdout, stderr =
run_ns3(
"build calibre")
1133 self.assertEqual(return_code, 0)
1136 shutil.rmtree(
"contrib/calibre", ignore_errors=
True)
1140 Test if CMake performance tracing works and produces the
1141 cmake_performance_trace.log file
1144 return_code, stdout, stderr =
run_ns3(
"configure --trace-performance")
1145 self.assertEqual(return_code, 0)
1146 self.assertIn(
"--profiling-format=google-trace --profiling-output=../cmake_performance_trace.log", stdout)
1147 self.assertTrue(os.path.exists(os.path.join(ns3_path,
"cmake_performance_trace.log")))
1152 Tests ns3 regarding building the project
1156 cleaned_once =
False
1160 Reuse cleaning/release configuration from NS3BaseTestCase if flag is cleaned
1163 if not NS3BuildBaseTestCase.cleaned_once:
1164 NS3BuildBaseTestCase.cleaned_once =
True
1165 NS3BaseTestCase.cleaned_once =
False
1172 Try building the core library
1175 return_code, stdout, stderr =
run_ns3(
"build core")
1176 self.assertEqual(return_code, 0)
1177 self.assertIn(
"Built target libcore", stdout)
1181 Try building core-test library without tests enabled
1185 return_code, stdout, stderr =
run_ns3(
"build core-test")
1186 self.assertEqual(return_code, 1)
1187 self.assertIn(
"Target to build does not exist: core-test", stdout)
1191 Try building the project:
1194 return_code, stdout, stderr =
run_ns3(
"build")
1195 self.assertEqual(return_code, 0)
1196 self.assertIn(
"Built target", stdout)
1198 self.assertTrue(os.path.exists(program))
1199 self.assertIn(cmake_build_project_command, stdout)
1203 Try hiding task lines
1206 return_code, stdout, stderr =
run_ns3(
"--quiet build")
1207 self.assertEqual(return_code, 0)
1208 self.assertIn(cmake_build_project_command, stdout)
1212 Try removing an essential file to break the build
1216 attribute_cc_path = os.sep.join([ns3_path,
"src",
"core",
"model",
"attribute.cc"])
1217 attribute_cc_bak_path = attribute_cc_path +
".bak"
1218 shutil.move(attribute_cc_path, attribute_cc_bak_path)
1221 return_code, stdout, stderr =
run_ns3(
"build")
1222 self.assertNotEqual(return_code, 0)
1225 shutil.move(attribute_cc_bak_path, attribute_cc_path)
1228 return_code, stdout, stderr =
run_ns3(
"build")
1229 self.assertEqual(return_code, 0)
1233 Test if changing the version file affects the library names
1236 version_file = os.sep.join([ns3_path,
"VERSION"])
1237 with open(version_file,
"w")
as f:
1241 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\"")
1242 self.
config_okconfig_ok(return_code, stdout)
1245 return_code, stdout, stderr =
run_ns3(
"build")
1246 self.assertEqual(return_code, 0)
1247 self.assertIn(
"Built target", stdout)
1253 for program
in new_programs:
1254 self.assertTrue(os.path.exists(program))
1261 new_libraries =
list(set(libraries).difference(set(self.
ns3_librariesns3_libraries)))
1262 self.assertEqual(len(new_libraries), len(self.
ns3_librariesns3_libraries))
1263 for library
in new_libraries:
1264 self.assertNotIn(
"libns3-dev", library)
1265 self.assertIn(
"libns3-00", library)
1266 self.assertTrue(os.path.exists(library))
1269 with open(version_file,
"w")
as f:
1273 NS3BuildBaseTestCase.cleaned_once =
False
1277 Try setting a different output directory and if everything is
1278 in the right place and still working correctly
1297 absolute_path = os.sep.join([ns3_path,
"build",
"release"])
1298 relative_path = os.sep.join([
"build",
"release"])
1299 for different_out_dir
in [absolute_path, relative_path]:
1300 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --out=%s" % different_out_dir)
1301 self.
config_okconfig_ok(return_code, stdout)
1302 self.assertIn(
"Build directory : %s" % absolute_path, stdout)
1310 for program
in new_programs:
1311 self.assertTrue(os.path.exists(program))
1315 new_libraries =
list(set(libraries).difference(set(self.
ns3_librariesns3_libraries)))
1316 self.assertEqual(len(new_libraries), len(self.
ns3_librariesns3_libraries))
1317 for library
in new_libraries:
1318 self.assertTrue(os.path.exists(library))
1321 shutil.rmtree(absolute_path)
1324 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --out=''")
1325 self.
config_okconfig_ok(return_code, stdout)
1326 self.assertIn(
"Build directory : %s" % usual_outdir, stdout)
1334 for program
in new_programs:
1335 self.assertTrue(os.path.exists(program))
1339 self.assertEqual(len(libraries), len(self.
ns3_librariesns3_libraries))
1340 for library
in libraries:
1341 self.assertTrue(os.path.exists(library))
1345 Tries setting a ns3 version, then installing it.
1346 After that, tries searching for ns-3 with CMake's find_package(ns3).
1347 Finally, tries using core library in a 3rd-party project
1352 for library
in libraries:
1356 version_file = os.sep.join([ns3_path,
"VERSION"])
1357 with open(version_file,
"w")
as f:
1361 install_prefix = os.sep.join([ns3_path,
"build",
"install"])
1362 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --prefix=%s" % install_prefix)
1363 self.
config_okconfig_ok(return_code, stdout)
1374 lib64 = os.path.exists(os.sep.join([install_prefix,
"lib64"]))
1375 installed_libdir = os.sep.join([install_prefix, (
"lib64" if lib64
else "lib")])
1379 installed_libraries_list =
";".join(installed_libraries)
1380 for library
in libraries:
1381 library_name = os.path.basename(library)
1382 self.assertIn(library_name, installed_libraries_list)
1386 missing_headers =
list(set([os.path.basename(x)
for x
in headers])
1387 - (set([os.path.basename(x)
for x
in installed_headers]))
1389 self.assertEqual(len(missing_headers), 0)
1392 test_main_file = os.sep.join([install_prefix,
"main.cpp"])
1393 with open(test_main_file,
"w")
as f:
1395 #include <ns3/core-module.h>
1396 using namespace ns3;
1399 Simulator::Stop (Seconds (1.0));
1401 Simulator::Destroy ();
1409 for version
in [
"",
"3.01",
"3.00"]:
1410 ns3_import_methods = []
1413 cmake_find_package_import =
"""
1414 list(APPEND CMAKE_PREFIX_PATH ./{lib}/cmake/ns3)
1415 find_package(ns3 {version} COMPONENTS libcore)
1416 target_link_libraries(test PRIVATE ns3::libcore)
1417 """.format(lib=(
"lib64" if lib64
else "lib"), version=version)
1418 ns3_import_methods.append(cmake_find_package_import)
1421 pkgconfig_import =
"""
1422 list(APPEND CMAKE_PREFIX_PATH ./)
1423 include(FindPkgConfig)
1424 pkg_check_modules(ns3 REQUIRED IMPORTED_TARGET ns3-core{version})
1425 target_link_libraries(test PUBLIC PkgConfig::ns3)
1426 """.format(lib=(
"lib64" if lib64
else "lib"),
1427 version=
"=" + version
if version
else ""
1429 if shutil.which(
"pkg-config"):
1430 ns3_import_methods.append(pkgconfig_import)
1433 for import_method
in ns3_import_methods:
1434 test_cmake_project =
"""
1435 cmake_minimum_required(VERSION 3.10..3.10)
1436 project(ns3_consumer CXX)
1437 set(CMAKE_CXX_STANDARD 17)
1438 set(CMAKE_CXX_STANDARD_REQUIRED ON)
1439 add_executable(test main.cpp)
1442 test_cmake_project_file = os.sep.join([install_prefix,
"CMakeLists.txt"])
1443 with open(test_cmake_project_file,
"w")
as f:
1444 f.write(test_cmake_project)
1447 cmake = shutil.which(
"cmake")
1449 "-DCMAKE_BUILD_TYPE=debug .",
1451 if version ==
"3.00":
1452 self.assertEqual(return_code, 1)
1453 if import_method == cmake_find_package_import:
1454 self.assertIn(
'Could not find a configuration file for package "ns3" that is compatible',
1455 stderr.replace(
"\n",
""))
1456 elif import_method == pkgconfig_import:
1457 self.assertIn(
'A required package was not found',
1458 stderr.replace(
"\n",
""))
1460 raise Exception(
"Unknown import type")
1462 self.assertEqual(return_code, 0)
1463 self.assertIn(
"Build files", stdout)
1466 return_code, stdout, stderr =
run_program(
"cmake",
"--build .", cwd=install_prefix)
1468 if version ==
"3.00":
1469 self.assertEqual(return_code, 2)
1470 self.assertGreater(len(stderr), 0)
1472 self.assertEqual(return_code, 0)
1473 self.assertIn(
"Built target", stdout)
1476 return_code, stdout, stderr =
run_program(
"./test",
"", cwd=install_prefix)
1477 self.assertEqual(return_code, 0)
1480 return_code, stdout, stderr =
run_ns3(
"uninstall")
1481 self.assertIn(
"Built target uninstall", stdout)
1484 with open(version_file,
"w")
as f:
1488 NS3BuildBaseTestCase.cleaned_once =
False
1492 Tries to build scratch-simulator and subdir/scratch-simulator-subdir
1496 targets = {
"scratch/scratch-simulator":
"scratch-simulator",
1497 "scratch/scratch-simulator.cc":
"scratch-simulator",
1498 "scratch-simulator":
"scratch-simulator",
1499 "scratch/subdir/scratch-simulator-subdir":
"subdir_scratch-simulator-subdir",
1500 "subdir/scratch-simulator-subdir":
"subdir_scratch-simulator-subdir",
1501 "scratch-simulator-subdir":
"subdir_scratch-simulator-subdir",
1503 for (target_to_run, target_cmake)
in targets.items():
1505 build_line =
"target scratch_%s" % target_cmake
1506 return_code, stdout, stderr =
run_ns3(
"build %s" % target_to_run)
1507 self.assertEqual(return_code, 0)
1508 self.assertIn(build_line, stdout)
1511 return_code, stdout, stderr =
run_ns3(
"run %s --verbose" % target_to_run)
1512 self.assertEqual(return_code, 0)
1513 self.assertIn(build_line, stdout)
1514 stdout = stdout.replace(
"scratch_%s" % target_cmake,
"")
1515 self.assertIn(target_to_run.split(
"/")[-1].replace(
".cc",
""), stdout)
1517 NS3BuildBaseTestCase.cleaned_once =
False
1521 Test if cmake is calling pybindgen through modulegen to generate
1522 the bindings source files correctly
1530 self.skipTest(
"Pybindgen is not available")
1534 self.assertEqual(len(python_scripts), 0)
1537 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --enable-examples --enable-tests --enable-python-bindings")
1538 self.assertEqual(return_code, 0)
1541 core_bindings_generated_sources_path = os.path.join(ns3_path,
"build",
"src",
"core",
"bindings")
1542 core_bindings_sources_path = os.path.join(ns3_path,
"src",
"core",
"bindings")
1543 core_bindings_path = os.path.join(ns3_path,
"build",
"bindings",
"python",
"ns")
1544 core_bindings_header = os.path.join(core_bindings_generated_sources_path,
"ns3module.h")
1545 core_bindings_source = os.path.join(core_bindings_generated_sources_path,
"ns3module.cc")
1546 self.assertTrue(os.path.exists(core_bindings_header))
1547 self.assertTrue(os.path.exists(core_bindings_source))
1550 return_code, stdout, stderr =
run_ns3(
"build core-bindings")
1551 self.assertEqual(return_code, 0)
1554 self.assertGreater(len(
list(filter(
lambda x:
"_core" in x, os.listdir(core_bindings_path)))), 0)
1557 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" -- -DNS3_SCAN_PYTHON_BINDINGS=ON")
1558 self.assertEqual(return_code, 0)
1561 bindings_sources = os.listdir(core_bindings_sources_path)
1562 bindings_sources = [os.path.join(core_bindings_sources_path, y)
for y
in bindings_sources]
1564 [timestamps.update({x: os.stat(x)})
for x
in bindings_sources]
1567 return_code, stdout, stderr =
run_ns3(
"build core-apiscan")
1568 self.assertEqual(return_code, 0)
1571 generated_python_files = [
"callbacks_list.py",
"modulegen__gcc_LP64.py"]
1572 for binding_file
in timestamps.keys():
1573 if os.path.basename(binding_file)
in generated_python_files:
1574 self.assertTrue(os.path.exists(binding_file))
1575 self.assertGreater(os.stat(binding_file).st_size, 0)
1576 new_fstat = os.stat(binding_file)
1577 self.assertNotEqual(timestamps[binding_file].st_mtime, new_fstat.st_mtime)
1580 for f
in os.listdir(core_bindings_generated_sources_path):
1581 os.remove(os.path.join(core_bindings_generated_sources_path, f))
1584 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\"")
1585 self.assertEqual(return_code, 0)
1588 self.assertTrue(os.path.exists(core_bindings_header))
1589 self.assertTrue(os.path.exists(core_bindings_source))
1592 return_code, stdout, stderr =
run_ns3(
"build core-bindings")
1593 self.assertEqual(return_code, 0)
1596 self.assertGreater(len(
list(filter(
lambda x:
"_core" in x, os.listdir(core_bindings_path)))), 0)
1599 sys.path.insert(0, os.path.join(core_bindings_path,
".."))
1603 self.assertTrue(
True)
1606 return_code, stdout, stderr =
run_ns3(
"run sample-simulator.py")
1607 self.assertEqual(return_code, 0)
1610 return_code, stdout, stderr =
run_program(
"./test.py",
"-p src/core/examples/sample-simulator.py", python=
True)
1611 self.assertEqual(return_code, 0)
1615 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --disable-examples")
1616 self.assertEqual(return_code, 0)
1620 self.assertGreater(len(python_scripts), 0)
1623 return_code, stdout, stderr =
run_ns3(
"run sample-simulator.py")
1624 self.assertEqual(return_code, 0)
1626 NS3BuildBaseTestCase.cleaned_once =
False
1630 Test if ns3 can alert correctly in case a shortcut collision happens
1635 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --enable-examples")
1636 self.assertEqual(return_code, 0)
1639 shutil.copy(
"./examples/tutorial/second.cc",
"./scratch/second.cc")
1642 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --enable-examples")
1643 self.assertEqual(return_code, 0)
1646 return_code, stdout, stderr =
run_ns3(
"build second")
1647 self.assertEqual(return_code, 1)
1649 'Build target "second" is ambiguous. Try one of these: "scratch/second", "examples/tutorial/second"',
1654 return_code, stdout, stderr =
run_ns3(
"build scratch/second")
1655 self.assertEqual(return_code, 0)
1659 return_code, stdout, stderr =
run_ns3(
"build tutorial/second")
1660 self.assertEqual(return_code, 0)
1664 return_code, stdout, stderr =
run_ns3(
"run second")
1665 self.assertEqual(return_code, 1)
1667 'Run target "second" is ambiguous. Try one of these: "scratch/second", "examples/tutorial/second"',
1672 return_code, stdout, stderr =
run_ns3(
"run scratch/second")
1673 self.assertEqual(return_code, 0)
1676 return_code, stdout, stderr =
run_ns3(
"run tutorial/second")
1677 self.assertEqual(return_code, 0)
1680 os.remove(
"./scratch/second.cc")
1682 NS3BuildBaseTestCase.cleaned_once =
False
1686 Test if we can build a static ns-3 library and link it to static programs
1690 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --enable-examples --disable-gtk --enable-static")
1693 self.assertEqual(return_code, 0)
1696 return_code, stdout, stderr =
run_ns3(
'build sample-simulator')
1697 self.assertEqual(return_code, 0)
1698 self.assertIn(
"Built target", stdout)
1701 NS3BuildBaseTestCase.cleaned_once =
False
1706 Tests ns3 usage in more realistic scenarios
1710 cleaned_once =
False
1714 Reuse cleaning/release configuration from NS3BaseTestCase if flag is cleaned
1715 Here examples, tests and documentation are also enabled.
1718 if not NS3ExpectedUseTestCase.cleaned_once:
1719 NS3ExpectedUseTestCase.cleaned_once =
True
1720 NS3BaseTestCase.cleaned_once =
False
1724 return_code, stdout, stderr =
run_ns3(
"configure -G \"Unix Makefiles\" --enable-examples --enable-tests")
1725 self.
config_okconfig_ok(return_code, stdout)
1728 self.assertTrue(os.path.exists(ns3_lock_filename))
1734 self.assertTrue(os.path.exists(ns3_lock_filename))
1741 Try to build the project
1744 return_code, stdout, stderr =
run_ns3(
"build")
1745 self.assertEqual(return_code, 0)
1746 self.assertIn(
"Built target", stdout)
1748 self.assertTrue(os.path.exists(program))
1751 self.assertIn(module.replace(
"ns3-",
""),
";".join(libraries))
1752 self.assertIn(cmake_build_project_command, stdout)
1756 Try to build and run test-runner
1759 return_code, stdout, stderr =
run_ns3(
'run "test-runner --list" --verbose')
1760 self.assertEqual(return_code, 0)
1761 self.assertIn(
"Built target test-runner", stdout)
1766 Try to build and run a library
1769 return_code, stdout, stderr =
run_ns3(
"run core")
1770 self.assertEqual(return_code, 1)
1771 self.assertIn(
"Couldn't find the specified program: core", stderr)
1775 Try to build and run an unknown target
1778 return_code, stdout, stderr =
run_ns3(
"run nonsense")
1779 self.assertEqual(return_code, 1)
1780 self.assertIn(
"Couldn't find the specified program: nonsense", stderr)
1784 Try to run test-runner without building
1787 return_code, stdout, stderr =
run_ns3(
'run "test-runner --list" --no-build --verbose')
1788 self.assertEqual(return_code, 0)
1789 self.assertNotIn(
"Built target test-runner", stdout)
1794 Test ns3 fails to run a library
1797 return_code, stdout, stderr =
run_ns3(
"run core --no-build")
1798 self.assertEqual(return_code, 1)
1799 self.assertIn(
"Couldn't find the specified program: core", stderr)
1803 Test ns3 fails to run an unknown program
1806 return_code, stdout, stderr =
run_ns3(
"run nonsense --no-build")
1807 self.assertEqual(return_code, 1)
1808 self.assertIn(
"Couldn't find the specified program: nonsense", stderr)
1812 Test if scratch simulator is executed through gdb and lldb
1815 if shutil.which(
"gdb")
is None:
1816 self.skipTest(
"Missing gdb")
1818 return_code, stdout, stderr =
run_ns3(
"run scratch-simulator --gdb --verbose --no-build")
1819 self.assertEqual(return_code, 0)
1820 self.assertIn(
"scratch-simulator", stdout)
1821 self.assertIn(
"No debugging symbols found", stdout)
1825 Test if scratch simulator is executed through valgrind
1828 if shutil.which(
"valgrind")
is None:
1829 self.skipTest(
"Missing valgrind")
1831 return_code, stdout, stderr =
run_ns3(
"run scratch-simulator --valgrind --verbose --no-build")
1832 self.assertEqual(return_code, 0)
1833 self.assertIn(
"scratch-simulator", stderr)
1834 self.assertIn(
"Memcheck", stderr)
1838 Test the doxygen target that does trigger a full build
1841 if shutil.which(
"doxygen")
is None:
1842 self.skipTest(
"Missing doxygen")
1844 doc_folder = os.path.abspath(os.sep.join([
".",
"doc"]))
1846 doxygen_files = [
"introspected-command-line.h",
"introspected-doxygen.h"]
1847 for filename
in doxygen_files:
1848 file_path = os.sep.join([doc_folder, filename])
1849 if os.path.exists(file_path):
1850 os.remove(file_path)
1857 return_code, stdout, stderr =
run_ns3(
"docs doxygen")
1858 self.assertEqual(return_code, 0)
1860 self.assertIn(
"Built target doxygen", stdout)
1864 Test the doxygen target that doesn't trigger a full build
1867 if shutil.which(
"doxygen")
is None:
1868 self.skipTest(
"Missing doxygen")
1876 return_code, stdout, stderr =
run_ns3(
"docs doxygen-no-build")
1877 self.assertEqual(return_code, 0)
1879 self.assertIn(
"Built target doxygen-no-build", stdout)
1883 Test every individual target for Sphinx-based documentation
1886 if shutil.which(
"sphinx-build")
is None:
1887 self.skipTest(
"Missing sphinx")
1889 doc_folder = os.path.abspath(os.sep.join([
".",
"doc"]))
1892 for target
in [
"contributing",
"manual",
"models",
"tutorial"]:
1894 doc_build_folder = os.sep.join([doc_folder, target,
"build"])
1895 doc_temp_folder = os.sep.join([doc_folder, target,
"source-temp"])
1896 if os.path.exists(doc_build_folder):
1897 shutil.rmtree(doc_build_folder)
1898 if os.path.exists(doc_temp_folder):
1899 shutil.rmtree(doc_temp_folder)
1902 return_code, stdout, stderr =
run_ns3(
"docs %s" % target)
1903 self.assertEqual(return_code, 0)
1905 self.assertIn(
"Built target sphinx_%s" % target, stdout)
1908 doc_build_folder = os.sep.join([doc_folder, target,
"build"])
1909 self.assertTrue(os.path.exists(doc_build_folder))
1912 for build_type
in [
"latex",
"html",
"singlehtml"]:
1913 self.assertTrue(os.path.exists(os.sep.join([doc_build_folder, build_type])))
1917 Test the documentation target that builds
1918 both doxygen and sphinx based documentation
1921 if shutil.which(
"doxygen")
is None:
1922 self.skipTest(
"Missing doxygen")
1923 if shutil.which(
"sphinx-build")
is None:
1924 self.skipTest(
"Missing sphinx")
1926 doc_folder = os.path.abspath(os.sep.join([
".",
"doc"]))
1935 for target
in [
"manual",
"models",
"tutorial"]:
1936 doc_build_folder = os.sep.join([doc_folder, target,
"build"])
1937 if os.path.exists(doc_build_folder):
1938 shutil.rmtree(doc_build_folder)
1940 return_code, stdout, stderr =
run_ns3(
"docs all")
1941 self.assertEqual(return_code, 0)
1943 self.assertIn(
"Built target sphinx", stdout)
1945 self.assertIn(
"Built target doxygen", stdout)
1949 Try to set ownership of scratch-simulator from current user to root,
1950 and change execution permissions
1955 sudo_password = os.getenv(
"SUDO_PASSWORD",
None)
1958 if sudo_password
is None:
1959 self.skipTest(
"SUDO_PASSWORD environment variable was not specified")
1962 self.assertFalse(enable_sudo
is True)
1965 return_code, stdout, stderr =
run_ns3(
'run scratch-simulator')
1966 self.assertEqual(return_code, 0)
1967 self.assertIn(
"Built target scratch_scratch-simulator", stdout)
1969 scratch_simulator_path =
list(filter(
lambda x: x
if "scratch-simulator" in x
else None,
1973 prev_fstat = os.stat(scratch_simulator_path)
1976 return_code, stdout, stderr =
run_ns3(
'run scratch-simulator --enable-sudo',
1977 env={
"SUDO_PASSWORD": sudo_password})
1978 self.assertEqual(return_code, 0)
1979 self.assertIn(
"Built target scratch_scratch-simulator", stdout)
1981 fstat = os.stat(scratch_simulator_path)
1986 likely_fuse_mount = ((prev_fstat.st_mode & stat.S_ISUID) == (fstat.st_mode & stat.S_ISUID))
and \
1987 prev_fstat.st_uid == 0
1989 if sys.platform ==
"win32" or likely_fuse_mount:
1990 self.skipTest(
"Windows or likely a FUSE mount")
1993 self.assertEqual(fstat.st_uid, 0)
1994 self.assertEqual(fstat.st_mode & stat.S_ISUID, stat.S_ISUID)
1997 return_code, stdout, stderr =
run_ns3(
'configure --enable-sudo')
1998 self.assertEqual(return_code, 0)
2002 self.assertTrue(enable_sudo)
2006 if os.path.exists(executable):
2007 os.remove(executable)
2010 return_code, stdout, stderr =
run_ns3(
'build', env={
"SUDO_PASSWORD": sudo_password})
2011 self.assertEqual(return_code, 0)
2014 self.assertIn(
"chown root", stdout)
2015 self.assertIn(
"chmod u+s", stdout)
2017 self.assertIn(os.path.basename(executable), stdout)
2020 fstat = os.stat(scratch_simulator_path)
2021 self.assertEqual(fstat.st_uid, 0)
2022 self.assertEqual(fstat.st_mode & stat.S_ISUID, stat.S_ISUID)
2026 Check if command template is working
2031 return_code0, stdout0, stderr0 =
run_ns3(
'run sample-simulator --command-template')
2032 self.assertEqual(return_code0, 2)
2033 self.assertIn(
"argument --command-template: expected one argument", stderr0)
2035 return_code1, stdout1, stderr1 =
run_ns3(
'run sample-simulator --command-template=" "')
2036 return_code2, stdout2, stderr2 =
run_ns3(
'run sample-simulator --command-template " "')
2037 return_code3, stdout3, stderr3 =
run_ns3(
'run sample-simulator --command-template "echo "')
2038 self.assertEqual((return_code1, return_code2, return_code3), (1, 1, 1))
2039 self.assertIn(
"not all arguments converted during string formatting", stderr1)
2040 self.assertEqual(stderr1, stderr2)
2041 self.assertEqual(stderr2, stderr3)
2044 return_code4, stdout4, _ =
run_ns3(
'run sample-simulator --command-template "%s --PrintVersion" --verbose')
2045 return_code5, stdout5, _ =
run_ns3(
'run sample-simulator --command-template="%s --PrintVersion" --verbose')
2046 self.assertEqual((return_code4, return_code5), (0, 0))
2047 self.assertIn(
"sample-simulator --PrintVersion", stdout4)
2048 self.assertIn(
"sample-simulator --PrintVersion", stdout5)
2052 Check if all flavors of different argument passing to
2053 executable targets are working
2058 return_code0, stdout0, stderr0 =
run_ns3(
'run "sample-simulator --help" --verbose')
2059 return_code1, stdout1, stderr1 =
run_ns3(
'run sample-simulator --command-template="%s --help" --verbose')
2060 return_code2, stdout2, stderr2 =
run_ns3(
'run sample-simulator --verbose -- --help')
2062 self.assertEqual((return_code0, return_code1, return_code2), (0, 0, 0))
2063 self.assertIn(
"sample-simulator --help", stdout0)
2064 self.assertIn(
"sample-simulator --help", stdout1)
2065 self.assertIn(
"sample-simulator --help", stdout2)
2068 return_code0, stdout0, stderr0 =
run_ns3(
'run "sample-simulator --help" --no-build')
2069 return_code1, stdout1, stderr1 =
run_ns3(
'run sample-simulator --command-template="%s --help" --no-build')
2070 return_code2, stdout2, stderr2 =
run_ns3(
'run sample-simulator --no-build -- --help')
2071 self.assertEqual((return_code0, return_code1, return_code2), (0, 0, 0))
2072 self.assertEqual(stdout0, stdout1)
2073 self.assertEqual(stdout1, stdout2)
2074 self.assertEqual(stderr0, stderr1)
2075 self.assertEqual(stderr1, stderr2)
2078 return_code0, stdout0, stderr0 =
run_ns3(
'run "sample-simulator --PrintGlobals" --verbose')
2079 return_code1, stdout1, stderr1 =
run_ns3(
'run "sample-simulator --PrintGroups" --verbose')
2080 return_code2, stdout2, stderr2 =
run_ns3(
'run "sample-simulator --PrintTypeIds" --verbose')
2082 self.assertEqual((return_code0, return_code1, return_code2), (0, 0, 0))
2083 self.assertIn(
"sample-simulator --PrintGlobals", stdout0)
2084 self.assertIn(
"sample-simulator --PrintGroups", stdout1)
2085 self.assertIn(
"sample-simulator --PrintTypeIds", stdout2)
2088 cmd =
'run "sample-simulator --PrintGlobals" --command-template="%s --PrintGroups" --verbose -- --PrintTypeIds'
2089 return_code, stdout, stderr =
run_ns3(cmd)
2090 self.assertEqual(return_code, 0)
2095 self.assertIn(
"sample-simulator --PrintGroups --PrintGlobals --PrintTypeIds", stdout)
2098 cmd0 =
'run sample-simulator --command-template="%s " --PrintTypeIds'
2099 cmd1 =
'run sample-simulator --PrintTypeIds'
2101 return_code0, stdout0, stderr0 =
run_ns3(cmd0)
2102 return_code1, stdout1, stderr1 =
run_ns3(cmd1)
2103 self.assertEqual((return_code0, return_code1), (1, 1))
2104 self.assertIn(
"To forward configuration or runtime options, put them after '--'", stderr0)
2105 self.assertIn(
"To forward configuration or runtime options, put them after '--'", stderr1)
2109 Test if scratch simulator is executed through lldb
2112 if shutil.which(
"lldb")
is None:
2113 self.skipTest(
"Missing lldb")
2115 return_code, stdout, stderr =
run_ns3(
"run scratch-simulator --lldb --verbose --no-build")
2116 self.assertEqual(return_code, 0)
2117 self.assertIn(
"scratch-simulator", stdout)
2118 self.assertIn(
"(lldb) target create", stdout)
2121 if __name__ ==
'__main__':
2122 loader = unittest.TestLoader()
2123 suite = unittest.TestSuite()
2126 suite.addTests(loader.loadTestsFromTestCase(NS3UnusedSourcesTestCase))
2127 suite.addTests(loader.loadTestsFromTestCase(NS3CommonSettingsTestCase))
2128 suite.addTests(loader.loadTestsFromTestCase(NS3ConfigureBuildProfileTestCase))
2129 suite.addTests(loader.loadTestsFromTestCase(NS3ConfigureTestCase))
2130 suite.addTests(loader.loadTestsFromTestCase(NS3BuildBaseTestCase))
2131 suite.addTests(loader.loadTestsFromTestCase(NS3ExpectedUseTestCase))
2134 tests = dict(map(
lambda x: (x._testMethodName, x), suite._tests))
2144 ns3rc_script_bak = ns3rc_script +
".bak"
2145 if os.path.exists(ns3rc_script)
and not os.path.exists(ns3rc_script_bak):
2146 shutil.move(ns3rc_script, ns3rc_script_bak)
2149 runner = unittest.TextTestRunner(failfast=
True)
2150 result = runner.run(suite)
2153 if os.path.exists(ns3rc_script_bak):
2154 shutil.move(ns3rc_script_bak, ns3rc_script)
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
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
Tests ns3 regarding building the project.
def test_06_TestVersionFile(self)
Test if changing the version file affects the library names.
def test_12_StaticBuilds(self)
Test if we can build a static ns-3 library and link it to static programs.
def test_01_BuildExistingTargets(self)
Try building the core library.
def test_10_PybindgenBindings(self)
Test if cmake is calling pybindgen through modulegen to generate the bindings source files correctly.
def test_08_InstallationAndUninstallation(self)
Tries setting a ns3 version, then installing it.
def test_11_AmbiguityCheck(self)
Test if ns3 can alert correctly in case a shortcut collision happens.
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
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
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.
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
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
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 related to checking if source files were left behind, not being used by CMake
dictionary directory_and_files
dictionary containing directories with .cc source files
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.
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.
cmake_build_target_command
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()
def run_ns3(args, env=None)
Runs the ns3 wrapper script with arguments.