GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( e68691...412f4e )
by Jackson
06:39
created

providers.TestNewECSRAMRoleCredentialsProvider   A

Complexity

Conditions 1

Size

Total Lines 15
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 12
nop 1
dl 0
loc 15
rs 9.8
c 0
b 0
f 0
1
package providers
2
3
import (
4
	"errors"
5
	"io"
6
	"io/ioutil"
7
	"net/http"
8
	"strconv"
9
	"testing"
10
	"time"
11
12
	"github.com/stretchr/testify/assert"
13
)
14
15
func TestNewECSRAMRoleCredentialsProvider(t *testing.T) {
16
	p, err := NewECSRAMRoleCredentialsProviderBuilder().Build()
17
	assert.Nil(t, err)
18
	assert.Equal(t, "", p.roleName)
19
	assert.Equal(t, 21600, p.metadataTokenDurationSeconds)
20
21
	_, err = NewECSRAMRoleCredentialsProviderBuilder().WithMetadataTokenDurationSeconds(1000000000).Build()
22
	assert.EqualError(t, err, "the metadata token duration seconds must be 1-21600")
23
24
	p, err = NewECSRAMRoleCredentialsProviderBuilder().WithRoleName("role").WithMetadataTokenDurationSeconds(3600).Build()
25
	assert.Nil(t, err)
26
	assert.Equal(t, "role", p.roleName)
27
	assert.Equal(t, 3600, p.metadataTokenDurationSeconds)
28
29
	assert.True(t, p.needUpdateCredential())
30
}
31
32
func TestECSRAMRoleCredentialsProvider_getRoleName(t *testing.T) {
33
	p, err := NewECSRAMRoleCredentialsProviderBuilder().Build()
34
	assert.Nil(t, err)
35
36
	originNewRequest := hookNewRequest
37
	defer func() { hookNewRequest = originNewRequest }()
38
39
	// case 1: mock new http request failed
40
	hookNewRequest = func(fn newReuqest) newReuqest {
41
		return func(method, url string, body io.Reader) (*http.Request, error) {
42
			return nil, errors.New("new http request failed")
43
		}
44
	}
45
	_, err = p.getRoleName()
46
	assert.NotNil(t, err)
47
	assert.Equal(t, "get role name failed: new http request failed", err.Error())
48
	// reset new request
49
	hookNewRequest = originNewRequest
50
51
	originDo := hookDo
52
	defer func() { hookDo = originDo }()
53
54
	// case 2: server error
55
	hookDo = func(fn do) do {
56
		return func(req *http.Request) (res *http.Response, err error) {
57
			err = errors.New("mock server error")
58
			return
59
		}
60
	}
61
	_, err = p.getRoleName()
62
	assert.NotNil(t, err)
63
	assert.Equal(t, "get role name failed: mock server error", err.Error())
64
65
	// case 3: 4xx error
66
	hookDo = func(fn do) do {
67
		return func(req *http.Request) (res *http.Response, err error) {
68
			res = mockResponse(400, "4xx error")
69
			return
70
		}
71
	}
72
73
	_, err = p.getRoleName()
74
	assert.NotNil(t, err)
75
	assert.Equal(t, "get role name failed: request http://100.100.100.200/latest/meta-data/ram/security-credentials/ 400", err.Error())
76
77
	// case 4: mock read response error
78
	hookDo = func(fn do) do {
79
		return func(req *http.Request) (res *http.Response, err error) {
80
			status := strconv.Itoa(200)
81
			res = &http.Response{
82
				Proto:      "HTTP/1.1",
83
				ProtoMajor: 1,
84
				Header:     map[string][]string{},
85
				StatusCode: 200,
86
				Status:     status + " " + http.StatusText(200),
87
			}
88
			res.Body = ioutil.NopCloser(&errorReader{})
89
			return
90
		}
91
	}
92
	_, err = p.getRoleName()
93
	assert.NotNil(t, err)
94
	assert.Equal(t, "read failed", err.Error())
95
96
	// case 5: value json
97
	hookDo = func(fn do) do {
98
		return func(req *http.Request) (res *http.Response, err error) {
99
			res = mockResponse(200, "rolename")
100
			return
101
		}
102
	}
103
	roleName, err := p.getRoleName()
104
	assert.Nil(t, err)
105
	assert.Equal(t, "rolename", roleName)
106
}
107
108
func TestECSRAMRoleCredentialsProvider_getRoleNameWithMetadataV2(t *testing.T) {
109
	p, err := NewECSRAMRoleCredentialsProviderBuilder().WithEnableIMDSv2(true).Build()
110
	assert.Nil(t, err)
111
112
	// case 1: get metadata token failed
113
	originDo := hookDo
114
	defer func() { hookDo = originDo }()
115
116
	hookDo = func(fn do) do {
117
		return func(req *http.Request) (res *http.Response, err error) {
118
			err = errors.New("mock server error")
119
			return
120
		}
121
	}
122
	_, err = p.getRoleName()
123
	assert.NotNil(t, err)
124
	assert.Equal(t, "get metadata token failed: mock server error", err.Error())
125
126
	// case 2: return token
127
	hookDo = func(fn do) do {
128
		return func(req *http.Request) (res *http.Response, err error) {
129
			if req.URL.Path == "/latest/api/token" {
130
				res = mockResponse(200, `tokenxxxxx`)
131
			} else {
132
				assert.Equal(t, "tokenxxxxx", req.Header.Get("x-aliyun-ecs-metadata-token"))
133
				res = mockResponse(200, "rolename")
134
			}
135
			return
136
		}
137
	}
138
139
	roleName, err := p.getRoleName()
140
	assert.Nil(t, err)
141
	assert.Equal(t, "rolename", roleName)
142
}
143
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
}
364
365
func TestECSRAMRoleCredentialsProvider_getCredentialsWithMetadataV2(t *testing.T) {
366
	originDo := hookDo
367
	defer func() { hookDo = originDo }()
368
369
	p, err := NewECSRAMRoleCredentialsProviderBuilder().WithRoleName("rolename").WithEnableIMDSv2(true).Build()
370
	assert.Nil(t, err)
371
372
	// case 1: get metadata token failed
373
	hookDo = func(fn do) do {
374
		return func(req *http.Request) (res *http.Response, err error) {
375
			err = errors.New("mock server error")
376
			return
377
		}
378
	}
379
	_, err = p.getCredentials()
380
	assert.NotNil(t, err)
381
	assert.Equal(t, "get metadata token failed: mock server error", err.Error())
382
383
	// case 2: return token
384
	hookDo = func(fn do) do {
385
		return func(req *http.Request) (res *http.Response, err error) {
386
			if req.URL.Path == "/latest/api/token" {
387
				res = mockResponse(200, `tokenxxxxx`)
388
				return
389
			}
390
			if req.URL.Path == "/latest/meta-data/ram/security-credentials/rolename" {
391
				assert.Equal(t, "tokenxxxxx", req.Header.Get("x-aliyun-ecs-metadata-token"))
392
				res = mockResponse(200, `{"AccessKeyId":"saki","AccessKeySecret":"saks","Expiration":"2021-10-20T04:27:09Z","SecurityToken":"token","Code":"Success"}`)
393
			}
394
			return
395
		}
396
	}
397
398
	creds, err := p.getCredentials()
399
	assert.Nil(t, err)
400
	assert.Equal(t, "saki", creds.AccessKeyId)
401
	assert.Equal(t, "saks", creds.AccessKeySecret)
402
	assert.Equal(t, "token", creds.SecurityToken)
403
	assert.Equal(t, "2021-10-20T04:27:09Z", creds.Expiration)
404
405
	// needUpdateCredential
406
	assert.True(t, p.needUpdateCredential())
407
	p.expirationTimestamp = time.Now().Unix()
408
	assert.True(t, p.needUpdateCredential())
409
410
	p.expirationTimestamp = time.Now().Unix() + 300
411
	assert.False(t, p.needUpdateCredential())
412
}
413
414
func TestECSRAMRoleCredentialsProviderGetCredentials(t *testing.T) {
415
	originDo := hookDo
416
	defer func() { hookDo = originDo }()
417
418
	p, err := NewECSRAMRoleCredentialsProviderBuilder().WithRoleName("rolename").Build()
419
	assert.Nil(t, err)
420
	// case 1: get credentials failed
421
	hookDo = func(fn do) do {
422
		return func(req *http.Request) (res *http.Response, err error) {
423
			err = errors.New("mock server error")
424
			return
425
		}
426
	}
427
	_, err = p.GetCredentials()
428
	assert.NotNil(t, err)
429
	assert.Equal(t, "refresh Ecs sts token err: mock server error", err.Error())
430
431
	// case 2: get invalid expiration
432
	hookDo = func(fn do) do {
433
		return func(req *http.Request) (res *http.Response, err error) {
434
			res = mockResponse(200, `{"AccessKeyId":"saki","AccessKeySecret":"saks","Expiration":"invalidexpiration","SecurityToken":"token","Code":"Success"}`)
435
			return
436
		}
437
	}
438
	_, err = p.GetCredentials()
439
	assert.NotNil(t, err)
440
	assert.Equal(t, "parsing time \"invalidexpiration\" as \"2006-01-02T15:04:05Z\": cannot parse \"invalidexpiration\" as \"2006\"", err.Error())
441
442
	// case 3: happy result
443
	hookDo = func(fn do) do {
444
		return func(req *http.Request) (res *http.Response, err error) {
445
			res = mockResponse(200, `{"AccessKeyId":"akid","AccessKeySecret":"aksecret","Expiration":"2021-10-20T04:27:09Z","SecurityToken":"token","Code":"Success"}`)
446
			return
447
		}
448
	}
449
	cc, err := p.GetCredentials()
450
	assert.Nil(t, err)
451
	assert.Equal(t, "akid", cc.AccessKeyId)
452
	assert.Equal(t, "aksecret", cc.AccessKeySecret)
453
	assert.Equal(t, "token", cc.SecurityToken)
454
	assert.True(t, p.needUpdateCredential())
455
}
456
457
func TestECSRAMRoleCredentialsProvider_getMetadataToken(t *testing.T) {
458
	originDo := hookDo
459
	defer func() { hookDo = originDo }()
460
461
	p, err := NewECSRAMRoleCredentialsProviderBuilder().Build()
462
	assert.Nil(t, err)
463
464
	// case 1: server error
465
	hookDo = func(fn do) do {
466
		return func(req *http.Request) (res *http.Response, err error) {
467
			err = errors.New("mock server error")
468
			return
469
		}
470
	}
471
	_, err = p.getMetadataToken()
472
	assert.NotNil(t, err)
473
	assert.Equal(t, "get metadata token failed: mock server error", err.Error())
474
	// case 2: return token
475
	hookDo = func(fn do) do {
476
		return func(req *http.Request) (res *http.Response, err error) {
477
			res = mockResponse(200, `tokenxxxxx`)
478
			return
479
		}
480
	}
481
	metadataToken, err := p.getMetadataToken()
482
	assert.Nil(t, err)
483
	assert.Equal(t, "tokenxxxxx", metadataToken)
484
}
485