nix: cleanup
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Ia88656a1d6bb152398a5c4ce83d40a3e6a6a6964
This commit is contained in:
parent
794e4a8e61
commit
62f8cdf4de
13 changed files with 514 additions and 529 deletions
|
|
@ -1,14 +1,17 @@
|
|||
# End-to-end tests: flake creation, evaluation, queue runner, notification, signing, GC, declarative, webhooks
|
||||
{
|
||||
pkgs,
|
||||
fc-packages,
|
||||
nixosModule,
|
||||
}:
|
||||
{pkgs, self}:
|
||||
pkgs.testers.nixosTest {
|
||||
name = "fc-e2e";
|
||||
|
||||
nodes.machine = import ./common.nix {inherit pkgs fc-packages nixosModule;};
|
||||
nodes.machine = {
|
||||
imports = [
|
||||
self.nixosModules.fc-ci
|
||||
../vm-common.nix
|
||||
];
|
||||
_module.args.self = self;
|
||||
};
|
||||
|
||||
# End-to-end tests: flake creation, evaluation, queue runner, notification,
|
||||
# signing, GC, declarative, webhooks
|
||||
testScript = ''
|
||||
import hashlib
|
||||
import json
|
||||
|
|
@ -24,7 +27,7 @@ pkgs.testers.nixosTest {
|
|||
# Wait for the server to start listening
|
||||
machine.wait_until_succeeds("curl -sf http://127.0.0.1:3000/health", timeout=30)
|
||||
|
||||
# ---- Seed an API key for write operations ----
|
||||
# Seed an API key for write operations
|
||||
# Token: fc_testkey123 -> SHA-256 hash inserted into api_keys table
|
||||
api_token = "fc_testkey123"
|
||||
api_hash = hashlib.sha256(api_token.encode()).hexdigest()
|
||||
|
|
@ -41,11 +44,7 @@ pkgs.testers.nixosTest {
|
|||
)
|
||||
ro_header = f"-H 'Authorization: Bearer {ro_token}'"
|
||||
|
||||
# ========================================================================
|
||||
# Phase E2E-1: End-to-End Evaluator Integration Test
|
||||
# ========================================================================
|
||||
|
||||
# ---- Create a test flake inside the VM ----
|
||||
# Create a test flake inside the VM
|
||||
with subtest("Create bare git repo with test flake"):
|
||||
machine.succeed("mkdir -p /var/lib/fc/test-repos")
|
||||
machine.succeed("git init --bare /var/lib/fc/test-repos/test-flake.git")
|
||||
|
|
@ -78,7 +77,7 @@ pkgs.testers.nixosTest {
|
|||
# Set ownership for fc user
|
||||
machine.succeed("chown -R fc:fc /var/lib/fc/test-repos")
|
||||
|
||||
# ---- Create project + jobset pointing to the local repo via API ----
|
||||
# Create project + jobset pointing to the local repo via API
|
||||
with subtest("Create E2E project and jobset via API"):
|
||||
result = machine.succeed(
|
||||
"curl -sf -X POST http://127.0.0.1:3000/api/v1/projects "
|
||||
|
|
@ -100,10 +99,10 @@ pkgs.testers.nixosTest {
|
|||
e2e_jobset_id = result.strip()
|
||||
assert len(e2e_jobset_id) == 36, f"Expected UUID for jobset, got '{e2e_jobset_id}'"
|
||||
|
||||
# ---- Wait for evaluator to pick it up and create an evaluation ----
|
||||
# Wait for evaluator to pick it up and create an evaluation
|
||||
with subtest("Evaluator discovers and evaluates the flake"):
|
||||
# The evaluator is already running (started in Phase 1)
|
||||
# Poll for evaluation to appear with status "completed"
|
||||
# The evaluator is already running, poll for evaluation to appear
|
||||
# with status "completed"
|
||||
machine.wait_until_succeeds(
|
||||
f"curl -sf 'http://127.0.0.1:3000/api/v1/evaluations?jobset_id={e2e_jobset_id}' "
|
||||
"| jq -e '.items[] | select(.status==\"completed\")'",
|
||||
|
|
@ -136,7 +135,7 @@ pkgs.testers.nixosTest {
|
|||
f"curl -sf 'http://127.0.0.1:3000/api/v1/builds?evaluation_id={e2e_eval_id}' | jq -r '.items[0].id'"
|
||||
).strip()
|
||||
|
||||
# ---- Test evaluation caching ----
|
||||
# Test evaluation caching
|
||||
with subtest("Same commit does not trigger a new evaluation"):
|
||||
# Get current evaluation count
|
||||
before_count = machine.succeed(
|
||||
|
|
@ -149,7 +148,7 @@ pkgs.testers.nixosTest {
|
|||
).strip()
|
||||
assert before_count == after_count, f"Evaluation count changed from {before_count} to {after_count} (should be cached)"
|
||||
|
||||
# ---- Test new commit triggers new evaluation ----
|
||||
# Test new commit triggers new evaluation
|
||||
with subtest("New commit triggers new evaluation"):
|
||||
before_count_int = int(machine.succeed(
|
||||
f"curl -sf 'http://127.0.0.1:3000/api/v1/evaluations?jobset_id={e2e_jobset_id}' | jq '.items | length'"
|
||||
|
|
@ -181,10 +180,6 @@ pkgs.testers.nixosTest {
|
|||
timeout=60
|
||||
)
|
||||
|
||||
# ========================================================================
|
||||
# Phase E2E-2: End-to-End Queue Runner Integration Test
|
||||
# ========================================================================
|
||||
|
||||
with subtest("Queue runner builds pending derivation"):
|
||||
# Poll the E2E build until completed (queue-runner is already running)
|
||||
machine.wait_until_succeeds(
|
||||
|
|
@ -230,10 +225,6 @@ pkgs.testers.nixosTest {
|
|||
).strip()
|
||||
assert code == "200", f"Expected 200 for build log, got {code}"
|
||||
|
||||
# ========================================================================
|
||||
# Phase E2E-3: Jobset Input Management API
|
||||
# ========================================================================
|
||||
|
||||
with subtest("Create jobset input via API"):
|
||||
result = machine.succeed(
|
||||
f"curl -sf -X POST http://127.0.0.1:3000/api/v1/projects/{e2e_project_id}/jobsets/{e2e_jobset_id}/inputs "
|
||||
|
|
@ -285,10 +276,6 @@ pkgs.testers.nixosTest {
|
|||
).strip()
|
||||
assert code == "403", f"Expected 403 for read-only input delete, got {code}"
|
||||
|
||||
# ========================================================================
|
||||
# Phase E2E-4: Notification Dispatch
|
||||
# ========================================================================
|
||||
|
||||
# Notifications are dispatched after builds complete (already tested above).
|
||||
# Verify run_command notifications work:
|
||||
with subtest("Notification run_command is invoked on build completion"):
|
||||
|
|
@ -300,10 +287,6 @@ pkgs.testers.nixosTest {
|
|||
).strip()
|
||||
assert result == "completed", f"Expected completed after notification, got {result}"
|
||||
|
||||
# ========================================================================
|
||||
# Phase E2E-5: Channel Auto-Promotion
|
||||
# ========================================================================
|
||||
|
||||
with subtest("Channel auto-promotion after all builds complete"):
|
||||
# Create a channel tracking the E2E jobset
|
||||
result = machine.succeed(
|
||||
|
|
@ -324,10 +307,6 @@ pkgs.testers.nixosTest {
|
|||
timeout=30
|
||||
)
|
||||
|
||||
# ========================================================================
|
||||
# Phase E2E-6: Binary Cache NARinfo Test
|
||||
# ========================================================================
|
||||
|
||||
with subtest("Binary cache serves NARinfo for built output"):
|
||||
# Get the build output path
|
||||
output_path = machine.succeed(
|
||||
|
|
@ -353,10 +332,6 @@ pkgs.testers.nixosTest {
|
|||
assert "StorePath:" in narinfo, f"NARinfo missing StorePath: {narinfo}"
|
||||
assert "NarHash:" in narinfo, f"NARinfo missing NarHash: {narinfo}"
|
||||
|
||||
# ========================================================================
|
||||
# Phase E2E-7: Build Retry on Failure
|
||||
# ========================================================================
|
||||
|
||||
with subtest("Build with invalid drv_path fails and retries"):
|
||||
# Insert a build with an invalid drv_path via SQL
|
||||
machine.succeed(
|
||||
|
|
@ -378,10 +353,6 @@ pkgs.testers.nixosTest {
|
|||
).strip()
|
||||
assert result == "failed", f"Expected failed for bad build, got '{result}'"
|
||||
|
||||
# ========================================================================
|
||||
# Phase E2E-8: Notification Dispatch (run_command)
|
||||
# ========================================================================
|
||||
|
||||
with subtest("Notification run_command invoked on build completion"):
|
||||
# Write a notification script
|
||||
machine.succeed("mkdir -p /var/lib/fc")
|
||||
|
|
@ -458,10 +429,6 @@ pkgs.testers.nixosTest {
|
|||
f"Expected BUILD_STATUS in notification output, got: {output}"
|
||||
assert notify_build_id in output, f"Expected build ID {notify_build_id} in output, got: {output}"
|
||||
|
||||
# ========================================================================
|
||||
# Phase E2E-9: Nix Signing
|
||||
# ========================================================================
|
||||
|
||||
with subtest("Generate signing key and configure signing"):
|
||||
# Generate a Nix signing key
|
||||
machine.succeed("mkdir -p /var/lib/fc/keys")
|
||||
|
|
@ -537,10 +504,6 @@ pkgs.testers.nixosTest {
|
|||
# The verify command should succeed (exit 0) if signatures are valid
|
||||
machine.succeed(f"nix store verify --sigs-needed 1 {output_path}")
|
||||
|
||||
# ========================================================================
|
||||
# Phase E2E-10: GC Roots
|
||||
# ========================================================================
|
||||
|
||||
with subtest("GC roots are created for build products"):
|
||||
# Enable GC in config
|
||||
machine.succeed("""
|
||||
|
|
@ -607,18 +570,14 @@ pkgs.testers.nixosTest {
|
|||
found_root = True
|
||||
break
|
||||
|
||||
# We might have GC roots - this is expected behavior
|
||||
# The key is that the build output exists and is protected from GC
|
||||
# We might have GC roots, this is expected behavior
|
||||
# The key thing is that the build output exists and is protected from GC
|
||||
machine.succeed(f"test -e {gc_build_output}")
|
||||
else:
|
||||
# If no GC roots yet, at least verify the build output exists
|
||||
# GC roots might be created asynchronously
|
||||
machine.succeed(f"test -e {gc_build_output}")
|
||||
|
||||
# ========================================================================
|
||||
# Phase E2E-11: Declarative In-Repo Config
|
||||
# ========================================================================
|
||||
|
||||
with subtest("Declarative .fc.toml in repo auto-creates jobset"):
|
||||
# Add .fc.toml to the test repo with a new jobset definition
|
||||
machine.succeed("""
|
||||
|
|
@ -641,10 +600,6 @@ pkgs.testers.nixosTest {
|
|||
timeout=60
|
||||
)
|
||||
|
||||
# ========================================================================
|
||||
# Phase E2E-12: Webhook Endpoint
|
||||
# ========================================================================
|
||||
|
||||
with subtest("Webhook endpoint accepts valid GitHub push"):
|
||||
# Create a webhook config via SQL (no REST endpoint for creation)
|
||||
machine.succeed(
|
||||
|
|
@ -697,7 +652,7 @@ pkgs.testers.nixosTest {
|
|||
).strip()
|
||||
assert code == "401", f"Expected 401 for invalid webhook signature, got {code}"
|
||||
|
||||
# ---- Cleanup: Delete project ----
|
||||
# Cleanup: Delete project
|
||||
with subtest("Delete E2E project"):
|
||||
code = machine.succeed(
|
||||
"curl -s -o /dev/null -w '%{http_code}' "
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue