-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
86 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,102 @@ | ||
from json import loads | ||
from os import getenv | ||
from unittest import TestCase, skipUnless | ||
|
||
import requests | ||
from sonarqube import SonarQubeClient | ||
|
||
PROJECT_CODE = getenv("PROJECT_CODE") | ||
PROJECT_RULES = getenv("PROJECT_RULES") | ||
CONFIG_FILE = getenv("CONFIG_FILE", "/src/config.json") | ||
|
||
|
||
class SonarTest(TestCase): | ||
def setUp(self) -> None: | ||
class FunctionalTest(TestCase): | ||
@classmethod | ||
def setUpClass(cls) -> None: | ||
with open(CONFIG_FILE, "r") as config_file: | ||
cls.config_json = loads(config_file.read()) | ||
sonar_port = getenv("SONAR_PORT", "9000") | ||
sonar_base_url = f"http://localhost:{sonar_port}" | ||
sonar_pass = getenv("SONARQUBE_PASSWORD", "admin") | ||
self.sonar_client = SonarQubeClient(sonarqube_url=sonar_base_url, username="admin", password=sonar_pass) | ||
cls.sonar_client = SonarQubeClient(sonarqube_url=sonar_base_url, username="admin", password=sonar_pass) | ||
cls.sonar_api = f"{sonar_base_url}/api" | ||
cls.sonar_auth = ("admin", sonar_pass) | ||
|
||
def test_java_profile(self): | ||
java_quality_profiles = self.sonar_client.qualityprofiles.search_quality_profiles(language="java") | ||
java_profile_names = [profile["name"] for profile in java_quality_profiles["profiles"]] | ||
self.assertIn("Sonar way", java_profile_names) | ||
def test_sonar_way_profile_remains(self): | ||
"""Ensure that the 'Sonar way' profile remains when an ICTU profile is defined for the language.""" | ||
self.assertIn("java", self.config_json["profiles"]) | ||
java_profiles = self.sonar_client.qualityprofiles.search_quality_profiles(defaults="false", language="java") | ||
self.assertIn("Sonar way", [profile["name"] for profile in java_profiles["profiles"]]) | ||
|
||
@skipUnless(PROJECT_CODE, "PROJECT_CODE was not passed") | ||
def test_csharpsquid_profile(self): | ||
search_result = self.sonar_client.qualityprofiles.search_quality_profiles( | ||
defaults="true", language="cs", qualityProfile=f"{PROJECT_CODE}-ictu-cs-profile-v9.13.0-20231222" | ||
@skipUnless(PROJECT_RULES, "PROJECT_RULES was not passed") | ||
def test_project_override_profile(self): | ||
"""Verify that overridden rule activation is applied.""" | ||
override_project_rules = PROJECT_RULES.split(";") | ||
self.assertTrue(any([rule_line == "+Web:WhiteSpaceAroundCheck" for rule_line in override_project_rules])) | ||
|
||
web_versioned_profile = f"{self.config_json['profiles']['web']['version']}-{self.config_json['rules_version']}" | ||
web_profile_search = self.sonar_client.qualityprofiles.search_quality_profiles( | ||
defaults="true", language="web", qualityProfile=f"{PROJECT_CODE}-ictu-{web_versioned_profile}" | ||
) | ||
self.assertEqual(len(search_result['profiles']), 1) | ||
cs_profile_key = search_result['profiles'][0]['key'] | ||
self.assertIsNotNone(cs_profile_key) # TODO - check activated rules within profile instead | ||
self.assertEqual(1, len(web_profile_search["profiles"])) | ||
|
||
@skipUnless(PROJECT_CODE, "PROJECT_CODE was not passed") | ||
def test_ts_profile(self): | ||
search_result = self.sonar_client.qualityprofiles.search_quality_profiles( | ||
defaults="true", language="ts", qualityProfile=f"{PROJECT_CODE}-ictu-ts-profile-v10.9.0-20231222" | ||
web_rule = self.sonar_client.rules.search_rules( | ||
activation="true", qprofile=web_profile_search["profiles"][0]["key"], rule_key="Web:WhiteSpaceAroundCheck" | ||
) | ||
self.assertEqual(1, web_rule["total"]) | ||
|
||
def test_type_profile(self): | ||
"""Verify that overridden rule type activation is applied.""" | ||
self.assertTrue(True) | ||
|
||
def test_rule_params_in_profile(self): | ||
"""Verify that custom profile rule params are applied.""" | ||
cs_param_rule_lines = [rule_line for rule_line in self.config_json["rules"]["cs"] if "|" in rule_line] | ||
self.assertNotEqual([], cs_param_rule_lines) | ||
|
||
cs_versioned_profile = f"{self.config_json['profiles']['cs']['version']}-{self.config_json['rules_version']}" | ||
cs_profile_search = self.sonar_client.qualityprofiles.search_quality_profiles( | ||
language="cs", qualityProfile=f"ictu-{cs_versioned_profile}" | ||
) | ||
self.assertEqual(len(search_result['profiles']), 1) | ||
ts_profile_key = search_result['profiles'][0]['key'] | ||
self.assertIsNotNone(ts_profile_key) # TODO - check activated rules within profile instead | ||
self.assertEqual(1, len(cs_profile_search["profiles"])) | ||
|
||
changelog_api = f"{self.sonar_api}/qualityprofiles/changelog" | ||
change_history_params = {"language": "cs", "qualityProfile": f"ictu-{cs_versioned_profile}", "ps": 500} | ||
api_result = requests.get(changelog_api, auth=self.sonar_auth, params=change_history_params).json() | ||
self.assertGreater(change_history_params["ps"], api_result["total"]) | ||
|
||
profile_changes = api_result["events"] | ||
for cs_rule_line in cs_param_rule_lines: | ||
if cs_rule_line[0] == "-": | ||
continue | ||
rule_key, rule_params_str = cs_rule_line[1:].split()[0].split("|") | ||
rule_changes = [change for change in profile_changes if change["ruleKey"] == rule_key] | ||
for rule_param_str in rule_params_str.split(";"): | ||
rule_params = rule_param_str.split("=") | ||
param_dict = {rule_params[0]: rule_params[1]} | ||
param_update = next( | ||
param_dict.items() <= rule_change.get('params', {}).items() for rule_change in rule_changes | ||
) | ||
self.assertTrue(param_update) | ||
|
||
def test_profile_rule_deactivation(self): | ||
"""Verify that custom profile rule deactivation is applied.""" | ||
ts_rule_lines = self.config_json["rules"]["ts"] | ||
self.assertTrue(any([rule_line.startswith("-") for rule_line in ts_rule_lines])) | ||
self.assertTrue(any([rule_line.startswith("+") for rule_line in ts_rule_lines])) | ||
|
||
ts_versioned_profile = f"{self.config_json['profiles']['ts']['version']}-{self.config_json['rules_version']}" | ||
ts_profile_search = self.sonar_client.qualityprofiles.search_quality_profiles( | ||
language="ts", qualityProfile=f"ictu-{ts_versioned_profile}" | ||
) | ||
|
||
for ts_rule_line in ts_rule_lines: | ||
activation = "yes" if ts_rule_line[0] == "+" else "no" | ||
rule_key = ts_rule_line[1:].split()[0].split("|")[0] | ||
if not rule_key.startswith("typescript"): | ||
continue | ||
ts_rule = self.sonar_client.rules.search_rules( | ||
activation=activation, qprofile=ts_profile_search["profiles"][0]["key"], rule_key=rule_key | ||
) | ||
self.assertEqual(1, ts_rule["total"]) |