Skip to content

Commit

Permalink
feat: modify run_community_analyzer to work for custom analyzers (#29)
Browse files Browse the repository at this point in the history
Resolves: ENG-972.
  • Loading branch information
eshaan-deepsource authored Feb 16, 2024
1 parent d824f2b commit bd0acfe
Show file tree
Hide file tree
Showing 2 changed files with 235 additions and 4 deletions.
11 changes: 7 additions & 4 deletions run_community_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,20 @@ def main(argv: list[str] | None = None) -> None:
toolbox_path = os.getenv("TOOLBOX_PATH", "/toolbox")
output_path = os.path.join(toolbox_path, "analysis_results.json")
artifacts_path = os.getenv("ARTIFACTS_PATH", "/artifacts")
issue_map_path = None

parser = argparse.ArgumentParser("sarif_parser")
parser.add_argument(
"--analyzer",
help="Which community analyzer to run. Example: 'kube-linter'",
required=True,
required=False,
)
args = parser.parse_args(argv, namespace=CommunityAnalyzerArgs)
if argv:
args = parser.parse_args(argv, namespace=CommunityAnalyzerArgs)
# analyzer name is mandatory in case of community analyzers but not custom analyzers
if analyzer_name := args.analyzer:
issue_map_path = get_issue_map(analyzer_name)

analyzer_name = args.analyzer
issue_map_path = get_issue_map(analyzer_name)
modified_files = get_files_to_analyze(code_path)
run_sarif_parser(
artifacts_path, output_path, issue_map_path, modified_files=modified_files
Expand Down
228 changes: 228 additions & 0 deletions tests/test_community_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,180 @@
"extra_data": {},
}

expected_result_no_issue_map = {
"is_passed": False,
"issues": [
{
"issue_code": "no-read-only-root-fs",
"issue_text": 'container "kube-scheduler" does not have a read-only root file system\nobject: <no namespace>/test-release-kube-scheduler apps/v1, Kind=Deployment',
"location": {
"path": "charts/kube-scheduler/templates/deployment.yaml",
"position": {
"begin": {"column": 1, "line": 1},
"end": {"column": 1, "line": 1},
},
},
},
{
"issue_code": "run-as-non-root",
"issue_text": 'container "kube-scheduler" is not set to runAsNonRoot\nobject: <no namespace>/test-release-kube-scheduler apps/v1, Kind=Deployment',
"location": {
"path": "charts/kube-scheduler/templates/deployment.yaml",
"position": {
"begin": {"column": 1, "line": 1},
"end": {"column": 1, "line": 1},
},
},
},
{
"issue_code": "env-var-secret",
"issue_text": 'environment variable TASK_IMAGE_PULL_SECRET_NAME in container "runner" found\nobject: <no namespace>/test-release-runner apps/v1, Kind=Deployment',
"location": {
"path": "charts/runner/templates/deployment.yaml",
"position": {
"begin": {"column": 1, "line": 1},
"end": {"column": 1, "line": 1},
},
},
},
{
"issue_code": "env-var-secret",
"issue_text": 'environment variable TASK_ARTIFACT_SECRET_NAME in container "runner" found\nobject: <no namespace>/test-release-runner apps/v1, Kind=Deployment',
"location": {
"path": "charts/runner/templates/deployment.yaml",
"position": {
"begin": {"column": 1, "line": 1},
"end": {"column": 1, "line": 1},
},
},
},
{
"issue_code": "no-read-only-root-fs",
"issue_text": 'container "runner" does not have a read-only root file system\nobject: <no namespace>/test-release-runner apps/v1, Kind=Deployment',
"location": {
"path": "charts/runner/templates/deployment.yaml",
"position": {
"begin": {"column": 1, "line": 1},
"end": {"column": 1, "line": 1},
},
},
},
{
"issue_code": "run-as-non-root",
"issue_text": 'container "runner" is not set to runAsNonRoot\nobject: <no namespace>/test-release-runner apps/v1, Kind=Deployment',
"location": {
"path": "charts/runner/templates/deployment.yaml",
"position": {
"begin": {"column": 1, "line": 1},
"end": {"column": 1, "line": 1},
},
},
},
{
"issue_code": "no-read-only-root-fs",
"issue_text": 'container "runner-rqlite" does not have a read-only root file system\nobject: <no namespace>/test-release-runner-rqlite apps/v1, Kind=StatefulSet',
"location": {
"path": "charts/runner/templates/rqlite-statefulset.yaml",
"position": {
"begin": {"column": 1, "line": 1},
"end": {"column": 1, "line": 1},
},
},
},
{
"issue_code": "run-as-non-root",
"issue_text": 'container "runner-rqlite" is not set to runAsNonRoot\nobject: <no namespace>/test-release-runner-rqlite apps/v1, Kind=StatefulSet',
"location": {
"path": "charts/runner/templates/rqlite-statefulset.yaml",
"position": {
"begin": {"column": 1, "line": 1},
"end": {"column": 1, "line": 1},
},
},
},
{
"issue_code": "latest-tag",
"issue_text": 'The container "wget" is using an invalid container image, "busybox". Please use images that are not blocked by the `BlockList` criteria : [".*:(latest)$" "^[^:]*$" "(.*/[^:]+)$"]\nobject: <no namespace>/test-release-runner-test-connection /v1, Kind=Pod',
"location": {
"path": "charts/runner/templates/tests/test-connection.yaml",
"position": {
"begin": {"column": 1, "line": 1},
"end": {"column": 1, "line": 1},
},
},
},
{
"issue_code": "no-read-only-root-fs",
"issue_text": 'container "wget" does not have a read-only root file system\nobject: <no namespace>/test-release-runner-test-connection /v1, Kind=Pod',
"location": {
"path": "charts/runner/templates/tests/test-connection.yaml",
"position": {
"begin": {"column": 1, "line": 1},
"end": {"column": 1, "line": 1},
},
},
},
{
"issue_code": "run-as-non-root",
"issue_text": 'container "wget" is not set to runAsNonRoot\nobject: <no namespace>/test-release-runner-test-connection /v1, Kind=Pod',
"location": {
"path": "charts/runner/templates/tests/test-connection.yaml",
"position": {
"begin": {"column": 1, "line": 1},
"end": {"column": 1, "line": 1},
},
},
},
{
"issue_code": "unset-cpu-requirements",
"issue_text": 'container "wget" has cpu request 0\nobject: <no namespace>/test-release-runner-test-connection /v1, Kind=Pod',
"location": {
"path": "charts/runner/templates/tests/test-connection.yaml",
"position": {
"begin": {"column": 1, "line": 1},
"end": {"column": 1, "line": 1},
},
},
},
{
"issue_code": "unset-cpu-requirements",
"issue_text": 'container "wget" has cpu limit 0\nobject: <no namespace>/test-release-runner-test-connection /v1, Kind=Pod',
"location": {
"path": "charts/runner/templates/tests/test-connection.yaml",
"position": {
"begin": {"column": 1, "line": 1},
"end": {"column": 1, "line": 1},
},
},
},
{
"issue_code": "unset-memory-requirements",
"issue_text": 'container "wget" has memory request 0\nobject: <no namespace>/test-release-runner-test-connection /v1, Kind=Pod',
"location": {
"path": "charts/runner/templates/tests/test-connection.yaml",
"position": {
"begin": {"column": 1, "line": 1},
"end": {"column": 1, "line": 1},
},
},
},
{
"issue_code": "unset-memory-requirements",
"issue_text": 'container "wget" has memory limit 0\nobject: <no namespace>/test-release-runner-test-connection /v1, Kind=Pod',
"location": {
"path": "charts/runner/templates/tests/test-connection.yaml",
"position": {
"begin": {"column": 1, "line": 1},
"end": {"column": 1, "line": 1},
},
},
},
],
"errors": [],
"metrics": [],
"extra_data": {},
}


def test_community_analyzer(tmp_path: Path) -> None:
"""Test for `run_community_analyzer.main()`, to test `issue_map.json` parsing."""
Expand Down Expand Up @@ -234,3 +408,57 @@ def test_community_analyzer(tmp_path: Path) -> None:
issue["location"]["path"]
== "charts/runner/templates/tests/test-connection.yaml"
)


def test_community_analyzer_without_issue_map(tmp_path: Path) -> None:
"""Test for `run_community_analyzer.main()` when no analyzer is specified and thus `issue_map.json` is not there."""
code_path = "/code"
toolbox_path = tmp_path.as_posix()
artifacts_path = os.path.join(os.path.dirname(__file__), "test_artifacts")
analysis_config_path = os.path.join(toolbox_path, "analysis_config.json")
modified_files = extract_filepaths_from_deepsource_json(code_path, expected_result)
os.environ["CODE_PATH"] = code_path
os.environ["TOOLBOX_PATH"] = toolbox_path
os.environ["ARTIFACTS_PATH"] = artifacts_path

# Case: when analysis config is not present, it should raise an error.
with pytest.raises(ValueError) as exe:
run_community_analyzer.main()
assert (
str(exe.value) == f"Could not find analysis config at {analysis_config_path}."
)

# Case: all files from the report are present in the analysis config.
with temp_analysis_config(analysis_config_path, modified_files):
run_community_analyzer.main()

analysis_results = tmp_path / "analysis_results.json"
assert analysis_results.exists()

with open(analysis_results) as file:
result = json.load(file)

assert result == expected_result_no_issue_map

# Case: only a subset of files from the report are present in the analysis config.
# Note: There are 7 issues in this file in our report fixture.
# See `expected_result`.
modified_files = [
os.path.join(code_path, "charts/runner/templates/tests/test-connection.yaml"),
]
with temp_analysis_config(analysis_config_path, modified_files):
run_community_analyzer.main()

analysis_results = tmp_path / "analysis_results.json"
assert analysis_results.exists()

with open(analysis_results) as file:
result = json.load(file)

assert len(result["issues"]) == 7

for issue in result["issues"]:
assert (
issue["location"]["path"]
== "charts/runner/templates/tests/test-connection.yaml"
)

0 comments on commit bd0acfe

Please sign in to comment.