github.com/spinnaker/spin@v1.30.0/cmd/pipeline/execution/get_test.go (about) 1 // Copyright (c) 2019, Google, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package execution 16 17 import ( 18 "fmt" 19 "io/ioutil" 20 "net/http" 21 "net/http/httptest" 22 "strings" 23 "testing" 24 25 "github.com/spinnaker/spin/cmd" 26 "github.com/spinnaker/spin/cmd/pipeline" 27 "github.com/spinnaker/spin/util" 28 ) 29 30 func TestExecutionGet_basic(t *testing.T) { 31 ts := testGateExecutionGetSuccess() 32 defer ts.Close() 33 34 rootCmd, rootOpts := cmd.NewCmdRoot(ioutil.Discard, ioutil.Discard) 35 pipelineCmd, pipelineOpts := pipeline.NewPipelineCmd(rootOpts) 36 pipelineCmd.AddCommand(NewExecutionCmd(pipelineOpts)) 37 rootCmd.AddCommand(pipelineCmd) 38 39 args := []string{"pipeline", "ex", "get", "someId", "--gate-endpoint", ts.URL} 40 rootCmd.SetArgs(args) 41 err := rootCmd.Execute() 42 if err != nil { 43 t.Fatalf("Command failed with: %s", err) 44 } 45 } 46 47 func TestExecutionGet_noinput(t *testing.T) { 48 ts := testGateExecutionGetSuccess() 49 defer ts.Close() 50 51 rootCmd, rootOpts := cmd.NewCmdRoot(ioutil.Discard, ioutil.Discard) 52 pipelineCmd, pipelineOpts := pipeline.NewPipelineCmd(rootOpts) 53 pipelineCmd.AddCommand(NewExecutionCmd(pipelineOpts)) 54 rootCmd.AddCommand(pipelineCmd) 55 56 args := []string{"pipeline", "ex", "get", "--gate-endpoint", ts.URL} 57 rootCmd.SetArgs(args) 58 err := rootCmd.Execute() 59 if err == nil { 60 t.Fatalf("Command failed with: %s", err) 61 } 62 } 63 64 func TestExecutionGet_failure(t *testing.T) { 65 ts := testGateFail() 66 defer ts.Close() 67 68 rootCmd, rootOpts := cmd.NewCmdRoot(ioutil.Discard, ioutil.Discard) 69 pipelineCmd, pipelineOpts := pipeline.NewPipelineCmd(rootOpts) 70 pipelineCmd.AddCommand(NewExecutionCmd(pipelineOpts)) 71 rootCmd.AddCommand(pipelineCmd) 72 73 args := []string{"pipeline", "ex", "get", "someId", "--gate-endpoint", ts.URL} 74 rootCmd.SetArgs(args) 75 err := rootCmd.Execute() 76 if err == nil { 77 t.Fatalf("Command failed with: %s", err) 78 } 79 } 80 81 // testGateExecutionGetSuccess spins up a local http server that we will configure the GateClient 82 // to direct requests to. Responds with a 200 and a well-formed pipeline get response. 83 func testGateExecutionGetSuccess() *httptest.Server { 84 mux := util.TestGateMuxWithVersionHandler() 85 mux.Handle("/executions/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 86 fmt.Fprintln(w, strings.TrimSpace(executionGetJson)) 87 })) 88 return httptest.NewServer(mux) 89 } 90 91 // testGateFail spins up a local http server that we will configure the GateClient 92 // to direct requests to. Responds with a 500 InternalServerError. 93 func testGateFail() *httptest.Server { 94 mux := util.TestGateMuxWithVersionHandler() 95 mux.Handle("/executions/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 96 // TODO(jacobkiefer): Mock more robust errors once implemented upstream. 97 http.Error(w, "Internal Server Error", http.StatusInternalServerError) 98 })) 99 return httptest.NewServer(mux) 100 } 101 102 const executionGetJson = ` 103 [ 104 { 105 "application": "jtk54", 106 "authentication": { 107 "allowedAccounts": [ 108 "gce", 109 "docker", 110 "default" 111 ], 112 "user": "anonymous" 113 }, 114 "canceled": false, 115 "id": "someId", 116 "initialConfig": {}, 117 "keepWaitingPipelines": false, 118 "limitConcurrent": true, 119 "name": "spin pipeline", 120 "notifications": [], 121 "origin": "api", 122 "pipelineConfigId": "1", 123 "stages": [ 124 { 125 "context": { 126 "comments": "I have no quarrel with ye.", 127 "startTime": 1550686554744, 128 "waitTime": 30 129 }, 130 "id": "01D461XRATNBYMXDFZ24V27WGJ", 131 "name": "Wait", 132 "outputs": {}, 133 "refId": "1", 134 "requisiteStageRefIds": [], 135 "startTime": 1550686554297, 136 "status": "RUNNING", 137 "tasks": [ 138 { 139 "id": "1", 140 "implementingClass": "com.netflix.spinnaker.orca.pipeline.tasks.WaitTask", 141 "loopEnd": false, 142 "loopStart": false, 143 "name": "wait", 144 "stageEnd": true, 145 "stageStart": true, 146 "startTime": 1550686554503, 147 "status": "RUNNING" 148 } 149 ], 150 "type": "wait" 151 } 152 ], 153 "startTime": 1550686554054, 154 "status": "RUNNING", 155 "systemNotifications": [], 156 "trigger": { 157 "artifacts": [], 158 "dryRun": false, 159 "notifications": [], 160 "parameters": {}, 161 "rebake": false, 162 "resolvedExpectedArtifacts": [], 163 "strategy": false, 164 "type": "manual", 165 "user": "anonymous" 166 }, 167 "type": "PIPELINE" 168 } 169 ] 170 `