3
3
package etre_test
4
4
5
5
import (
6
+ "context"
6
7
"encoding/json"
7
- "io/ioutil "
8
+ "io"
8
9
"net/http"
9
10
"net/http/httptest"
10
11
"net/url"
34
35
respError * etre.Error // if respData is nil
35
36
respStatusCode int
36
37
)
37
- var httpClient = & http.Client {}
38
+ var httpRT = & rt {}
39
+ var httpClient = & http.Client {
40
+ Transport : httpRT ,
41
+ }
38
42
39
43
func init () {
40
44
ts = httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
@@ -44,7 +48,7 @@ func init() {
44
48
45
49
if r .Method == "POST" || r .Method == "PUT" {
46
50
var err error
47
- gotBody , err = ioutil .ReadAll (r .Body )
51
+ gotBody , err = io .ReadAll (r .Body )
48
52
if err != nil {
49
53
panic (err .Error ())
50
54
}
@@ -146,15 +150,17 @@ func TestQueryOK(t *testing.T) {
146
150
ec := etre .NewEntityClient ("node" , ts .URL , httpClient )
147
151
148
152
// Normal query that returns status code 200 and respData
153
+ ctx := testContext ()
149
154
query := "x=y"
150
- got , err := ec .Query (query , etre.QueryFilter {})
155
+ got , err := ec .WithContext ( ctx ). Query (query , etre.QueryFilter {})
151
156
require .NoError (t , err )
152
157
153
158
// Verify call and response
154
159
assert .Equal (t , "GET" , gotMethod )
155
160
assert .Equal (t , etre .API_ROOT + "/entities/node" , gotPath )
156
161
assert .Equal (t , "query=" + query , gotQuery )
157
162
assert .Equal (t , got , respData )
163
+ assert .Equal (t , ctx , httpRT .gotCtx )
158
164
}
159
165
160
166
func TestQueryNoResults (t * testing.T ) {
@@ -206,6 +212,82 @@ func TestQueryUnhandledError(t *testing.T) {
206
212
assert .Nil (t , got )
207
213
}
208
214
215
+ // //////////////////////////////////////////////////////////////////////////
216
+ // Get
217
+ // //////////////////////////////////////////////////////////////////////////
218
+ func TestGetOK (t * testing.T ) {
219
+ setup (t )
220
+
221
+ // Set global vars used by httptest.Server
222
+ respData = etre.Entity {
223
+ "_id" : "abc" ,
224
+ "hostname" : "localhost" ,
225
+ }
226
+
227
+ ec := etre .NewEntityClient ("node" , ts .URL , httpClient )
228
+
229
+ // Normal get that returns status code 200 and respData
230
+ ctx := testContext ()
231
+ got , err := ec .WithContext (ctx ).Get ("abc" )
232
+ require .NoError (t , err )
233
+
234
+ // Verify call and response
235
+ assert .Equal (t , "GET" , gotMethod )
236
+ assert .Equal (t , etre .API_ROOT + "/entity/node/abc" , gotPath )
237
+ assert .Equal (t , got , respData )
238
+ assert .Equal (t , ctx , httpRT .gotCtx )
239
+ }
240
+
241
+ func TestGetHandledError (t * testing.T ) {
242
+ // Test that client returns error on API error and no entity
243
+ setup (t )
244
+
245
+ // Set global vars used by httptest.Server
246
+ respStatusCode = http .StatusInternalServerError
247
+ respError = & etre.Error {
248
+ Type : "fake_error" ,
249
+ Message : "this is a fake error" ,
250
+ }
251
+
252
+ ec := etre .NewEntityClient ("node" , ts .URL , httpClient )
253
+ got , err := ec .Get ("abc" )
254
+ require .Error (t , err )
255
+ assert .Contains (t , err .Error (), respError .Type )
256
+ assert .Nil (t , got )
257
+ }
258
+
259
+ func TestGetUnhandledError (t * testing.T ) {
260
+ // Like TestGetHandledError above, but simulating a more severe error,
261
+ // like a panic, that makes the API _not_ return an etre.Error. The client
262
+ // should handle this and still return an error.
263
+ setup (t )
264
+
265
+ // Set global vars used by httptest.Server
266
+ respStatusCode = http .StatusInternalServerError
267
+
268
+ ec := etre .NewEntityClient ("node" , ts .URL , httpClient )
269
+ got , err := ec .Get ("abc" )
270
+ require .Error (t , err )
271
+ assert .Contains (t , err .Error (), "no response" )
272
+ assert .Nil (t , got )
273
+ }
274
+
275
+ func TestGetNotFound (t * testing.T ) {
276
+ // Like TestGetHandledError above, but simulating a more severe error,
277
+ // like a panic, that makes the API _not_ return an etre.Error. The client
278
+ // should handle this and still return an error.
279
+ setup (t )
280
+
281
+ // Set global vars used by httptest.Server
282
+ respStatusCode = http .StatusNotFound
283
+
284
+ ec := etre .NewEntityClient ("node" , ts .URL , httpClient )
285
+ got , err := ec .Get ("abc" )
286
+ require .Error (t , err )
287
+ assert .Contains (t , err .Error (), "not found" )
288
+ assert .Nil (t , got )
289
+ }
290
+
209
291
// //////////////////////////////////////////////////////////////////////////
210
292
// Insert
211
293
// //////////////////////////////////////////////////////////////////////////
@@ -233,14 +315,16 @@ func TestInsertOK(t *testing.T) {
233
315
"foo" : "bar" ,
234
316
},
235
317
}
236
- got , err := ec .Insert (entities )
318
+ ctx := testContext ()
319
+ got , err := ec .WithContext (ctx ).Insert (entities )
237
320
require .NoError (t , err )
238
321
239
322
// Verify call and response
240
323
assert .Equal (t , "POST" , gotMethod )
241
324
assert .Equal (t , etre .API_ROOT + "/entities/node" , gotPath )
242
325
assert .Empty (t , gotQuery )
243
326
assert .Equal (t , respData , got )
327
+ assert .Equal (t , ctx , httpRT .gotCtx )
244
328
}
245
329
246
330
func TestInsertAPIError (t * testing.T ) {
@@ -323,14 +407,16 @@ func TestUpdateOK(t *testing.T) {
323
407
entity := etre.Entity {
324
408
"foo" : "bar" , // patch foo:foo -> for:bar
325
409
}
326
- got , err := ec .Update ("foo=bar" , entity )
410
+ ctx := testContext ()
411
+ got , err := ec .WithContext (ctx ).Update ("foo=bar" , entity )
327
412
require .NoError (t , err )
328
413
329
414
// Verify call and response
330
415
assert .Equal (t , "PUT" , gotMethod )
331
416
assert .Equal (t , etre .API_ROOT + "/entities/node" , gotPath )
332
417
assert .Equal (t , "query=foo=bar" , gotQuery )
333
418
assert .Equal (t , respData , got )
419
+ assert .Equal (t , ctx , httpRT .gotCtx )
334
420
}
335
421
336
422
func TestUpdateAPIError (t * testing.T ) {
@@ -429,14 +515,16 @@ func TestDeleteOK(t *testing.T) {
429
515
430
516
// Normal delete that returns status code 200 and a write result
431
517
query := "foo=bar"
432
- got , err := ec .Delete (query )
518
+ ctx := testContext ()
519
+ got , err := ec .WithContext (ctx ).Delete (query )
433
520
require .NoError (t , err )
434
521
435
522
// Verify call and response
436
523
assert .Equal (t , "DELETE" , gotMethod )
437
524
assert .Equal (t , etre .API_ROOT + "/entities/node" , gotPath )
438
525
assert .Equal (t , "query=" + query , gotQuery )
439
526
assert .Equal (t , respData , got )
527
+ assert .Equal (t , ctx , httpRT .gotCtx )
440
528
}
441
529
442
530
func TestDeleteWithSet (t * testing.T ) {
@@ -475,7 +563,6 @@ func TestDeleteWithSet(t *testing.T) {
475
563
assert .Equal (t , etre .API_ROOT + "/entities/node" , gotPath )
476
564
assert .Equal (t , "query=" + query + "&setId=setid&setOp=setop&setSize=3" , gotQuery )
477
565
assert .Equal (t , respData , got )
478
-
479
566
}
480
567
481
568
// //////////////////////////////////////////////////////////////////////////
@@ -500,13 +587,15 @@ func TestDeleteOneOK(t *testing.T) {
500
587
501
588
ec := etre .NewEntityClient ("node" , ts .URL , httpClient )
502
589
503
- got , err := ec .DeleteOne ("abc" )
590
+ ctx := testContext ()
591
+ got , err := ec .WithContext (ctx ).DeleteOne ("abc" )
504
592
require .NoError (t , err )
505
593
506
594
assert .Equal (t , "DELETE" , gotMethod )
507
595
assert .Equal (t , etre .API_ROOT + "/entity/node/abc" , gotPath )
508
596
assert .Empty (t , gotQuery )
509
597
assert .Equal (t , respData , got )
598
+ assert .Equal (t , ctx , httpRT .gotCtx )
510
599
}
511
600
512
601
func TestDeleteOneWithSet (t * testing.T ) {
@@ -554,12 +643,14 @@ func TestLabelsOK(t *testing.T) {
554
643
555
644
ec := etre .NewEntityClient ("node" , ts .URL , httpClient )
556
645
557
- got , err := ec .Labels ("abc" )
646
+ ctx := testContext ()
647
+ got , err := ec .WithContext (ctx ).Labels ("abc" )
558
648
require .NoError (t , err )
559
649
assert .Equal (t , "GET" , gotMethod )
560
650
assert .Equal (t , etre .API_ROOT + "/entity/node/abc/labels" , gotPath )
561
651
assert .Empty (t , gotQuery )
562
652
assert .Equal (t , respData , got )
653
+ assert .Equal (t , ctx , httpRT .gotCtx )
563
654
}
564
655
565
656
func TestDeleteLabelOK (t * testing.T ) {
@@ -579,12 +670,14 @@ func TestDeleteLabelOK(t *testing.T) {
579
670
580
671
ec := etre .NewEntityClient ("node" , ts .URL , httpClient )
581
672
582
- got , err := ec .DeleteLabel ("abc" , "foo" )
673
+ ctx := testContext ()
674
+ got , err := ec .WithContext (ctx ).DeleteLabel ("abc" , "foo" )
583
675
require .NoError (t , err )
584
676
assert .Equal (t , "DELETE" , gotMethod )
585
677
assert .Equal (t , etre .API_ROOT + "/entity/node/abc/labels/foo" , gotPath )
586
678
assert .Empty (t , gotQuery )
587
679
assert .Equal (t , respData , got )
680
+ assert .Equal (t , ctx , httpRT .gotCtx )
588
681
}
589
682
590
683
// //////////////////////////////////////////////////////////////////////////
@@ -771,3 +864,31 @@ func TestCDCClient(t *testing.T) {
771
864
gotError := ec .Error ().Error ()
772
865
assert .Contains (t , gotError , "fake error" )
773
866
}
867
+
868
+ func TestWithContext (t * testing.T ) {
869
+ ctx1 := context .Background ()
870
+ ctx2 := context .WithValue (ctx1 , "key" , "value" )
871
+
872
+ // client w/o context should return context.Background()
873
+ client1 := etre .NewEntityClient ("node" , ts .URL , httpClient )
874
+ require .NotNil (t , client1 .Context ())
875
+ assert .Equal (t , ctx1 , client1 .Context ())
876
+
877
+ // set the context. should not change client1's context
878
+ client2 := client1 .WithContext (ctx2 )
879
+ assert .Equal (t , ctx2 , client2 .Context ())
880
+ assert .Equal (t , ctx1 , client1 .Context ())
881
+ }
882
+
883
+ func testContext () context.Context {
884
+ return context .WithValue (context .Background (), "key" , "test-context-" + time .Now ().String ())
885
+ }
886
+
887
+ type rt struct {
888
+ gotCtx context.Context
889
+ }
890
+
891
+ func (t * rt ) RoundTrip (r * http.Request ) (* http.Response , error ) {
892
+ t .gotCtx = r .Context ()
893
+ return http .DefaultTransport .RoundTrip (r )
894
+ }
0 commit comments