summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Moody <dmoody256@gmail.com>2020-05-07 04:25:15 (GMT)
committerWilliam Deegan <bill@baddogconsulting.com>2021-04-13 20:53:54 (GMT)
commitd7626f28eadfcf4b6ec4a23f51fe37617bb68ff5 (patch)
treea25b42809da7abc1d7a27a6ca13ed58e8607ec2c
parent76437269647a1a58c57c16d6008f2e2605653b44 (diff)
downloadSCons-d7626f28eadfcf4b6ec4a23f51fe37617bb68ff5.zip
SCons-d7626f28eadfcf4b6ec4a23f51fe37617bb68ff5.tar.gz
SCons-d7626f28eadfcf4b6ec4a23f51fe37617bb68ff5.tar.bz2
added more test, including ninja speed test
-rw-r--r--test/ninja/build_libraries.py92
-rw-r--r--test/ninja/generate_source.py102
-rw-r--r--test/ninja/iterative_speedup.py226
-rw-r--r--test/ninja/multi_env.py89
-rw-r--r--test/ninja/ninja-fixture/bar.c2
-rw-r--r--test/ninja/ninja-fixture/test1.c13
-rw-r--r--test/ninja/ninja-fixture/test2.C3
-rw-r--r--test/ninja/ninja-fixture/test_impl.c8
8 files changed, 528 insertions, 7 deletions
diff --git a/test/ninja/build_libraries.py b/test/ninja/build_libraries.py
new file mode 100644
index 0000000..662c584
--- /dev/null
+++ b/test/ninja/build_libraries.py
@@ -0,0 +1,92 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os
+import sys
+import TestSCons
+
+_python_ = TestSCons._python_
+_exe = TestSCons._exe
+
+test = TestSCons.TestSCons()
+
+test.dir_fixture('ninja-fixture')
+
+ninja = test.where_is('ninja', os.environ['PATH'])
+
+if not ninja:
+ test.skip_test("Could not find ninja in environment")
+
+test.write('SConstruct', """
+env = Environment()
+env.Tool('ninja')
+
+shared_lib = env.SharedLibrary(target = 'test_impl', source = 'test_impl.c')
+env.Program(target = 'test', source = 'test1.c', LIBS=[shared_lib], LIBPATH=['.'], RPATH='.')
+
+static_lib = env.StaticLibrary(target = 'test_impl_static', source = 'test_impl.c')
+static_obj = env.Object(target = 'test_static.o', source = 'test1.c')
+env.Program(target = 'test_static', source = static_obj, LIBS=[static_lib], LIBPATH=['.'])
+""")
+# generate simple build
+test.run(stdout=None)
+test.must_contain_all_lines(test.stdout(),
+ ['Generating: build.ninja', 'Executing: build.ninja'])
+test.run(program = test.workpath('test'), stdout="library_function" + os.linesep)
+test.run(program = test.workpath('test_static'), stdout="library_function" + os.linesep)
+
+# clean build and ninja files
+test.run(arguments='-c', stdout=None)
+test.must_contain_all_lines(test.stdout(), [
+ 'Removed test_impl.os',
+ 'Removed libtest_impl.so',
+ 'Removed test1.o',
+ 'Removed test',
+ 'Removed test_impl.o',
+ 'Removed libtest_impl_static.a',
+ 'Removed test_static.o',
+ 'Removed test_static',
+ 'Removed build.ninja'])
+
+# only generate the ninja file
+test.run(arguments='--disable-auto-ninja', stdout=None)
+test.must_contain_all_lines(test.stdout(),
+ ['Generating: build.ninja'])
+test.must_not_contain_any_line(test.stdout(),
+ ['Executing: build.ninja'])
+
+# run ninja independently
+test.run(program = ninja, stdout=None)
+test.run(program = test.workpath('test'), stdout="library_function" + os.linesep)
+test.run(program = test.workpath('test_static'), stdout="library_function" + os.linesep)
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/ninja/generate_source.py b/test/ninja/generate_source.py
new file mode 100644
index 0000000..8ae0a80
--- /dev/null
+++ b/test/ninja/generate_source.py
@@ -0,0 +1,102 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os
+import sys
+import TestSCons
+
+_python_ = TestSCons._python_
+_exe = TestSCons._exe
+
+test = TestSCons.TestSCons()
+
+test.dir_fixture('ninja-fixture')
+
+ninja = test.where_is('ninja', os.environ['PATH'])
+
+if not ninja:
+ test.skip_test("Could not find ninja in environment")
+
+test.write('SConstruct', """
+env = Environment()
+env.Tool('ninja')
+env.Program(target = 'generate_source', source = 'generate_source.c')
+env.Command('generated_source.c', ['generate_source'], './generate_source')
+env.Program(target = 'generated_source', source = 'generated_source.c')
+""")
+
+test.write('generate_source.c', """
+#include <stdio.h>
+
+int main(int argc, char *argv[]) {
+ FILE *fp;
+
+ fp = fopen("generated_source.c", "w");
+ fprintf(fp, "#include <stdio.h>\\n");
+ fprintf(fp, "#include <stdlib.h>\\n");
+ fprintf(fp, "\\n");
+ fprintf(fp, "int\\n");
+ fprintf(fp, "main(int argc, char *argv[])\\n");
+ fprintf(fp, "{\\n");
+ fprintf(fp, " printf(\\"generated_source.c\\\\n\\");\\n");
+ fprintf(fp, " exit (0);\\n");
+ fprintf(fp, "}\\n");
+ fclose(fp);
+}
+""")
+
+# generate simple build
+test.run(stdout=None)
+test.run(program = test.workpath('generated_source'), stdout="generated_source.c" + os.linesep)
+
+# clean build and ninja files
+test.run(arguments='-c', stdout=None)
+test.must_contain_all_lines(test.stdout(), [
+ 'Removed generate_source.o',
+ 'Removed generate_source',
+ 'Removed generated_source.c',
+ 'Removed generated_source.o',
+ 'Removed generated_source',
+ 'Removed build.ninja'])
+
+# only generate the ninja file
+test.run(arguments='--disable-auto-ninja', stdout=None)
+test.must_contain_all_lines(test.stdout(),
+ ['Generating: build.ninja'])
+test.must_not_contain_any_line(test.stdout(),
+ ['Executing: build.ninja'])
+
+# run ninja independently
+test.run(program = ninja, stdout=None)
+test.run(program = test.workpath('generated_source'), stdout="generated_source.c" + os.linesep)
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/ninja/iterative_speedup.py b/test/ninja/iterative_speedup.py
new file mode 100644
index 0000000..018ba7b
--- /dev/null
+++ b/test/ninja/iterative_speedup.py
@@ -0,0 +1,226 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os
+import sys
+import time
+import random
+import TestSCons
+
+_python_ = TestSCons._python_
+_exe = TestSCons._exe
+
+test = TestSCons.TestSCons()
+
+test.dir_fixture('ninja-fixture')
+
+ninja = test.where_is('ninja', os.environ['PATH'])
+
+if not ninja:
+ test.skip_test("Could not find ninja in environment")
+
+test.write('source_0.c', """
+#include <stdio.h>
+#include <stdlib.h>
+#include "source_0.h"
+
+int
+print_function0()
+{
+ printf("main print\\n");
+}
+""")
+
+test.write('source_0.h', """
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+print_function0();
+""")
+
+def get_num_cpus():
+ """
+ Function to get the number of CPUs the system has.
+ """
+ # Linux, Unix and MacOS:
+ if hasattr(os, "sysconf"):
+ if 'SC_NPROCESSORS_ONLN' in os.sysconf_names:
+ # Linux & Unix:
+ ncpus = os.sysconf("SC_NPROCESSORS_ONLN")
+ if isinstance(ncpus, int) and ncpus > 0:
+ return ncpus
+ # OSX:
+ return int(os.popen("sysctl -n hw.ncpu")[1].read())
+ # Windows:
+ if 'NUMBER_OF_PROCESSORS' in os.environ:
+ ncpus = int(os.environ["NUMBER_OF_PROCESSORS"])
+ if ncpus > 0:
+ return ncpus
+ # Default
+ return 1
+
+def generate_source(parent_source, current_source):
+ test.write('source_{}.c'.format(current_source), """
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include "source_%(parent_source)s.h"
+ #include "source_%(current_source)s.h"
+
+ int
+ print_function%(current_source)s()
+ {
+ print_function%(parent_source)s();
+ }
+ """ % locals())
+
+ test.write('source_{}.h'.format(current_source), """
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ int
+ print_function%(current_source)s();
+ """ % locals())
+
+def mod_source_return(test_num):
+ parent_source = test_num-1
+ test.write('source_{}.c'.format(test_num), """
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include "source_%(parent_source)s.h"
+ #include "source_%(test_num)s.h"
+
+ int
+ print_function%(test_num)s()
+ {
+ int test = 5 + 5;
+ print_function%(parent_source)s();
+ return test;
+ }
+ """ % locals())
+
+def mod_source_orig(test_num):
+ parent_source = test_num-1
+ test.write('source_{}.c'.format(test_num), """
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include "source_%(parent_source)s.h"
+ #include "source_%(test_num)s.h"
+
+ int
+ print_function%(test_num)s()
+ {
+ print_function%(parent_source)s();
+ }
+ """ % locals())
+
+num_source = 200
+for i in range(1, num_source+1):
+ generate_source(i-1, i)
+
+test.write('main.c', """
+#include <stdio.h>
+#include <stdlib.h>
+#include "source_%(num_source)s.h"
+int
+main()
+{
+ print_function%(num_source)s();
+}
+""" % locals())
+
+test.write('SConstruct', """
+env = Environment()
+env.Tool('ninja')
+sources = ['main.c'] + env.Glob('source*.c')
+env.Program(target = 'print_bin', source = sources)
+""")
+
+test.write('SConstruct_no_ninja', """
+env = Environment()
+sources = ['main.c'] + env.Glob('source*.c')
+env.Program(target = 'print_bin', source = sources)
+""")
+
+tests_mods = []
+ninja_times = []
+scons_times = []
+for _ in range(10):
+ tests_mods += [random.randrange(1, num_source, 1)]
+jobs = '-j' + str(get_num_cpus())
+
+start = time.perf_counter()
+test.run(arguments='--disable-auto-ninja', stdout=None)
+test.run(program = ninja, arguments=[jobs], stdout=None)
+stop = time.perf_counter()
+ninja_times += [stop - start]
+test.run(program = test.workpath('print_bin'), stdout="main print" + os.linesep)
+
+for test_mod in tests_mods:
+ mod_source_return(test_mod)
+ start = time.perf_counter()
+ test.run(program = ninja, arguments=[jobs], stdout=None)
+ stop = time.perf_counter()
+ ninja_times += [stop - start]
+
+for test_mod in tests_mods:
+ mod_source_orig(test_mod)
+
+# clean build and ninja files
+test.run(arguments='-c', stdout=None)
+test.must_contain_all_lines(test.stdout(), [
+ 'Removed build.ninja'])
+
+start = time.perf_counter()
+test.run(arguments = ["-f", "SConstruct_no_ninja", jobs], stdout=None)
+stop = time.perf_counter()
+scons_times += [stop - start]
+test.run(program = test.workpath('print_bin'), stdout="main print" + os.linesep)
+
+for test_mod in tests_mods:
+ mod_source_return(test_mod)
+ start = time.perf_counter()
+ test.run(arguments = ["-f", "SConstruct_no_ninja", jobs], stdout=None)
+ stop = time.perf_counter()
+ scons_times += [stop - start]
+
+full_build_print = True
+for ninja, scons in zip(ninja_times, scons_times):
+ if ninja > scons:
+ test.fail_test()
+ if full_build_print:
+ full_build_print = False
+ print("Clean build {} files - SCons: {:.3f}s Ninja: {:.3f}s".format(num_source, scons, ninja))
+ else:
+ print("Single File Rebuild - SCons: {:.3f}s Ninja: {:.3f}s".format(scons, ninja))
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/ninja/multi_env.py b/test/ninja/multi_env.py
new file mode 100644
index 0000000..3612d7b
--- /dev/null
+++ b/test/ninja/multi_env.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os
+import sys
+import TestSCons
+
+_python_ = TestSCons._python_
+_exe = TestSCons._exe
+
+test = TestSCons.TestSCons()
+
+test.dir_fixture('ninja-fixture')
+
+ninja = test.where_is('ninja', os.environ['PATH'])
+
+if not ninja:
+ test.skip_test("Could not find ninja in environment")
+
+test.write('SConstruct', """
+env = Environment()
+env.Tool('ninja')
+env.Program(target = 'foo', source = 'foo.c')
+
+env2 = Environment()
+env2.Tool('ninja')
+env2.Program(target = 'bar', source = 'bar.c')
+""")
+
+# generate simple build
+test.run(stdout=None)
+test.must_contain_all_lines(test.stdout(),
+ ['Generating: build.ninja', 'Executing: build.ninja'])
+test.run(program = test.workpath('foo'), stdout="foo.c" + os.linesep)
+test.run(program = test.workpath('bar'), stdout="bar.c" + os.linesep)
+
+# clean build and ninja files
+test.run(arguments='-c', stdout=None)
+test.must_contain_all_lines(test.stdout(), [
+ 'Removed foo.o',
+ 'Removed foo',
+ 'Removed bar.o',
+ 'Removed bar',
+ 'Removed build.ninja'])
+
+# only generate the ninja file
+test.run(arguments='--disable-auto-ninja', stdout=None)
+test.must_contain_all_lines(test.stdout(),
+ ['Generating: build.ninja'])
+test.must_not_contain_any_line(test.stdout(),
+ ['Executing: build.ninja'])
+
+# run ninja independently
+test.run(program = ninja, stdout=None)
+test.run(program = test.workpath('foo'), stdout="foo.c" + os.linesep)
+test.run(program = test.workpath('bar'), stdout="bar.c" + os.linesep)
+
+
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/ninja/ninja-fixture/bar.c b/test/ninja/ninja-fixture/bar.c
index de1e6e5..3767857 100644
--- a/test/ninja/ninja-fixture/bar.c
+++ b/test/ninja/ninja-fixture/bar.c
@@ -5,6 +5,6 @@ int
main(int argc, char *argv[])
{
argv[argc++] = "--";
- printf("foo.c\n");
+ printf("bar.c\n");
exit (0);
}
diff --git a/test/ninja/ninja-fixture/test1.c b/test/ninja/ninja-fixture/test1.c
index 7535b0a..c53f54a 100644
--- a/test/ninja/ninja-fixture/test1.c
+++ b/test/ninja/ninja-fixture/test1.c
@@ -1,3 +1,10 @@
-This is a .c file.
-/*cc*/
-/*link*/
+#include <stdio.h>
+#include <stdlib.h>
+
+extern int library_function(void);
+
+int
+main(int argc, char *argv[])
+{
+ library_function();
+}
diff --git a/test/ninja/ninja-fixture/test2.C b/test/ninja/ninja-fixture/test2.C
deleted file mode 100644
index a1ee9e3..0000000
--- a/test/ninja/ninja-fixture/test2.C
+++ /dev/null
@@ -1,3 +0,0 @@
-This is a .C file.
-/*cc*/
-/*link*/
diff --git a/test/ninja/ninja-fixture/test_impl.c b/test/ninja/ninja-fixture/test_impl.c
new file mode 100644
index 0000000..ae5effc
--- /dev/null
+++ b/test/ninja/ninja-fixture/test_impl.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+library_function(void)
+{
+ printf("library_function\n");
+}