# Build a project This scenario tests the controller API to simulate a build. SCENARIO build a project Set up the controller. GIVEN an access token for user with scopes ... uapi_pipelines_post ... uapi_pipelines_get ... uapi_pipelines_id_delete ... uapi_projects_post ... uapi_projects_get ... uapi_projects_id_delete ... uapi_projects_id_status_put ... uapi_projects_id_status_get ... uapi_projects_id_builds_get ... uapi_workers_id_delete ... uapi_workers_id_get ... uapi_builds_get ... uapi_builds_id_delete ... uapi_builds_id_get ... uapi_logs_get ... uapi_logs_id_delete ... uapi_logs_id_get AND a running ick controller Add up a project with some named pipelines. WHEN user makes request POST /pipelines with a valid token and body ... { ... "pipeline": "construct", ... "parameters": ["foo"], ... "actions": [ ... { "where": "host", "shell": "day 1" }, ... { "where": "host", "shell": "day 2" } ... ] ... } THEN result has status code 201 WHEN user makes request POST /projects with a valid token and body ... { ... "project": "rome", ... "parameters": { ... "foo": "bar" ... }, ... "pipelines": ["construct"] ... } THEN result has status code 201 Define another project that doesn't define the parameter for the pipeline. This should succeed, as we don't check parameters until a build starts, and the pipeline might not even exist at this time, and it may change before the build starts. WHEN user makes request POST /projects with a valid token and body ... { ... "project": "bad_rome", ... "parameters": {}, ... "pipelines": ["construct"] ... } THEN result has status code 201 Add another project so we know each project gets its own work steps. WHEN user makes request POST /projects with a valid token and body ... { ... "project": "constantinople", ... "parameters": { ... "hey": "there" ... }, ... "pipelines": ["construct"] ... } THEN result has status code 201 There are no builds yet. WHEN user makes request GET /builds THEN result has status code 200 AND body matches { "builds": [] } 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 AND worker id is OBELIX Trigger build of project that doesn't exist. WHEN user makes request GET /projects/eldorado/+trigger THEN result has status code 404 Trigger build of project with missing parameter. WHEN user makes request GET /projects/bad_rome/+trigger THEN result has status code 409 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. If the worker asks again, it gets the same answer. **FIXME: should the name of the worker be in the path or can we get it in the access token?** Note that the controller has inserted a special additional step to get the worker to construct a new workspace for the 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": { ... "foo": "bar" ... }, ... "action_id": "1", ... "step": { ... "action": "create_workspace", ... "where": "host" ... } ... } 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": { ... "foo": "bar" ... }, ... "action_id": "1", ... "step": { ... "action": "create_workspace", ... "where": "host" ... } ... } User can now see pipeline is running and which worker is building it. WHEN user makes request GET /workers/${OBELIX} THEN result has status code 200 AND body matches ... { ... "worker": "${OBELIX}", ... "doing": { ... "build_id": "rome/1", ... "build_number": 1, ... "log": "/logs/rome/1", ... "worker": "${OBELIX}", ... "project": "rome", ... "parameters": { ... "foo": "bar" ... }, ... "action_id": "1", ... "step": { ... "action": "create_workspace", ... "where": "host" ... } ... } ... } 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", ... "graph": { ... "1": { ... "status": "building", ... "depends": [], ... "action": {"where": "host", "action": "create_workspace" } ... }, ... "2": { ... "status": "blocked", ... "depends": ["1"], ... "action": {"where": "host", "shell": "day 1" } ... }, ... "3": { ... "status": "blocked", ... "depends": ["2"], ... "action": {"where": "host", "shell": "day 2" } ... } ... }, ... "parameters": { ... "foo": "bar" ... }, ... "status": "building", ... "exit_code": null, ... "log": "/logs/rome/1" ... } ... ] ... } WHEN user makes request GET /logs/rome/1 THEN result has status code 200 AND result has header Content-Type: text/plain Worker reports workspace creation is done. Note the zero exit code. 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": 0, ... "stdout": "", ... "stderr": "", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 Worker requests more work, and gets the first actual build step. 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": { ... "foo": "bar" ... }, ... "action_id": "2", ... "step": { ... "shell": "day 1", ... "where": "host" ... } ... } Worker reports some build output. Note the null exit code. The step hasn't finished yet. WHEN obelix makes request POST /work with a valid token and body ... { ... "build_id": "rome/1", ... "action_id": "2", ... "worker": "${OBELIX}", ... "project": "rome", ... "exit_code": null, ... "stdout": "hey ho", ... "stderr": "", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 Worker-manager still gets the same step, since the build step didn't finish. 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": { ... "foo": "bar" ... }, ... "action_id": "2", ... "step": { ... "shell": "day 1", ... "where": "host" ... } ... } The build log is immediately accessible. 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 "hey ho" Report the step is done, and successfully. WHEN obelix makes request POST /work with a valid token and body ... { ... "build_id": "rome/1", ... "action_id": "2", ... "worker": "${OBELIX}", ... "project": "rome", ... "exit_code": 0, ... "stdout": ", hey ho\n", ... "stderr": "", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 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 "hey ho, hey ho\n" The build status now shows the next step as the active one. 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": { ... "foo": "bar" ... }, ... "graph": { ... "1": { ... "status": "done", ... "depends": [], ... "action": {"where": "host", "action": "create_workspace" } ... }, ... "2": { ... "status": "done", ... "depends": ["1"], ... "action": {"where": "host", "shell": "day 1" } ... }, ... "3": { ... "status": "ready", ... "depends": ["2"], ... "action": {"where": "host", "shell": "day 2" } ... } ... }, ... "status": "building", ... "exit_code": 0, ... "log": "/logs/rome/1" ... } ... ] ... } Now there's another step to do. 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": { ... "foo": "bar" ... }, ... "action_id": "3", ... "step": { ... "shell": "day 2", ... "where": "host" ... } ... } User sees changed status. WHEN user makes request GET /workers/${OBELIX} THEN result has status code 200 AND body matches ... { ... "worker": "${OBELIX}", ... "doing": { ... "build_id": "rome/1", ... "build_number": 1, ... "worker": "${OBELIX}", ... "project": "rome", ... "parameters": { ... "foo": "bar" ... }, ... "action_id": "3", ... "step": { ... "shell": "day 2", ... "where": "host" ... }, ... "log": "/logs/rome/1" ... } ... } Report it done. WHEN obelix makes request POST /work with a valid token and body ... { ... "build_id": "rome/1", ... "action_id": "3", ... "worker": "${OBELIX}", ... "project": "rome", ... "exit_code": 0, ... "stdout": "to the gold mine we go!\n", ... "stderr": "", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 Worker now gets told to notify about the build. WHEN obelix makes request GET /work THEN result has status code 200 AND body matches ... { ... "build_id": "rome/1", ... "build_number": 1, ... "worker": "${OBELIX}", ... "project": "rome", ... "parameters": { ... "foo": "bar" ... }, ... "action_id": "4", ... "step": { ... "action": "notify" ... }, ... "log": "/logs/rome/1" ... } Report it's done. 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": "", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 Now there's no more work to do. WHEN obelix makes request GET /work THEN result has status code 200 AND body matches {} There's a build with a log. Also, the build status shows there's no current action. 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": { ... "foo": "bar" ... }, ... "graph": { ... "1": { ... "status": "done", ... "depends": [], ... "action": {"where": "host", "action": "create_workspace" } ... }, ... "2": { ... "status": "done", ... "depends": ["1"], ... "action": {"where": "host", "shell": "day 1" } ... }, ... "3": { ... "status": "done", ... "depends": ["2"], ... "action": {"where": "host", "shell": "day 2" } ... }, ... "4": { ... "status": "done", ... "depends": [], ... "action": {"action": "notify" } ... } ... }, ... "status": "done", ... "exit_code": 0 ... } ... ] ... } 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": { ... "foo": "bar" ... }, ... "graph": { ... "1": { ... "status": "done", ... "depends": [], ... "action": {"where": "host", "action": "create_workspace" } ... }, ... "2": { ... "status": "done", ... "depends": ["1"], ... "action": {"where": "host", "shell": "day 1" } ... }, ... "3": { ... "status": "done", ... "depends": ["2"], ... "action": {"where": "host", "shell": "day 2" } ... }, ... "4": { ... "status": "done", ... "depends": [], ... "action": {"action": "notify" } ... } ... }, ... "status": "done", ... "exit_code": 0 ... } 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 "hey ho, hey ho\n" AND body text contains "to the gold mine we go!\n" Start build again. This should become build number 2. WHEN user makes request GET /projects/rome/+trigger THEN result has status code 200 WHEN obelix makes request GET /work THEN result has status code 200 AND body matches ... { ... "build_id": "rome/2", ... "build_number": 2, ... "log": "/logs/rome/2", ... "worker": "${OBELIX}", ... "project": "rome", ... "parameters": { ... "foo": "bar" ... }, ... "action_id": "1", ... "step": { ... "action": "create_workspace", ... "where": "host" ... } ... } 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": { ... "foo": "bar" ... }, ... "graph": { ... "1": { ... "status": "done", ... "depends": [], ... "action": {"where": "host", "action": "create_workspace" } ... }, ... "2": { ... "status": "done", ... "depends": ["1"], ... "action": {"where": "host", "shell": "day 1" } ... }, ... "3": { ... "status": "done", ... "depends": ["2"], ... "action": {"where": "host", "shell": "day 2" } ... }, ... "4": { ... "status": "done", ... "depends": [], ... "action": {"action": "notify" } ... } ... }, ... "status": "done", ... "exit_code": 0 ... }, ... { ... "build_id": "rome/2", ... "build_number": 2, ... "log": "/logs/rome/2", ... "worker": "${OBELIX}", ... "project": "rome", ... "parameters": { ... "foo": "bar" ... }, ... "graph": { ... "1": { ... "status": "building", ... "depends": [], ... "action": {"where": "host", "action": "create_workspace" } ... }, ... "2": { ... "status": "blocked", ... "depends": ["1"], ... "action": {"where": "host", "shell": "day 1" } ... }, ... "3": { ... "status": "blocked", ... "depends": ["2"], ... "action": {"where": "host", "shell": "day 2" } ... } ... }, ... "status": "building", ... "exit_code": null ... } ... ] ... } WHEN obelix makes request POST /work with a valid token and body ... { ... "build_id": "rome/2", ... "action_id": "1", ... "worker": "${OBELIX}", ... "project": "rome", ... "exit_code": 0, ... "stdout": "", ... "stderr": "", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 WHEN obelix makes request GET /work THEN result has status code 200 AND body matches ... { ... "build_id": "rome/2", ... "build_number": 2, ... "log": "/logs/rome/2", ... "worker": "${OBELIX}", ... "project": "rome", ... "parameters": { ... "foo": "bar" ... }, ... "action_id": "2", ... "step": { ... "shell": "day 1", ... "where": "host" ... } ... } WHEN obelix makes request POST /work with a valid token and body ... { ... "build_id": "rome/2", ... "action_id": "2", ... "worker": "${OBELIX}", ... "project": "rome", ... "exit_code": 0, ... "stdout": "hey ho", ... "stderr": "", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 WHEN obelix makes request GET /work THEN result has status code 200 WHEN obelix makes request POST /work with a valid token and body ... { ... "build_id": "rome/2", ... "action_id": "3", ... "worker": "${OBELIX}", ... "project": "rome", ... "exit_code": 0, ... "stdout": "hey ho", ... "stderr": "", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 WHEN obelix makes request GET /work THEN result has status code 200 AND body matches ... { ... "build_id": "rome/2", ... "build_number": 2, ... "worker": "${OBELIX}", ... "project": "rome", ... "parameters": { ... "foo": "bar" ... }, ... "action_id": "4", ... "step": { ... "action": "notify" ... }, ... "log": "/logs/rome/2" ... } WHEN obelix makes request POST /work with a valid token and body ... { ... "build_id": "rome/2", ... "action_id": "4", ... "worker": "${OBELIX}", ... "project": "rome", ... "exit_code": 0, ... "stdout": "", ... "stderr": "", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 WHEN obelix makes request GET /work THEN result has status code 200 AND body matches {} 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": { ... "foo": "bar" ... }, ... "graph": { ... "1": { ... "status": "done", ... "depends": [], ... "action": {"where": "host", "action": "create_workspace" } ... }, ... "2": { ... "status": "done", ... "depends": ["1"], ... "action": {"where": "host", "shell": "day 1" } ... }, ... "3": { ... "status": "done", ... "depends": ["2"], ... "action": {"where": "host", "shell": "day 2" } ... }, ... "4": { ... "status": "done", ... "depends": [], ... "action": {"action": "notify" } ... } ... }, ... "status": "done", ... "exit_code": 0 ... }, ... { ... "build_id": "rome/2", ... "build_number": 2, ... "log": "/logs/rome/2", ... "worker": "${OBELIX}", ... "project": "rome", ... "parameters": { ... "foo": "bar" ... }, ... "graph": { ... "1": { ... "status": "done", ... "depends": [], ... "action": {"where": "host", "action": "create_workspace" } ... }, ... "2": { ... "status": "done", ... "depends": ["1"], ... "action": {"where": "host", "shell": "day 1" } ... }, ... "3": { ... "status": "done", ... "depends": ["2"], ... "action": {"where": "host", "shell": "day 2" } ... }, ... "4": { ... "status": "done", ... "depends": [], ... "action": {"action": "notify" } ... } ... }, ... "status": "done", ... "exit_code": 0 ... } ... ] ... } WHEN user makes request DELETE /projects/bad_rome AND user makes request DELETE /projects/rome AND user makes request DELETE /projects/constantinople AND user makes request DELETE /pipelines/construct AND user makes request DELETE /workers/${OBELIX} AND user makes request DELETE /builds/rome/1 AND user makes request DELETE /builds/rome/2 AND user makes request DELETE /logs/rome/1 AND user makes request DELETE /logs/rome/2 WHEN user makes request GET /projects THEN body matches {"projects":[]} WHEN user makes request GET /pipelines THEN body matches {"pipelines":[]} WHEN user makes request GET /builds THEN body matches {"builds":[]} WHEN user makes request GET /logs THEN body matches {"log":[]} FINALLY stop ick controller # Build two projects sequentially This scenario tests the controller API to simulate a build. SCENARIO build two projects sequentially Set up the controller. GIVEN an access token for user with scopes ... uapi_pipelines_get ... uapi_pipelines_post ... uapi_pipelines_id_delete ... uapi_projects_get ... uapi_projects_post ... uapi_projects_id_delete ... uapi_projects_id_status_put ... uapi_projects_id_status_get ... uapi_projects_id_builds_get ... uapi_workers_id_get ... uapi_workers_id_delete ... uapi_builds_get ... uapi_builds_id_delete ... uapi_builds_id_get ... uapi_logs_get ... uapi_logs_id_delete ... uapi_logs_id_get AND a running ick controller Add a couple of projects. WHEN user makes request POST /pipelines with a valid token and body ... { ... "pipeline": "do_something", ... "actions": [ ... { "where": "host", "shell": "something" } ... ] ... } THEN result has status code 201 WHEN user makes request POST /projects with a valid token and body ... { ... "project": "first", ... "pipelines": ["do_something"] ... } THEN result has status code 201 WHEN user makes request POST /projects with a valid token and body ... { ... "project": "second", ... "pipelines": ["do_something"] ... } 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 AND worker id is OBELIX Build the first project. WHEN user makes request GET /projects/first/+trigger THEN result has status code 200 WHEN obelix makes request GET /work THEN result is step ... { ... "action": "create_workspace", ... "where": "host" ... } WHEN obelix makes request POST /work with a valid token and body ... { ... "build_id": "first/1", ... "action_id": "1", ... "build_number": 1, ... "worker": "${OBELIX}", ... "project": "first", ... "exit_code": 0, ... "stdout": "", ... "stderr": "", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 WHEN obelix makes request GET /work THEN result is step ... { ... "shell": "something", ... "where": "host" ... } WHEN obelix makes request POST /work with a valid token and body ... { ... "build_id": "first/1", ... "action_id": "2", ... "build_number": 1, ... "worker": "${OBELIX}", ... "project": "first", ... "exit_code": 0, ... "stdout": "", ... "stderr": "", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 WHEN obelix makes request GET /work THEN result is step ... { ... "action": "notify" ... } WHEN obelix makes request POST /work with a valid token and body ... { ... "build_id": "first/1", ... "action_id": "3", ... "build_number": 1, ... "worker": "${OBELIX}", ... "project": "first", ... "exit_code": 0, ... "stdout": "", ... "stderr": "", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 WHEN obelix makes request GET /work THEN body matches {} WHEN user requests list of builds THEN the list of builds is ["first/1"] Build second project. WHEN user makes request GET /projects/second/+trigger THEN result has status code 200 WHEN obelix makes request GET /work THEN result is step ... { ... "action": "create_workspace", ... "where": "host" ... } WHEN obelix makes request POST /work with a valid token and body ... { ... "build_id": "second/1", ... "action_id": "1", ... "worker": "${OBELIX}", ... "project": "second", ... "exit_code": 0, ... "stdout": "", ... "stderr": "", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 WHEN obelix makes request GET /work THEN result is step ... { ... "shell": "something", ... "where": "host" ... } WHEN obelix makes request POST /work with a valid token and body ... { ... "build_id": "second/1", ... "action_id": "2", ... "worker": "${OBELIX}", ... "project": "second", ... "exit_code": 0, ... "stdout": "", ... "stderr": "", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 WHEN obelix makes request GET /work THEN result is step ... { ... "action": "notify" ... } WHEN obelix makes request POST /work with a valid token and body ... { ... "build_id": "second/1", ... "action_id": "3", ... "build_number": 1, ... "worker": "${OBELIX}", ... "project": "second", ... "exit_code": 0, ... "stdout": "", ... "stderr": "", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 WHEN obelix makes request GET /work THEN body matches {} WHEN user requests list of builds THEN the list of builds is ["first/1", "second/1"] Finish up. WHEN user makes request DELETE /projects/first AND user makes request DELETE /projects/second AND user makes request DELETE /pipelines/do_something AND user makes request DELETE /workers/${OBELIX} AND user makes request DELETE /builds/first/1 AND user makes request DELETE /builds/second/1 AND user makes request DELETE /logs/first/1 AND user makes request DELETE /logs/second/1 WHEN user makes request GET /projects THEN body matches {"projects":[]} WHEN user makes request GET /pipelines THEN body matches {"pipelines":[]} WHEN user makes request GET /builds THEN body matches {"builds":[]} WHEN user makes request GET /logs THEN body matches {"log":[]} FINALLY stop ick controller # Build two projects concurrently This scenario tests the controller API to simulate a build. SCENARIO build two projects concurrently Set up the controller. GIVEN an access token for user with scopes ... uapi_pipelines_get ... uapi_pipelines_post ... uapi_pipelines_id_delete ... uapi_projects_get ... uapi_projects_post ... uapi_projects_id_delete ... uapi_projects_id_status_put ... uapi_projects_id_status_get ... uapi_projects_id_builds_get ... uapi_workers_id_get ... uapi_workers_id_delete ... uapi_builds_get ... uapi_builds_id_delete ... uapi_builds_id_get ... uapi_logs_get ... uapi_logs_id_delete ... uapi_logs_id_get AND a running ick controller Add a couple of projects. WHEN user makes request POST /pipelines with a valid token and body ... { ... "pipeline": "do_something", ... "actions": [ ... { "where": "host", "shell": "something" } ... ] ... } THEN result has status code 201 WHEN user makes request POST /projects with a valid token and body ... { ... "project": "first", ... "pipelines": ["do_something"] ... } THEN result has status code 201 WHEN user makes request POST /projects with a valid token and body ... { ... "project": "second", ... "pipelines": ["do_something"] ... } THEN result has status code 201 Register a couple of workers. GIVEN an access token for asterix with scopes ... uapi_workers_post ... uapi_work_post ... uapi_work_get WHEN asterix makes request POST /workers with a valid token and body ... { ... } THEN result has status code 201 AND worker id is ASTERIX 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 AND worker id is OBELIX Trigger both projects. WHEN user makes request GET /projects/first/+trigger THEN result has status code 200 WHEN user requests list of builds THEN the list of builds is ["first/1"] WHEN asterix makes request GET /work THEN result is step ... { ... "action": "create_workspace", ... "where": "host" ... } WHEN user requests list of builds THEN the list of builds is ["first/1"] WHEN user makes request GET /projects/second/+trigger THEN result has status code 200 WHEN obelix makes request GET /work THEN result is step ... { ... "action": "create_workspace", ... "where": "host" ... } WHEN user requests list of builds THEN the list of builds is ["first/1", "second/1"] WHEN asterix makes request POST /work with a valid token and body ... { ... "build_id": "first/1", ... "action_id": "1", ... "build_number": 1, ... "worker": "${ASTERIX}", ... "project": "first", ... "exit_code": 0, ... "stdout": "", ... "stderr": "", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 WHEN asterix makes request GET /work THEN result is step ... { ... "shell": "something", ... "where": "host" ... } WHEN obelix makes request GET /work THEN result is step ... { ... "action": "create_workspace", ... "where": "host" ... } WHEN obelix makes request POST /work with a valid token and body ... { ... "build_id": "second/1", ... "action_id": "1", ... "build_number": 1, ... "worker": "${OBELIX}", ... "project": "second", ... "exit_code": 0, ... "stdout": "", ... "stderr": "", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 WHEN obelix makes request GET /work THEN result is step ... { ... "shell": "something", ... "where": "host" ... } WHEN asterix makes request POST /work with a valid token and body ... { ... "build_id": "first/1", ... "action_id": "2", ... "worker": "${ASTERIX}", ... "project": "first", ... "exit_code": 0, ... "stdout": "", ... "stderr": "", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 WHEN asterix makes request GET /work THEN result is step ... { ... "action": "notify" ... } WHEN asterix makes request POST /work with a valid token and body ... { ... "build_id": "first/1", ... "action_id": "3", ... "worker": "${ASTERIX}", ... "project": "first", ... "exit_code": 0, ... "stdout": "", ... "stderr": "", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 WHEN asterix makes request GET /work THEN body matches {} WHEN obelix makes request POST /work with a valid token and body ... { ... "build_id": "second/1", ... "action_id": "2", ... "worker": "${OBELIX}", ... "project": "second", ... "exit_code": 0, ... "stdout": "", ... "stderr": "", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 WHEN obelix makes request GET /work THEN result is step ... { ... "action": "notify" ... } WHEN obelix makes request POST /work with a valid token and body ... { ... "build_id": "second/1", ... "action_id": "3", ... "worker": "${OBELIX}", ... "project": "second", ... "exit_code": 0, ... "stdout": "", ... "stderr": "", ... "timestamp": "2017-10-27T17:08:49" ... } THEN result has status code 201 WHEN obelix makes request GET /work THEN body matches {} WHEN user requests list of builds THEN the list of builds is ["first/1", "second/1"] Finish up. Delete the resource we created. WHEN user makes request DELETE /projects/first AND user makes request DELETE /projects/second AND user makes request DELETE /pipelines/do_something AND user makes request DELETE /workers/${ASTERIX} AND user makes request DELETE /workers/${OBELIX} AND user makes request DELETE /builds/first/1 AND user makes request DELETE /builds/second/1 AND user makes request DELETE /logs/first/1 AND user makes request DELETE /logs/second/1 WHEN user makes request GET /projects THEN body matches {"projects":[]} WHEN user makes request GET /pipelines THEN body matches {"pipelines":[]} WHEN user makes request GET /builds THEN body matches {"builds":[]} WHEN user makes request GET /logs THEN body matches {"log":[]} FINALLY stop ick controller