diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9d55315..0ceef01 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -44,8 +44,6 @@ hadolint: import httpx import os import sys - import uuid - import hashlib BASE_URL = os.environ.get("BASE_URL") if not BASE_URL: @@ -55,78 +53,32 @@ hadolint: print(f"Running integration tests against {BASE_URL}") client = httpx.Client(base_url=BASE_URL, timeout=30.0) - # Generate unique names for this test run - test_id = uuid.uuid4().hex[:8] - project_name = f"ci-test-{test_id}" - package_name = f"test-package-{test_id}" - test_content = f"Test content from CI pipeline {test_id}" - expected_hash = hashlib.sha256(test_content.encode()).hexdigest() - errors = [] - try: - # Test 1: Health endpoint - print("\n=== Test 1: Health endpoint ===") - r = client.get("/health") - if r.status_code == 200: - print("PASS: Health check passed") - else: - errors.append(f"Health check failed: {r.status_code}") + # Test 1: Health endpoint + print("\n=== Test 1: Health endpoint ===") + r = client.get("/health") + if r.status_code == 200: + print("PASS: Health check passed") + else: + errors.append(f"Health check failed: {r.status_code}") - # Test 2: Create project - print("\n=== Test 2: Create project ===") - r = client.post("/api/v1/projects", json={"name": project_name}) - if r.status_code == 201: - print(f"PASS: Created project: {project_name}") - else: - errors.append(f"Failed to create project: {r.status_code} - {r.text}") + # Test 2: API responds (list projects) + print("\n=== Test 2: API responds ===") + r = client.get("/api/v1/projects") + if r.status_code == 200: + projects = r.json() + print(f"PASS: API responding, found {len(projects)} project(s)") + else: + errors.append(f"API check failed: {r.status_code}") - # Test 3: Create package - print("\n=== Test 3: Create package ===") - r = client.post(f"/api/v1/project/{project_name}/packages", json={"name": package_name}) - if r.status_code == 201: - print(f"PASS: Created package: {package_name}") - else: - errors.append(f"Failed to create package: {r.status_code} - {r.text}") - - # Test 4: Upload artifact - print("\n=== Test 4: Upload artifact ===") - files = {"file": ("test.txt", test_content.encode(), "text/plain")} - r = client.post(f"/api/v1/project/{project_name}/{package_name}/upload", files=files) - if r.status_code == 201: - upload_data = r.json() - print(f"PASS: Uploaded artifact: {upload_data.get('artifact_id', 'unknown')[:16]}...") - else: - errors.append(f"Failed to upload: {r.status_code} - {r.text}") - - # Test 5: Download artifact by hash - print("\n=== Test 5: Download artifact ===") - r = client.get(f"/api/v1/project/{project_name}/{package_name}/+/artifact:{expected_hash}", follow_redirects=True) - if r.status_code == 200: - if r.content.decode() == test_content: - print("PASS: Downloaded content matches uploaded content") - else: - errors.append(f"Content mismatch: got '{r.content.decode()}'") - else: - errors.append(f"Failed to download: {r.status_code}") - - # Test 6: List artifacts - print("\n=== Test 6: List artifacts ===") - r = client.get(f"/api/v1/project/{project_name}/{package_name}/artifacts") - if r.status_code == 200: - artifacts = r.json() - print(f"PASS: Found {len(artifacts)} artifact(s)") - else: - errors.append(f"Failed to list artifacts: {r.status_code}") - - finally: - # Cleanup: Delete the test project - print("\n=== Cleanup ===") - r = client.delete(f"/api/v1/project/{project_name}") - if r.status_code in (200, 204): - print(f"PASS: Cleaned up project: {project_name}") - else: - print(f"Warning: Failed to cleanup project: {r.status_code}") + # Test 3: Frontend served + print("\n=== Test 3: Frontend served ===") + r = client.get("/") + if r.status_code == 200 and "" in r.text: + print("PASS: Frontend is being served") + else: + errors.append(f"Frontend check failed: {r.status_code}") # Report results print("\n" + "=" * 50) diff --git a/.gitleaksignore b/.gitleaksignore index 100b39c..a79ee3c 100644 --- a/.gitleaksignore +++ b/.gitleaksignore @@ -1,7 +1,5 @@ # Gitleaks ignore file # https://github.com/gitleaks/gitleaks#gitleaksignore - -# False positive: s3_key is an attribute name, not a secret -35fda65d381acc5ab59bc592ee3013f75906c197:backend/tests/unit/test_storage.py:generic-api-key:381 -08dce6cbb836b687002751fed4159bfc2da61f8b:backend/tests/unit/test_storage.py:generic-api-key:381 -f6b79a7af03a371bf010d2dccb0613ad9b025335:backend/tests/unit/test_storage.py:generic-api-key:381 +# +# Note: s3_key false positives are now handled with inline # gitleaks:allow comments +# in backend/tests/unit/test_storage.py diff --git a/backend/tests/unit/test_storage.py b/backend/tests/unit/test_storage.py index 3fbe6eb..5358b12 100644 --- a/backend/tests/unit/test_storage.py +++ b/backend/tests/unit/test_storage.py @@ -378,7 +378,7 @@ class TestDeduplicationBehavior: result2 = mock_storage._store_simple(file2) assert result1.sha256 == result2.sha256 - assert result1.s3_key == result2.s3_key + assert result1.s3_key == result2.s3_key # gitleaks:allow @pytest.mark.unit def test_different_content_different_keys(self, mock_storage): @@ -393,7 +393,7 @@ class TestDeduplicationBehavior: result2 = mock_storage._store_simple(file2) assert result1.sha256 != result2.sha256 - assert result1.s3_key != result2.s3_key + assert result1.s3_key != result2.s3_key # gitleaks:allow # =============================================================================