From 9759c2b51a1250aa345c21b7cc6b793f4965ac2d Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Mon, 28 May 2018 19:51:58 +0300 Subject: Add: BuildStateMachine class --- yarns/400-build.yarn | 207 +++++++++++++++++++++++++++++++++++++++++++--- yarns/500-build-fail.yarn | 53 ++++++++++-- yarns/900-implements.yarn | 22 +++-- 3 files changed, 259 insertions(+), 23 deletions(-) (limited to 'yarns') diff --git a/yarns/400-build.yarn b/yarns/400-build.yarn index 5ab5895..1674189 100644 --- a/yarns/400-build.yarn +++ b/yarns/400-build.yarn @@ -197,6 +197,7 @@ User can now see pipeline is running and which worker is building it. ... "foo": "bar" ... }, ... "status": "building", + ... "exit_code": null, ... "log": "/logs/rome/1" ... } ... ] @@ -205,7 +206,6 @@ User can now see pipeline is running and which worker is building it. 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 is "" Worker reports workspace creation is done. Note the zero exit code. @@ -286,7 +286,7 @@ 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 is "hey ho" + AND body text contains "hey ho" Report the step is done, and successfully. @@ -306,7 +306,7 @@ Report the step is done, and successfully. 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 is "hey ho, hey ho\n" + AND body text contains "hey ho, hey ho\n" The build status now shows the next step as the active one. @@ -342,6 +342,7 @@ The build status now shows the next step as the active one. ... } ... }, ... "status": "building", + ... "exit_code": null, ... "log": "/logs/rome/1" ... } ... ] @@ -407,6 +408,41 @@ Report it done. ... } 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 @@ -445,9 +481,15 @@ current action. ... "status": "done", ... "depends": ["2"], ... "action": {"where": "host", "shell": "day 2" } + ... }, + ... "4": { + ... "status": "done", + ... "depends": [], + ... "action": {"action": "notify" } ... } ... }, - ... "status": 0 + ... "status": "done", + ... "exit_code": 0 ... } ... ] ... } @@ -479,15 +521,22 @@ current action. ... "status": "done", ... "depends": ["2"], ... "action": {"where": "host", "shell": "day 2" } + ... }, + ... "4": { + ... "status": "done", + ... "depends": [], + ... "action": {"action": "notify" } ... } ... }, - ... "status": 0 + ... "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 is "hey ho, hey ho\nto the gold mine we go!\n" + 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. @@ -542,9 +591,15 @@ Start build again. This should become build number 2. ... "status": "done", ... "depends": ["2"], ... "action": {"where": "host", "shell": "day 2" } + ... }, + ... "4": { + ... "status": "done", + ... "depends": [], + ... "action": {"action": "notify" } ... } ... }, - ... "status": 0 + ... "status": "done", + ... "exit_code": 0 ... }, ... { ... "build_id": "rome/2", @@ -572,7 +627,8 @@ Start build again. This should become build number 2. ... "action": {"where": "host", "shell": "day 2" } ... } ... }, - ... "status": "building" + ... "status": "building", + ... "exit_code": null ... } ... ] ... } @@ -638,6 +694,41 @@ Start build again. This should become build number 2. ... } 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 @@ -667,9 +758,15 @@ Start build again. This should become build number 2. ... "status": "done", ... "depends": ["2"], ... "action": {"where": "host", "shell": "day 2" } + ... }, + ... "4": { + ... "status": "done", + ... "depends": [], + ... "action": {"action": "notify" } ... } ... }, - ... "status": 0 + ... "status": "done", + ... "exit_code": 0 ... }, ... { ... "build_id": "rome/2", @@ -695,9 +792,15 @@ Start build again. This should become build number 2. ... "status": "done", ... "depends": ["2"], ... "action": {"where": "host", "shell": "day 2" } + ... }, + ... "4": { + ... "status": "done", + ... "depends": [], + ... "action": {"action": "notify" } ... } ... }, - ... "status": 0 + ... "status": "done", + ... "exit_code": 0 ... } ... ] ... } @@ -810,6 +913,29 @@ Build the first project. ... } 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"] @@ -858,6 +984,29 @@ Build second project. ... } 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"] @@ -1028,6 +1177,25 @@ Trigger both projects. ... } 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 {} @@ -1044,6 +1212,25 @@ Trigger both projects. ... } 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 {} diff --git a/yarns/500-build-fail.yarn b/yarns/500-build-fail.yarn index 4d4071a..204bfd5 100644 --- a/yarns/500-build-fail.yarn +++ b/yarns/500-build-fail.yarn @@ -101,6 +101,7 @@ 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, @@ -110,8 +111,38 @@ failure. ... } THEN result has status code 201 -A build step failed, so now the build has ended, and there's no more -work to do. +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 @@ -159,9 +190,15 @@ There's a build with a log. ... "status": "blocked", ... "depends": ["2"], ... "action": {"shell": "day 2", "where": "host"} + ... }, + ... "4": { + ... "status": "done", + ... "depends": [], + ... "action": {"action": "notify"} ... } ... }, - ... "status": 1 + ... "status": "failed", + ... "exit_code": 1 ... } ... ] ... } @@ -194,14 +231,20 @@ There's a build with a log. ... "status": "blocked", ... "depends": ["2"], ... "action": {"shell": "day 2", "where": "host"} + ... }, + ... "4": { + ... "status": "done", + ... "depends": [], + ... "action": {"action": "notify"} ... } ... }, - ... "status": 1 + ... "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 is "eek!" + AND body text contains "eek!" FINALLY stop ick controller diff --git a/yarns/900-implements.yarn b/yarns/900-implements.yarn index 4086a2f..5468a6c 100644 --- a/yarns/900-implements.yarn +++ b/yarns/900-implements.yarn @@ -108,17 +108,23 @@ along with this program. If not, see . expected_text = get_next_match() expected = json.loads(expected_text) actual = json.loads(vars['body']) - print('expected', json.dumps(expected, indent=4)) - print('actual', json.dumps(actual, indent=4)) + print 'expected' + json.dump(expected, sys.stdout, indent=4, sort_keys=True) + print + print 'actual' + json.dump(actual, sys.stdout, indent=4, sort_keys=True) + print diff = dict_diff(expected, actual) if diff is not None: print(diff) assert 0 - IMPLEMENTS THEN body text is "(.*)" - expected = unescape(get_next_match()) - actual = vars['body'] - assertEqual(expected, actual) + IMPLEMENTS THEN body text contains "(.*)" + pattern = unescape(get_next_match()) + text = vars['body'] + print 'pattern:', repr(pattern) + print 'text:', text + assertTrue(pattern in text) IMPLEMENTS THEN body is the same as the blob (\S+) filename = get_next_match() @@ -142,10 +148,10 @@ along with this program. If not, see . IMPLEMENTS THEN result is step (.+) step = json.loads(get_next_match()) - body = json.loads(vars['body']) - actual_step = body['step'] print('expected step', step) + body = json.loads(vars['body']) print('actual body', body) + actual_step = body['step'] print('actual step', actual_step) diff = dict_diff(step, actual_step) print('diff', diff) -- cgit v1.2.1