diff options
author | Daniel Moody <dmoody256@gmail.com> | 2020-05-07 04:25:15 (GMT) |
---|---|---|
committer | William Deegan <bill@baddogconsulting.com> | 2021-04-13 20:53:54 (GMT) |
commit | d7626f28eadfcf4b6ec4a23f51fe37617bb68ff5 (patch) | |
tree | a25b42809da7abc1d7a27a6ca13ed58e8607ec2c | |
parent | 76437269647a1a58c57c16d6008f2e2605653b44 (diff) | |
download | SCons-d7626f28eadfcf4b6ec4a23f51fe37617bb68ff5.zip SCons-d7626f28eadfcf4b6ec4a23f51fe37617bb68ff5.tar.gz SCons-d7626f28eadfcf4b6ec4a23f51fe37617bb68ff5.tar.bz2 |
added more test, including ninja speed test
-rw-r--r-- | test/ninja/build_libraries.py | 92 | ||||
-rw-r--r-- | test/ninja/generate_source.py | 102 | ||||
-rw-r--r-- | test/ninja/iterative_speedup.py | 226 | ||||
-rw-r--r-- | test/ninja/multi_env.py | 89 | ||||
-rw-r--r-- | test/ninja/ninja-fixture/bar.c | 2 | ||||
-rw-r--r-- | test/ninja/ninja-fixture/test1.c | 13 | ||||
-rw-r--r-- | test/ninja/ninja-fixture/test2.C | 3 | ||||
-rw-r--r-- | test/ninja/ninja-fixture/test_impl.c | 8 |
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"); +} |