github.com/spinnaker/spin@v1.30.0/cmd/pipeline/get_test.go (about) 1 // Copyright (c) 2018, 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 pipeline 16 17 import ( 18 "bytes" 19 "fmt" 20 "io/ioutil" 21 "net/http" 22 "net/http/httptest" 23 "strings" 24 "testing" 25 26 "github.com/andreyvit/diff" 27 28 "github.com/spinnaker/spin/cmd" 29 "github.com/spinnaker/spin/util" 30 ) 31 32 func TestPipelineGet_json(t *testing.T) { 33 ts := testGatePipelineGetSuccess() 34 defer ts.Close() 35 36 buffer := new(bytes.Buffer) 37 rootCmd, rootOpts := cmd.NewCmdRoot(buffer, buffer) 38 pipelineCmd, _ := NewPipelineCmd(rootOpts) 39 rootCmd.AddCommand(pipelineCmd) 40 41 args := []string{"pipeline", "get", "--application", "app", "--name", "one", "--gate-endpoint", ts.URL} 42 rootCmd.SetArgs(args) 43 err := rootCmd.Execute() 44 if err != nil { 45 t.Fatalf("Command failed with: %s", err) 46 } 47 48 expected := strings.TrimSpace(pipelineGetJson) 49 recieved := strings.TrimSpace(buffer.String()) 50 if expected != recieved { 51 t.Fatalf("Unexpected command output:\n%s", diff.LineDiff(expected, recieved)) 52 } 53 } 54 55 func TestPipelineGet_yaml(t *testing.T) { 56 ts := testGatePipelineGetSuccess() 57 defer ts.Close() 58 59 buffer := new(bytes.Buffer) 60 rootCmd, rootOpts := cmd.NewCmdRoot(buffer, buffer) 61 pipelineCmd, _ := NewPipelineCmd(rootOpts) 62 rootCmd.AddCommand(pipelineCmd) 63 64 args := []string{"pipeline", "get", "--application", "app", "--name", "one", "--output", "yaml", "--gate-endpoint", ts.URL} 65 rootCmd.SetArgs(args) 66 err := rootCmd.Execute() 67 if err != nil { 68 t.Fatalf("Command failed with: %s", err) 69 } 70 71 expected := strings.TrimSpace(pipelineGetYaml) 72 recieved := strings.TrimSpace(buffer.String()) 73 if expected != recieved { 74 t.Fatalf("Unexpected command output:\n%s", diff.LineDiff(expected, recieved)) 75 } 76 } 77 78 func TestPipelineGet_flags(t *testing.T) { 79 ts := testGatePipelineGetSuccess() 80 defer ts.Close() 81 82 rootCmd, rootOpts := cmd.NewCmdRoot(ioutil.Discard, ioutil.Discard) 83 pipelineCmd, _ := NewPipelineCmd(rootOpts) 84 rootCmd.AddCommand(pipelineCmd) 85 86 args := []string{"pipeline", "get", "--gate-endpoint", ts.URL} // Missing application and name. 87 rootCmd.SetArgs(args) 88 err := rootCmd.Execute() 89 if err == nil { 90 t.Fatalf("Command failed with: %s", err) 91 } 92 } 93 94 func TestPipelineGet_fail(t *testing.T) { 95 ts := testGateFail() 96 defer ts.Close() 97 98 rootCmd, rootOpts := cmd.NewCmdRoot(ioutil.Discard, ioutil.Discard) 99 pipelineCmd, _ := NewPipelineCmd(rootOpts) 100 rootCmd.AddCommand(pipelineCmd) 101 102 args := []string{"pipeline", "get", "--application", "app", "--name", "one", "--gate-endpoint", ts.URL} 103 rootCmd.SetArgs(args) 104 err := rootCmd.Execute() 105 if err == nil { 106 t.Fatalf("Command failed with: %s", err) 107 } 108 } 109 110 func TestPipelineGet_notfound(t *testing.T) { 111 ts := testGatePipelineGetMissing() 112 defer ts.Close() 113 114 rootCmd, rootOpts := cmd.NewCmdRoot(ioutil.Discard, ioutil.Discard) 115 pipelineCmd, _ := NewPipelineCmd(rootOpts) 116 rootCmd.AddCommand(pipelineCmd) 117 118 args := []string{"pipeline", "get", "--application", "app", "--name", "two", "--gate-endpoint", ts.URL} 119 rootCmd.SetArgs(args) 120 err := rootCmd.Execute() 121 if err == nil { 122 t.Fatalf("Command failed with: %s", err) 123 } 124 } 125 126 // testGatePipelineGetSuccess spins up a local http server that we will configure the GateClient 127 // to direct requests to. Responds with a 200 and a well-formed pipeline get response. 128 func testGatePipelineGetSuccess() *httptest.Server { 129 mux := util.TestGateMuxWithVersionHandler() 130 mux.Handle("/applications/app/pipelineConfigs/one", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 131 w.Header().Add("content-type", "application/json") 132 fmt.Fprintln(w, strings.TrimSpace(pipelineGetJson)) 133 })) 134 return httptest.NewServer(mux) 135 } 136 137 // testGatePipelineGetMissing returns a 404 Not Found for an errant pipeline name|application pair. 138 func testGatePipelineGetMissing() *httptest.Server { 139 mux := util.TestGateMuxWithVersionHandler() 140 mux.Handle("/applications/app/pipelineConfigs/two", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 141 http.NotFound(w, r) 142 })) 143 return httptest.NewServer(mux) 144 } 145 146 const pipelineGetJson = ` 147 { 148 "application": "app", 149 "id": "pipeline_one", 150 "index": 0, 151 "keepWaitingPipelines": false, 152 "lastModifiedBy": "jacobkiefer@google.com", 153 "limitConcurrent": true, 154 "name": "one", 155 "parameterConfig": [ 156 { 157 "default": "blah", 158 "description": "A foo.", 159 "name": "foooB", 160 "required": true 161 } 162 ], 163 "stages": [ 164 { 165 "comments": "${ parameters.derp }", 166 "name": "Wait", 167 "refId": "1", 168 "requisiteStageRefIds": [], 169 "type": "wait", 170 "waitTime": 30 171 } 172 ], 173 "triggers": [], 174 "updateTs": "1526578883109" 175 } 176 ` 177 178 const pipelineGetYaml = ` 179 application: app 180 id: pipeline_one 181 index: 0 182 keepWaitingPipelines: false 183 lastModifiedBy: jacobkiefer@google.com 184 limitConcurrent: true 185 name: one 186 parameterConfig: 187 - default: blah 188 description: A foo. 189 name: foooB 190 required: true 191 stages: 192 - comments: ${ parameters.derp } 193 name: Wait 194 refId: "1" 195 requisiteStageRefIds: [] 196 type: wait 197 waitTime: 30 198 triggers: [] 199 updateTs: "1526578883109" 200 `