summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlberto Sartori <alberto.sartori@huawei.com>2024-12-09 18:27:55 +0100
committerAlberto Sartori <alberto.sartori@huawei.com>2024-12-12 10:03:18 +0100
commit0eb56d57a2f24c603981f34b5dfe21e14e810cfc (patch)
tree951beed68bd843f0d597e5cb56376c07b1652dad
parentd7e42b7d8e2f5951ce4d38584014534e7d6d2ab1 (diff)
downloadrules-cc-0eb56d57a2f24c603981f34b5dfe21e14e810cfc.tar.gz
tests: define test cases for ["CC/auto","config_file"] rule
The unit tests for runner can be run via the ["test_cases/config", "pytest"] target, which requires `pytest` and `hypothesis`.
-rw-r--r--tests/TARGETS6
-rw-r--r--tests/test_cases/config/TARGETS57
-rw-r--r--tests/test_cases/config/data/TARGETS48
-rw-r--r--tests/test_cases/config/data/foo.in13
-rwxr-xr-xtests/test_cases/config/run_pytest.sh3
-rw-r--r--tests/test_cases/config/runner_test.py134
6 files changed, 260 insertions, 1 deletions
diff --git a/tests/TARGETS b/tests/TARGETS
index c64245e..e9b0f2a 100644
--- a/tests/TARGETS
+++ b/tests/TARGETS
@@ -1,6 +1,10 @@
{ "ALL":
{ "type": "install"
- , "deps": [["test_cases/deps", "ALL"], ["test_cases/cflags", "ALL"]]
+ , "deps":
+ [ ["test_cases/deps", "ALL"]
+ , ["test_cases/cflags", "ALL"]
+ , ["test_cases/config", "ALL"]
+ ]
, "tainted": ["test"]
}
}
diff --git a/tests/test_cases/config/TARGETS b/tests/test_cases/config/TARGETS
new file mode 100644
index 0000000..b751130
--- /dev/null
+++ b/tests/test_cases/config/TARGETS
@@ -0,0 +1,57 @@
+{ "both":
+ { "type": ["test_rules", "test_case"]
+ , "name": ["config_both"]
+ , "targets": ["+header_both"]
+ , "asserts":
+ [ "test -f header_both/foo.h"
+ , "cat header_both/foo.h"
+ , "grep '// comment 1$' header_both/foo.h"
+ , "grep '#define FOO 1$' header_both/foo.h"
+ , "grep '#define BAX 0$' header_both/foo.h"
+ , "grep '#define BAR \"foofoo bar foo\"$' header_both/foo.h"
+ , "grep '/\\* #undef BAZ \\*/$' header_both/foo.h"
+ , "grep '/\\* #undef BAX \\*/$' header_both/foo.h"
+ , "grep '#define FOO$' header_both/foo.h"
+ , "grep '// comment 2$' header_both/foo.h"
+ , "grep 'magic_at$' header_both/foo.h"
+ , "grep 'magic_curly$' header_both/foo.h"
+ , "grep 'undefined_at--$' header_both/foo.h"
+ , "grep 'undefined_curly--$' header_both/foo.h"
+ ]
+ , "data": [["TREE", null, "data"]]
+ }
+, "@only":
+ { "type": ["test_rules", "test_case"]
+ , "name": ["config_@only"]
+ , "targets": ["+header_@only"]
+ , "asserts":
+ [ "test -f header_@only/foo.h"
+ , "cat header_@only/foo.h"
+ , "grep '// comment 1$' header_@only/foo.h"
+ , "grep '#define FOO 1$' header_@only/foo.h"
+ , "grep '#define BAX 0$' header_@only/foo.h"
+ , "grep '#define BAR \"foofoo bar \\${FOO}\"$' header_@only/foo.h"
+ , "grep '/\\* #undef BAZ \\*/$' header_@only/foo.h"
+ , "grep '/\\* #undef BAX \\*/$' header_@only/foo.h"
+ , "grep '#define FOO$' header_@only/foo.h"
+ , "grep '// comment 2$' header_@only/foo.h"
+ , "grep 'magic_at$' header_@only/foo.h"
+ , "grep '\\${NO_MAGIC_CURLY}' header_@only/foo.h"
+ , "grep 'undefined_at--$' header_@only/foo.h"
+ , "grep 'undefined_curly-\\${UNDEFINED}-$' header_@only/foo.h"
+ ]
+ , "data": [["TREE", null, "data"]]
+ }
+, "runner.py":
+ { "type": "install"
+ , "files": {"runner.py": ["@", "rules", "CC/auto", "runner"]}
+ }
+, "pytest":
+ { "type": ["@", "rules", "shell/test", "script"]
+ , "name": ["config_pytest"]
+ , "test": ["run_pytest.sh"]
+ , "deps": ["runner.py", "runner_test.py"]
+ }
+, "ALL":
+ {"type": "install", "deps": ["both", "@only", "pytest"], "tainted": ["test"]}
+}
diff --git a/tests/test_cases/config/data/TARGETS b/tests/test_cases/config/data/TARGETS
new file mode 100644
index 0000000..f3e7cf0
--- /dev/null
+++ b/tests/test_cases/config/data/TARGETS
@@ -0,0 +1,48 @@
+{ "blueprint":
+ { "type": ["@", "rules", "CC/auto", "config_file"]
+ , "input": ["foo.in"]
+ , "output": ["foo.h"]
+ , "magic_string": ["cmakedefine"]
+ }
+, "blueprint_@only":
+ { "type": ["@", "rules", "CC/auto", "config_file"]
+ , "input": ["foo.in"]
+ , "output": ["foo.h"]
+ , "magic_string": ["cmakedefine"]
+ , "@only": ["true"]
+ }
+, "header_both":
+ { "type": "configure"
+ , "target": "blueprint"
+ , "config":
+ { "type": "let*"
+ , "bindings":
+ [ [ "defines"
+ , [ ["FOO", "foo"]
+ , ["BAR", "bar"]
+ , ["NO_MAGIC_AT", "magic_at"]
+ , ["NO_MAGIC_CURLY", "magic_curly"]
+ ]
+ ]
+ ]
+ , "body": {"type": "env", "vars": ["defines"]}
+ }
+ }
+, "header_@only":
+ { "type": "configure"
+ , "target": "blueprint_@only"
+ , "config":
+ { "type": "let*"
+ , "bindings":
+ [ [ "defines"
+ , [ ["FOO", "foo"]
+ , ["BAR", "bar"]
+ , ["NO_MAGIC_AT", "magic_at"]
+ , ["NO_MAGIC_CURLY", "magic_curly"]
+ ]
+ ]
+ ]
+ , "body": {"type": "env", "vars": ["defines"]}
+ }
+ }
+}
diff --git a/tests/test_cases/config/data/foo.in b/tests/test_cases/config/data/foo.in
new file mode 100644
index 0000000..66bd9ba
--- /dev/null
+++ b/tests/test_cases/config/data/foo.in
@@ -0,0 +1,13 @@
+// comment 1
+#cmakedefine01 FOO
+#cmakedefine01 BAX
+#cmakedefine FOO "@FOO@"
+#cmakedefine BAR "@FOO@@FOO@ bar ${FOO}"
+#cmakedefine BAZ "baz"
+#cmakedefine BAX
+#cmakedefine FOO
+// comment 2
+@NO_MAGIC_AT@
+${NO_MAGIC_CURLY}
+undefined_at-@UNDEFINED@-
+undefined_curly-${UNDEFINED}-
diff --git a/tests/test_cases/config/run_pytest.sh b/tests/test_cases/config/run_pytest.sh
new file mode 100755
index 0000000..fc886ea
--- /dev/null
+++ b/tests/test_cases/config/run_pytest.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+python3 -m pytest
diff --git a/tests/test_cases/config/runner_test.py b/tests/test_cases/config/runner_test.py
new file mode 100644
index 0000000..2f0920e
--- /dev/null
+++ b/tests/test_cases/config/runner_test.py
@@ -0,0 +1,134 @@
+# Copyright 2024 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.
+
+from runner import (
+ compute_value,
+ get_tokens,
+ handle01,
+ replace_value,
+ undefine,
+)
+
+from hypothesis import given
+from hypothesis.strategies import text
+import re
+
+
+def test_get_tokens():
+ magic_string = "cmakedefine"
+ match, is_01 = get_tokens(
+ f"# \t \t {magic_string} \t TOKEN_KEY \t\t TOKEN_VALUE \t\n", magic_string
+ )
+ assert match
+ assert not is_01
+ groups = match.groups()
+ assert len(groups) == 6
+ assert groups[1] == magic_string
+ assert groups[3] == "TOKEN_KEY"
+ assert groups[5] == "TOKEN_VALUE \t"
+
+ match, _ = get_tokens("#cmakedefine TOKEN_KEY TOKEN_VALUE", magic_string)
+ assert match
+ groups = match.groups()
+ assert groups[1] == magic_string
+ assert groups[3] == "TOKEN_KEY"
+ assert groups[5] == "TOKEN_VALUE"
+
+ match, _ = get_tokens("#cmakedefine TOKEN_KEY @TOKEN_VALUE@", magic_string)
+ assert match
+ groups = match.groups()
+ assert len(groups) == 6
+ assert groups[1] == magic_string
+ assert groups[3] == "TOKEN_KEY"
+ assert groups[5] == "@TOKEN_VALUE@"
+
+ match, _ = get_tokens("#cmakedefine TOKEN_KEY ${TOKEN_VALUE}", magic_string)
+ assert match
+ groups = match.groups()
+ assert len(groups) == 6
+ assert groups[1] == magic_string
+ assert groups[3] == "TOKEN_KEY"
+ assert groups[5] == "${TOKEN_VALUE}"
+
+ match, _ = get_tokens("#cmakedefine TOKEN_KEY", magic_string)
+ assert match
+ groups = match.groups()
+ assert len(groups) == 6
+ assert groups[1] == magic_string
+ assert groups[3] == "TOKEN_KEY"
+ assert groups[5] == ""
+
+ match, _ = get_tokens("#differnt_magic_string TOKEN_KEY", magic_string)
+ assert not match
+
+ match, is_01 = get_tokens(f"#{magic_string}01 TOKEN_KEY", magic_string)
+ assert match
+ assert is_01
+
+ match, _ = get_tokens(f'#cmakedefine FOO "@FOO@"', "cmakedefine")
+ groups = match.groups()
+ assert groups[5] == '"@FOO@"'
+
+
+def test_handle_01():
+ line = "#cmakedefine01 FOO"
+ tokens, _ = get_tokens(line, "cmakedefine")
+ assert handle01(line, tokens, True) == "#define FOO 1"
+ assert handle01(line, tokens, False) == "#define FOO 0"
+
+
+def test_undefine():
+ lines = [
+ "#cmakedefine FOO",
+ "#cmakedefine FOO foo",
+ "#cmakedefine FOO ${FOO}",
+ "#cmakedefine FOO @FOO@",
+ ]
+ for line in lines:
+ tokens, _ = get_tokens(line, "cmakedefine")
+ assert undefine(tokens) == "/* #undef FOO */"
+
+
+def test_replace_value():
+ line = "#cmakedefine FOO whatever@VVV@${FFF}"
+ tokens, _ = get_tokens(line, "cmakedefine")
+ groups = tokens.groups()
+ assert len(groups) == 6
+ assert groups[1] == "cmakedefine"
+ assert groups[3] == "FOO"
+ assert groups[5] == "whatever@VVV@${FFF}"
+ assert replace_value(tokens, "FOO", "VALUE") == "#define FOO VALUE"
+
+
+def test_compute_value():
+ token = "@KEY1@foo${KEY2}@KEY3@@KEY4@"
+ key_value_dict = {
+ "KEY1": "value1",
+ "KEY2": "value2",
+ "KEY3": "value3",
+ "KEY4": "value4",
+ "KEY5": "0",
+ }
+
+ assert compute_value(token, True, key_value_dict) == "value1foo${KEY2}value3value4"
+ assert compute_value(token, False, key_value_dict) == "value1foovalue2value3value4"
+ assert compute_value("@KEY5@", True, key_value_dict) == "0"
+
+
+@given(text())
+def test_substitution_with_given_value(s):
+ kv = {"FOO": s}
+ assert compute_value("@FOO@", True, kv) == s
+ assert compute_value("${FOO}", False, kv) == s
+ assert compute_value("${FOO}", True, kv) == "${FOO}"