github.com/jonaz/heapster@v1.3.0-beta.0.0.20170208112634-cd3c15ca3d29/metrics/sinks/monasca/init_test.go (about) 1 // Copyright 2015 Google Inc. All Rights Reserved. 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 monasca 16 17 import ( 18 "encoding/json" 19 "fmt" 20 "io/ioutil" 21 "net/http" 22 "net/http/httptest" 23 "net/url" 24 "os" 25 "sync" 26 "testing" 27 28 "github.com/stretchr/testify/mock" 29 ) 30 31 type keystoneClientMock struct { 32 *KeystoneClientImpl 33 mock.Mock 34 } 35 36 func (ks *keystoneClientMock) MonascaURL() (*url.URL, error) { 37 args := ks.Called() 38 return args.Get(0).(*url.URL), args.Error(1) 39 } 40 41 func (ks *keystoneClientMock) GetToken() (string, error) { 42 args := ks.Called() 43 return args.String(0), args.Error(1) 44 } 45 46 var monascaAPIStub *httptest.Server 47 var keystoneAPIStub *httptest.Server 48 49 type ksAuthRequest struct { 50 Auth ksAuth `json:"auth"` 51 } 52 53 type ksAuth struct { 54 Identity ksIdentity `json:"identity"` 55 Scope ksScope `json:"scope"` 56 } 57 58 type ksIdentity struct { 59 Methods []string `json:"methods"` 60 Password ksPassword `json:"password"` 61 } 62 63 type ksPassword struct { 64 User ksUser `json:"user"` 65 } 66 67 type ksUser struct { 68 ID string `json:"id"` 69 Password string `json:"password"` 70 } 71 72 type ksScope struct { 73 Project ksProject `json:"project"` 74 } 75 76 type ksProject struct { 77 ID string `json:"id"` 78 } 79 80 // prepare before testing 81 func TestMain(m *testing.M) { 82 // monasca stub 83 monascaMutex := &sync.Mutex{} 84 defer monascaAPIStub.Close() 85 monascaAPIStub = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 86 monascaMutex.Lock() 87 defer monascaMutex.Unlock() 88 w.Header().Set("Content-Type", "application/json") 89 switch r.URL.Path { 90 case "/metrics": 91 defer r.Body.Close() 92 contents, err := ioutil.ReadAll(r.Body) 93 if err != nil { 94 w.WriteHeader(http.StatusInternalServerError) 95 w.Write([]byte(fmt.Sprintf("%s", err))) 96 break 97 } 98 99 // umarshal & do type checking on the fly 100 metrics := []metric{} 101 err = json.Unmarshal(contents, &metrics) 102 if err != nil { 103 w.WriteHeader(http.StatusInternalServerError) 104 w.Write([]byte(fmt.Sprintf("%s", err))) 105 break 106 } 107 108 // check for empty dimensions 109 for _, metric := range metrics { 110 for _, dimVal := range metric.Dimensions { 111 if dimVal == "" { 112 w.WriteHeader(http.StatusInternalServerError) 113 w.Write([]byte(monEmptyDimResp)) 114 break 115 } 116 } 117 } 118 119 // check token 120 token := r.Header.Get("X-Auth-Token") 121 if token != testToken { 122 w.WriteHeader(http.StatusUnauthorized) 123 w.Write([]byte(monUnauthorizedResp)) 124 break 125 } 126 w.WriteHeader(http.StatusNoContent) 127 break 128 case "/versions": 129 w.WriteHeader(http.StatusOK) 130 break 131 } 132 })) 133 134 // keystone stub 135 keystoneMutex := &sync.Mutex{} 136 defer keystoneAPIStub.Close() 137 keystoneAPIStub = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 138 keystoneMutex.Lock() 139 defer keystoneMutex.Unlock() 140 w.Header().Add("Content-Type", "application/json") 141 switch r.URL.Path { 142 case "/": 143 w.Write([]byte(ksVersionResp)) 144 break 145 case "/v3/auth/tokens": 146 if r.Method == "HEAD" { 147 ksToken := r.Header.Get("X-Auth-Token") 148 if ksToken != testToken { 149 w.WriteHeader(http.StatusUnauthorized) 150 break 151 } 152 token := r.Header.Get("X-Subject-Token") 153 if token == testToken { 154 // token valid 155 w.WriteHeader(http.StatusNoContent) 156 break 157 } 158 // token invalid 159 w.WriteHeader(http.StatusNotFound) 160 break 161 } 162 163 // read request 164 defer r.Body.Close() 165 contents, err := ioutil.ReadAll(r.Body) 166 if err != nil { 167 w.WriteHeader(http.StatusInternalServerError) 168 return 169 } 170 req := ksAuthRequest{} 171 err = json.Unmarshal(contents, &req) 172 if err != nil { 173 w.WriteHeader(http.StatusInternalServerError) 174 return 175 } 176 177 // authenticate 178 if req.Auth.Identity.Password.User.ID != testConfig.UserID || 179 req.Auth.Identity.Password.User.Password != testConfig.Password { 180 w.WriteHeader(http.StatusUnauthorized) 181 return 182 } 183 184 // check if the request is for a scoped token 185 returnedToken := testToken 186 returnedBody := ksUnscopedAuthResp 187 if req.Auth.Scope.Project.ID != "" { 188 if req.Auth.Scope.Project.ID != testTenantID { 189 w.WriteHeader(http.StatusInternalServerError) 190 return 191 } 192 returnedToken = testScopedToken 193 returnedBody = ksScopedAuthResp 194 } 195 // return a token 196 w.Header().Add("X-Subject-Token", returnedToken) 197 w.WriteHeader(http.StatusAccepted) 198 w.Write([]byte(returnedBody)) 199 break 200 case "/v3/services": 201 w.Write([]byte(ksServicesResp)) 202 break 203 case "/v3/endpoints": 204 w.Write([]byte(ksEndpointsResp)) 205 default: 206 w.WriteHeader(http.StatusInternalServerError) 207 } 208 })) 209 initKeystoneRespStubs() 210 211 testConfig.Password = "bar" 212 testConfig.UserID = "0ca8f6" 213 testConfig.IdentityEndpoint = keystoneAPIStub.URL + "/v3" 214 os.Exit(m.Run()) 215 }