public async Task WorkflowCanContainMinimalReadmeInfo() { var stubRequests = Yaml <StubHttpClientHandlerFactory>(@" Responses: https://localhost/minimal/workflow.yaml: GET: status: 200 body: | operations: - message: Just a workflow file https://localhost/minimal/readme.md: GET: status: 200 body: | ``` yaml info: title: minimal ``` "); InitializeServices(stubRequests); Services.App.Execute("deploy", "https://localhost/minimal/workflow.yaml"); Console.AssertContainsInOrder("Just a workflow file"); }
public async Task OutputFlowsBackMultipleLevelsWhenNotInterrupted() { var stubs = Yaml <StubBlueprintManager>(@" Blueprints: the-test: Files: workflow.yaml: | operations: - message: (['data is ', @]) - message: has nested operations operations: - message: (['data is ', @]) - message: returning 42 output: {x: 42} - message: (['data is ', @]) - message: (['data is ', @]) "); InitializeServices(stubs); var result = Services.App.Execute("deploy", "the-test"); Assert.AreEqual(0, result); Console.AssertContainsInOrder("returning 42", "x: 42"); }
public async Task OnlyWorkflowOperationValuesPassThrough() { var stubs = Yaml <StubHttpClientHandlerFactory>(@" Files: https://localhost/the-test/workflow.yaml: | operations: - workflow: ../step1 values: { x: ( xValue ) } https://localhost/step1/workflow.yaml: | operations: - message: (['x=<', x, '>']) - message: (['y=<', y, '>']) - message: (['xValue=<', xValue, '>']) - message: (['yValue=<', yValue, '>']) "); InitializeServices(stubs); var result = Services.App.Execute( "deploy", "https://localhost/the-test", "--set", "xValue=alpha", "--set", "yValue=beta", "--set", "x=gamma", "--set", "y=delta"); Assert.AreEqual(0, result); Console.AssertContainsInOrder("x=<alpha>", "y=<>", "xValue=<>", "yValue=<>"); }
public async Task WorkflowOutputWorksSameAsOperationOutput() { var stubs = Yaml <StubHttpClientHandlerFactory>(@" Files: https://localhost/the-test/workflow.yaml: | operations: - workflow: ../step1 output: { xOut: ( result.x ) } - message: ([ 'everything is ', to_string(@) ]) https://localhost/step1/workflow.yaml: | operations: - output: xOperation: alpha yOperation: beta output: x: ( xOperation ) "); InitializeServices(stubs); var result = Services.App.Execute("deploy", "https://localhost/the-test"); Assert.AreEqual(0, result); Console.AssertContainsInOrder(@"everything is {""xOut"":""alpha""}"); }
public async Task FileSystemRelativeReferenceImportsFiles() { var stubs = Yaml <StubFileSystem>(@" Files: the-test/readme.md: | ``` yaml info: title: TheTest workflows: local: inputs: - step1 ``` the-test/workflow.yaml: | operations: - message: Before - workflow: workflows/step1 - message: After step1/workflow.yaml: | operations: - message: During "); InitializeServices(stubs); var result = Services.App.Execute("deploy", "the-test"); Assert.AreEqual(0, result); Console.AssertContainsInOrder("Before", "During", "After"); }
public void SeveralArraysCanBeIterated() { var stubBlueprints = Yaml <StubBlueprintManager>(@" Blueprints: the-test: Files: workflow.yaml: | operations: - foreach: values: x: ['a', 'b', 'c'] y: z: ['d', 'e', 'f'] message: (['x is ', x, ' y.z is ', y.z]) "); InitializeServices(stubBlueprints); var result = Services.App.Execute("deploy", "the-test"); Assert.AreEqual(0, result); Console.AssertContainsInOrder( "x is a", "y.z is d", "x is b", "y.z is e", "x is c", "y.z is f"); }
public void WorkflowCanRunEntirelyFromStubHttpResponses() { var stubHttpClients = Yaml <StubHttpClientHandlerFactory>(@" Responses: https://example.net/the-test/readme.md: GET: status: 200 body: | ``` yaml info: title: TheTest ``` https://example.net/the-test/workflow.yaml: GET: status: 200 body: operations: - message: This is a test output: { x: green } "); InitializeServices(stubHttpClients); var result = Services.App.Execute("deploy", "https://example.net/the-test"); System.Console.Error.WriteLine(Console.ErrorStringWriter.ToString()); System.Console.Out.WriteLine(Console.OutStringWriter.ToString()); Assert.AreEqual(0, result); Console.AssertContainsInOrder("This is a test", "x: green"); }
public void NotCaughtIfConditionIsFalse() { var stubBlueprints = Yaml <StubBlueprintManager>(@" Blueprints: the-test: Files: workflow.yaml: | operations: - message: Catching operation operations: - message: Throwing operation throw: { message: different } catch: condition: Message == 'boom' - message: Still Running "); InitializeServices(stubBlueprints); var ex = Assert.ThrowsException <OperationException>(() => Services.App.Execute("deploy", "the-test")); Assert.AreEqual("different", ex.Message); Console.AssertContainsInOrder("Catching operation", "Throwing operation", "different"); }
public void CatchesIfConditionIsTrue() { var stubBlueprints = Yaml <StubBlueprintManager>(@" Blueprints: the-test: Files: workflow.yaml: | operations: - message: Catching operation operations: - message: Throwing operation throw: { message: boom } catch: condition: error.message == 'boom' - message: Still Running "); InitializeServices(stubBlueprints); var result = Services.App.Execute("deploy", "the-test"); Assert.AreEqual(0, result); Console.AssertContainsInOrder("Catching operation", "Throwing operation", "Still Running"); }
public void ResponseBodyMayBeQueried() { var stubBlueprints = Yaml <StubBlueprintManager>(@" Blueprints: the-test: Files: workflow.yaml: | operations: - request: request.yaml output: x: (result.body.color) y: (result.body.id) request.yaml: | method: GET url: https://localhost/ "); var stubHttpClients = Yaml <StubHttpClientHandlerFactory>(@" Responses: https://localhost/: GET: status: 200 body: id: 4 color: green "); InitializeServices(stubBlueprints, stubHttpClients); var result = Services.App.Execute("deploy", "the-test"); Assert.AreEqual(0, result); Console.AssertContainsInOrder("x: green", "y:", "4"); }
public async Task SimpleGetOperationBeingExecuted() { var stubHttpClients = Yaml <StubHttpClientHandlerFactory>($@" Responses: https://example.net/the-test/readme.md: GET: status: 200 body: | ``` yaml info: title: TheTest swagger: foo: target: apis/path source: https://example.org/specs/ inputs: - testing/swagger.json ``` https://example.net/the-test/workflow.yaml: GET: status: 200 body: operations: - request: apis/path/TestingClient/Me_Get.yaml output: ( result ) https://example.org/specs/testing/swagger.json: GET: status: 200 body: swagger: 2.0 info: title: TestingClient host: example.com paths: /me: get: operationId: Me_Get https://example.com/me: GET: status: 200 body: name: one id: 42 "); InitializeServices(stubHttpClients); var result = Services.App.Execute("deploy", "https://example.net/the-test"); System.Console.Error.WriteLine(Console.ErrorStringWriter.ToString()); System.Console.Out.WriteLine(Console.OutStringWriter.ToString()); Assert.AreEqual(0, result); Console.AssertContainsInOrder("name: one", "id: 42"); }
public void ExceptionAndResultDetailsCanBeSavedInCatch() { var stubBlueprints = Yaml <StubBlueprintManager>(@" Blueprints: the-test: Files: workflow.yaml: | operations: - message: Catching 400 request: badrequest.yaml catch: output: the-result: (result) the-error: (error) - message: Still Running badrequest.yaml: | method: GET url: https://localhost/badrequest "); var stubHttpClients = Yaml <StubHttpClientHandlerFactory>(@" Responses: https://localhost/badrequest: GET: status: 400 headers: { Content-Type: ['application/json'] } body: oops: code: 1234 summary: This is a bad request "); InitializeServices(stubBlueprints, stubHttpClients); var result = Services.App.Execute("deploy", "the-test"); Assert.AreEqual(0, result); Console.AssertContainsInOrder( "Catching 400", "Still Running", "the-result:", "status: 400", "body:", "oops:", "code:", "1234", "summary: This is a bad request", "the-error:", "message:", "400"); }
public async Task WebServerTransitiveRelativeReferenceImportsFiles() { var stubs = Yaml <StubHttpClientHandlerFactory>(@" Files: https://localhost/the-test/readme.md: | ``` yaml info: title: TheTest workflows: local: inputs: - step1 ``` https://localhost/the-test/workflow.yaml: | operations: - message: BeginTheTest - workflow: workflows/step1 - message: EndTheTest https://localhost/step1/readme.md: | ``` yaml info: title: Step1 workflows: local: inputs: - step2 ``` https://localhost/step1/workflow.yaml: | operations: - message: BeginStep1 - workflow: workflows/step2 - message: EndStep1 https://localhost/step2/readme.md: | ``` yaml info: title: Step2 ``` https://localhost/step2/workflow.yaml: | operations: - message: DuringStep2 "); InitializeServices(stubs); var result = Services.App.Execute("deploy", "https://localhost/the-test"); Assert.AreEqual(0, result); Console.AssertContainsInOrder("BeginTheTest", "BeginStep1", "DuringStep2", "EndStep1", "EndTheTest"); }
public void CatchByStatusCode() { var stubBlueprints = Yaml <StubBlueprintManager>(@" Blueprints: the-test: Files: workflow.yaml: | operations: - message: Catching 404 request: notfound.yaml catch: condition: result.status == `404` - message: Not Catching 503 request: servererror.yaml catch: condition: result.status == `404` - message: Still Running notfound.yaml: | method: GET url: https://localhost/notfound servererror.yaml: | method: GET url: https://localhost/servererror "); var stubHttpClients = Yaml <StubHttpClientHandlerFactory>(@" Responses: https://localhost/notfound: GET: status: 404 body: Page error https://localhost/servererror: GET: status: 503 body: Page error "); InitializeServices(stubBlueprints, stubHttpClients); var ex = Assert.ThrowsException <RequestException>(() => Services.App.Execute("deploy", "the-test")); Assert.IsTrue(ex.Message.Contains("503")); Assert.AreEqual(503, ex.Response.status); Console.AssertContainsInOrder("Catching 404", "Not Catching 503"); Console.AssertNotContains("Still Running"); }
public async Task WorkflowCanRunWithOnlyHttpsWorkflowYamlFile() { var stubRequests = Yaml <StubHttpClientHandlerFactory>(@" Responses: https://localhost/just/workflow.yaml: GET: status: 200 body: | operations: - message: Just a workflow file "); InitializeServices(stubRequests); Services.App.Execute("deploy", "https://localhost/just/workflow.yaml"); Console.AssertContainsInOrder("Just a workflow file"); }
public void ForeachHashObject() { var stubBlueprints = Yaml <StubBlueprintManager>(@" Blueprints: the-test: Files: values.yaml: | hash: a: b c: d e: f workflow.yaml: | operations: - foreach: values: ( map(&{ key:[0], value:[1] }, items(hash)) ) message: ""(['1: ', key, ' is ', value])"" - foreach: values: key: ( keys(hash) ) value: ( values(hash) ) message: ""(['2: ', key, ' is ', value])"" - foreach: values: kv: ( items(hash) ) message: ""(['3: ', kv[0], ' is ', kv[1]])"" "); InitializeServices(stubBlueprints); var result = Services.App.Execute("deploy", "the-test"); Assert.AreEqual(0, result); Console.AssertContainsInOrder( "1: a is b", "1: c is d", "1: e is f", "2: a is b", "2: c is d", "2: e is f", "3: a is b", "3: c is d", "3: e is f"); }
public void HttpResponseSecretsAreHidden() { var stubBlueprints = Yaml <StubBlueprintManager>(@" Blueprints: hide-secrets: Files: workflow.yaml: | operations: - message: Fetching secrets request: request.yaml output: things: one: (keys[0].value) two: (keys[1].value) request.yaml: | method: GET url: https://localhost/ secret: keys[*].value "); var stubHttpClients = Yaml <StubHttpClientHandlerFactory>(@" Responses: https://localhost/: GET: status: 200 body: keys: - name: key-1 value: alpha - name: key-2 value: beta "); InitializeServices(stubBlueprints, stubHttpClients); var result = Services.App.Execute("deploy", "hide-secrets"); Assert.AreEqual(0, result); Console.AssertContainsInOrder("Fetching secrets", "one: xxxxxxxx", "two: xxxxxxxx"); }
public void ResponseHeadersMayBeSecret() { var stubBlueprints = Yaml <StubBlueprintManager>(@" Blueprints: hide-secrets: Files: workflow.yaml: | operations: - message: Fetching secrets request: request.yaml output: things: one: (result.headers.""Set-Cookie""[0]) two: (result.headers.""Set-Cookie""[1]) request.yaml: | method: GET url: https://localhost/ secret: result.headers.""Set-Cookie"" "); var stubHttpClients = Yaml <StubHttpClientHandlerFactory>(@" Responses: https://localhost/: GET: status: 200 headers: Set-Cookie: - secret-cookie-one - secret-cookie-two body: doesn't matter "); InitializeServices(stubBlueprints, stubHttpClients); var result = Services.App.Execute("deploy", "hide-secrets"); Assert.AreEqual(0, result); Console.AssertContainsInOrder("Fetching secrets", "one: xxxxxxxx", "two: xxxxxxxx"); }
public void ForeachValuesAreIterated() { var stubBlueprints = Yaml <StubBlueprintManager>(@" Blueprints: the-test: Files: workflow.yaml: | operations: - foreach: values: x: ['a', 'b', 'c'] message: (['x is ', x]) "); InitializeServices(stubBlueprints); var result = Services.App.Execute("deploy", "the-test"); Assert.AreEqual(0, result); Console.AssertContainsInOrder("x is a", "x is b", "x is c"); }
public async Task FileSystemSubWorkflowCanBeCalled() { var stubs = Yaml <StubFileSystem>(@" Files: the-test/workflow.yaml: | operations: - message: Before - workflow: lib/step1 - message: After the-test/lib/step1/workflow.yaml: | operations: - message: During "); InitializeServices(stubs); var result = Services.App.Execute("deploy", "the-test"); Assert.AreEqual(0, result); Console.AssertContainsInOrder("Before", "During", "After"); }
public async Task WebServerSubWorkflowCanBeCalled() { var stubRequests = Yaml <StubHttpClientHandlerFactory>(@" Files: https://localhost/the-test/workflow.yaml: | operations: - message: Before - workflow: lib/step1 - message: After https://localhost/the-test/lib/step1/workflow.yaml: | operations: - message: During "); InitializeServices(stubRequests, new StubFileSystem()); var result = Services.App.Execute("deploy", "https://localhost/the-test/workflow.yaml"); Assert.AreEqual(0, result); Console.AssertContainsInOrder("Before", "During", "After"); }
public void ThrowDetailsCanBeSavedInCatch() { var stubBlueprints = Yaml <StubBlueprintManager>(@" Blueprints: the-test: Files: workflow.yaml: | operations: - message: Catching Exception operations: - message: Throwing Exception throw: message: one details: x: two y: three catch: output: the-details: (error.details) the-message: (error.message) - message: Still Running "); InitializeServices(stubBlueprints); var result = Services.App.Execute("deploy", "the-test"); Assert.AreEqual(0, result); Console.AssertContainsInOrder( "Catching Exception", "Throwing Exception", "Still Running", "the-details:", "x: two", "y: three", "the-message: one"); }
public void StatusAndHeadersAreAvailable() { var stubBlueprints = Yaml <StubBlueprintManager>(@" Blueprints: the-test: Files: workflow.yaml: | operations: - request: request.yaml output: x: (result.status) y: (result.headers.""Content-Type""[0]) z: (result.headers.""Content-Length""[0]) request.yaml: | method: GET url: https://localhost/ "); var stubHttpClients = Yaml <StubHttpClientHandlerFactory>(@" Responses: https://localhost/: GET: status: 200 headers: Content-Type: [text/plain] Content-Length: [12] body: Hello world! "); InitializeServices(stubBlueprints, stubHttpClients); var result = Services.App.Execute("deploy", "the-test"); Assert.AreEqual(0, result); Console.AssertContainsInOrder("x:", "200", "y:", "text/plain", "z:", "12"); }
public void ResponseMayBeMergedWithWorkingMemory() { var stubBlueprints = Yaml <StubBlueprintManager>(@" Blueprints: the-test: Files: workflow.yaml: | operations: - output: b: [three,four] - values: a: [one,two] request: request.yaml output: d: ([a,b,result.body,c][]) request.yaml: | method: GET url: https://localhost/ "); var stubHttpClients = Yaml <StubHttpClientHandlerFactory>(@" Responses: https://localhost/: GET: status: 200 body: c: [five,six] "); InitializeServices(stubBlueprints, stubHttpClients); var result = Services.App.Execute("deploy", "the-test"); Assert.AreEqual(0, result); Console.AssertContainsInOrder("d:", "one", "two", "three", "four", "five", "six"); }
public void ForeachOutputIsConcatinated() { var stubBlueprints = Yaml <StubBlueprintManager>(@" Blueprints: the-test: Files: workflow.yaml: | operations: - foreach: values: x: ['a', 'b', 'c'] output: y: ([x]) - message: (join('+', y)) "); InitializeServices(stubBlueprints); var result = Services.App.Execute("deploy", "the-test"); Assert.AreEqual(0, result); Console.AssertContainsInOrder("a+b+c"); }
public async Task ApiVersionComesFromInfoVersionByDefault() { var stubHttpClients = Yaml <StubHttpClientHandlerFactory>($@" Responses: https://example.net/the-test/readme.md: GET: status: 200 body: | ``` yaml info: title: TheTest swagger: foo: target: apis/path source: https://example.org/specs/ inputs: - testing/swagger.json ``` https://example.net/the-test/workflow.yaml: GET: status: 200 body: operations: - request: apis/path/TestingClient/MethodOne.yaml output: one: ( result ) - request: apis/path/TestingClient/MethodTwo.yaml output: two: ( result ) https://example.org/specs/testing/swagger.json: GET: status: 200 body: swagger: 2.0 info: title: TestingClient version: 5.0-preview.2 host: example.com paths: /method/one: get: operationId: MethodOne parameters: - name: api-version in: query required: true /v{{api-version}}/method/two: get: operationId: MethodTwo parameters: - name: api-version in: path required: true https://example.com/method/one?api-version=5.0-preview.2: GET: status: 200 body: - request has arrived https://example.com/v5.0-preview.2/method/two: GET: status: 200 body: - request has arrived "); InitializeServices(stubHttpClients); var result = Services.App.Execute("deploy", "https://example.net/the-test"); System.Console.Error.WriteLine(Console.ErrorStringWriter.ToString()); System.Console.Out.WriteLine(Console.OutStringWriter.ToString()); Assert.AreEqual(0, result); Console.AssertContainsInOrder("request has arrived", "request has arrived"); }
public async Task ParametersAppearInPathQueryAndBody() { var stubHttpClients = Yaml <StubHttpClientHandlerFactory>($@" Responses: https://example.net/the-test/readme.md: GET: status: 200 body: | ``` yaml info: title: TheTest swagger: foo: target: apis/path source: https://example.org/specs/ inputs: - testing/swagger.json ``` https://example.net/the-test/workflow.yaml: GET: status: 200 body: operations: - request: apis/path/TestingClient/CreateSomething.yaml values: request: parameters: one: uno two: dos body: four: quatro five: 5 output: ( result ) https://example.org/specs/testing/swagger.json: GET: status: 200 body: swagger: 2.0 info: title: TestingClient host: example.com paths: /somethings/{{one}}: put: operationId: CreateSomething parameters: - name: one in: path - name: two in: query - name: three in: body schema: type: object properties: four: type: string five: type: integer https://example.com/somethings/uno?two=dos: PUT: status: 200 body: - request has arrived "); InitializeServices(stubHttpClients); var result = Services.App.Execute("deploy", "https://example.net/the-test"); System.Console.Error.WriteLine(Console.ErrorStringWriter.ToString()); System.Console.Out.WriteLine(Console.OutStringWriter.ToString()); Assert.AreEqual(0, result); Console.AssertContainsInOrder("request has arrived"); var put = stubHttpClients.AssertRequest("PUT", "https://example.com/somethings/uno?two=dos"); var body = await put.Content.ReadAsStringAsync(); Assert.IsTrue(body.Contains("\"four\": \"quatro\""), "Unable to find expected text in " + body); Assert.IsTrue(body.Contains("\"five\": 5"), "Unable to find expected text in " + body); }