| Conditions | 43 |
| Total Lines | 219 |
| Code Lines | 141 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like providers.TestECSRAMRoleCredentialsProvider_getCredentials often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
| 1 | package providers |
||
| 144 | func TestECSRAMRoleCredentialsProvider_getCredentials(t *testing.T) { |
||
| 145 | originDo := hookDo |
||
| 146 | defer func() { hookDo = originDo }() |
||
| 147 | |||
| 148 | p, err := NewECSRAMRoleCredentialsProviderBuilder().Build() |
||
| 149 | assert.Nil(t, err) |
||
| 150 | |||
| 151 | // case 1: server error |
||
| 152 | hookDo = func(fn do) do { |
||
| 153 | return func(req *http.Request) (res *http.Response, err error) { |
||
| 154 | err = errors.New("mock server error") |
||
| 155 | return |
||
| 156 | } |
||
| 157 | } |
||
| 158 | _, err = p.getCredentials() |
||
| 159 | assert.NotNil(t, err) |
||
| 160 | assert.Equal(t, "get role name failed: mock server error", err.Error()) |
||
| 161 | |||
| 162 | hookDo = func(fn do) do { |
||
| 163 | return func(req *http.Request) (res *http.Response, err error) { |
||
| 164 | if req.URL.Path == "/latest/meta-data/ram/security-credentials/" { |
||
| 165 | res = mockResponse(200, "rolename") |
||
| 166 | return |
||
| 167 | } |
||
| 168 | |||
| 169 | err = errors.New("mock server error") |
||
| 170 | return |
||
| 171 | } |
||
| 172 | } |
||
| 173 | |||
| 174 | originNewRequest := hookNewRequest |
||
| 175 | defer func() { hookNewRequest = originNewRequest }() |
||
| 176 | |||
| 177 | // case 2: mock new http request failed |
||
| 178 | hookNewRequest = func(fn newReuqest) newReuqest { |
||
| 179 | return func(method, url string, body io.Reader) (*http.Request, error) { |
||
| 180 | if url == "http://100.100.100.200/latest/meta-data/ram/security-credentials/rolename" { |
||
| 181 | return nil, errors.New("new http request failed") |
||
| 182 | } |
||
| 183 | return http.NewRequest(method, url, body) |
||
| 184 | } |
||
| 185 | } |
||
| 186 | |||
| 187 | _, err = p.getCredentials() |
||
| 188 | assert.NotNil(t, err) |
||
| 189 | assert.Equal(t, "refresh Ecs sts token err: new http request failed", err.Error()) |
||
| 190 | |||
| 191 | hookNewRequest = originNewRequest |
||
| 192 | |||
| 193 | // case 3 |
||
| 194 | hookDo = func(fn do) do { |
||
| 195 | return func(req *http.Request) (res *http.Response, err error) { |
||
| 196 | if req.URL.Path == "/latest/meta-data/ram/security-credentials/" { |
||
| 197 | res = mockResponse(200, "rolename") |
||
| 198 | return |
||
| 199 | } |
||
| 200 | |||
| 201 | if req.URL.Path == "/latest/meta-data/ram/security-credentials/rolename" { |
||
| 202 | err = errors.New("mock server error") |
||
| 203 | return |
||
| 204 | } |
||
| 205 | return |
||
| 206 | } |
||
| 207 | } |
||
| 208 | _, err = p.getCredentials() |
||
| 209 | assert.NotNil(t, err) |
||
| 210 | assert.Equal(t, "refresh Ecs sts token err: mock server error", err.Error()) |
||
| 211 | |||
| 212 | // case 4: mock read response error |
||
| 213 | hookDo = func(fn do) do { |
||
| 214 | return func(req *http.Request) (res *http.Response, err error) { |
||
| 215 | if req.URL.Path == "/latest/meta-data/ram/security-credentials/" { |
||
| 216 | res = mockResponse(200, "rolename") |
||
| 217 | return |
||
| 218 | } |
||
| 219 | |||
| 220 | if req.URL.Path == "/latest/meta-data/ram/security-credentials/rolename" { |
||
| 221 | status := strconv.Itoa(200) |
||
| 222 | res = &http.Response{ |
||
| 223 | Proto: "HTTP/1.1", |
||
| 224 | ProtoMajor: 1, |
||
| 225 | Header: map[string][]string{}, |
||
| 226 | StatusCode: 200, |
||
| 227 | Status: status + " " + http.StatusText(200), |
||
| 228 | } |
||
| 229 | res.Body = ioutil.NopCloser(&errorReader{}) |
||
| 230 | return |
||
| 231 | } |
||
| 232 | return |
||
| 233 | } |
||
| 234 | } |
||
| 235 | _, err = p.getCredentials() |
||
| 236 | assert.NotNil(t, err) |
||
| 237 | assert.Equal(t, "read failed", err.Error()) |
||
| 238 | |||
| 239 | // case 4: 4xx error |
||
| 240 | hookDo = func(fn do) do { |
||
| 241 | return func(req *http.Request) (res *http.Response, err error) { |
||
| 242 | if req.URL.Path == "/latest/meta-data/ram/security-credentials/" { |
||
| 243 | res = mockResponse(200, "rolename") |
||
| 244 | return |
||
| 245 | } |
||
| 246 | |||
| 247 | if req.URL.Path == "/latest/meta-data/ram/security-credentials/rolename" { |
||
| 248 | res = mockResponse(400, "4xx error") |
||
| 249 | return |
||
| 250 | } |
||
| 251 | return |
||
| 252 | } |
||
| 253 | } |
||
| 254 | _, err = p.getCredentials() |
||
| 255 | assert.NotNil(t, err) |
||
| 256 | assert.Equal(t, "refresh Ecs sts token err, httpStatus: 400, message = 4xx error", err.Error()) |
||
| 257 | |||
| 258 | // case 5: invalid json |
||
| 259 | hookDo = func(fn do) do { |
||
| 260 | return func(req *http.Request) (res *http.Response, err error) { |
||
| 261 | if req.URL.Path == "/latest/meta-data/ram/security-credentials/" { |
||
| 262 | res = mockResponse(200, "rolename") |
||
| 263 | return |
||
| 264 | } |
||
| 265 | |||
| 266 | if req.URL.Path == "/latest/meta-data/ram/security-credentials/rolename" { |
||
| 267 | res = mockResponse(200, "invalid json") |
||
| 268 | return |
||
| 269 | } |
||
| 270 | return |
||
| 271 | } |
||
| 272 | } |
||
| 273 | _, err = p.getCredentials() |
||
| 274 | assert.NotNil(t, err) |
||
| 275 | assert.Equal(t, "refresh Ecs sts token err, json.Unmarshal fail: invalid character 'i' looking for beginning of value", err.Error()) |
||
| 276 | |||
| 277 | // case 6: empty response json |
||
| 278 | hookDo = func(fn do) do { |
||
| 279 | return func(req *http.Request) (res *http.Response, err error) { |
||
| 280 | if req.URL.Path == "/latest/meta-data/ram/security-credentials/" { |
||
| 281 | res = mockResponse(200, "rolename") |
||
| 282 | return |
||
| 283 | } |
||
| 284 | |||
| 285 | if req.URL.Path == "/latest/meta-data/ram/security-credentials/rolename" { |
||
| 286 | res = mockResponse(200, "null") |
||
| 287 | return |
||
| 288 | } |
||
| 289 | return |
||
| 290 | } |
||
| 291 | } |
||
| 292 | _, err = p.getCredentials() |
||
| 293 | assert.NotNil(t, err) |
||
| 294 | assert.Equal(t, "refresh Ecs sts token err, fail to get credentials", err.Error()) |
||
| 295 | |||
| 296 | // case 7: empty session ak response json |
||
| 297 | hookDo = func(fn do) do { |
||
| 298 | return func(req *http.Request) (res *http.Response, err error) { |
||
| 299 | if req.URL.Path == "/latest/meta-data/ram/security-credentials/" { |
||
| 300 | res = mockResponse(200, "rolename") |
||
| 301 | return |
||
| 302 | } |
||
| 303 | |||
| 304 | if req.URL.Path == "/latest/meta-data/ram/security-credentials/rolename" { |
||
| 305 | res = mockResponse(200, `{}`) |
||
| 306 | return |
||
| 307 | } |
||
| 308 | return |
||
| 309 | } |
||
| 310 | } |
||
| 311 | _, err = p.getCredentials() |
||
| 312 | assert.NotNil(t, err) |
||
| 313 | assert.Equal(t, "refresh Ecs sts token err, fail to get credentials", err.Error()) |
||
| 314 | |||
| 315 | // case 8: non-success response |
||
| 316 | hookDo = func(fn do) do { |
||
| 317 | return func(req *http.Request) (res *http.Response, err error) { |
||
| 318 | if req.URL.Path == "/latest/meta-data/ram/security-credentials/" { |
||
| 319 | res = mockResponse(200, "rolename") |
||
| 320 | return |
||
| 321 | } |
||
| 322 | |||
| 323 | if req.URL.Path == "/latest/meta-data/ram/security-credentials/rolename" { |
||
| 324 | res = mockResponse(200, `{"AccessKeyId":"saki","AccessKeySecret":"saks","Expiration":"2021-10-20T04:27:09Z","SecurityToken":"token","Code":"Failed"}`) |
||
| 325 | return |
||
| 326 | } |
||
| 327 | return |
||
| 328 | } |
||
| 329 | } |
||
| 330 | _, err = p.getCredentials() |
||
| 331 | assert.NotNil(t, err) |
||
| 332 | assert.Equal(t, "refresh Ecs sts token err, Code is not Success", err.Error()) |
||
| 333 | |||
| 334 | // case 8: mock ok value |
||
| 335 | hookDo = func(fn do) do { |
||
| 336 | return func(req *http.Request) (res *http.Response, err error) { |
||
| 337 | if req.URL.Path == "/latest/meta-data/ram/security-credentials/" { |
||
| 338 | res = mockResponse(200, "rolename") |
||
| 339 | return |
||
| 340 | } |
||
| 341 | |||
| 342 | if req.URL.Path == "/latest/meta-data/ram/security-credentials/rolename" { |
||
| 343 | res = mockResponse(200, `{"AccessKeyId":"saki","AccessKeySecret":"saks","Expiration":"2021-10-20T04:27:09Z","SecurityToken":"token","Code":"Success"}`) |
||
| 344 | return |
||
| 345 | } |
||
| 346 | return |
||
| 347 | } |
||
| 348 | } |
||
| 349 | creds, err := p.getCredentials() |
||
| 350 | assert.Nil(t, err) |
||
| 351 | assert.Equal(t, "saki", creds.AccessKeyId) |
||
| 352 | assert.Equal(t, "saks", creds.AccessKeySecret) |
||
| 353 | assert.Equal(t, "token", creds.SecurityToken) |
||
| 354 | assert.Equal(t, "2021-10-20T04:27:09Z", creds.Expiration) |
||
| 355 | |||
| 356 | // needUpdateCredential |
||
| 357 | assert.True(t, p.needUpdateCredential()) |
||
| 358 | p.expirationTimestamp = time.Now().Unix() |
||
| 359 | assert.True(t, p.needUpdateCredential()) |
||
| 360 | |||
| 361 | p.expirationTimestamp = time.Now().Unix() + 300 |
||
| 362 | assert.False(t, p.needUpdateCredential()) |
||
| 363 | } |
||
| 485 |