diff options
-rw-r--r-- | etc/imports/gtest.TARGETS | 6 | ||||
-rw-r--r-- | etc/imports/libs.TARGETS | 3 | ||||
-rw-r--r-- | etc/repos.json | 22 | ||||
-rw-r--r-- | etc/repos.template.json | 22 | ||||
-rw-r--r-- | tests/test_cases/deps/TARGETS | 41 | ||||
-rw-r--r-- | tests/test_cases/deps/cmake/TARGETS | 52 | ||||
-rw-r--r-- | tests/test_cases/deps/cmake/main.cpp | 8 | ||||
-rw-r--r-- | tests/test_cases/deps/cmake/test.cpp | 3 | ||||
-rw-r--r-- | tests/test_cases/deps/cmake/test.sh | 5 | ||||
-rw-r--r-- | tests/test_rules/README.md | 5 | ||||
-rw-r--r-- | tests/test_rules/RULES | 95 |
11 files changed, 252 insertions, 10 deletions
diff --git a/etc/imports/gtest.TARGETS b/etc/imports/gtest.TARGETS new file mode 100644 index 0000000..a9b2217 --- /dev/null +++ b/etc/imports/gtest.TARGETS @@ -0,0 +1,6 @@ +{ "tree": + { "type": "install" + , "dirs": [[["TREE", null, "."], "googletest"]] + , "tainted": ["test"] + } +} diff --git a/etc/imports/libs.TARGETS b/etc/imports/libs.TARGETS new file mode 100644 index 0000000..f455122 --- /dev/null +++ b/etc/imports/libs.TARGETS @@ -0,0 +1,3 @@ +{ "tree": + {"type": "tree", "deps": [["@", "gtest", "", "tree"]], "tainted": ["test"]} +} diff --git a/etc/repos.json b/etc/repos.json index 0e26865..06158d3 100644 --- a/etc/repos.json +++ b/etc/repos.json @@ -7,7 +7,11 @@ } , "tests": { "repository": {"type": "file", "path": "tests"} - , "bindings": {"test-just": "just", "test-rules": "test-rules"} + , "bindings": + { "test-just": "just" + , "test-rules": "test-rules" + , "test-libs": "test-libs" + } } , "imports": {"repository": {"type": "file", "path": "etc/imports"}} , "test-rules": @@ -15,6 +19,22 @@ , "target_root": "imports" , "target_file_name": "rules.TARGETS" } + , "test-libs": + { "repository": "imports" + , "target_file_name": "libs.TARGETS" + , "bindings": {"gtest": "gtest"} + } + , "gtest": + { "repository": + { "type": "archive" + , "fetch": "https://github.com/google/googletest/archive/refs/tags/v1.13.0.tar.gz" + , "content": "cbd19f97df3ab86b174520cd850d238617c156e0" + , "sha256": "ad7fdba11ea011c1d925b3289cf4af2c66a352e18d4c7264392fead75e919363" + , "subdir": "googletest-1.13.0" + } + , "target_root": "imports" + , "target_file_name": "gtest.TARGETS" + } , "just": { "repository": { "type": "git" diff --git a/etc/repos.template.json b/etc/repos.template.json index 1b54fe9..4bdd1dc 100644 --- a/etc/repos.template.json +++ b/etc/repos.template.json @@ -7,7 +7,11 @@ } , "tests": { "repository": {"type": "file", "path": "tests"} - , "bindings": {"test-just": "just", "test-rules": "test-rules"} + , "bindings": + { "test-just": "just" + , "test-rules": "test-rules" + , "test-libs": "test-libs" + } } , "imports": {"repository": {"type": "file", "path": "etc/imports"}} , "test-rules": @@ -15,5 +19,21 @@ , "target_root": "imports" , "target_file_name": "rules.TARGETS" } + , "test-libs": + { "repository": "imports" + , "target_file_name": "libs.TARGETS" + , "bindings": {"gtest": "gtest"} + } + , "gtest": + { "repository": + { "type": "archive" + , "fetch": "https://github.com/google/googletest/archive/refs/tags/v1.13.0.tar.gz" + , "content": "cbd19f97df3ab86b174520cd850d238617c156e0" + , "sha256": "ad7fdba11ea011c1d925b3289cf4af2c66a352e18d4c7264392fead75e919363" + , "subdir": "googletest-1.13.0" + } + , "target_root": "imports" + , "target_file_name": "gtest.TARGETS" + } } } diff --git a/tests/test_cases/deps/TARGETS b/tests/test_cases/deps/TARGETS index c4cfdbc..450d1a3 100644 --- a/tests/test_cases/deps/TARGETS +++ b/tests/test_cases/deps/TARGETS @@ -148,9 +148,48 @@ ] , "data": ["prebuilt_tests"] } +, "cmake": + { "type": ["test_rules", "test_case"] + , "name": ["deps_cmake"] + , "libs": ["googletest"] + , "targets": + [ "+gtest" + , "+test" + , "+gtest_main" + , "+testbin" + , "+shell_test" + , "+install_gtest" + , "+install_gtest_main" + , "+install_testbin" + ] + , "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.*share/pkgconfig/gtest.cflags' install_gtest/share/pkgconfig/gtest.pc" + , "grep 'Libs.*libgtest.a' install_gtest/share/pkgconfig/gtest.pc" + , "grep 'Libs.*share/pkgconfig/gtest.ldflags' install_gtest/share/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.*share/pkgconfig/gtest_main.cflags' install_gtest_main/share/pkgconfig/gtest_main.pc" + , "grep 'Libs.*libgtest.so.1.13.0' install_gtest_main/share/pkgconfig/gtest_main.pc" + , "grep 'Libs.*libgtest_main.so.1.13.0' install_gtest_main/share/pkgconfig/gtest_main.pc" + , "grep 'Libs.*share/pkgconfig/gtest_main.ldflags' install_gtest_main/share/pkgconfig/gtest_main.pc" + , "./install_testbin/bin/test | grep 'PASSED.*1 test'" + ] + , "data": [["TREE", null, "cmake"]] + } , "ALL": { "type": "install" - , "deps": ["private", "public", "shared", "prebuilt"] + , "deps": ["private", "public", "shared", "prebuilt", "cmake"] , "tainted": ["test"] } } diff --git a/tests/test_cases/deps/cmake/TARGETS b/tests/test_cases/deps/cmake/TARGETS new file mode 100644 index 0000000..74633b9 --- /dev/null +++ b/tests/test_cases/deps/cmake/TARGETS @@ -0,0 +1,52 @@ +{ "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"]} +} 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_rules/README.md b/tests/test_rules/README.md index 8ed8f91..5a1baed 100644 --- a/tests/test_rules/README.md +++ b/tests/test_rules/README.md @@ -7,11 +7,13 @@ should fail or succeed. After processing all targets, additional assertions ## Setup -The test rules expect to find the following two bindings: +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"]` @@ -20,6 +22,7 @@ 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 index 1a65ec8..f53efba 100644 --- a/tests/test_rules/RULES +++ b/tests/test_rules/RULES @@ -1,9 +1,14 @@ { "test_case": { "doc": ["Define a test case for rule tests."] - , "string_fields": ["name", "targets", "asserts"] + , "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." @@ -23,6 +28,7 @@ { "runner": ["test_runner.py"] , "rules": [["@", "test-rules", "", "tree"]] , "just": [["@", "test-just", "", ""]] + , "libs_tree": [["@", "test-libs", "", "tree"]] } , "imports": {"stage_artifact": "stage_singleton_field"} , "expression": @@ -35,6 +41,18 @@ , ["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"}] @@ -43,6 +61,67 @@ , ["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" @@ -54,15 +133,17 @@ { "type": "let*" , "bindings": [ ["workspace_root", ["file", "work"]] - , ["rules", "rules"] - , ["bindings", {"type": "env", "vars": ["rules"]}] + , ["bindings", {"type": "var", "name": "work_bindings"}] , [ "work" , {"type": "env", "vars": ["workspace_root", "bindings"]} ] - , ["workspace_root", ["file", "rules"]] - , ["rules", {"type": "env", "vars": ["workspace_root"]}] , [ "repositories" - , {"type": "env", "vars": ["rules", "work"]} + , { "type": "map_union" + , "$1": + [ {"type": "env", "vars": ["work"]} + , {"type": "var", "name": "work_deps"} + ] + } ] , ["main", "work"] ] @@ -92,6 +173,8 @@ [ {"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"} |