Skip to content

Commit

Permalink
Test based on config data
Browse files Browse the repository at this point in the history
  • Loading branch information
wkoot committed Mar 5, 2024
1 parent 2150ea6 commit c7cfcba
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 22 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:

env:
CODE: "PROJ1"
RULES: "+csharpsquid:S104;-ts:S1561"
RULES: "+csharpsquid:S104;-ts:S1561;+Web:WhiteSpaceAroundCheck"

jobs:
build:
Expand Down
2 changes: 1 addition & 1 deletion docker/docker-compose.ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ services:
SONAR_JDBC_PASSWORD: "sonar_pass"
SONARQUBE_PASSWORD: "admin123"
PROJECT_CODE: "PROJ1"
PROJECT_RULES: "+csharpsquid:S104;-ts:S1561"
PROJECT_RULES: "+csharpsquid:S104;-ts:S1561;+Web:WhiteSpaceAroundCheck"

db:
environment:
Expand Down
104 changes: 84 additions & 20 deletions tests/test_smoke.py
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"])

0 comments on commit c7cfcba

Please sign in to comment.