From 1f6546ed56666ba6af4eb05057ef6b9a3da95500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Csord=C3=A1s?= Date: Thu, 7 Apr 2022 09:14:34 +0200 Subject: [PATCH] [test] Environment variable on forcing ctu related tests CTU related tests should be forced in an environment which contains an underlying Clang that supports this feature. Automatic detection is not enough because there may be a bug in the automatic detection itself. --- analyzer/tests/functional/ctu/test_ctu.py | 7 +-- .../ctu_failure/test_ctu_failure.py | 13 +++-- analyzer/tests/libtest/codechecker.py | 50 +++++++++++++++++++ 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/analyzer/tests/functional/ctu/test_ctu.py b/analyzer/tests/functional/ctu/test_ctu.py index f0e1267325..dbff6b080e 100644 --- a/analyzer/tests/functional/ctu/test_ctu.py +++ b/analyzer/tests/functional/ctu/test_ctu.py @@ -18,7 +18,8 @@ from typing import IO from libtest import env -from libtest.codechecker import call_command +from libtest.codechecker import call_command, is_ctu_capable, \ + is_ctu_on_demand_capable from libtest.ctu_decorators import makeSkipUnlessCTUCapable, \ makeSkipUnlessCTUOnDemandCapable @@ -53,11 +54,11 @@ def setUp(self): cmd = [self._codechecker_cmd, 'analyze', '-h'] output, _, result = call_command(cmd, cwd=self.test_dir, env=self.env) self.assertEqual(result, 0, "Analyzing failed.") - setattr(self, CTU_ATTR, '--ctu-' in output) + setattr(self, CTU_ATTR, is_ctu_capable(output)) print("'analyze' reported CTU-compatibility? " + str(getattr(self, CTU_ATTR))) - setattr(self, ON_DEMAND_ATTR, '--ctu-ast-mode' in output) + setattr(self, ON_DEMAND_ATTR, is_ctu_on_demand_capable(output)) print("'analyze' reported CTU-on-demand-compatibility? " + str(getattr(self, ON_DEMAND_ATTR))) diff --git a/analyzer/tests/functional/ctu_failure/test_ctu_failure.py b/analyzer/tests/functional/ctu_failure/test_ctu_failure.py index 9bfe1b3ab2..e9a81d6609 100644 --- a/analyzer/tests/functional/ctu_failure/test_ctu_failure.py +++ b/analyzer/tests/functional/ctu_failure/test_ctu_failure.py @@ -15,11 +15,10 @@ import unittest import zipfile -from codechecker_analyzer import host_check - from libtest import env from libtest import project -from libtest.codechecker import call_command +from libtest.codechecker import call_command, is_ctu_capable, \ + is_ctu_on_demand_capable, is_ctu_display_progress_capable from libtest.ctu_decorators import makeSkipUnlessCTUCapable, \ makeSkipUnlessCTUOnDemandCapable, makeSkipUnlessCTUDisplayCapable @@ -57,17 +56,17 @@ def setUp(self): output, _, result = call_command(cmd, cwd=self.test_workspace, env=self.env) self.assertEqual(result, 0, "Analyzing failed.") - setattr(self, CTU_ATTR, '--ctu-' in output) + setattr(self, CTU_ATTR, is_ctu_capable(output)) print("'analyze' reported CTU compatibility? " + str(getattr(self, CTU_ATTR))) - setattr(self, ON_DEMAND_ATTR, '--ctu-ast-mode' in output) + setattr(self, ON_DEMAND_ATTR, is_ctu_on_demand_capable(output)) print("'analyze' reported CTU-on-demand-compatibility? " + str(getattr(self, ON_DEMAND_ATTR))) setattr(self, DISPLAY_PROGRESS_ATTR, - host_check.has_analyzer_config_option( - self.__getClangSaPath(), 'display-ctu-progress', self.env)) + is_ctu_display_progress_capable( + self.__getClangSaPath(), self.env)) print("Has display-ctu-progress=true? " + str(getattr(self, DISPLAY_PROGRESS_ATTR))) diff --git a/analyzer/tests/libtest/codechecker.py b/analyzer/tests/libtest/codechecker.py index 8d637bbeba..9cb5af2052 100644 --- a/analyzer/tests/libtest/codechecker.py +++ b/analyzer/tests/libtest/codechecker.py @@ -14,6 +14,11 @@ import shlex import subprocess +from distutils import util +from typing import Dict + +from codechecker_analyzer import host_check + from . import project @@ -120,3 +125,48 @@ def log_and_analyze(codechecker_cfg, test_project_path, clean_project=True): except subprocess.CalledProcessError as cerr: print("Failed to call:\n" + ' '.join(cerr.cmd)) return cerr.returncode + + +def check_force_ctu_capable(is_capable): + """ + Returns True if the given parameter is True of if CTU is force enabled by + the 'CC_TEST_FORCE_CTU_CAPABLE' environment variable. + """ + if not is_capable: + try: + return bool(util.strtobool( + os.environ['CC_TEST_FORCE_CTU_CAPABLE'])) + except (ValueError, KeyError): + pass + + return is_capable + + +def is_ctu_capable(output: str) -> bool: + """ + Returns True if the used clang is CTU capable or if it's force enabled by + environment variable. + """ + return check_force_ctu_capable('--ctu' in output) + + +def is_ctu_on_demand_capable(output: str) -> bool: + """ + Returns True if the used clang is CTU on demand capable or if it's force + enabled by environment variable. + """ + return check_force_ctu_capable('--ctu-ast-mode' in output) + + +def is_ctu_display_progress_capable( + clangsa_path: str, + env: Dict +) -> bool: + """ + Returns True if the used clang is CTU display progress capable or if it's + force enabled by environment variable. + """ + ctu_display_progress_capable = host_check.has_analyzer_config_option( + clangsa_path, 'display-ctu-progress', env) + + return check_force_ctu_capable(ctu_display_progress_capable)