diff --git a/test/unit/compile_commands/BUILD b/test/unit/compile_commands/BUILD index 9c5c8ace..9767bd2f 100644 --- a/test/unit/compile_commands/BUILD +++ b/test/unit/compile_commands/BUILD @@ -16,8 +16,10 @@ load("@rules_cc//cc:defs.bzl", "cc_library") load("//:defs.bzl", "compile_commands") load( ":analysis_test.bzl", + "c_only_has_conlyopt_flag_test", "compile_flags_test_suite", "custom_ccinfo", + "cxx_only_has_cxx_flag_test", "defines_from_impl_deps_test", "includes_from_impl_deps_test", "local_defines_in_impl_deps_test", @@ -264,3 +266,28 @@ no_duplicate_records_test( name = "no_duplicate_records", target_under_test = ":records", ) + +# cxxopt / conlyopt filtering +# ---------------------------- +# Verifies that --cxxopt flags only appear on C++ files and +# --conlyopt flags only appear on C files. + +cc_library( + name = "target_with_c_and_cc", + srcs = [ + "testdata/bar.c", + "testdata/bar.cc", + ], + hdrs = ["testdata/bar.h"], + tags = ["manual"], +) + +cxx_only_has_cxx_flag_test( + name = "cxx_only_has_cxx_flag", + target_under_test = ":target_with_c_and_cc", +) + +c_only_has_conlyopt_flag_test( + name = "c_only_has_conlyopt_flag", + target_under_test = ":target_with_c_and_cc", +) diff --git a/test/unit/compile_commands/analysis_test.bzl b/test/unit/compile_commands/analysis_test.bzl index d9e67783..f5747453 100644 --- a/test/unit/compile_commands/analysis_test.bzl +++ b/test/unit/compile_commands/analysis_test.bzl @@ -318,6 +318,74 @@ quote_includes_from_deps_test = analysistest.make( extra_target_under_test_aspects = [compile_commands_aspect], ) +def _cxx_only_has_cxx_flag_test_impl(ctx): + """cxxopt flags must only appear in compile commands for c++ files.""" + env = analysistest.begin(ctx) + commands = _get_compile_commands(analysistest.target_under_test(env)[SourceFilesInfo]) + + # Has cxx flags + cc_commands = [c for c in commands if "bar.cc" in c] + asserts.true(env, len(cc_commands) > 0, "Should have a command for bar.cc") + asserts.true( + env, + "__CXX__" in cc_commands[0], + "C++ file should contain cxxopt flag __CXX__, got: %s" % cc_commands[0], + ) + + # Doesn't have conly flags + cc_commands = [c for c in commands if "bar.cc" in c] + asserts.true(env, len(cc_commands) > 0, "Should have a command for bar.cc") + asserts.false( + env, + "__CONLY__" in cc_commands[0], + "C++ file should NOT contain conlyopt flag __CONLY__, got: %s" % cc_commands[0], + ) + + return analysistest.end(env) + +cxx_only_has_cxx_flag_test = analysistest.make( + _cxx_only_has_cxx_flag_test_impl, + extra_target_under_test_aspects = [compile_commands_aspect], + config_settings = { + "//command_line_option:conlyopt": ["__CONLY__"], + "//command_line_option:cxxopt": ["__CXX__"], + }, +) + +def _c_only_has_conlyopt_flag_test_impl(ctx): + """conlyopt flags must only appear in compile commands for .c files.""" + env = analysistest.begin(ctx) + commands = _get_compile_commands(analysistest.target_under_test(env)[SourceFilesInfo]) + + # Has conly flags + c_commands = [c for c in commands if c.endswith("/bar.c")] + asserts.true(env, len(c_commands) > 0, "Should have a command for bar.c") + asserts.true( + env, + "__CONLY__" in c_commands[0], + "C file should contain conlyopt flag __CONLY__, got: %s" % c_commands[0], + ) + + # Doesn't have cxx flags + c_commands = [c for c in commands if c.endswith("/bar.c")] + asserts.true(env, len(c_commands) > 0, "Should have a command for bar.c") + asserts.false( + env, + "__CXX__" in c_commands[0], + "C file should NOT contain cxxopt flag __CXX__, got: %s" % c_commands[0], + ) + + return analysistest.end(env) + +c_only_has_conlyopt_flag_test = analysistest.make( + _c_only_has_conlyopt_flag_test_impl, + extra_target_under_test_aspects = [compile_commands_aspect], + config_settings = { + "//command_line_option:conlyopt": ["__CONLY__"], + "//command_line_option:cxxopt": ["__CXX__"], + }, +) + def _no_duplicates_test_impl(ctx): """Compile flags should not contain duplicates.""" env = analysistest.begin(ctx) diff --git a/test/unit/compile_flags/BUILD b/test/unit/compile_flags/BUILD deleted file mode 100644 index b6943762..00000000 --- a/test/unit/compile_flags/BUILD +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright 2023 Ericsson AB -# -# 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. - -# cc_binary for simple C++ tests -load( - "@rules_cc//cc:defs.bzl", - "cc_library", -) -load( - "//:defs.bzl", - "codechecker_test", - "compile_commands", -) - -cc_library( - name = "target_with_both_extension", - srcs = [ - "simple_c.c", - "simple_cc.cc", - ], - tags = ["manual"], -) - -compile_commands( - name = "compile_commands_filter", - targets = [ - ":target_with_both_extension", - ], -) - -# The distributed rule uses a different -# method for generating compile_commands.json -codechecker_test( - name = "per_file_filter", - per_file = True, - tags = ["manual"], - targets = [ - "target_with_both_extension", - ], -) diff --git a/test/unit/compile_flags/simple_c.c b/test/unit/compile_flags/simple_c.c deleted file mode 100644 index 751b23f1..00000000 --- a/test/unit/compile_flags/simple_c.c +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2023 Ericsson AB - * - * 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. - */ - -// The content of this file, is irrelevant, only its extension matters -int main() { return 0; } diff --git a/test/unit/compile_flags/simple_cc.cc b/test/unit/compile_flags/simple_cc.cc deleted file mode 100644 index 430090c2..00000000 --- a/test/unit/compile_flags/simple_cc.cc +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2023 Ericsson AB - * - * 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. - */ - - // The content of this file, is irrelevant, only its extension matters -int main() { return 0; } diff --git a/test/unit/compile_flags/test_compile_flags.py b/test/unit/compile_flags/test_compile_flags.py deleted file mode 100644 index 5c784480..00000000 --- a/test/unit/compile_flags/test_compile_flags.py +++ /dev/null @@ -1,115 +0,0 @@ -# Copyright 2023 Ericsson AB -# -# 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. - -""" -Unit and functional tests -""" -import os -import json -import unittest -from common.base import TestBase - -# The documentation for the build command can be found here: -# https://bazel.build/docs/user-manual#cconlyopt - - -class TestBasic(TestBase): - """Basic tests""" - - # Set working directory - __test_path__ = os.path.dirname(os.path.abspath(__file__)) - BAZEL_BIN_DIR = os.path.join( - "../../..", "bazel-bin", "test", "unit", "compile_flags" - ) - BAZEL_TESTLOGS_DIR = os.path.join( - "../../..", "bazel-testlogs", "test", "unit", "compile_flags" - ) - - def test_bazel_test_compile_commands_filter(self): - """Test: bazel test :compile_commands_filter""" - build_cmd = ( - "bazel build " - + "//test/unit/compile_flags:compile_commands_filter " - + "--cxxopt=__CXX__ --conlyopt=__CONLY__" - ) - exit_code, _, stderr = self.run_command(build_cmd) - self.assertEqual(0, exit_code, stderr) - compile_commands = os.path.join( - self.BAZEL_BIN_DIR, # pyright: ignore - "compile_commands_filter", - "compile_commands.json", - ) - - with open(compile_commands, "r", encoding="utf-8") as f: - json_content = json.load(f) - for source in json_content: - if source["file"].endswith(".c"): - self.assertNotIn( - "__CXX__", source["command"], "C++ flag on C file!" - ) - self.assertIn( - "__CONLY__", - source["command"], - "C only flag not on C file!", - ) - if source["file"].endswith(".cc"): - self.assertIn( - "__CXX__", source["command"], "C++ flag on C file!" - ) - self.assertNotIn( - "__CONLY__", - source["command"], - "C only flag not on C file!", - ) - - def test_bazel_test_per_file_filter(self): - """Test: bazel test :per_file_filter""" - build_cmd = ( - "bazel build " - + "//test/unit/compile_flags:per_file_filter " - + "--cxxopt=__CXX__ --conlyopt=__CONLY__" - ) - exit_code, _, stderr = self.run_command(build_cmd) - self.assertEqual(0, exit_code, stderr) - compile_commands = os.path.join( - self.BAZEL_BIN_DIR, # pyright: ignore - "per_file_filter", - "compile_commands.json", - ) - self.assertTrue(os.path.exists(compile_commands)) - with open(compile_commands, "r", encoding="utf-8") as f: - json_content = json.load(f) - for source in json_content: - if source["file"].endswith(".c"): - self.assertNotIn( - "__CXX__", source["command"], "C++ flag on C file!" - ) - self.assertIn( - "__CONLY__", - source["command"], - "C only flag not on C file!", - ) - if source["file"].endswith(".cc"): - self.assertIn( - "__CXX__", source["command"], "C++ flag on C file!" - ) - self.assertNotIn( - "__CONLY__", - source["command"], - "C only flag not on C file!", - ) - - -if __name__ == "__main__": - unittest.main(buffer=True)