# Build step fails This scenario tests the controller API to simulate a build, when one build step fails. SCENARIO build step fails Set up the controller. GIVEN an RSA key pair for token signing AND controller config uses statedir at the state directory AND controller config uses https://blobs.example.com as artifact store AND controller config uses https://auth.example.com as authentication AND controller config uses https://notify.example.com as notify AND an access token for user with scopes ... uapi_pipelines_post ... uapi_projects_post ... uapi_projects_id_status_put ... uapi_projects_id_status_get ... uapi_projects_id_builds_get ... uapi_workers_id_get ... uapi_builds_get ... uapi_builds_id_get ... uapi_logs_id_get AND a running ick controller Add up a project and its pipelines. WHEN user makes request POST /pipelines with a valid token and body ... { ... "pipeline": "construct", ... "actions": [ ... { "shell": "day 1", "where": "host" }, ... { "shell": "day 2", "where": "host" } ... ] ... } THEN result has status code 201 WHEN user makes request POST /projects with a valid token and body ... { ... "project": "rome", ... "pipelines": ["construct"] ... } THEN result has status code 201 Register a worker. GIVEN an access token for obelix with scopes ... uapi_workers_post ... uapi_work_post ... uapi_work_get WHEN obelix makes request POST /workers with a valid token and body ... { ... } THEN result has status code 201 Trigger build. WHEN user makes request GET /projects/rome/+trigger THEN result has status code 200 Worker wants work and gets the first step to run. WHEN obelix makes request GET /work THEN result has status code 200 AND body matches ... { ... "build_id": "rome/1", ... "build_number": 1, ... "log": "/logs/rome/1", ... "worker": "obelix", ... "project": "rome", ... "parameters": {}, ... "action_id": "1", ... "step": { ... "action": "create_workspace", ... "where": "host" ... } ... } Worker reports some build output. Note the exit code indicating failure. WHEN obelix makes request POST /work with a valid token and body ... { ... "build_id": "rome/1", ... "action_id": "1", ... "worker": "obelix", ... "project": "rome", ... "exit_code": 1, ... "stdout": "", ... "stderr": "eek!", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 Worker is next told to notify end of build. WHEN obelix makes request GET /work THEN result has status code 200 AND body matches ... { ... "build_id": "rome/1", ... "build_number": 1, ... "log": "/logs/rome/1", ... "worker": "obelix", ... "project": "rome", ... "parameters": {}, ... "action_id": "4", ... "step": { ... "action": "notify" ... } ... } WHEN obelix makes request POST /work with a valid token and body ... { ... "build_id": "rome/1", ... "action_id": "4", ... "worker": "obelix", ... "project": "rome", ... "exit_code": 0, ... "stdout": "", ... "stderr": "eek!", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 The build has ended, and there's no more work to do. WHEN obelix makes request GET /work THEN result has status code 200 AND body matches {} User sees changed status. WHEN user makes request GET /workers/obelix THEN result has status code 200 AND body matches ... { ... "worker": "obelix", ... "doing": {} ... } There's a build with a log. WHEN user makes request GET /builds THEN result has status code 200 AND body matches ... { ... "builds": [ ... { ... "build_id": "rome/1", ... "build_number": 1, ... "log": "/logs/rome/1", ... "worker": "obelix", ... "project": "rome", ... "parameters": {}, ... "graph": { ... "1": { ... "status": "failed", ... "depends": [], ... "action": { ... "action": "create_workspace", ... "where": "host" ... } ... }, ... "2": { ... "status": "blocked", ... "depends": ["1"], ... "action": {"shell": "day 1", "where": "host"} ... }, ... "3": { ... "status": "blocked", ... "depends": ["2"], ... "action": {"shell": "day 2", "where": "host"} ... }, ... "4": { ... "status": "done", ... "depends": [], ... "action": {"action": "notify"} ... } ... }, ... "status": "failed", ... "exit_code": 1 ... } ... ] ... } WHEN user makes request GET /builds/rome/1 THEN result has status code 200 AND body matches ... { ... "build_id": "rome/1", ... "build_number": 1, ... "log": "/logs/rome/1", ... "worker": "obelix", ... "project": "rome", ... "parameters": {}, ... "graph": { ... "1": { ... "status": "failed", ... "depends": [], ... "action": { ... "action": "create_workspace", ... "where": "host" ... } ... }, ... "2": { ... "status": "blocked", ... "depends": ["1"], ... "action": {"shell": "day 1", "where": "host"} ... }, ... "3": { ... "status": "blocked", ... "depends": ["2"], ... "action": {"shell": "day 2", "where": "host"} ... }, ... "4": { ... "status": "done", ... "depends": [], ... "action": {"action": "notify"} ... } ... }, ... "status": "failed", ... "exit_code": 1 ... } WHEN user makes request GET /logs/rome/1 THEN result has status code 200 AND result has header Content-Type: text/plain AND body text contains "eek!" FINALLY stop ick controller