diff options
Diffstat (limited to 'tests')
120 files changed, 2458 insertions, 0 deletions
diff --git a/tests/ROOT b/tests/ROOT new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/ROOT diff --git a/tests/TARGETS b/tests/TARGETS new file mode 100644 index 0000000..c64245e --- /dev/null +++ b/tests/TARGETS @@ -0,0 +1,6 @@ +{ "ALL": + { "type": "install" + , "deps": [["test_cases/deps", "ALL"], ["test_cases/cflags", "ALL"]] + , "tainted": ["test"] + } +} diff --git a/tests/test_cases/cflags/TARGETS b/tests/test_cases/cflags/TARGETS new file mode 100644 index 0000000..44c99f1 --- /dev/null +++ b/tests/test_cases/cflags/TARGETS @@ -0,0 +1,19 @@ +{ "public": + { "type": ["test_rules", "test_case"] + , "name": ["cflags_public"] + , "targets": + [ "+main_use_half3" + , "+test_use_half3" + , "+main_use_half3f" + , "+test_use_half3f" + ] + , "asserts": + [ "./main_use_half3/main_use_half3 | grep 1.5" + , "[ \"$(cat ./test_use_half3/result)\" = \"PASS\" ]" + , "./main_use_half3f/main_use_half3f | grep 1.5" + , "[ \"$(cat ./test_use_half3f/result)\" = \"PASS\" ]" + ] + , "data": [["TREE", null, "public"]] + } +, "ALL": {"type": "install", "deps": ["public"], "tainted": ["test"]} +} diff --git a/tests/test_cases/cflags/public/TARGETS b/tests/test_cases/cflags/public/TARGETS new file mode 100644 index 0000000..79aadb3 --- /dev/null +++ b/tests/test_cases/cflags/public/TARGETS @@ -0,0 +1,49 @@ +{ "half": + { "type": ["@", "rules", "CC", "library"] + , "name": ["half"] + , "hdrs": ["half.hpp"] + , "srcs": ["half.cpp"] + , "cflags": ["-DHALF_PRECISION_DOUBLE"] + , "stage": ["half"] + } +, "half3": + { "type": ["@", "rules", "CC", "library"] + , "name": ["half3"] + , "hdrs": ["half3.hpp"] + , "srcs": ["half3.cpp"] + , "deps": ["half"] + , "stage": ["half3"] + } +, "half3f": + { "type": ["@", "rules", "CC", "library"] + , "name": ["half3f"] + , "hdrs": ["half3f.hpp"] + , "srcs": ["half3f.cpp"] + , "private-deps": ["half3"] + , "stage": ["half3f"] + } +, "main_use_half3": + { "type": ["@", "rules", "CC", "binary"] + , "name": ["main_use_half3"] + , "srcs": ["main_use_half3.cpp"] + , "private-deps": ["half3"] + } +, "test_use_half3": + { "type": ["@", "rules", "CC/test", "test"] + , "name": ["test_use_half3"] + , "srcs": ["test_use_half3.cpp"] + , "private-deps": ["half3"] + } +, "main_use_half3f": + { "type": ["@", "rules", "CC", "binary"] + , "name": ["main_use_half3f"] + , "srcs": ["main_use_half3f.cpp"] + , "private-deps": ["half3f"] + } +, "test_use_half3f": + { "type": ["@", "rules", "CC/test", "test"] + , "name": ["test_use_half3f"] + , "srcs": ["test_use_half3f.cpp"] + , "private-deps": ["half3f"] + } +} diff --git a/tests/test_cases/cflags/public/half.cpp b/tests/test_cases/cflags/public/half.cpp new file mode 100644 index 0000000..e26ff6e --- /dev/null +++ b/tests/test_cases/cflags/public/half.cpp @@ -0,0 +1,5 @@ +#include "half.hpp" + +HALF_RESULT_TYPE half(int val) { + return static_cast<HALF_RESULT_TYPE>(val / 2.0); +} diff --git a/tests/test_cases/cflags/public/half.hpp b/tests/test_cases/cflags/public/half.hpp new file mode 100644 index 0000000..0baebcb --- /dev/null +++ b/tests/test_cases/cflags/public/half.hpp @@ -0,0 +1,12 @@ +#ifndef HALF_HPP +#define HALF_HPP + +#ifdef HALF_PRECISION_DOUBLE +#define HALF_RESULT_TYPE double +#else +#define HALF_RESULT_TYPE int +#endif + +HALF_RESULT_TYPE half(int val); + +#endif diff --git a/tests/test_cases/cflags/public/half3.cpp b/tests/test_cases/cflags/public/half3.cpp new file mode 100644 index 0000000..484f7f8 --- /dev/null +++ b/tests/test_cases/cflags/public/half3.cpp @@ -0,0 +1,3 @@ +#include "half3.hpp" + +HALF_RESULT_TYPE half3() { return half(3); } diff --git a/tests/test_cases/cflags/public/half3.hpp b/tests/test_cases/cflags/public/half3.hpp new file mode 100644 index 0000000..271ed68 --- /dev/null +++ b/tests/test_cases/cflags/public/half3.hpp @@ -0,0 +1,8 @@ +#ifndef HALF3_HPP +#define HALF3_HPP + +#include "half/half.hpp" + +HALF_RESULT_TYPE half3(); + +#endif diff --git a/tests/test_cases/cflags/public/half3f.cpp b/tests/test_cases/cflags/public/half3f.cpp new file mode 100644 index 0000000..88b6d55 --- /dev/null +++ b/tests/test_cases/cflags/public/half3f.cpp @@ -0,0 +1,7 @@ +#include "half3/half3.hpp" + +#ifndef HALF_PRECISION_DOUBLE +#error should be defined +#endif + +float half3f() { return static_cast<float>(half3()); } diff --git a/tests/test_cases/cflags/public/half3f.hpp b/tests/test_cases/cflags/public/half3f.hpp new file mode 100644 index 0000000..1207f63 --- /dev/null +++ b/tests/test_cases/cflags/public/half3f.hpp @@ -0,0 +1,6 @@ +#ifndef BAZ_HPP +#define BAZ_HPP + +float half3f(); + +#endif diff --git a/tests/test_cases/cflags/public/main_use_half3.cpp b/tests/test_cases/cflags/public/main_use_half3.cpp new file mode 100644 index 0000000..1c9d6ba --- /dev/null +++ b/tests/test_cases/cflags/public/main_use_half3.cpp @@ -0,0 +1,7 @@ +#include "half3/half3.hpp" +#include <iostream> + +int main() { + std::cout << half3() << std::endl; + return 0; +} diff --git a/tests/test_cases/cflags/public/main_use_half3f.cpp b/tests/test_cases/cflags/public/main_use_half3f.cpp new file mode 100644 index 0000000..3e855cd --- /dev/null +++ b/tests/test_cases/cflags/public/main_use_half3f.cpp @@ -0,0 +1,11 @@ +#include "half3f/half3f.hpp" +#include <iostream> + +#ifdef HALF_PRECISION_DOUBLE +#error should not be defined +#endif + +int main() { + std::cout << half3f() << std::endl; + return 0; +} diff --git a/tests/test_cases/cflags/public/test_use_half3.cpp b/tests/test_cases/cflags/public/test_use_half3.cpp new file mode 100644 index 0000000..1cf50ad --- /dev/null +++ b/tests/test_cases/cflags/public/test_use_half3.cpp @@ -0,0 +1,6 @@ +#include "half3/half3.hpp" + +int main() { + auto result = half3(); + return result > 1 and result < 2 ? 0 : 1; +} diff --git a/tests/test_cases/cflags/public/test_use_half3f.cpp b/tests/test_cases/cflags/public/test_use_half3f.cpp new file mode 100644 index 0000000..078e69c --- /dev/null +++ b/tests/test_cases/cflags/public/test_use_half3f.cpp @@ -0,0 +1,10 @@ +#include "half3f/half3f.hpp" + +#ifdef HALF_PRECISION_DOUBLE +#error should not be defined +#endif + +int main() { + auto result = half3f(); + return result > 1 and result < 2 ? 0 : 1; +} diff --git a/tests/test_cases/deps/TARGETS b/tests/test_cases/deps/TARGETS new file mode 100644 index 0000000..0ac2f3e --- /dev/null +++ b/tests/test_cases/deps/TARGETS @@ -0,0 +1,419 @@ +{ "private": + { "type": ["test_rules", "test_case"] + , "name": ["deps_private"] + , "targets": + [ "+foo" + , "-main_includes_foo" + , "+main_links_foo" + , "+main_links_bar_foo" + , "+install_bar" + ] + , "asserts": + [ "test -f foo/foo/libfoo.a" + , "test -f foo/foo/foo.hpp" + , "! test -f foo/bar/bar.hpp" + , "./main_links_foo/main | grep foo" + , "./main_links_bar_foo/main | grep bar" + , "./main_links_bar_foo/main | grep foo" + , "test -f install_bar/lib/bar/libbar.a" + , "test -f install_bar/include/bar/bar.hpp" + , "test -f install_bar/lib/foo/libfoo.a" + , "! test -f install_bar/include/foo/foo.hpp" + ] + , "data": [["TREE", null, "private"]] + } +, "public": + { "type": ["test_rules", "test_case"] + , "name": ["deps_public"] + , "targets": + [ "+foo" + , "+main_includes_foo" + , "+main_links_foo" + , "+main_links_bar_foo" + , "+install_bar" + ] + , "asserts": + [ "test -f foo/foo/libfoo.a" + , "test -f foo/foo/foo.hpp" + , "! test -f foo/bar/bar.hpp" + , "./main_includes_foo/main | grep main" + , "./main_links_foo/main | grep foo" + , "./main_links_bar_foo/main | grep bar" + , "./main_links_bar_foo/main | grep foo" + , "test -f install_bar/lib/bar/libbar.a" + , "test -f install_bar/include/bar/bar.hpp" + , "test -f install_bar/lib/foo/libfoo.a" + , "test -f install_bar/include/foo/foo.hpp" + ] + , "data": [["TREE", null, "public"]] + } +, "shared": + { "type": ["test_rules", "test_case"] + , "name": ["deps_shared"] + , "targets": + [ "+foo" + , "+bar" + , "+main_uses_foo" + , "+test_uses_foo" + , "+main_uses_bar" + , "+test_uses_bar" + , "+test_uses_bar_s" + , "+test_uses_baz" + , "+test_uses_main" + , "+test_diamond" + , "+install_foo" + , "+install_bar_s" + , "+install_baz" + , "+install_main" + ] + , "asserts": + [ "test -f foo/libfoo.so.1.2.3" + , "test -f foo/foo/foo.hpp" + , "test -f bar/libbar.so" + , "test -f bar/bar/bar.hpp" + , "! test -f bar/foo/foo.hpp" + , "test -f install_foo/lib/libfoo.so.1.2.3" + , "test -f install_foo/include/foo/foo.hpp" + , "grep 'Name: foo' install_foo/lib/pkgconfig/foo.pc" + , "grep 'Version: 1.2.3' install_foo/lib/pkgconfig/foo.pc" + , "grep -- '-L${libdir}' install_foo/lib/pkgconfig/foo.pc" + , "grep -- '-l:libfoo.so.1.2.3' install_foo/lib/pkgconfig/foo.pc" + , "test -f install_bar_s/lib/bar/libbar.a" + , "test -f install_bar_s/include/bar/bar.hpp" + , "test -f install_bar_s/lib/libfoo.so.1.2.3" + , "! test -f install_bar_s/include/foo/foo.hpp" + , "grep 'Name: bar' install_bar_s/lib/pkgconfig/bar.pc" + , "grep '${libdir}/bar/libbar.a' install_bar_s/lib/pkgconfig/bar.pc" + , "grep '${libdir}/libfoo.so.1.2.3' install_bar_s/lib/pkgconfig/bar.pc" + , "test -f install_baz/lib/libbaz.so" + , "test -f install_baz/include/baz/baz.hpp" + , "! test -f install_baz/lib/foo/libfoo.a" + , "! test -f install_baz/include/foo/foo.hpp" + , "./install_main/bin/main_uses_bar | grep main" + , "./install_main/bin/main_uses_bar | grep bar" + , "./install_main/bin/main_uses_bar | grep foo" + , "! test -d install_main/include" + ] + , "data": [["TREE", null, "shared"]] + } +, "object": + { "type": ["test_rules", "test_case"] + , "name": ["deps_object"] + , "targets": ["+foo", "+bar", "+baz", "+main", "+test_main", "+install_main"] + , "asserts": + [ "[ -f ./foo/libfoo.so ]" + , "[ -f ./bar/bar/bar.o ]" + , "[ -f ./baz/libbaz.so ]" + , "[ -f ./install_main/lib/libfoo.so ]" + , "[ ! -f ./install_main/lib/bar/bar.o ]" + , "[ \"$(./install_main/bin/main)\" = 'Hello World and Galaxy' ]" + ] + , "data": [["TREE", null, "object"]] + } +, "prebuilt_tests": + { "type": "tree" + , "deps": + [ ["test_cases/deps/prebuilt", "foo.hpp"] + , ["test_cases/deps/prebuilt", "bar.hpp"] + , ["test_cases/deps/prebuilt", "TARGETS"] + , ["TREE", null, "shared"] + ] + } +, "prebuilt": + { "type": ["test_rules", "test_case"] + , "name": ["deps_prebuilt"] + , "targets": + [ "+foo" + , "+bar" + , "+main_uses_foo" + , "+test_uses_foo" + , "+main_uses_bar" + , "+test_uses_bar" + , "+test_uses_bar_s" + , "+test_uses_main" + , "+install_foo" + , "+install_bar" + , "+install_main" + , "+test_uses_foobar" + , "+test_uses_foobar_s" + , "+install_foobar" + ] + , "asserts": + [ "test -f foo/libfoo.so.1.2.3" + , "test -f foo/foo/foo.hpp" + , "test -f bar/libbar.so" + , "test -f bar/bar/bar.hpp" + , "test -f install_foo/lib/pkgconfig/foo/foo.cflags" + , "test -f install_foo/lib/pkgconfig/foo/foo.ldflags" + , "test -f install_bar/lib/pkgconfig/foo/foo.cflags" + , "test -f install_bar/lib/pkgconfig/foo/foo.ldflags" + , "test -f install_bar/lib/pkgconfig/bar/bar.cflags" + , "test -f install_bar/lib/pkgconfig/bar/bar.ldflags" + , "./install_main/bin/main_uses_bar | grep main" + , "./install_main/bin/main_uses_bar | grep bar" + , "./install_main/bin/main_uses_bar | grep foo" + , "test -f install_foobar/lib/libfoo.so.1.2.3" + , "test -f install_foobar/lib/libbar.so" + , "test -f install_foobar/lib/pkgconfig/foobar.pc" + , "grep 'Cflags:.*@${prefix}/lib/pkgconfig/bar/foobar.cflags' install_foobar/lib/pkgconfig/foobar.pc" + , "grep -- '-DUSE_BAR=1 -DUSE_FOO=1' install_foobar/lib/pkgconfig/bar/foobar.cflags" + , "grep 'Libs:.*@${prefix}/lib/pkgconfig/bar/foobar.ldflags' install_foobar/lib/pkgconfig/foobar.pc" + , "grep -- '-lm -lpthread' install_foobar/lib/pkgconfig/bar/foobar.ldflags" + ] + , "data": ["prebuilt_tests"] + } +, "cmake": + { "type": ["test_rules", "test_case"] + , "name": ["deps_cmake"] + , "libs": ["googletest", "libz", "libcurl"] + , "targets": + [ "+gtest" + , "+test" + , "+gtest_main" + , "+testbin" + , "+shell_test" + , "+install_gtest" + , "+install_gtest_main" + , "+install_testbin" + , "+install_libcurl" + ] + , "asserts": + [ "test -f gtest/libgtest.a" + , "test -f gtest/gtest/gtest.h" + , "grep 'PASSED.*1 test' test/stdout" + , "test -f gtest_main/libgtest.so.1.13.0" + , "test -f gtest_main/libgtest_main.so.1.13.0" + , "test -f gtest_main/gtest/gtest.h" + , "test -f ./testbin/test" + , "grep 'PASSED.*1 test' shell_test/stdout" + , "test -f install_gtest/lib/libgtest.a" + , "test -f install_gtest/include/gtest/gtest.h" + , "grep 'Cflags.*lib/pkgconfig/gtest.cflags' install_gtest/lib/pkgconfig/gtest.pc" + , "grep 'Libs.*libgtest.a' install_gtest/lib/pkgconfig/gtest.pc" + , "grep 'Libs.*lib/pkgconfig/gtest.ldflags' install_gtest/lib/pkgconfig/gtest.pc" + , "test -f install_gtest_main/lib/libgtest.so.1.13.0" + , "test -f install_gtest_main/lib/libgtest_main.so.1.13.0" + , "test -f install_gtest_main/include/gtest/gtest.h" + , "grep 'Cflags.*lib/pkgconfig/gtest_main.cflags' install_gtest_main/lib/pkgconfig/gtest_main.pc" + , "grep 'Libs.*libgtest.so.1.13.0' install_gtest_main/lib/pkgconfig/gtest_main.pc" + , "grep 'Libs.*libgtest_main.so.1.13.0' install_gtest_main/lib/pkgconfig/gtest_main.pc" + , "grep 'Libs.*lib/pkgconfig/gtest_main.ldflags' install_gtest_main/lib/pkgconfig/gtest_main.pc" + , "./install_testbin/bin/test | grep 'PASSED.*1 test'" + , "path=$(ldd install_libcurl/lib/libcurl.so.4.8.0 | awk '/libz/{print $3}') && test -z \"${path##$(pwd)*}\"" + ] + , "data": [["TREE", null, "cmake"]] + } +, "install": + { "type": ["test_rules", "test_case"] + , "name": ["deps_install"] + , "targets": + [ "+install_bar_release" + , "+install_main_release" + , "+install_bar_debug" + , "+install_main_debug" + , "+install_bar_debug_slim" + , "+install_main_debug_slim" + ] + , "asserts": + [ "test -f install_bar_release/lib/bar/libbar.a" + , "test -f install_bar_release/lib/foo/libfoo.a" + , "test -f install_bar_release/lib/baz/libbaz.a" + , "test -f install_bar_release/lib/pkgconfig/bar.pc" + , "test -f install_bar_release/include/bar/bar.hpp" + , "test -f install_bar_release/include/foo/foo.hpp" + , "! test -f install_bar_release/include/baz/baz.hpp" + , "! test -d install_bar_release/work" + , "test -f install_main_release/bin/main" + , "! test -f install_main_release/lib/bar/libbar.a" + , "! test -f install_main_release/lib/foo/libfoo.a" + , "! test -f install_main_release/lib/baz/libbaz.a" + , "! test -d install_main_release/lib/pkgconfig" + , "! test -d install_main_release/include" + , "! test -d install_main_release/work" + , "test -f install_bar_debug/lib/bar/libbar.a" + , "test -f install_bar_debug/lib/foo/libfoo.a" + , "test -f install_bar_debug/lib/baz/libbaz.a" + , "test -f install_bar_debug/lib/pkgconfig/bar.pc" + , "test -f install_bar_debug/include/bar/bar.hpp" + , "test -f install_bar_debug/include/foo/foo.hpp" + , "test -f install_bar_debug/include/baz/baz.hpp" + , "test -f install_bar_debug/work/bar/bar.cpp" + , "test -f install_bar_debug/work/bar/bar.hpp" + , "test -f install_bar_debug/work/foo/foo.cpp" + , "test -f install_bar_debug/work/foo/foo.hpp" + , "test -f install_bar_debug/work/foo/qux.hpp" + , "test -f install_bar_debug/work/baz/baz.cpp" + , "test -f install_bar_debug/work/baz/baz.hpp" + , "test -f install_main_debug/bin/main" + , "test -f install_main_debug/include/bar/bar.hpp" + , "test -f install_main_debug/include/foo/foo.hpp" + , "test -f install_main_debug/include/baz/baz.hpp" + , "test -f install_main_debug/work/bar/bar.cpp" + , "test -f install_main_debug/work/bar/bar.hpp" + , "test -f install_main_debug/work/foo/foo.cpp" + , "test -f install_main_debug/work/foo/foo.hpp" + , "test -f install_main_debug/work/foo/qux.hpp" + , "test -f install_main_debug/work/baz/baz.cpp" + , "test -f install_main_debug/work/baz/baz.hpp" + , "test -f install_main_debug/work/main.cpp" + , "! test -f install_main_debug/lib/bar/libbar.a" + , "! test -f install_main_debug/lib/foo/libfoo.a" + , "! test -f install_main_debug/lib/baz/libbaz.a" + , "! test -d install_main_debug/lib/pkgconfig" + , "test -f install_bar_debug_slim/lib/bar/libbar.a" + , "test -f install_bar_debug_slim/lib/foo/libfoo.a" + , "test -f install_bar_debug_slim/lib/baz/libbaz.a" + , "test -f install_bar_debug_slim/lib/pkgconfig/bar.pc" + , "test -f install_bar_debug_slim/include/bar/bar.hpp" + , "test -f install_bar_debug_slim/include/foo/foo.hpp" + , "! test -f install_bar_debug_slim/include/baz/baz.hpp" + , "! test -d install_bar_debug_slim/work" + , "test -f install_main_debug_slim/bin/main" + , "! test -f install_main_debug_slim/lib/bar/libbar.a" + , "! test -f install_main_debug_slim/lib/foo/libfoo.a" + , "! test -f install_main_debug_slim/lib/baz/libbaz.a" + , "! test -d install_main_debug_slim/lib/pkgconfig" + , "! test -d install_main_debug_slim/include" + , "! test -d install_main_debug_slim/work" + ] + , "data": [["TREE", null, "install"]] + } +, "components": + { "type": ["test_rules", "test_case"] + , "name": ["deps_components"] + , "targets": + [ "+foo" + , "+bar" + , "+combined_static_lib" + , "+combined_shared_lib" + , "+main" + , "+main-dynamic" + , "+installed_static" + , "+installed_shared" + ] + , "asserts": + [ "test -f foo/foo.hpp" + , "test -f foo/libfoo.a" + , "! test -e foo/libfoo.so" + , "test -f bar/bar.hpp" + , "test -f bar/libbar.a" + , "! test -e bar/libbar.so" + , "test -f combined_static_lib/libcombstatic.a" + , "test -f combined_static_lib/foo.hpp" + , "test -f combined_static_lib/bar.hpp" + , "! test -f combined_static_lib/libfoo.a" + , "! test -f combined_static_lib/libbar.a" + , "! test -f combined_static_lib/foodep.hpp" + , "! test -f combined_static_lib/foo.o" + , "! test -f combined_static_lib/bar.o" + , "test -f combined_shared_lib/libcombshared.so" + , "test -f combined_shared_lib/foo.hpp" + , "test -f combined_shared_lib/bar.hpp" + , "! test -f combined_shared_lib/foodep.hpp" + , "! test -f combined_shared_lib/libfoo.a" + , "! test -f combined_shared_lib/libbar.a" + , "! test -f combined_shared_lib/libfoo.so" + , "! test -f combined_shared_lib/libbar.so" + , "! test -f combined_shared_lib/foo.o" + , "! test -f combined_shared_lib/bar.o" + , "./main/main" + , "./main/main | grep 'Hello-from-main'" + , "./main/main | grep 'bar.3'" + , "./main/main | grep 'foo.15'" + , "./main-dynamic/bin/main" + , "./main-dynamic/bin/main | grep 'Hello-from-main'" + , "./main-dynamic/bin/main | grep 'bar.3'" + , "./main-dynamic/bin/main | grep 'foo.15'" + , "test -f installed_static/include/bar.hpp" + , "test -f installed_static/include/foo.hpp" + , "test -f installed_static/include/foodep.hpp" + , "test -f installed_static/lib/libcombstatic.a" + , "test -f installed_static/lib/libfoodep.a" + , "! test -f installed_static/lib/libbar.a" + , "! test -f installed_static/lib/libfoo.a" + , "test -f installed_shared/include/bar.hpp" + , "test -f installed_shared/include/foo.hpp" + , "test -f installed_shared/include/foodep.hpp" + , "test -f installed_shared/lib/libcombshared.so" + , "! test -f installed_shared/lib/libfoodep.a" + , "! test -f installed_shared/lib/libfoodep.so" + , "! test -f installed_shared/lib/libbar.a" + , "! test -f installed_shared/lib/libbar.so" + , "! test -f installed_shared/lib/libfoo.a" + , "! test -f installed_shared/lib/libfoo.so" + ] + , "data": [["TREE", null, "components"]] + } +, "transitive-components": + { "type": ["test_rules", "test_case"] + , "name": ["deps_transitive_components"] + , "targets": + ["+baz", "+bar", "+foo", "+main", "+shared-foo", "+installed-shared-main"] + , "asserts": + [ "test -f foo/libfoo.a" + , "test -f foo/foo.hpp" + , "test -f foo/bar.hpp" + , "test -f foo/baz.hpp" + , "! test -f foo/foodep.hpp" + , "! test -f foo/bardep.hpp" + , "! test -f foo/bazdep.hpp" + , "./main/main" + , "./main/main | grep main" + , "./main/main | grep foodep" + , "./main/main | grep bardep" + , "./main/main | grep bazdep" + , "test -f shared-foo/libfoo.so" + , "test -f shared-foo/foo.hpp" + , "test -f shared-foo/bar.hpp" + , "test -f shared-foo/baz.hpp" + , "! test -f shared-foo/foodep.hpp" + , "! test -f shared-foo/bardep.hpp" + , "! test -f shared-foo/bazdep.hpp" + , "./installed-shared-main/bin/main" + , "./installed-shared-main/bin/main | grep main" + , "./installed-shared-main/bin/main | grep foodep" + , "./installed-shared-main/bin/main | grep bardep" + , "./installed-shared-main/bin/main | grep bazdep" + ] + , "data": [["TREE", null, "transitive-components"]] + } +, "lint": + { "type": ["test_rules", "test_case"] + , "name": ["lint"] + , "targets": ["+test", "+test-shared", "+verifier", "+lint", "+lint-shared"] + , "asserts": + [ "cat lint/report" + , "cat lint-shared/report" + , "./verifier/expect lint/out/invocations.json foo.hpp foo.cpp foodep.hpp foodep.cpp bar.hpp bar.cpp bardep.hpp bardep.cpp plain.hpp plain.cpp main.cpp" + , "./verifier/expect lint-shared/out/invocations.json foo.hpp foo.cpp foodep.hpp foodep.cpp bar.hpp bar.cpp bardep.hpp bardep.cpp plain.hpp plain.cpp main.cpp" + ] + , "data": [["TREE", null, "lint"]] + } +, "chain": + { "type": ["test_rules", "test_case"] + , "name": ["chain"] + , "targets": ["+main", "+main-with-deps"] + , "asserts": + [ "./main-with-deps/bin/main | grep 'foo.*fine'" + , "./main-with-deps/bin/main | grep 'qux.*ok'" + ] + , "data": [["TREE", null, "chain"]] + } +, "ALL": + { "type": "install" + , "deps": + [ "private" + , "public" + , "shared" + , "object" + , "prebuilt" + , "cmake" + , "install" + , "components" + , "transitive-components" + , "lint" + , "chain" + ] + , "tainted": ["test"] + } +} diff --git a/tests/test_cases/deps/chain/TARGETS b/tests/test_cases/deps/chain/TARGETS new file mode 100644 index 0000000..974df61 --- /dev/null +++ b/tests/test_cases/deps/chain/TARGETS @@ -0,0 +1,38 @@ +{ "foo": + { "type": ["@", "rules", "CC", "library"] + , "name": ["foo"] + , "shared": ["yes"] + , "hdrs": ["foo.hpp"] + , "srcs": ["foo.cpp"] + , "deps": ["bar"] + } +, "bar": + { "type": ["@", "rules", "CC", "library"] + , "name": ["bar"] + , "shared": ["yes"] + , "hdrs": ["bar.hpp"] + , "srcs": ["bar.cpp"] + , "deps": ["baz"] + } +, "baz": + { "type": ["@", "rules", "CC", "library"] + , "name": ["baz"] + , "hdrs": ["baz.hpp"] + , "srcs": ["baz.cpp"] + , "deps": ["qux"] + } +, "qux": + { "type": ["@", "rules", "CC", "library"] + , "name": ["qux"] + , "hdrs": ["qux.hpp"] + , "srcs": ["qux.cpp"] + } +, "main": + { "type": ["@", "rules", "CC", "binary"] + , "name": ["main"] + , "srcs": ["main.cpp"] + , "private-deps": ["foo", "qux"] + } +, "main-with-deps": + {"type": ["@", "rules", "CC", "install-with-deps"], "targets": ["main"]} +} diff --git a/tests/test_cases/deps/chain/bar.cpp b/tests/test_cases/deps/chain/bar.cpp new file mode 100644 index 0000000..e79bcf1 --- /dev/null +++ b/tests/test_cases/deps/chain/bar.cpp @@ -0,0 +1,5 @@ +#include "bar.hpp" + +#include "baz.hpp" + +void print_bar(std::string s) { print_baz("[bar]: " + s); } diff --git a/tests/test_cases/deps/chain/bar.hpp b/tests/test_cases/deps/chain/bar.hpp new file mode 100644 index 0000000..cf3cb8c --- /dev/null +++ b/tests/test_cases/deps/chain/bar.hpp @@ -0,0 +1,8 @@ +#ifndef BAR_HPP +#define BAR_HPP + +#include <string> + +void print_bar(std::string); + +#endif diff --git a/tests/test_cases/deps/chain/baz.cpp b/tests/test_cases/deps/chain/baz.cpp new file mode 100644 index 0000000..b22163b --- /dev/null +++ b/tests/test_cases/deps/chain/baz.cpp @@ -0,0 +1,5 @@ +#include "baz.hpp" + +#include "qux.hpp" + +void print_baz(std::string s) { print_qux("[baz]: " + s); } diff --git a/tests/test_cases/deps/chain/baz.hpp b/tests/test_cases/deps/chain/baz.hpp new file mode 100644 index 0000000..f700c9c --- /dev/null +++ b/tests/test_cases/deps/chain/baz.hpp @@ -0,0 +1,8 @@ +#ifndef BAZ_HPP +#define BAZ_HPP + +#include <string> + +void print_baz(std::string); + +#endif diff --git a/tests/test_cases/deps/chain/foo.cpp b/tests/test_cases/deps/chain/foo.cpp new file mode 100644 index 0000000..a981b95 --- /dev/null +++ b/tests/test_cases/deps/chain/foo.cpp @@ -0,0 +1,5 @@ +#include "foo.hpp" + +#include "bar.hpp" + +void print_foo(std::string s) { print_bar("[foo]: " + s); } diff --git a/tests/test_cases/deps/chain/foo.hpp b/tests/test_cases/deps/chain/foo.hpp new file mode 100644 index 0000000..9d66a9d --- /dev/null +++ b/tests/test_cases/deps/chain/foo.hpp @@ -0,0 +1,8 @@ +#ifndef FOO_HPP +#define FOO_HPP + +#include <string> + +void print_foo(std::string); + +#endif diff --git a/tests/test_cases/deps/chain/main.cpp b/tests/test_cases/deps/chain/main.cpp new file mode 100644 index 0000000..db539d4 --- /dev/null +++ b/tests/test_cases/deps/chain/main.cpp @@ -0,0 +1,7 @@ +#include "foo.hpp" +#include "qux.hpp" + +int main() { + print_foo("Everthing is fine."); + print_qux("Everthing is ok."); +} diff --git a/tests/test_cases/deps/chain/qux.cpp b/tests/test_cases/deps/chain/qux.cpp new file mode 100644 index 0000000..e0499cc --- /dev/null +++ b/tests/test_cases/deps/chain/qux.cpp @@ -0,0 +1,5 @@ +#include "qux.hpp" + +#include <cstdio> + +void print_qux(std::string s) { printf("[qux]: %s\n", s.data()); } diff --git a/tests/test_cases/deps/chain/qux.hpp b/tests/test_cases/deps/chain/qux.hpp new file mode 100644 index 0000000..2975cad --- /dev/null +++ b/tests/test_cases/deps/chain/qux.hpp @@ -0,0 +1,8 @@ +#ifndef QUX_HPP +#define QUX_HPP + +#include <string> + +void print_qux(std::string); + +#endif diff --git a/tests/test_cases/deps/cmake/TARGETS b/tests/test_cases/deps/cmake/TARGETS new file mode 100644 index 0000000..2c02f53 --- /dev/null +++ b/tests/test_cases/deps/cmake/TARGETS @@ -0,0 +1,76 @@ +{ "gtest": + { "type": ["@", "rules", "CC/foreign/cmake", "library"] + , "name": ["gtest"] + , "version": ["1", "13", "0"] + , "project": [["@", "googletest", "", "tree"]] + , "out_hdr_dirs": ["gtest"] + , "out_libs": ["libgtest.a"] + , "pkg-config": ["gtest.pc"] + } +, "testlib": + { "type": ["@", "rules", "CC", "library"] + , "name": ["testlib"] + , "shared": ["yes"] + , "srcs": ["main.cpp"] + , "private-deps": ["gtest"] + } +, "test": + { "type": ["@", "rules", "CC/test", "test"] + , "name": ["test"] + , "private-deps": ["testlib", "gtest"] + } +, "gtest_main": + { "type": ["@", "rules", "CC/foreign/cmake", "library"] + , "name": ["gtest_main"] + , "version": ["1", "13", "0"] + , "project": [["@", "googletest", "", "tree"]] + , "defines": ["BUILD_SHARED_LIBS=ON"] + , "out_hdr_dirs": ["gtest"] + , "out_libs": ["libgtest_main.so.1.13.0", "libgtest.so.1.13.0"] + , "pkg-config": ["gtest_main.pc", "gtest.pc"] + } +, "testbin": + { "type": ["@", "rules", "CC", "binary"] + , "name": ["test"] + , "srcs": ["test.cpp"] + , "private-deps": ["gtest_main"] + } +, "shell_test": + { "type": ["@", "rules", "shell/test", "script"] + , "name": ["shell_test"] + , "test": ["test.sh"] + , "deps": ["testbin"] + } +, "install_gtest": + {"type": ["@", "rules", "CC", "install-with-deps"], "targets": ["gtest"]} +, "install_gtest_main": + { "type": ["@", "rules", "CC", "install-with-deps"] + , "targets": ["gtest_main"] + } +, "install_testbin": + {"type": ["@", "rules", "CC", "install-with-deps"], "targets": ["testbin"]} +, "libz": + { "type": ["@", "rules", "CC/foreign/cmake", "library"] + , "name": ["libz"] + , "version": ["1", "2", "13"] + , "project": [["@", "libz", "", "tree"]] + , "defines": ["BUILD_SHARED_LIBS=ON"] + , "out_hdrs": ["zconf.h", "zlib.h"] + , "out_libs": ["libz.so", "libz.so.1", "libz.so.1.2.13"] + , "pc_prefix": ["share/pkgconfig"] + , "pkg-config": ["zlib.pc"] + } +, "libcurl": + { "type": ["@", "rules", "CC/foreign/cmake", "library"] + , "name": ["libcurl"] + , "version": ["8", "0", "1"] + , "project": [["@", "libcurl", "", "tree"]] + , "defines": ["BUILD_SHARED_LIBS=ON", "CURL_ENABLE_SSL=OFF", "USE_ZLIB=ON"] + , "out_hdr_dirs": ["curl"] + , "out_libs": ["libcurl.so.4.8.0"] + , "pkg-config": ["libcurl.pc"] + , "deps": ["libz"] + } +, "install_libcurl": + {"type": ["@", "rules", "CC", "install-with-deps"], "targets": ["libcurl"]} +} diff --git a/tests/test_cases/deps/cmake/main.cpp b/tests/test_cases/deps/cmake/main.cpp new file mode 100644 index 0000000..575a358 --- /dev/null +++ b/tests/test_cases/deps/cmake/main.cpp @@ -0,0 +1,8 @@ +#include <gtest/gtest.h> + +TEST(CastTest, float) { EXPECT_EQ(42.0f, float(42)); } + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/tests/test_cases/deps/cmake/test.cpp b/tests/test_cases/deps/cmake/test.cpp new file mode 100644 index 0000000..b1811d8 --- /dev/null +++ b/tests/test_cases/deps/cmake/test.cpp @@ -0,0 +1,3 @@ +#include <gtest/gtest.h> + +TEST(CastTest, double) { EXPECT_EQ(42.0, double(42)); } diff --git a/tests/test_cases/deps/cmake/test.sh b/tests/test_cases/deps/cmake/test.sh new file mode 100644 index 0000000..80b7965 --- /dev/null +++ b/tests/test_cases/deps/cmake/test.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +set -e + +./test | grep PASSED diff --git a/tests/test_cases/deps/components/TARGETS b/tests/test_cases/deps/components/TARGETS new file mode 100644 index 0000000..62a599c --- /dev/null +++ b/tests/test_cases/deps/components/TARGETS @@ -0,0 +1,55 @@ +{ "combined_static_lib": + { "type": ["@", "rules", "CC", "library"] + , "name": ["combstatic"] + , "components": ["foo", "bar"] + } +, "combined_shared_lib": + { "type": ["@", "rules", "CC", "library"] + , "name": ["combshared"] + , "shared": [""] + , "components": ["foo", "bar"] + } +, "foo": + { "type": ["@", "rules", "CC", "library"] + , "name": ["foo"] + , "hdrs": ["foo.hpp"] + , "srcs": ["foo.cpp"] + , "deps": ["foodep"] + } +, "foodep": + { "type": ["@", "rules", "CC", "library"] + , "name": ["foodep"] + , "hdrs": ["foodep.hpp"] + , "srcs": ["foodep.cpp"] + } +, "bar": + { "type": ["@", "rules", "CC", "library"] + , "name": ["bar"] + , "hdrs": ["bar.hpp"] + , "srcs": ["bar.cpp"] + } +, "main": + { "type": ["@", "rules", "CC", "binary"] + , "name": ["main"] + , "srcs": ["main.cpp"] + , "private-deps": ["combined_static_lib"] + } +, "main-shared": + { "type": ["@", "rules", "CC", "binary"] + , "name": ["main"] + , "srcs": ["main.cpp"] + , "private-deps": ["combined_shared_lib"] + } +, "main-dynamic": + { "type": ["@", "rules", "CC", "install-with-deps"] + , "targets": ["main-shared"] + } +, "installed_static": + { "type": ["@", "rules", "CC", "install-with-deps"] + , "targets": ["combined_static_lib"] + } +, "installed_shared": + { "type": ["@", "rules", "CC", "install-with-deps"] + , "targets": ["combined_shared_lib"] + } +} diff --git a/tests/test_cases/deps/components/bar.cpp b/tests/test_cases/deps/components/bar.cpp new file mode 100644 index 0000000..525a3a4 --- /dev/null +++ b/tests/test_cases/deps/components/bar.cpp @@ -0,0 +1,9 @@ +#include "bar.hpp" + +#include <iostream> +#include <ostream> + +int bar(int x) { + std::cout << "bar(" << x << ")" << std::endl; + return x * 5; +} diff --git a/tests/test_cases/deps/components/bar.hpp b/tests/test_cases/deps/components/bar.hpp new file mode 100644 index 0000000..63f851d --- /dev/null +++ b/tests/test_cases/deps/components/bar.hpp @@ -0,0 +1,6 @@ +#ifndef BAR_HPP +#define BAR_HPP + +int bar(int); + +#endif diff --git a/tests/test_cases/deps/components/foo.cpp b/tests/test_cases/deps/components/foo.cpp new file mode 100644 index 0000000..163c6e2 --- /dev/null +++ b/tests/test_cases/deps/components/foo.cpp @@ -0,0 +1,10 @@ +#include "foo.hpp" + +#include "foodep.hpp" +#include <iostream> +#include <ostream> + +int foo(int x) { + std::cout << "foo(" << x << ")" << std::endl; + return foodep(x) + 7; +} diff --git a/tests/test_cases/deps/components/foo.hpp b/tests/test_cases/deps/components/foo.hpp new file mode 100644 index 0000000..45c286c --- /dev/null +++ b/tests/test_cases/deps/components/foo.hpp @@ -0,0 +1,8 @@ +#ifndef FOO_HPP +#define FOO_HPP + +#include "foodep.hpp" + +foo_t foo(foo_t); + +#endif diff --git a/tests/test_cases/deps/components/foodep.cpp b/tests/test_cases/deps/components/foodep.cpp new file mode 100644 index 0000000..e26c335 --- /dev/null +++ b/tests/test_cases/deps/components/foodep.cpp @@ -0,0 +1,9 @@ +#include "foodep.hpp" + +#include <iostream> +#include <ostream> + +foo_t foodep(foo_t x) { + std::cout << "foodep(" << x << ")" << std::endl; + return x + 2; +} diff --git a/tests/test_cases/deps/components/foodep.hpp b/tests/test_cases/deps/components/foodep.hpp new file mode 100644 index 0000000..ea16bb0 --- /dev/null +++ b/tests/test_cases/deps/components/foodep.hpp @@ -0,0 +1,8 @@ +#ifndef FOODEP_HPP +#define FOODEP_HPP + +typedef int foo_t; + +foo_t foodep(foo_t); + +#endif diff --git a/tests/test_cases/deps/components/main.cpp b/tests/test_cases/deps/components/main.cpp new file mode 100644 index 0000000..b6734a2 --- /dev/null +++ b/tests/test_cases/deps/components/main.cpp @@ -0,0 +1,10 @@ +#include "foo.hpp" +#include "bar.hpp" + +#include <iostream> +#include <ostream> + +int main(int argc, char **argv) { + std::cout << "Hello-from-main" << std::endl; + std::cout << foo(bar(3)) << std::endl; +} diff --git a/tests/test_cases/deps/install/TARGETS b/tests/test_cases/deps/install/TARGETS new file mode 100644 index 0000000..c2cab52 --- /dev/null +++ b/tests/test_cases/deps/install/TARGETS @@ -0,0 +1,69 @@ +{ "baz": + { "type": ["@", "rules", "CC", "library"] + , "name": ["baz"] + , "hdrs": ["baz.hpp"] + , "srcs": ["baz.cpp"] + , "stage": ["baz"] + } +, "foo": + { "type": ["@", "rules", "CC", "library"] + , "name": ["foo"] + , "hdrs": ["foo.hpp"] + , "private-hdrs": ["qux.hpp"] + , "srcs": ["foo.cpp"] + , "private-deps": ["baz"] + , "stage": ["foo"] + } +, "bar": + { "type": ["@", "rules", "CC", "library"] + , "name": ["bar"] + , "hdrs": ["bar.hpp"] + , "srcs": ["bar.cpp"] + , "deps": ["foo"] + , "stage": ["bar"] + } +, "main": + { "type": ["@", "rules", "CC", "binary"] + , "name": ["main"] + , "srcs": ["main.cpp"] + , "private-deps": ["bar"] + } +, "install_bar_release": + {"type": ["@", "rules", "CC", "install-with-deps"], "targets": ["bar"]} +, "install_main_release": + {"type": ["@", "rules", "CC", "install-with-deps"], "targets": ["main"]} +, "bar debug": + { "type": "configure" + , "target": "bar" + , "config": + { "type": "let*" + , "bindings": [["DEBUG", true], ["ADD_CXXFLAGS", ["-g"]]] + , "body": {"type": "env", "vars": ["DEBUG", "ADD_CXXFLAGS"]} + } + } +, "main debug": + { "type": "configure" + , "target": "main" + , "config": + { "type": "let*" + , "bindings": [["DEBUG", true], ["ADD_CXXFLAGS", ["-g"]]] + , "body": {"type": "env", "vars": ["DEBUG", "ADD_CXXFLAGS"]} + } + } +, "install_bar_debug": + {"type": ["@", "rules", "CC", "install-with-deps"], "targets": ["bar debug"]} +, "install_main_debug": + { "type": ["@", "rules", "CC", "install-with-deps"] + , "targets": ["main debug"] + } +, "install_bar_debug_slim": + { "type": ["@", "rules", "CC", "install-with-deps"] + , "skip-debug-stage": ["yes"] + , "targets": ["bar debug"] + } +, "install_main_debug_slim": + { "type": ["@", "rules", "CC", "install-with-deps"] + , "skip-debug-stage": ["yes"] + , "targets": ["main debug"] + } +} diff --git a/tests/test_cases/deps/install/bar.cpp b/tests/test_cases/deps/install/bar.cpp new file mode 100644 index 0000000..6cc1260 --- /dev/null +++ b/tests/test_cases/deps/install/bar.cpp @@ -0,0 +1,7 @@ +#include "bar.hpp" +#include <iostream> + +int bar(Foo *foo) { + std::cout << "bar" << std::endl; + return (foo == nullptr) ? -1 : foo->foo(); +} diff --git a/tests/test_cases/deps/install/bar.hpp b/tests/test_cases/deps/install/bar.hpp new file mode 100644 index 0000000..ec9c165 --- /dev/null +++ b/tests/test_cases/deps/install/bar.hpp @@ -0,0 +1,8 @@ +#ifndef BAR_HPP +#define BAR_HPP + +#include "foo/foo.hpp" + +int bar(Foo *foo); + +#endif diff --git a/tests/test_cases/deps/install/baz.cpp b/tests/test_cases/deps/install/baz.cpp new file mode 100644 index 0000000..c2c26f0 --- /dev/null +++ b/tests/test_cases/deps/install/baz.cpp @@ -0,0 +1,7 @@ +#include "baz.hpp" +#include <iostream> + +int baz() { + std::cout << baz_str() << std::endl; + return 0; +} diff --git a/tests/test_cases/deps/install/baz.hpp b/tests/test_cases/deps/install/baz.hpp new file mode 100644 index 0000000..f0f8377 --- /dev/null +++ b/tests/test_cases/deps/install/baz.hpp @@ -0,0 +1,10 @@ +#ifndef BAZ_HPP +#define BAZ_HPP + +int baz(); + +#include <string> + +static inline std::string baz_str() { return "baz"; } + +#endif diff --git a/tests/test_cases/deps/install/foo.cpp b/tests/test_cases/deps/install/foo.cpp new file mode 100644 index 0000000..4a3b17a --- /dev/null +++ b/tests/test_cases/deps/install/foo.cpp @@ -0,0 +1,10 @@ +#include "foo.hpp" +#include "baz/baz.hpp" +#include "qux.hpp" +#include <iostream> + +int Foo::foo() { + std::cout << "foo & inline " << baz_str() << std::endl; + qux(); + return baz(); +} diff --git a/tests/test_cases/deps/install/foo.hpp b/tests/test_cases/deps/install/foo.hpp new file mode 100644 index 0000000..025f3ef --- /dev/null +++ b/tests/test_cases/deps/install/foo.hpp @@ -0,0 +1,8 @@ +#ifndef FOO_HPP +#define FOO_HPP + +struct Foo { + int foo(); +}; + +#endif diff --git a/tests/test_cases/deps/install/main.cpp b/tests/test_cases/deps/install/main.cpp new file mode 100644 index 0000000..2e46d75 --- /dev/null +++ b/tests/test_cases/deps/install/main.cpp @@ -0,0 +1,10 @@ +// test binary consuming libraries + +#include "bar/bar.hpp" +#include <iostream> + +int main() { + std::cout << "main" << std::endl; + Foo foo{}; + return bar(&foo); +} diff --git a/tests/test_cases/deps/install/qux.hpp b/tests/test_cases/deps/install/qux.hpp new file mode 100644 index 0000000..b2f1611 --- /dev/null +++ b/tests/test_cases/deps/install/qux.hpp @@ -0,0 +1,8 @@ +#ifndef QUX_HPP +#define QUX_HPP + +#include <iostream> + +void qux() { std::cout << "qux" << std::endl; } + +#endif
\ No newline at end of file diff --git a/tests/test_cases/deps/lint/TARGETS b/tests/test_cases/deps/lint/TARGETS new file mode 100644 index 0000000..425815b --- /dev/null +++ b/tests/test_cases/deps/lint/TARGETS @@ -0,0 +1,78 @@ +{ "foo": + { "type": ["@", "rules", "CC", "library"] + , "name": ["foo"] + , "hdrs": ["foo.hpp"] + , "srcs": ["foo.cpp"] + , "deps": ["foodep"] + , "components": ["bar"] + } +, "foodep": + { "type": ["@", "rules", "CC", "library"] + , "name": ["foodep"] + , "hdrs": ["foodep.hpp"] + , "srcs": ["foodep.cpp"] + } +, "bar": + { "type": ["@", "rules", "CC", "library"] + , "name": ["bar"] + , "hdrs": ["bar.hpp"] + , "srcs": ["bar.cpp"] + , "deps": ["bardep"] + } +, "bardep": + { "type": ["@", "rules", "CC", "library"] + , "name": ["bardep"] + , "hdrs": ["bardep.hpp"] + , "srcs": ["bardep.cpp"] + } +, "plain": + { "type": ["@", "rules", "CC", "library"] + , "name": ["plain"] + , "arguments_config": ["TEST_SHARED"] + , "shared": + { "type": "if" + , "cond": {"type": "var", "name": "TEST_SHARED"} + , "then": ["yes"] + } + , "hdrs": ["plain.hpp"] + , "srcs": ["plain.cpp"] + , "deps": ["foo"] + } +, "main": + { "type": ["@", "rules", "CC", "binary"] + , "name": ["main"] + , "srcs": ["main.cpp"] + , "private-deps": ["plain"] + } +, "test": + { "type": ["@", "rules", "shell/test", "script"] + , "name": ["test"] + , "test": ["check-main.sh"] + , "deps": ["main"] + } +, "suite": + { "type": ["@", "rules", "test", "suite"] + , "deps": ["test"] + , "stage": ["suite"] + } +, "lint": + { "type": ["@", "rules", "lint", "targets"] + , "targets": ["suite"] + , "tainted": ["test"] + , "linter": ["pretend_lint.py"] + , "summarizer": ["summary.py"] + } +, "lint-shared": + { "type": "configure" + , "target": "lint" + , "tainted": ["lint", "test"] + , "config": {"type": "singleton_map", "key": "TEST_SHARED", "value": true} + } +, "test-shared": + { "type": "configure" + , "target": "test" + , "tainted": ["test"] + , "config": {"type": "singleton_map", "key": "TEST_SHARED", "value": true} + } +, "verifier": {"type": "install", "files": {"expect": "expect.py"}} +} diff --git a/tests/test_cases/deps/lint/bar.cpp b/tests/test_cases/deps/lint/bar.cpp new file mode 100644 index 0000000..437619c --- /dev/null +++ b/tests/test_cases/deps/lint/bar.cpp @@ -0,0 +1,10 @@ +#include "bar.hpp" + +#include "bardep.hpp" +#include <iostream> +#include <ostream> + +int bar(int x) { + std::cout << "bar(" << x << ")" << std::endl; + return bardep(x) * 7; +} diff --git a/tests/test_cases/deps/lint/bar.hpp b/tests/test_cases/deps/lint/bar.hpp new file mode 100644 index 0000000..e29bfd7 --- /dev/null +++ b/tests/test_cases/deps/lint/bar.hpp @@ -0,0 +1,8 @@ +#ifndef BAR_HPP +#define BAR_HPP + +#include "bardep.hpp" + +bar_t bar(bar_t); + +#endif diff --git a/tests/test_cases/deps/lint/bardep.cpp b/tests/test_cases/deps/lint/bardep.cpp new file mode 100644 index 0000000..33931da --- /dev/null +++ b/tests/test_cases/deps/lint/bardep.cpp @@ -0,0 +1,9 @@ +#include "bardep.hpp" + +#include <iostream> +#include <ostream> + +bar_t bardep(bar_t x) { + std::cout << "bardep(" << x << ")" << std::endl; + return x + 5; +} diff --git a/tests/test_cases/deps/lint/bardep.hpp b/tests/test_cases/deps/lint/bardep.hpp new file mode 100644 index 0000000..ebfaef4 --- /dev/null +++ b/tests/test_cases/deps/lint/bardep.hpp @@ -0,0 +1,8 @@ +#ifndef BARDEP_HPP +#define BARDEP_HPP + +typedef int bar_t; + +bar_t bardep(bar_t); + +#endif diff --git a/tests/test_cases/deps/lint/check-main.sh b/tests/test_cases/deps/lint/check-main.sh new file mode 100644 index 0000000..1705968 --- /dev/null +++ b/tests/test_cases/deps/lint/check-main.sh @@ -0,0 +1,3 @@ +set -eu + +./main | grep result: diff --git a/tests/test_cases/deps/lint/expect.py b/tests/test_cases/deps/lint/expect.py new file mode 100755 index 0000000..d26343d --- /dev/null +++ b/tests/test_cases/deps/lint/expect.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 + +import json +import os +import sys + +with open(sys.argv[1]) as f: + invocations = json.load(f) + +expected = set(sys.argv[2:]) +found = set() + +for name, cmd in invocations.items(): + print("- %s compiled as %r" % (name, cmd)) + found.add(os.path.basename(name)) + +if expected != found: + print() + print("Found: %r" % (found,)) + print("missing:%r" % (expected - found,)) + print("unexpected: %r" % (found - expected,)) + sys.exit(1) +else: + print("OK") diff --git a/tests/test_cases/deps/lint/foo.cpp b/tests/test_cases/deps/lint/foo.cpp new file mode 100644 index 0000000..197e1fb --- /dev/null +++ b/tests/test_cases/deps/lint/foo.cpp @@ -0,0 +1,10 @@ +#include "foo.hpp" + +#include "foodep.hpp" +#include <iostream> +#include <ostream> + +int foo(int x) { + std::cout << "foo(" << x << ")" << std::endl; + return foodep(x) * 3; +} diff --git a/tests/test_cases/deps/lint/foo.hpp b/tests/test_cases/deps/lint/foo.hpp new file mode 100644 index 0000000..45c286c --- /dev/null +++ b/tests/test_cases/deps/lint/foo.hpp @@ -0,0 +1,8 @@ +#ifndef FOO_HPP +#define FOO_HPP + +#include "foodep.hpp" + +foo_t foo(foo_t); + +#endif diff --git a/tests/test_cases/deps/lint/foodep.cpp b/tests/test_cases/deps/lint/foodep.cpp new file mode 100644 index 0000000..e26c335 --- /dev/null +++ b/tests/test_cases/deps/lint/foodep.cpp @@ -0,0 +1,9 @@ +#include "foodep.hpp" + +#include <iostream> +#include <ostream> + +foo_t foodep(foo_t x) { + std::cout << "foodep(" << x << ")" << std::endl; + return x + 2; +} diff --git a/tests/test_cases/deps/lint/foodep.hpp b/tests/test_cases/deps/lint/foodep.hpp new file mode 100644 index 0000000..ea16bb0 --- /dev/null +++ b/tests/test_cases/deps/lint/foodep.hpp @@ -0,0 +1,8 @@ +#ifndef FOODEP_HPP +#define FOODEP_HPP + +typedef int foo_t; + +foo_t foodep(foo_t); + +#endif diff --git a/tests/test_cases/deps/lint/main.cpp b/tests/test_cases/deps/lint/main.cpp new file mode 100644 index 0000000..7453eb9 --- /dev/null +++ b/tests/test_cases/deps/lint/main.cpp @@ -0,0 +1,9 @@ +#include "plain.hpp" + +#include <iostream> +#include <ostream> + +int main(int argc, char **argv) { + std::cout << "result: " << foobar(1) << std::endl; + return 0; +} diff --git a/tests/test_cases/deps/lint/plain.cpp b/tests/test_cases/deps/lint/plain.cpp new file mode 100644 index 0000000..1db123f --- /dev/null +++ b/tests/test_cases/deps/lint/plain.cpp @@ -0,0 +1,5 @@ +#include "plain.hpp" + +bar_t foobar(foo_t x) { + return bar(static_cast<bar_t>(foo(x))); +} diff --git a/tests/test_cases/deps/lint/plain.hpp b/tests/test_cases/deps/lint/plain.hpp new file mode 100644 index 0000000..20b84f5 --- /dev/null +++ b/tests/test_cases/deps/lint/plain.hpp @@ -0,0 +1,9 @@ +#ifndef PLAIN_HPP +#define PLAIN_HPP + +#include "foo.hpp" +#include "bar.hpp" + +bar_t foobar(foo_t); + +#endif diff --git a/tests/test_cases/deps/lint/pretend_lint.py b/tests/test_cases/deps/lint/pretend_lint.py new file mode 100755 index 0000000..c84285b --- /dev/null +++ b/tests/test_cases/deps/lint/pretend_lint.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 + +import json +import os +import subprocess +import sys + +# log the invocation +with open(os.path.join(os.environ["OUT"], "invocation.json"), "w") as f: + json.dump(sys.argv[1:], f) + +# verify the given command succeeds +result = subprocess.run(sys.argv[2:]) + +sys.exit(result.returncode) diff --git a/tests/test_cases/deps/lint/summary.py b/tests/test_cases/deps/lint/summary.py new file mode 100755 index 0000000..361f681 --- /dev/null +++ b/tests/test_cases/deps/lint/summary.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 + +import json +import os +import sys + +status = 0 +invocations = {} + +for lint in sorted(os.listdir()): + if os.path.isdir(lint): + with open(os.path.join(lint, "result")) as f: + result = f.read().strip() + if result != "PASS": + status = 1 + with open(os.path.join(lint, "stdout")) as f: + print(f.read()) + with open(os.path.join(lint, "stderr")) as f: + print(f.read()) + with open(os.path.join(lint, "out/invocation.json")) as f: + invocation = json.load(f) + invocations[invocation[0]] = invocation[1:] + +with open(os.path.join(os.environ["OUT"], "invocations.json"), "w") as f: + json.dump(invocations, f) + +sys.exit(status) diff --git a/tests/test_cases/deps/object/TARGETS b/tests/test_cases/deps/object/TARGETS new file mode 100644 index 0000000..412d2ea --- /dev/null +++ b/tests/test_cases/deps/object/TARGETS @@ -0,0 +1,49 @@ +{ "foo": + { "type": ["@", "rules", "CC", "library"] + , "name": ["foo"] + , "shared": ["yes"] + , "hdrs": ["foo.hpp"] + , "srcs": ["foo.cpp"] + , "deps": ["bar"] + , "stage": ["foo"] + } +, "bar": + { "type": "configure" + , "target": "bar (plain)" + , "config": + {"type": "singleton_map", "key": "BUILD_OBJECT_ONLY", "value": "true"} + } +, "bar (plain)": + { "type": ["@", "rules", "CC", "library"] + , "name": ["bar"] + , "hdrs": ["bar.hpp"] + , "srcs": ["bar.cpp"] + , "stage": ["bar"] + } +, "baz": + { "type": ["@", "rules", "CC", "library"] + , "name": ["baz"] + , "shared": ["yes"] + , "deps": ["bar"] + , "stage": ["baz"] + } +, "main": + { "type": ["@", "rules", "CC", "binary"] + , "name": ["main"] + , "srcs": ["main.cpp"] + , "private-deps": ["foo"] + } +, "test_main": + { "type": ["@", "rules", "shell/test", "script"] + , "name": ["test_main"] + , "test": ["test_main.sh"] + , "deps": ["main"] + } +, "test_main.sh": + { "type": "file_gen" + , "name": "test.sh" + , "data": "set -e\n[ \"$(./main)\" = \"Hello World and Galaxy\" ]" + } +, "install_main": + {"type": ["@", "rules", "CC", "install-with-deps"], "targets": ["main"]} +} diff --git a/tests/test_cases/deps/object/bar.cpp b/tests/test_cases/deps/object/bar.cpp new file mode 100644 index 0000000..5d7c616 --- /dev/null +++ b/tests/test_cases/deps/object/bar.cpp @@ -0,0 +1,3 @@ +#include <string> + +std::string bar() { return "and Galaxy"; } diff --git a/tests/test_cases/deps/object/bar.hpp b/tests/test_cases/deps/object/bar.hpp new file mode 100644 index 0000000..9c97d54 --- /dev/null +++ b/tests/test_cases/deps/object/bar.hpp @@ -0,0 +1,9 @@ +#ifndef BAR_HPP +#define BAR_HPP + +#include <string> + +// use this object lib to extend the public symbols of shared lib 'foo' by 'bar' +std::string bar(); + +#endif diff --git a/tests/test_cases/deps/object/foo.cpp b/tests/test_cases/deps/object/foo.cpp new file mode 100644 index 0000000..9687a6a --- /dev/null +++ b/tests/test_cases/deps/object/foo.cpp @@ -0,0 +1,3 @@ +#include "foo.hpp" + +std::string foo() { return "Hello World"; } diff --git a/tests/test_cases/deps/object/foo.hpp b/tests/test_cases/deps/object/foo.hpp new file mode 100644 index 0000000..d880c27 --- /dev/null +++ b/tests/test_cases/deps/object/foo.hpp @@ -0,0 +1,8 @@ +#ifndef FOO_HPP +#define FOO_HPP + +#include <string> + +std::string foo(); + +#endif diff --git a/tests/test_cases/deps/object/main.cpp b/tests/test_cases/deps/object/main.cpp new file mode 100644 index 0000000..cfc2a4f --- /dev/null +++ b/tests/test_cases/deps/object/main.cpp @@ -0,0 +1,8 @@ +#include "bar/bar.hpp" +#include "foo/foo.hpp" +#include <iostream> + +int main(int argc, char const *argv[]) { + std::cout << foo() << " " << bar() << std::endl; + return 0; +} diff --git a/tests/test_cases/deps/prebuilt/TARGETS b/tests/test_cases/deps/prebuilt/TARGETS new file mode 100644 index 0000000..c923995 --- /dev/null +++ b/tests/test_cases/deps/prebuilt/TARGETS @@ -0,0 +1,158 @@ +{ "foo.pc": + { "type": "file_gen" + , "name": "foo.pc" + , "data": + { "type": "join" + , "separator": "\n" + , "$1": + [ "Name: foo" + , "Version: 1.2.3" + , "Description: test prebuilt foo" + , "URL: unknown" + , "Cflags: -I/usr/include -DUSE_FOO=1" + , "Libs: -L/usr/lib -lfoo -lpthread" + ] + } + } +, "foo": + { "type": ["@", "rules", "CC/prebuilt", "library"] + , "name": ["foo"] + , "version": ["1", "2", "3"] + , "hdrs": ["foo.hpp"] + , "lib": [["shared", "foo"]] + , "pkg-config": ["foo.pc"] + , "stage": ["foo"] + } +, "foo_s": + { "type": ["@", "rules", "CC/prebuilt", "library"] + , "name": ["foo"] + , "version": ["1", "2", "3"] + , "hdrs": ["foo.hpp"] + , "lib": [["shared", "foo_s"]] + , "pkg-config": ["foo.pc"] + , "stage": ["foo"] + } +, "bar.pc": + { "type": "file_gen" + , "name": "bar.pc" + , "data": + { "type": "join" + , "separator": "\n" + , "$1": + [ "Name: bar" + , "Version: unknown" + , "Description: test prebuilt bar" + , "URL: unknown" + , "Cflags: -I/usr/include -DUSE_BAR=1" + , "Libs: -L/usr/lib -lbar -lpthread -lm" + ] + } + } +, "bar": + { "type": ["@", "rules", "CC/prebuilt", "library"] + , "name": ["bar"] + , "hdrs": ["bar.hpp"] + , "lib": [["shared", "bar"]] + , "pkg-config": ["bar.pc"] + , "stage": ["bar"] + , "deps": ["foo"] + } +, "bar_s": + { "type": ["@", "rules", "CC/prebuilt", "library"] + , "name": ["bar"] + , "hdrs": ["bar.hpp"] + , "lib": [["shared", "bar_s"]] + , "pkg-config": ["bar.pc"] + , "stage": ["bar"] + , "deps": ["foo"] + } +, "main_uses_foo": + { "type": ["@", "rules", "CC", "binary"] + , "name": ["main_uses_foo"] + , "srcs": [["shared", "main_uses_foo.cpp"]] + , "private-deps": ["foo"] + } +, "test_uses_foo": + { "type": ["@", "rules", "CC/test", "test"] + , "name": ["test_uses_foo"] + , "srcs": [["shared", "test_uses_foo.cpp"]] + , "private-deps": ["foo"] + } +, "main_uses_bar": + { "type": ["@", "rules", "CC", "binary"] + , "name": ["main_uses_bar"] + , "srcs": [["shared", "main_uses_bar.cpp"]] + , "private-deps": ["bar"] + } +, "test_uses_bar": + { "type": ["@", "rules", "CC/test", "test"] + , "name": ["test_uses_bar"] + , "srcs": [["shared", "test_uses_bar.cpp"]] + , "private-deps": ["bar"] + } +, "test_uses_bar_s": + { "type": ["@", "rules", "CC/test", "test"] + , "name": ["test_uses_bar"] + , "srcs": [["shared", "test_uses_bar.cpp"]] + , "private-deps": ["bar_s"] + } +, "test_uses_main": + { "type": ["@", "rules", "shell/test", "script"] + , "name": ["test_uses_main"] + , "test": [["shared", "test_uses_main.sh"]] + , "deps": ["main_uses_bar"] + } +, "install_foo": + {"type": ["@", "rules", "CC", "install-with-deps"], "targets": ["foo"]} +, "install_bar": + {"type": ["@", "rules", "CC", "install-with-deps"], "targets": ["bar"]} +, "install_main": + { "type": ["@", "rules", "CC", "install-with-deps"] + , "targets": ["main_uses_bar"] + } +, "foobar.pc": + { "type": "file_gen" + , "name": "foobar.pc" + , "data": + { "type": "join" + , "separator": "\n" + , "$1": + [ "Name: foobar" + , "Version: unknown" + , "Description: test compound prebuilt foobar" + , "URL: unknown" + , "Requires: bar, foo >= 1.2.3" + ] + } + } +, "foobar": + { "type": ["@", "rules", "CC/prebuilt", "library"] + , "name": ["foobar"] + , "hdrs": ["bar.hpp"] + , "lib": [["shared", "bar"], ["shared", "foo"]] + , "pkg-config": ["foobar.pc", "foo.pc", "bar.pc"] + , "stage": ["bar"] + } +, "foobar_s": + { "type": ["@", "rules", "CC/prebuilt", "library"] + , "name": ["foobar"] + , "hdrs": ["bar.hpp"] + , "lib": [["shared", "bar_s"], ["shared", "foo_s"]] + , "pkg-config": ["foobar.pc", "foo.pc", "bar.pc"] + , "stage": ["bar"] + } +, "test_uses_foobar": + { "type": ["@", "rules", "CC/test", "test"] + , "name": ["test_uses_bar"] + , "srcs": [["shared", "test_uses_bar.cpp"]] + , "private-deps": ["foobar"] + } +, "test_uses_foobar_s": + { "type": ["@", "rules", "CC/test", "test"] + , "name": ["test_uses_bar"] + , "srcs": [["shared", "test_uses_bar.cpp"]] + , "private-deps": ["foobar_s"] + } +, "install_foobar": + {"type": ["@", "rules", "CC", "install-with-deps"], "targets": ["foobar"]} +} diff --git a/tests/test_cases/deps/prebuilt/bar.hpp b/tests/test_cases/deps/prebuilt/bar.hpp new file mode 100644 index 0000000..243dba6 --- /dev/null +++ b/tests/test_cases/deps/prebuilt/bar.hpp @@ -0,0 +1,8 @@ +#ifndef BAR_HPP +#define BAR_HPP + +#ifdef USE_BAR +int bar(); +#endif + +#endif diff --git a/tests/test_cases/deps/prebuilt/foo.hpp b/tests/test_cases/deps/prebuilt/foo.hpp new file mode 100644 index 0000000..4f040d4 --- /dev/null +++ b/tests/test_cases/deps/prebuilt/foo.hpp @@ -0,0 +1,8 @@ +#ifndef FOO_HPP +#define FOO_HPP + +#ifdef USE_FOO +int foo(); +#endif + +#endif diff --git a/tests/test_cases/deps/private/TARGETS b/tests/test_cases/deps/private/TARGETS new file mode 100644 index 0000000..dd72948 --- /dev/null +++ b/tests/test_cases/deps/private/TARGETS @@ -0,0 +1,36 @@ +{ "foo": + { "type": ["@", "rules", "CC", "library"] + , "name": ["foo"] + , "hdrs": ["foo.hpp"] + , "srcs": ["foo.cpp"] + , "stage": ["foo"] + } +, "bar": + { "type": ["@", "rules", "CC", "library"] + , "name": ["bar"] + , "hdrs": ["bar.hpp"] + , "srcs": ["bar.cpp"] + , "private-deps": ["foo"] + , "stage": ["bar"] + } +, "main_includes_foo": + { "type": ["@", "rules", "CC", "binary"] + , "name": ["main"] + , "srcs": ["main_includes_foo.cpp"] + , "private-deps": ["bar"] + } +, "main_links_foo": + { "type": ["@", "rules", "CC", "binary"] + , "name": ["main"] + , "srcs": ["main_links_foo.cpp"] + , "private-deps": ["bar"] + } +, "main_links_bar_foo": + { "type": ["@", "rules", "CC", "binary"] + , "name": ["main"] + , "srcs": ["main_links_bar_foo.cpp"] + , "private-deps": ["bar"] + } +, "install_bar": + {"type": ["@", "rules", "CC", "install-with-deps"], "targets": ["bar"]} +} diff --git a/tests/test_cases/deps/private/bar.cpp b/tests/test_cases/deps/private/bar.cpp new file mode 100644 index 0000000..dfce0e8 --- /dev/null +++ b/tests/test_cases/deps/private/bar.cpp @@ -0,0 +1,8 @@ +#include "foo/foo.hpp" +#include "bar.hpp" +#include <iostream> + +int bar() { + std::cout << "bar\n"; + return foo(); +} diff --git a/tests/test_cases/deps/private/bar.hpp b/tests/test_cases/deps/private/bar.hpp new file mode 100644 index 0000000..94d4f16 --- /dev/null +++ b/tests/test_cases/deps/private/bar.hpp @@ -0,0 +1,6 @@ +#ifndef BAR_HPP +#define BAR_HPP + +int bar(); + +#endif diff --git a/tests/test_cases/deps/private/foo.cpp b/tests/test_cases/deps/private/foo.cpp new file mode 100644 index 0000000..f985022 --- /dev/null +++ b/tests/test_cases/deps/private/foo.cpp @@ -0,0 +1,7 @@ +#include "foo.hpp" +#include <iostream> + +int foo() { + std::cout << "foo\n"; + return 0; +} diff --git a/tests/test_cases/deps/private/foo.hpp b/tests/test_cases/deps/private/foo.hpp new file mode 100644 index 0000000..1a28686 --- /dev/null +++ b/tests/test_cases/deps/private/foo.hpp @@ -0,0 +1,6 @@ +#ifndef FOO_HPP +#define FOO_HPP + +int foo(); + +#endif diff --git a/tests/test_cases/deps/private/main_includes_foo.cpp b/tests/test_cases/deps/private/main_includes_foo.cpp new file mode 100644 index 0000000..16701c7 --- /dev/null +++ b/tests/test_cases/deps/private/main_includes_foo.cpp @@ -0,0 +1,9 @@ +// test that foo.hpp not available + +#include "foo/foo.hpp" +#include <iostream> + +int main() { + std::cout << "main\n"; + return 0; +} diff --git a/tests/test_cases/deps/private/main_links_bar_foo.cpp b/tests/test_cases/deps/private/main_links_bar_foo.cpp new file mode 100644 index 0000000..e936074 --- /dev/null +++ b/tests/test_cases/deps/private/main_links_bar_foo.cpp @@ -0,0 +1,9 @@ +// test that foo is linked after bar + +#include "bar/bar.hpp" +#include <iostream> + +int main() { + std::cout << "main\n"; + return bar(); +} diff --git a/tests/test_cases/deps/private/main_links_foo.cpp b/tests/test_cases/deps/private/main_links_foo.cpp new file mode 100644 index 0000000..1e1e07a --- /dev/null +++ b/tests/test_cases/deps/private/main_links_foo.cpp @@ -0,0 +1,10 @@ +// test that foo is linked + +#include <iostream> + +int foo(); // forward declare + +int main() { + std::cout << "main\n"; + return foo(); +} diff --git a/tests/test_cases/deps/public/TARGETS b/tests/test_cases/deps/public/TARGETS new file mode 100644 index 0000000..bc1807a --- /dev/null +++ b/tests/test_cases/deps/public/TARGETS @@ -0,0 +1,36 @@ +{ "foo": + { "type": ["@", "rules", "CC", "library"] + , "name": ["foo"] + , "hdrs": ["foo.hpp"] + , "srcs": ["foo.cpp"] + , "stage": ["foo"] + } +, "bar": + { "type": ["@", "rules", "CC", "library"] + , "name": ["bar"] + , "hdrs": ["bar.hpp"] + , "srcs": ["bar.cpp"] + , "deps": ["foo"] + , "stage": ["bar"] + } +, "main_includes_foo": + { "type": ["@", "rules", "CC", "binary"] + , "name": ["main"] + , "srcs": ["main_includes_foo.cpp"] + , "private-deps": ["bar"] + } +, "main_links_foo": + { "type": ["@", "rules", "CC", "binary"] + , "name": ["main"] + , "srcs": ["main_links_foo.cpp"] + , "private-deps": ["bar"] + } +, "main_links_bar_foo": + { "type": ["@", "rules", "CC", "binary"] + , "name": ["main"] + , "srcs": ["main_links_bar_foo.cpp"] + , "private-deps": ["bar"] + } +, "install_bar": + {"type": ["@", "rules", "CC", "install-with-deps"], "targets": ["bar"]} +} diff --git a/tests/test_cases/deps/public/bar.cpp b/tests/test_cases/deps/public/bar.cpp new file mode 100644 index 0000000..f2a779a --- /dev/null +++ b/tests/test_cases/deps/public/bar.cpp @@ -0,0 +1,7 @@ +#include "bar.hpp" +#include <iostream> + +int bar(Foo *foo) { + std::cout << "bar\n"; + return (foo == nullptr) ? -1 : foo->foo(); +} diff --git a/tests/test_cases/deps/public/bar.hpp b/tests/test_cases/deps/public/bar.hpp new file mode 100644 index 0000000..ec9c165 --- /dev/null +++ b/tests/test_cases/deps/public/bar.hpp @@ -0,0 +1,8 @@ +#ifndef BAR_HPP +#define BAR_HPP + +#include "foo/foo.hpp" + +int bar(Foo *foo); + +#endif diff --git a/tests/test_cases/deps/public/foo.cpp b/tests/test_cases/deps/public/foo.cpp new file mode 100644 index 0000000..6899c7a --- /dev/null +++ b/tests/test_cases/deps/public/foo.cpp @@ -0,0 +1,7 @@ +#include "foo.hpp" +#include <iostream> + +int Foo::foo() { + std::cout << "foo\n"; + return 0; +} diff --git a/tests/test_cases/deps/public/foo.hpp b/tests/test_cases/deps/public/foo.hpp new file mode 100644 index 0000000..025f3ef --- /dev/null +++ b/tests/test_cases/deps/public/foo.hpp @@ -0,0 +1,8 @@ +#ifndef FOO_HPP +#define FOO_HPP + +struct Foo { + int foo(); +}; + +#endif diff --git a/tests/test_cases/deps/public/main_includes_foo.cpp b/tests/test_cases/deps/public/main_includes_foo.cpp new file mode 100644 index 0000000..e8a85b6 --- /dev/null +++ b/tests/test_cases/deps/public/main_includes_foo.cpp @@ -0,0 +1,9 @@ +// test that foo.hpp is available (despite unused here) + +#include "foo/foo.hpp" +#include <iostream> + +int main() { + std::cout << "main\n"; + return 0; +} diff --git a/tests/test_cases/deps/public/main_links_bar_foo.cpp b/tests/test_cases/deps/public/main_links_bar_foo.cpp new file mode 100644 index 0000000..02c2966 --- /dev/null +++ b/tests/test_cases/deps/public/main_links_bar_foo.cpp @@ -0,0 +1,10 @@ +// test that foo is linked after bar + +#include "bar/bar.hpp" +#include <iostream> + +int main() { + std::cout << "main\n"; + Foo foo{}; + return bar(&foo); +} diff --git a/tests/test_cases/deps/public/main_links_foo.cpp b/tests/test_cases/deps/public/main_links_foo.cpp new file mode 100644 index 0000000..f9cc308 --- /dev/null +++ b/tests/test_cases/deps/public/main_links_foo.cpp @@ -0,0 +1,10 @@ +// test that foo is linked + +#include "foo/foo.hpp" +#include <iostream> + +int main() { + std::cout << "main\n"; + Foo{}.foo(); + return 0; +} diff --git a/tests/test_cases/deps/shared/TARGETS b/tests/test_cases/deps/shared/TARGETS new file mode 100644 index 0000000..9db7fb8 --- /dev/null +++ b/tests/test_cases/deps/shared/TARGETS @@ -0,0 +1,104 @@ +{ "foo": + { "type": ["@", "rules", "CC", "library"] + , "shared": ["yes"] + , "name": ["foo"] + , "soversion": ["1", "2", "3"] + , "hdrs": ["foo.hpp"] + , "srcs": ["foo.cpp"] + , "stage": ["foo"] + } +, "foo_s": + { "type": ["@", "rules", "CC", "library"] + , "name": ["foo"] + , "hdrs": ["foo.hpp"] + , "srcs": ["foo.cpp"] + , "stage": ["foo"] + } +, "bar": + { "type": ["@", "rules", "CC", "library"] + , "shared": ["yes"] + , "name": ["bar"] + , "hdrs": ["bar.hpp"] + , "srcs": ["bar.cpp"] + , "stage": ["bar"] + , "private-deps": ["foo"] + } +, "bar_s": + { "type": ["@", "rules", "CC", "library"] + , "name": ["bar"] + , "hdrs": ["bar.hpp"] + , "srcs": ["bar.cpp"] + , "stage": ["bar"] + , "private-deps": ["foo"] + } +, "baz": + { "type": ["@", "rules", "CC", "library"] + , "name": ["baz"] + , "shared": ["yes"] + , "hdrs": ["baz.hpp"] + , "srcs": ["baz.cpp"] + , "stage": ["baz"] + , "private-deps": ["foo_s"] + } +, "main_uses_foo": + { "type": ["@", "rules", "CC", "binary"] + , "name": ["main_uses_foo"] + , "srcs": ["main_uses_foo.cpp"] + , "private-deps": ["foo"] + } +, "test_uses_foo": + { "type": ["@", "rules", "CC/test", "test"] + , "name": ["test_uses_foo"] + , "srcs": ["test_uses_foo.cpp"] + , "private-deps": ["foo"] + } +, "main_uses_bar": + { "type": ["@", "rules", "CC", "binary"] + , "name": ["main_uses_bar"] + , "srcs": ["main_uses_bar.cpp"] + , "private-deps": ["bar"] + } +, "test_uses_bar": + { "type": ["@", "rules", "CC/test", "test"] + , "name": ["test_uses_bar"] + , "srcs": ["test_uses_bar.cpp"] + , "private-deps": ["bar"] + } +, "test_uses_bar_s": + { "type": ["@", "rules", "CC/test", "test"] + , "name": ["test_uses_bar_s"] + , "srcs": ["test_uses_bar.cpp"] + , "private-deps": ["bar_s"] + } +, "test_uses_baz": + { "type": ["@", "rules", "CC/test", "test"] + , "name": ["test_uses_baz"] + , "srcs": ["test_uses_baz.cpp"] + , "private-deps": ["baz"] + } +, "test_uses_main": + { "type": ["@", "rules", "shell/test", "script"] + , "name": ["test_uses_main"] + , "test": ["test_uses_main.sh"] + , "deps": ["main_uses_bar"] + } +, "test_diamond": + { "type": ["@", "rules", "CC/test", "test"] + , "name": ["test_diamond"] + , "srcs": ["test_diamond.cpp"] + , "private-deps": ["foo_s", "baz"] + } +, "install_foo": + { "type": ["@", "rules", "CC", "install-with-deps"] + , "targets": ["foo"] + , "flat-libs": ["yes"] + } +, "install_bar_s": + {"type": ["@", "rules", "CC", "install-with-deps"], "targets": ["bar_s"]} +, "install_baz": + {"type": ["@", "rules", "CC", "install-with-deps"], "targets": ["baz"]} +, "install_main": + { "type": ["@", "rules", "CC", "install-with-deps"] + , "targets": ["main_uses_bar"] + } +} diff --git a/tests/test_cases/deps/shared/bar.cpp b/tests/test_cases/deps/shared/bar.cpp new file mode 100644 index 0000000..dfce0e8 --- /dev/null +++ b/tests/test_cases/deps/shared/bar.cpp @@ -0,0 +1,8 @@ +#include "foo/foo.hpp" +#include "bar.hpp" +#include <iostream> + +int bar() { + std::cout << "bar\n"; + return foo(); +} diff --git a/tests/test_cases/deps/shared/bar.hpp b/tests/test_cases/deps/shared/bar.hpp new file mode 100644 index 0000000..94d4f16 --- /dev/null +++ b/tests/test_cases/deps/shared/bar.hpp @@ -0,0 +1,6 @@ +#ifndef BAR_HPP +#define BAR_HPP + +int bar(); + +#endif diff --git a/tests/test_cases/deps/shared/baz.cpp b/tests/test_cases/deps/shared/baz.cpp new file mode 100644 index 0000000..fae4845 --- /dev/null +++ b/tests/test_cases/deps/shared/baz.cpp @@ -0,0 +1,8 @@ +#include "foo/foo.hpp" +#include "baz.hpp" +#include <iostream> + +int baz() { + std::cout << "baz\n"; + return foo(); +} diff --git a/tests/test_cases/deps/shared/baz.hpp b/tests/test_cases/deps/shared/baz.hpp new file mode 100644 index 0000000..643cf65 --- /dev/null +++ b/tests/test_cases/deps/shared/baz.hpp @@ -0,0 +1,6 @@ +#ifndef BAZ_HPP +#define BAZ_HPP + +int baz(); + +#endif diff --git a/tests/test_cases/deps/shared/foo.cpp b/tests/test_cases/deps/shared/foo.cpp new file mode 100644 index 0000000..f985022 --- /dev/null +++ b/tests/test_cases/deps/shared/foo.cpp @@ -0,0 +1,7 @@ +#include "foo.hpp" +#include <iostream> + +int foo() { + std::cout << "foo\n"; + return 0; +} diff --git a/tests/test_cases/deps/shared/foo.hpp b/tests/test_cases/deps/shared/foo.hpp new file mode 100644 index 0000000..1a28686 --- /dev/null +++ b/tests/test_cases/deps/shared/foo.hpp @@ -0,0 +1,6 @@ +#ifndef FOO_HPP +#define FOO_HPP + +int foo(); + +#endif diff --git a/tests/test_cases/deps/shared/main_uses_bar.cpp b/tests/test_cases/deps/shared/main_uses_bar.cpp new file mode 100644 index 0000000..9cfc855 --- /dev/null +++ b/tests/test_cases/deps/shared/main_uses_bar.cpp @@ -0,0 +1,8 @@ +#include "bar/bar.hpp" +#include <iostream> + +int main() { + std::cout << "main\n"; + bar(); + return 0; +} diff --git a/tests/test_cases/deps/shared/main_uses_foo.cpp b/tests/test_cases/deps/shared/main_uses_foo.cpp new file mode 100644 index 0000000..0fb3bb6 --- /dev/null +++ b/tests/test_cases/deps/shared/main_uses_foo.cpp @@ -0,0 +1,8 @@ +#include "foo/foo.hpp" +#include <iostream> + +int main() { + std::cout << "main\n"; + foo(); + return 0; +} diff --git a/tests/test_cases/deps/shared/test_diamond.cpp b/tests/test_cases/deps/shared/test_diamond.cpp new file mode 100644 index 0000000..9298230 --- /dev/null +++ b/tests/test_cases/deps/shared/test_diamond.cpp @@ -0,0 +1,4 @@ +#include "baz/baz.hpp" +#include "foo/foo.hpp" + +int main() { return foo() + baz(); } diff --git a/tests/test_cases/deps/shared/test_uses_bar.cpp b/tests/test_cases/deps/shared/test_uses_bar.cpp new file mode 100644 index 0000000..c2076ec --- /dev/null +++ b/tests/test_cases/deps/shared/test_uses_bar.cpp @@ -0,0 +1,3 @@ +#include "bar/bar.hpp" + +int main() { return bar(); } diff --git a/tests/test_cases/deps/shared/test_uses_baz.cpp b/tests/test_cases/deps/shared/test_uses_baz.cpp new file mode 100644 index 0000000..02d67f9 --- /dev/null +++ b/tests/test_cases/deps/shared/test_uses_baz.cpp @@ -0,0 +1,3 @@ +#include "baz/baz.hpp" + +int main() { return baz(); } diff --git a/tests/test_cases/deps/shared/test_uses_foo.cpp b/tests/test_cases/deps/shared/test_uses_foo.cpp new file mode 100644 index 0000000..88feb93 --- /dev/null +++ b/tests/test_cases/deps/shared/test_uses_foo.cpp @@ -0,0 +1,3 @@ +#include "foo/foo.hpp" + +int main() { return foo(); } diff --git a/tests/test_cases/deps/shared/test_uses_main.sh b/tests/test_cases/deps/shared/test_uses_main.sh new file mode 100644 index 0000000..ab8672f --- /dev/null +++ b/tests/test_cases/deps/shared/test_uses_main.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +set -e + +./main_uses_bar | grep main +./main_uses_bar | grep bar +./main_uses_bar | grep foo diff --git a/tests/test_cases/deps/transitive-components/TARGETS b/tests/test_cases/deps/transitive-components/TARGETS new file mode 100644 index 0000000..347b94c --- /dev/null +++ b/tests/test_cases/deps/transitive-components/TARGETS @@ -0,0 +1,64 @@ +{ "foo": + { "type": ["@", "rules", "CC", "library"] + , "name": ["foo"] + , "hdrs": ["foo.hpp"] + , "srcs": ["foo.cpp"] + , "deps": ["foodep"] + , "components": ["bar"] + } +, "foodep": + { "type": ["@", "rules", "CC", "library"] + , "name": ["foodep"] + , "hdrs": ["foodep.hpp"] + , "srcs": ["foodep.cpp"] + } +, "bar": + { "type": ["@", "rules", "CC", "library"] + , "name": ["bar"] + , "hdrs": ["bar.hpp"] + , "srcs": ["bar.cpp"] + , "deps": ["bardep"] + , "components": ["baz"] + } +, "bardep": + { "type": ["@", "rules", "CC", "library"] + , "name": ["bardep"] + , "hdrs": ["bardep.hpp"] + , "srcs": ["bardep.cpp"] + } +, "baz": + { "type": ["@", "rules", "CC", "library"] + , "name": ["baz"] + , "hdrs": ["baz.hpp"] + , "srcs": ["baz.cpp"] + , "deps": ["bazdep"] + } +, "bazdep": + { "type": ["@", "rules", "CC", "library"] + , "name": ["bazdep"] + , "hdrs": ["bazdep.hpp"] + , "srcs": ["bazdep.cpp"] + } +, "main": + { "type": ["@", "rules", "CC", "binary"] + , "name": ["main"] + , "srcs": ["main.cpp"] + , "private-deps": ["foo"] + } +, "shared-foo": + { "type": ["@", "rules", "CC", "library"] + , "name": ["foo"] + , "shared": [""] + , "components": ["foo"] + } +, "shared-main": + { "type": ["@", "rules", "CC", "binary"] + , "name": ["main"] + , "srcs": ["main.cpp"] + , "private-deps": ["shared-foo"] + } +, "installed-shared-main": + { "type": ["@", "rules", "CC", "install-with-deps"] + , "targets": ["shared-main"] + } +} diff --git a/tests/test_cases/deps/transitive-components/bar.cpp b/tests/test_cases/deps/transitive-components/bar.cpp new file mode 100644 index 0000000..437619c --- /dev/null +++ b/tests/test_cases/deps/transitive-components/bar.cpp @@ -0,0 +1,10 @@ +#include "bar.hpp" + +#include "bardep.hpp" +#include <iostream> +#include <ostream> + +int bar(int x) { + std::cout << "bar(" << x << ")" << std::endl; + return bardep(x) * 7; +} diff --git a/tests/test_cases/deps/transitive-components/bar.hpp b/tests/test_cases/deps/transitive-components/bar.hpp new file mode 100644 index 0000000..e29bfd7 --- /dev/null +++ b/tests/test_cases/deps/transitive-components/bar.hpp @@ -0,0 +1,8 @@ +#ifndef BAR_HPP +#define BAR_HPP + +#include "bardep.hpp" + +bar_t bar(bar_t); + +#endif diff --git a/tests/test_cases/deps/transitive-components/bardep.cpp b/tests/test_cases/deps/transitive-components/bardep.cpp new file mode 100644 index 0000000..33931da --- /dev/null +++ b/tests/test_cases/deps/transitive-components/bardep.cpp @@ -0,0 +1,9 @@ +#include "bardep.hpp" + +#include <iostream> +#include <ostream> + +bar_t bardep(bar_t x) { + std::cout << "bardep(" << x << ")" << std::endl; + return x + 5; +} diff --git a/tests/test_cases/deps/transitive-components/bardep.hpp b/tests/test_cases/deps/transitive-components/bardep.hpp new file mode 100644 index 0000000..ebfaef4 --- /dev/null +++ b/tests/test_cases/deps/transitive-components/bardep.hpp @@ -0,0 +1,8 @@ +#ifndef BARDEP_HPP +#define BARDEP_HPP + +typedef int bar_t; + +bar_t bardep(bar_t); + +#endif diff --git a/tests/test_cases/deps/transitive-components/baz.cpp b/tests/test_cases/deps/transitive-components/baz.cpp new file mode 100644 index 0000000..0354d55 --- /dev/null +++ b/tests/test_cases/deps/transitive-components/baz.cpp @@ -0,0 +1,10 @@ +#include "baz.hpp" + +#include "bazdep.hpp" +#include <iostream> +#include <ostream> + +int baz(int x) { + std::cout << "baz(" << x << ")" << std::endl; + return bazdep(x) * 13; +} diff --git a/tests/test_cases/deps/transitive-components/baz.hpp b/tests/test_cases/deps/transitive-components/baz.hpp new file mode 100644 index 0000000..926dd6d --- /dev/null +++ b/tests/test_cases/deps/transitive-components/baz.hpp @@ -0,0 +1,8 @@ +#ifndef BAZ_HPP +#define BAZ_HPP + +#include "bazdep.hpp" + +baz_t baz(baz_t); + +#endif diff --git a/tests/test_cases/deps/transitive-components/bazdep.cpp b/tests/test_cases/deps/transitive-components/bazdep.cpp new file mode 100644 index 0000000..c097661 --- /dev/null +++ b/tests/test_cases/deps/transitive-components/bazdep.cpp @@ -0,0 +1,9 @@ +#include "bazdep.hpp" + +#include <iostream> +#include <ostream> + +baz_t bazdep(baz_t x) { + std::cout << "bazdep(" << x << ")" << std::endl; + return x + 11; +} diff --git a/tests/test_cases/deps/transitive-components/bazdep.hpp b/tests/test_cases/deps/transitive-components/bazdep.hpp new file mode 100644 index 0000000..d2add97 --- /dev/null +++ b/tests/test_cases/deps/transitive-components/bazdep.hpp @@ -0,0 +1,8 @@ +#ifndef BAZDEP_HPP +#define BAZDEP_HPP + +typedef int baz_t; + +baz_t bazdep(baz_t); + +#endif diff --git a/tests/test_cases/deps/transitive-components/foo.cpp b/tests/test_cases/deps/transitive-components/foo.cpp new file mode 100644 index 0000000..197e1fb --- /dev/null +++ b/tests/test_cases/deps/transitive-components/foo.cpp @@ -0,0 +1,10 @@ +#include "foo.hpp" + +#include "foodep.hpp" +#include <iostream> +#include <ostream> + +int foo(int x) { + std::cout << "foo(" << x << ")" << std::endl; + return foodep(x) * 3; +} diff --git a/tests/test_cases/deps/transitive-components/foo.hpp b/tests/test_cases/deps/transitive-components/foo.hpp new file mode 100644 index 0000000..45c286c --- /dev/null +++ b/tests/test_cases/deps/transitive-components/foo.hpp @@ -0,0 +1,8 @@ +#ifndef FOO_HPP +#define FOO_HPP + +#include "foodep.hpp" + +foo_t foo(foo_t); + +#endif diff --git a/tests/test_cases/deps/transitive-components/foodep.cpp b/tests/test_cases/deps/transitive-components/foodep.cpp new file mode 100644 index 0000000..e26c335 --- /dev/null +++ b/tests/test_cases/deps/transitive-components/foodep.cpp @@ -0,0 +1,9 @@ +#include "foodep.hpp" + +#include <iostream> +#include <ostream> + +foo_t foodep(foo_t x) { + std::cout << "foodep(" << x << ")" << std::endl; + return x + 2; +} diff --git a/tests/test_cases/deps/transitive-components/foodep.hpp b/tests/test_cases/deps/transitive-components/foodep.hpp new file mode 100644 index 0000000..ea16bb0 --- /dev/null +++ b/tests/test_cases/deps/transitive-components/foodep.hpp @@ -0,0 +1,8 @@ +#ifndef FOODEP_HPP +#define FOODEP_HPP + +typedef int foo_t; + +foo_t foodep(foo_t); + +#endif diff --git a/tests/test_cases/deps/transitive-components/main.cpp b/tests/test_cases/deps/transitive-components/main.cpp new file mode 100644 index 0000000..3e2ae1c --- /dev/null +++ b/tests/test_cases/deps/transitive-components/main.cpp @@ -0,0 +1,11 @@ +#include "foo.hpp" +#include "bar.hpp" +#include "baz.hpp" + +#include <iostream> +#include <ostream> + +int main(int argc, char **argv) { + std::cout << "Hello-from-main" << std::endl; + std::cout << foo(bar(baz(13))) << std::endl; +} diff --git a/tests/test_rules/EXPRESSIONS b/tests/test_rules/EXPRESSIONS new file mode 100644 index 0000000..f1ca6f4 --- /dev/null +++ b/tests/test_rules/EXPRESSIONS @@ -0,0 +1,46 @@ +{ "stage_singleton_field": + { "vars": ["fieldname", "transition", "location"] + , "expression": + { "type": "assert_non_empty" + , "msg": + ["No artifact specified in field", {"type": "var", "name": "fieldname"}] + , "$1": + { "type": "disjoint_map_union" + , "msg": + [ "Expecting (essentially) a single artifact in field" + , {"type": "var", "name": "fieldname"} + ] + , "$1": + { "type": "foreach" + , "var": "src" + , "range": + {"type": "FIELD", "name": {"type": "var", "name": "fieldname"}} + , "body": + { "type": "disjoint_map_union" + , "$1": + { "type": "foreach" + , "var": "artifact" + , "range": + { "type": "values" + , "$1": + { "type": "DEP_ARTIFACTS" + , "dep": {"type": "var", "name": "src"} + , "transition": + { "type": "var" + , "name": "transition" + , "default": {"type": "empty_map"} + } + } + } + , "body": + { "type": "singleton_map" + , "key": {"type": "var", "name": "location"} + , "value": {"type": "var", "name": "artifact"} + } + } + } + } + } + } + } +} diff --git a/tests/test_rules/README.md b/tests/test_rules/README.md new file mode 100644 index 0000000..5a1baed --- /dev/null +++ b/tests/test_rules/README.md @@ -0,0 +1,28 @@ +# Test Rules + +This is a test rule that supports building and installing multiple targets with +a given set of rules. For each target, it can be specified whether building it +should fail or succeed. After processing all targets, additional assertions +(list of shell commands) can be run. + +## Setup + +The test rules expect to find the following three bindings: + - `[["@", "test-rules", "", "tree"]]`, which contains a single tree artifact + with the rules to test. + - `[["@", "test-just", "", ""]]`, which contains a single executable artifact + that is the JustBuild binary to use for the tests. + - `[["@", "test-libs", "", "tree"]]`, which contains a single tree artifact + that holds the file trees of external libraries. + +## Rule `["test_rules", "test_case"]` + +Define a test case for rule tests. + +| Field | Description | +| ----- | ----------- | +| `"name"` | Name of the test (multiple entries are joined). | +| `"libs"` | Paths to external libraries' trees provided by the `"test-libs"` repository. From within a test cases, the library's tree can be accessed via `["@", "<libname>", "", "tree"]`. | +| `"targets"` | Target names to build and install. Each target name is prefixed by `"+"` or `"-"`, indicating if the build should fail or not. Targets that build successfully will be installed to a directory named identical to the target name (without the prefix). | +| `"asserts"` | List of commands to execute after all targets were processed. To access artifacts from installed targets, use the corresponding target name as prefix dir (e.g., target `"+foo"` installs to `"./foo/"`). | +| `"data"` | The directory that contains the project with the targets to test. | diff --git a/tests/test_rules/RULES b/tests/test_rules/RULES new file mode 100644 index 0000000..3d2aba5 --- /dev/null +++ b/tests/test_rules/RULES @@ -0,0 +1,243 @@ +{ "test_case": + { "doc": + [ "Define a test case for rule tests." + , "The config variables \"ENV\", \"ARCH\", \"HOST_ARCH\", \"TARGET_ARCH\"," + , "\"BUILD_ARCH\", \"OS\" are collected in a file named \"conf_vars.json\"." + , "The test runner will pass that file as argument to \"-c\" to the \"just\"" + , "binary, which is internally called." + ] + , "string_fields": ["name", "libs", "targets", "asserts"] + , "target_fields": ["data"] + , "field_doc": + { "name": ["Name of the test (multiple entries are joined)."] + , "libs": + [ "Paths to external libraries' trees provided by the \"test-libs\"" + , "repository. From within a test cases, the library's tree can be" + , "accessed via [\"@\", \"<libpath>\", \"\", \"tree\"]." + ] + , "targets": + [ "Target names to build and install. Each target name is prefixed by" + , "\"+\" or \"-\", indicating if the build should fail or not." + , "Targets that build successfully will be installed to a directory" + , "named identical to the target name (without the prefix)." + ] + , "asserts": + [ "List of commands to execute after all targets were processed. To" + , "access artifacts from installed targets, use the corresponding target" + , "name as prefix dir (e.g., target \"+foo\" installs to \"./foo/\")." + ] + , "data": + ["The directory that contains the project with the targets to test."] + } + , "tainted": ["test"] + , "config_vars": + [ "ENV" + , "ARCH" + , "HOST_ARCH" + , "TARGET_ARCH" + , "BUILD_ARCH" + , "OS" + , "TOOLCHAIN_CONFIG" + ] + , "implicit": + { "runner": ["test_runner.py"] + , "rules": [["@", "test-rules", "", "tree"]] + , "just": [["@", "test-just", "", ""]] + , "libs_tree": [["@", "test-libs", "", "tree"]] + } + , "imports": {"stage_artifact": "stage_singleton_field"} + , "expression": + { "type": "let*" + , "bindings": + [ ["name", {"type": "join", "$1": {"type": "FIELD", "name": "name"}}] + , ["fieldname", "just"] + , ["location", "bin/just"] + , ["just", {"type": "CALL_EXPRESSION", "name": "stage_artifact"}] + , ["fieldname", "rules"] + , ["location", "rules"] + , ["rules", {"type": "CALL_EXPRESSION", "name": "stage_artifact"}] + , [ "imports" + , { "type": "singleton_map" + , "key": "imports/TARGETS" + , "value": + { "type": "BLOB" + , "data": "{\"tree\":{\"type\":\"install\",\"dirs\":[[[\"TREE\",null,\".\"],\".\"]]}}" + } + } + ] + , ["fieldname", "libs_tree"] + , ["location", "libs"] + , ["libs", {"type": "CALL_EXPRESSION", "name": "stage_artifact"}] + , ["fieldname", "data"] + , ["location", "work"] + , ["work", {"type": "CALL_EXPRESSION", "name": "stage_artifact"}] + , ["fieldname", "runner"] + , ["location", "runner"] + , ["runner", {"type": "CALL_EXPRESSION", "name": "stage_artifact"}] + , ["targets", {"type": "FIELD", "name": "targets"}] + , ["asserts", {"type": "FIELD", "name": "asserts"}] + , [ "work_bindings" + , { "type": "map_union" + , "$1": + { "type": "++" + , "$1": + [ [{"type": "singleton_map", "key": "rules", "value": "rules"}] + , { "type": "foreach" + , "range": {"type": "FIELD", "name": "libs"} + , "var": "libpath" + , "body": + { "type": "singleton_map" + , "key": {"type": "var", "name": "libpath"} + , "value": {"type": "var", "name": "libpath"} + } + } + ] + } + } + ] + , [ "work_deps" + , { "type": "map_union" + , "$1": + { "type": "++" + , "$1": + [ [ { "type": "let*" + , "bindings": + [ ["workspace_root", ["file", "rules"]] + , ["rules", {"type": "env", "vars": ["workspace_root"]}] + ] + , "body": {"type": "env", "vars": ["rules"]} + } + ] + , { "type": "foreach" + , "range": {"type": "FIELD", "name": "libs"} + , "var": "libpath" + , "body": + { "type": "let*" + , "bindings": + [ [ "workspace_root" + , [ "file" + , { "type": "join" + , "$1": ["libs/", {"type": "var", "name": "libpath"}] + } + ] + ] + , ["target_root", ["file", "imports"]] + ] + , "body": + { "type": "singleton_map" + , "key": {"type": "var", "name": "libpath"} + , "value": + { "type": "env" + , "vars": ["workspace_root", "target_root"] + } + } + } + } + ] + } + } + ] + , [ "repos" + , { "type": "singleton_map" + , "key": "repos.json" + , "value": + { "type": "BLOB" + , "data": + { "type": "json_encode" + , "$1": + { "type": "let*" + , "bindings": + [ ["workspace_root", ["file", "work"]] + , ["bindings", {"type": "var", "name": "work_bindings"}] + , [ "work" + , {"type": "env", "vars": ["workspace_root", "bindings"]} + ] + , [ "repositories" + , { "type": "map_union" + , "$1": + [ {"type": "env", "vars": ["work"]} + , {"type": "var", "name": "work_deps"} + ] + } + ] + , ["main", "work"] + ] + , "body": {"type": "env", "vars": ["main", "repositories"]} + } + } + } + } + ] + , [ "config" + , { "type": "singleton_map" + , "key": "config.json" + , "value": + { "type": "BLOB" + , "data": + { "type": "json_encode" + , "$1": {"type": "env", "vars": ["targets", "asserts"]} + } + } + } + ] + , [ "conf_vars" + , { "type": "singleton_map" + , "key": "conf_vars.json" + , "value": + { "type": "BLOB" + , "data": + { "type": "json_encode" + , "$1": + { "type": "env" + , "vars": + [ "ENV" + , "ARCH" + , "HOST_ARCH" + , "TARGET_ARCH" + , "BUILD_ARCH" + , "OS" + , "TOOLCHAIN_CONFIG" + ] + } + } + } + } + ] + , [ "results" + , { "type": "ACTION" + , "inputs": + { "type": "map_union" + , "$1": + [ {"type": "var", "name": "runner"} + , {"type": "var", "name": "rules"} + , {"type": "var", "name": "just"} + , {"type": "var", "name": "imports"} + , {"type": "var", "name": "libs"} + , {"type": "var", "name": "repos"} + , {"type": "var", "name": "work"} + , {"type": "var", "name": "config"} + , {"type": "var", "name": "conf_vars"} + ] + } + , "outs": ["stdout", "stderr", "result", "time-start", "time-stop"] + , "cmd": ["./runner"] + , "may_fail": ["test"] + , "fail_message": + { "type": "join" + , "$1": ["Rule test ", {"type": "var", "name": "name"}, " failed"] + } + } + ] + ] + , "body": + { "type": "RESULT" + , "artifacts": {"type": "var", "name": "results"} + , "runfiles": + { "type": "singleton_map" + , "key": {"type": "var", "name": "name"} + , "value": {"type": "TREE", "$1": {"type": "var", "name": "results"}} + } + } + } + } +} diff --git a/tests/test_rules/TARGETS b/tests/test_rules/TARGETS new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/test_rules/TARGETS @@ -0,0 +1 @@ +{} diff --git a/tests/test_rules/test_runner.py b/tests/test_rules/test_runner.py new file mode 100755 index 0000000..5c0d129 --- /dev/null +++ b/tests/test_rules/test_runner.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +# Copyright 2022 Huawei Cloud Computing Technology Co., Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import os +import subprocess +import time + +time_start: float = time.time() +time_stop: float = 0 +result: str = "UNKNOWN" +stderr: str = "" +stdout: str = "" + + +def dump_results() -> None: + with open("result", "w") as f: + f.write("%s\n" % (result, )) + with open("time-start", "w") as f: + f.write("%d\n" % (time_start, )) + with open("time-stop", "w") as f: + f.write("%d\n" % (time_stop, )) + with open("stdout", "w") as f: + f.write("%s\n" % (stdout, )) + with open("stderr", "w") as f: + f.write("%s\n" % (stderr, )) + + +dump_results() + +with open('config.json') as f: + config = json.load(f) + +os.makedirs("./outs") + +# install targets +failed_targets = 0 +stdout += "Test targets:\n" +for t in config.get('targets', []): + target = t[1:] + should_fail = t[0] == "-" + ret = subprocess.run([ + "./bin/just", "install", "--local-build-root", "./build_root", "-C", + "repos.json", "-o", "/".join(["./outs", target]), + "-c", "conf_vars.json", target + ], + capture_output=True) + success = ret.returncode != 0 if should_fail else ret.returncode == 0 + failed_targets += 0 if success else 1 + stdout += f" [{'PASS' if success else 'FAIL'}] {target}\n" + stderr += "".join([ + f"stdout/stderr of test target '{target}':\n", + ret.stdout.decode("utf-8"), + ret.stderr.decode("utf-8"), "\n" + ]) +stdout += f" {failed_targets} targets failed\n" + +# run asserts +failed_asserts = 0 +stdout += "Test asserts:\n" +for cmd in config.get('asserts', []): + ret = subprocess.run(cmd, cwd="./outs", shell=True, capture_output=True) + success = ret.returncode == 0 + failed_asserts += 0 if success else 1 + stdout += f" [{'PASS' if success else 'FAIL'}] {cmd}\n" + stderr += "".join([ + f"stdout/stderr of test assert '{cmd}':\n", + ret.stdout.decode("utf-8"), + ret.stderr.decode("utf-8"), "\n" + ]) +stdout += f" {failed_asserts} asserts failed\n" + +retval = min(failed_targets + failed_asserts, 125) +result = "PASS" if retval == 0 else "FAIL" + +time_stop = time.time() +dump_results() +exit(retval) |