Skip to content

Commit

Permalink
Fail a request if a Go workspace exists in the repository
Browse files Browse the repository at this point in the history
Since Cachito is not fully adapted to process Go workspaces, this
check aims to avoid incorrect results in case this feature is used
accidentaly.

CLOUDBLD-11068

Signed-off-by: Bruno Pimentel <bpimente@redhat.com>
  • Loading branch information
brunoapimentel committed Oct 3, 2022
1 parent 22bda26 commit c7fbbb1
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 2 deletions.
27 changes: 26 additions & 1 deletion cachito/workers/tasks/gomod.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# SPDX-License-Identifier: GPL-3.0-or-later
import logging
import os
from pathlib import Path

from cachito.common.packages_data import PackagesData
from cachito.errors import FileAccessError, GoModError, UnsupportedFeature
from cachito.errors import FileAccessError, GoModError, InvalidRepoStructure, UnsupportedFeature
from cachito.workers import run_cmd
from cachito.workers.config import get_worker_config
from cachito.workers.paths import RequestBundleDir
Expand Down Expand Up @@ -39,6 +40,28 @@ def _find_missing_gomod_files(bundle_dir, subpaths):
return invalid_gomod_files


def _is_workspace(repo_root: Path, subpath: str):
current_path = repo_root / subpath

while current_path != repo_root:
if (current_path / "go.work").exists():
log.warning("go.work file found at %s", current_path)
return True
current_path = current_path.parent

if (repo_root / "go.work").exists():
log.warning("go.work file found at %s", repo_root)
return True

return False


def _fail_if_bundle_dir_has_workspaces(bundle_dir: RequestBundleDir, subpaths: list[str]):
for subpath in subpaths:
if _is_workspace(bundle_dir.source_root_dir, subpath):
raise InvalidRepoStructure("Go workspaces are not supported by Cachito.")


@app.task
@runs_if_request_in_progress
def fetch_gomod_source(request_id, dep_replacements=None, package_configs=None):
Expand Down Expand Up @@ -68,6 +91,8 @@ def fetch_gomod_source(request_id, dep_replacements=None, package_configs=None):
# Default to the root of the application source
subpaths = [os.curdir]

_fail_if_bundle_dir_has_workspaces(bundle_dir, subpaths)

invalid_gomod_files = _find_missing_gomod_files(bundle_dir, subpaths)
if invalid_gomod_files:
invalid_files_print = "; ".join(invalid_gomod_files)
Expand Down
5 changes: 5 additions & 0 deletions tests/integration/test_data/gomod_packages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1956,3 +1956,8 @@ without_pkg_manager:
app: https://github.com/cachito-testing/cachito-gomod-without-deps/tarball/a888f7261b9a9683972fbd77da2d12fe86faef5e
deps: null
content_manifest: []
# The test data for gomod package manager test: check for Go workspaces
with_workspace:
repo: https://github.com/cachito-testing/cachito-gomod-with-workspace.git
ref: 8149e2e6996ec6e5b572a15b243773a277229f32
pkg_managers: ["gomod"]
27 changes: 27 additions & 0 deletions tests/integration/test_gomod_packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,30 @@ def test_gomod_vendor_check_fail(env_name, test_env):
f"#{completed_response.id}: Request failed correctly, but with unexpected message: "
f"{completed_response.data['state_reason']}. Expected message was: {error_msg}"
)


def test_gomod_workspace_check(test_env):
"""
Validate failing of gomod requests that contain workspaces.
Checks:
* The request fails with expected error message
"""
env_data = utils.load_test_data("gomod_packages.yaml")["with_workspace"]
client = utils.Client(test_env["api_url"], test_env["api_auth_type"], test_env.get("timeout"))
initial_response = client.create_new_request(
payload={
"repo": env_data["repo"],
"ref": env_data["ref"],
"pkg_managers": env_data["pkg_managers"],
},
)
completed_response = client.wait_for_complete_request(initial_response)
assert completed_response.status == 200
assert completed_response.data["state"] == "failed"
error_msg = "Go workspaces are not supported by Cachito."

assert error_msg in completed_response.data["state_reason"], (
f"#{completed_response.id}: Request failed correctly, but with unexpected message: "
f"{completed_response.data['state_reason']}. Expected message was: {error_msg}"
)
53 changes: 52 additions & 1 deletion tests/test_workers/test_tasks/test_gomod.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
import pytest

from cachito.common.packages_data import PackagesData
from cachito.errors import FileAccessError, UnsupportedFeature
from cachito.common.paths import RequestBundleDir
from cachito.errors import FileAccessError, InvalidRepoStructure, UnsupportedFeature
from cachito.workers import tasks
from cachito.workers.tasks import gomod

Expand Down Expand Up @@ -66,6 +67,7 @@
),
)
@pytest.mark.parametrize("has_pkg_lvl_deps", (True, False))
@mock.patch("cachito.workers.tasks.gomod._fail_if_bundle_dir_has_workspaces")
@mock.patch("cachito.workers.tasks.gomod.RequestBundleDir")
@mock.patch("cachito.workers.tasks.gomod.update_request_env_vars")
@mock.patch("cachito.workers.tasks.gomod.set_request_state")
Expand All @@ -77,6 +79,7 @@ def test_fetch_gomod_source(
mock_set_request_state,
mock_update_request_env_vars,
mock_bundle_dir,
mock_fail_workspaces,
dep_replacements,
expect_state_update,
pkg_config,
Expand Down Expand Up @@ -264,13 +267,15 @@ def directory_present(*args, **kwargs):
),
),
)
@mock.patch("cachito.workers.tasks.gomod._fail_if_bundle_dir_has_workspaces")
@mock.patch("cachito.workers.tasks.gomod.get_worker_config")
@mock.patch("cachito.workers.tasks.gomod.RequestBundleDir")
@mock.patch("cachito.workers.tasks.gomod.resolve_gomod")
def test_fetch_gomod_source_no_go_mod_file(
mock_resolve_gomod,
mock_bundle_dir,
mock_gwc,
mock_fail_workspaces,
ignore_missing_gomod_file,
exception_expected,
pkg_config,
Expand Down Expand Up @@ -313,3 +318,49 @@ def directory_present(*args, **kwargs):
)
def test_package_subpath(module_name, package_name, module_subpath, expect_subpath):
assert gomod._package_subpath(module_name, package_name, module_subpath) == expect_subpath


@pytest.mark.parametrize(
"repo, subpath, expected_result",
[
("repo", "workspace", True),
("repo", "workspace/mod_a", True),
("repo", "workspace/mod_b", True),
("repo", "nonworspace", False),
("repo", "nonworspace/mod_c", False),
("repo", "randompath", False),
("anotherrepo", ".", True),
],
)
def test_is_workspace(repo, subpath, expected_result, tmpdir):
tmpdir.mkdir("repo")
tmpdir.mkdir("repo/workspace")
tmpdir.mkdir("repo/workspace/mod_a")
tmpdir.mkdir("repo/workspace/mod_b")
tmpdir.mkdir("repo/nonworspace")
tmpdir.mkdir("repo/nonworspace/mod_c")
tmpdir.mkdir("anotherrepo")

Path(tmpdir / "repo/workspace" / "go.work").touch()
Path(tmpdir / "anotherrepo" / "go.work").touch()

repo_root = Path(tmpdir / repo)
result = gomod._is_workspace(repo_root, subpath)

assert result == expected_result


@pytest.mark.parametrize("add_go_work_file", [True, False])
def test_fail_if_bundle_dir_has_workspaces(add_go_work_file, tmpdir):
tmpdir.mkdir("temp")
tmpdir.mkdir("temp/1")
tmpdir.mkdir("temp/1/app")

bundle_dir = RequestBundleDir(1, tmpdir)

if add_go_work_file:
Path(bundle_dir.source_root_dir / "go.work").touch()
with pytest.raises(InvalidRepoStructure):
gomod._fail_if_bundle_dir_has_workspaces(bundle_dir, ["."])
else:
gomod._fail_if_bundle_dir_has_workspaces(bundle_dir, ["."])

0 comments on commit c7fbbb1

Please sign in to comment.