github.com/jonsyu1/godel@v0.0.0-20171017211503-64567a0cf169/apps/distgo/cmd/publish/almanac_test.go (about) 1 // Copyright 2016 Palantir Technologies, 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 publish_test 16 17 import ( 18 "io/ioutil" 19 "net/http" 20 "net/http/httptest" 21 "regexp" 22 "testing" 23 24 "github.com/pkg/errors" 25 "github.com/stretchr/testify/assert" 26 "github.com/stretchr/testify/require" 27 28 "github.com/palantir/godel/apps/distgo/cmd/publish" 29 ) 30 31 type errorRoundTripper struct{} 32 33 func (s *errorRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { 34 return nil, errors.Errorf("Unable to connect") 35 } 36 37 func TestAlmanacConnectionInfo(t *testing.T) { 38 var handlerFunc func(w http.ResponseWriter, r *http.Request) 39 handlerFuncPtr := &handlerFunc 40 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 41 localHandlerFunc := *handlerFuncPtr 42 localHandlerFunc(w, r) 43 })) 44 defer ts.Close() 45 a := publish.AlmanacInfo{ 46 URL: ts.URL, 47 } 48 49 for i, currCase := range []struct { 50 action func(a publish.AlmanacInfo) error 51 handler func(w http.ResponseWriter, r *http.Request) 52 verifier func(caseNum int, err error) 53 }{ 54 { 55 action: func(a publish.AlmanacInfo) error { 56 return a.CheckConnectivity(http.DefaultClient) 57 }, 58 handler: func(w http.ResponseWriter, r *http.Request) { 59 assert.Equal(t, "/v1/units", r.URL.String()) 60 assert.Equal(t, http.MethodGet, r.Method) 61 _, ok := r.Header[http.CanonicalHeaderKey("X-timestamp")] 62 assert.True(t, ok) 63 _, ok = r.Header[http.CanonicalHeaderKey("X-authorization")] 64 assert.True(t, ok) 65 _, err := w.Write([]byte("hello")) 66 require.NoError(t, err) 67 }, 68 verifier: func(caseNum int, err error) { 69 assert.NoError(t, err, "Case %d", caseNum) 70 }, 71 }, 72 { 73 action: func(a publish.AlmanacInfo) error { 74 return a.CheckConnectivity(http.DefaultClient) 75 }, 76 handler: func(w http.ResponseWriter, r *http.Request) { 77 w.WriteHeader(http.StatusNotFound) 78 }, 79 verifier: func(caseNum int, err error) { 80 assert.Regexp(t, regexp.MustCompile("Received non-success status code: 404 Not Found."), err.Error(), "Case %d", caseNum) 81 }, 82 }, 83 { 84 action: func(a publish.AlmanacInfo) error { 85 client := &http.Client{Transport: &errorRoundTripper{}} 86 return a.CreateProduct(client, "foo") 87 }, 88 verifier: func(caseNum int, err error) { 89 assert.Regexp(t, `Almanac request failed: .+`, err.Error(), "Case %d", caseNum) 90 // error should not contain authorization header 91 assert.NotRegexp(t, `X-Authorization`, err.Error(), "Case %d", caseNum) 92 }, 93 }, 94 { 95 action: func(a publish.AlmanacInfo) error { 96 return a.CreateUnit(http.DefaultClient, publish.AlmanacUnit{ 97 Product: "testProduct", 98 Tags: []string{"tag-1", "tag2"}, 99 }, "0.0.1", ioutil.Discard) 100 }, 101 handler: func(w http.ResponseWriter, r *http.Request) { 102 assert.Equal(t, "/v1/units", r.URL.String()) 103 assert.Equal(t, http.MethodPost, r.Method) 104 _, ok := r.Header[http.CanonicalHeaderKey("X-timestamp")] 105 assert.True(t, ok) 106 _, ok = r.Header[http.CanonicalHeaderKey("X-authorization")] 107 assert.True(t, ok) 108 109 bytes, err := ioutil.ReadAll(r.Body) 110 require.NoError(t, err) 111 assert.JSONEq(t, `{"product":"testProduct","branch":"","revision":"","url":"","metadata":{"version":"0.0.1"},"tags":["tag-1","tag2"]}`, string(bytes)) 112 113 _, err = w.Write([]byte("hello")) 114 require.NoError(t, err) 115 }, 116 verifier: func(caseNum int, err error) { 117 assert.NoError(t, err, "Case %d", caseNum) 118 }, 119 }, 120 { 121 action: func(a publish.AlmanacInfo) error { 122 return a.ReleaseProduct(http.DefaultClient, "testProduct", "testBranch", "testRevision") 123 }, 124 handler: func(w http.ResponseWriter, r *http.Request) { 125 assert.Equal(t, "/v1/units/testProduct/testBranch/testRevision/releases", r.URL.String()) 126 assert.Equal(t, http.MethodPost, r.Method) 127 _, ok := r.Header[http.CanonicalHeaderKey("X-timestamp")] 128 assert.True(t, ok) 129 _, ok = r.Header[http.CanonicalHeaderKey("X-authorization")] 130 assert.True(t, ok) 131 132 bytes, err := ioutil.ReadAll(r.Body) 133 require.NoError(t, err) 134 assert.JSONEq(t, `{"name":"GA"}`, string(bytes)) 135 136 _, err = w.Write([]byte("hello")) 137 require.NoError(t, err) 138 }, 139 verifier: func(caseNum int, err error) { 140 assert.NoError(t, err, "Case %d", caseNum) 141 }, 142 }, 143 } { 144 handlerFunc = currCase.handler 145 err := currCase.action(a) 146 currCase.verifier(i, err) 147 } 148 }