@@ -18,6 +18,7 @@ package v1
18
18
import (
19
19
"context"
20
20
"encoding/json"
21
+ "errors"
21
22
"fmt"
22
23
"net/http"
23
24
"net/url"
@@ -30,9 +31,10 @@ import (
30
31
)
31
32
32
33
type apiTest struct {
33
- do func () (interface {}, error )
34
- inErr error
35
- inRes interface {}
34
+ do func () (interface {}, error )
35
+ inErr error
36
+ inStatusCode int
37
+ inRes interface {}
36
38
37
39
reqPath string
38
40
reqParam url.Values
@@ -75,7 +77,9 @@ func (c *apiTestClient) Do(ctx context.Context, req *http.Request) (*http.Respon
75
77
}
76
78
77
79
resp := & http.Response {}
78
- if test .inErr != nil {
80
+ if test .inStatusCode != 0 {
81
+ resp .StatusCode = test .inStatusCode
82
+ } else if test .inErr != nil {
79
83
resp .StatusCode = statusAPIError
80
84
} else {
81
85
resp .StatusCode = http .StatusOK
@@ -194,6 +198,42 @@ func TestAPIs(t *testing.T) {
194
198
},
195
199
err : fmt .Errorf ("some error" ),
196
200
},
201
+ {
202
+ do : doQuery ("2" , testTime ),
203
+ inRes : "some body" ,
204
+ inStatusCode : 500 ,
205
+ inErr : & Error {
206
+ Type : ErrServer ,
207
+ Msg : "server error: 500" ,
208
+ Detail : "some body" ,
209
+ },
210
+
211
+ reqMethod : "GET" ,
212
+ reqPath : "/api/v1/query" ,
213
+ reqParam : url.Values {
214
+ "query" : []string {"2" },
215
+ "time" : []string {testTime .Format (time .RFC3339Nano )},
216
+ },
217
+ err : errors .New ("server_error: server error: 500" ),
218
+ },
219
+ {
220
+ do : doQuery ("2" , testTime ),
221
+ inRes : "some body" ,
222
+ inStatusCode : 404 ,
223
+ inErr : & Error {
224
+ Type : ErrClient ,
225
+ Msg : "client error: 404" ,
226
+ Detail : "some body" ,
227
+ },
228
+
229
+ reqMethod : "GET" ,
230
+ reqPath : "/api/v1/query" ,
231
+ reqParam : url.Values {
232
+ "query" : []string {"2" },
233
+ "time" : []string {testTime .Format (time .RFC3339Nano )},
234
+ },
235
+ err : errors .New ("client_error: client error: 404" ),
236
+ },
197
237
198
238
{
199
239
do : doQueryRange ("2" , Range {
@@ -498,29 +538,34 @@ func TestAPIs(t *testing.T) {
498
538
var tests []apiTest
499
539
tests = append (tests , queryTests ... )
500
540
501
- for _ , test := range tests {
502
- client .curTest = test
503
-
504
- res , err := test .do ()
505
-
506
- if test .err != nil {
507
- if err == nil {
508
- t .Errorf ("expected error %q but got none" , test .err )
509
- continue
541
+ for i , test := range tests {
542
+ t .Run (fmt .Sprintf ("%d" , i ), func (t * testing.T ) {
543
+ client .curTest = test
544
+
545
+ res , err := test .do ()
546
+
547
+ if test .err != nil {
548
+ if err == nil {
549
+ t .Fatalf ("expected error %q but got none" , test .err )
550
+ }
551
+ if err .Error () != test .err .Error () {
552
+ t .Errorf ("unexpected error: want %s, got %s" , test .err , err )
553
+ }
554
+ if apiErr , ok := err .(* Error ); ok {
555
+ if apiErr .Detail != test .inRes {
556
+ t .Errorf ("%q should be %q" , apiErr .Detail , test .inRes )
557
+ }
558
+ }
559
+ return
510
560
}
511
- if err . Error () != test . err . Error () {
512
- t .Errorf ("unexpected error: want %s, got %s" , test . err , err )
561
+ if err != nil {
562
+ t .Fatalf ("unexpected error: %s" , err )
513
563
}
514
- continue
515
- }
516
- if err != nil {
517
- t .Errorf ("unexpected error: %s" , err )
518
- continue
519
- }
520
564
521
- if ! reflect .DeepEqual (res , test .res ) {
522
- t .Errorf ("unexpected result: want %v, got %v" , test .res , res )
523
- }
565
+ if ! reflect .DeepEqual (res , test .res ) {
566
+ t .Errorf ("unexpected result: want %v, got %v" , test .res , res )
567
+ }
568
+ })
524
569
}
525
570
}
526
571
@@ -532,10 +577,10 @@ type testClient struct {
532
577
}
533
578
534
579
type apiClientTest struct {
535
- code int
536
- response interface {}
537
- expected string
538
- err * Error
580
+ code int
581
+ response interface {}
582
+ expectedBody string
583
+ expectedErr * Error
539
584
}
540
585
541
586
func (c * testClient ) URL (ep string , args map [string ]string ) * url.URL {
@@ -575,98 +620,108 @@ func (c *testClient) Do(ctx context.Context, req *http.Request) (*http.Response,
575
620
func TestAPIClientDo (t * testing.T ) {
576
621
tests := []apiClientTest {
577
622
{
623
+ code : statusAPIError ,
578
624
response : & apiResponse {
579
625
Status : "error" ,
580
626
Data : json .RawMessage (`null` ),
581
627
ErrorType : ErrBadData ,
582
628
Error : "failed" ,
583
629
},
584
- err : & Error {
630
+ expectedErr : & Error {
585
631
Type : ErrBadData ,
586
632
Msg : "failed" ,
587
633
},
588
- code : statusAPIError ,
589
- expected : `null` ,
634
+ expectedBody : `null` ,
590
635
},
591
636
{
637
+ code : statusAPIError ,
592
638
response : & apiResponse {
593
639
Status : "error" ,
594
640
Data : json .RawMessage (`"test"` ),
595
641
ErrorType : ErrTimeout ,
596
642
Error : "timed out" ,
597
643
},
598
- err : & Error {
644
+ expectedErr : & Error {
599
645
Type : ErrTimeout ,
600
646
Msg : "timed out" ,
601
647
},
602
- code : statusAPIError ,
603
- expected : `test` ,
648
+ expectedBody : `test` ,
604
649
},
605
650
{
606
- response : "bad json" ,
607
- err : & Error {
608
- Type : ErrBadResponse ,
609
- Msg : "bad response code 500" ,
651
+ code : http .StatusInternalServerError ,
652
+ response : "500 error details" ,
653
+ expectedErr : & Error {
654
+ Type : ErrServer ,
655
+ Msg : "server error: 500" ,
656
+ Detail : "500 error details" ,
657
+ },
658
+ },
659
+ {
660
+ code : http .StatusNotFound ,
661
+ response : "404 error details" ,
662
+ expectedErr : & Error {
663
+ Type : ErrClient ,
664
+ Msg : "client error: 404" ,
665
+ Detail : "404 error details" ,
610
666
},
611
- code : http .StatusInternalServerError ,
612
667
},
613
668
{
669
+ code : http .StatusBadRequest ,
614
670
response : & apiResponse {
615
671
Status : "error" ,
616
672
Data : json .RawMessage (`null` ),
617
673
ErrorType : ErrBadData ,
618
674
Error : "end timestamp must not be before start time" ,
619
675
},
620
- err : & Error {
676
+ expectedErr : & Error {
621
677
Type : ErrBadData ,
622
678
Msg : "end timestamp must not be before start time" ,
623
679
},
624
- code : http .StatusBadRequest ,
625
680
},
626
681
{
682
+ code : statusAPIError ,
627
683
response : "bad json" ,
628
- err : & Error {
684
+ expectedErr : & Error {
629
685
Type : ErrBadResponse ,
630
686
Msg : "invalid character 'b' looking for beginning of value" ,
631
687
},
632
- code : statusAPIError ,
633
688
},
634
689
{
690
+ code : statusAPIError ,
635
691
response : & apiResponse {
636
692
Status : "success" ,
637
693
Data : json .RawMessage (`"test"` ),
638
694
},
639
- err : & Error {
695
+ expectedErr : & Error {
640
696
Type : ErrBadResponse ,
641
697
Msg : "inconsistent body for response code" ,
642
698
},
643
- code : statusAPIError ,
644
699
},
645
700
{
701
+ code : statusAPIError ,
646
702
response : & apiResponse {
647
703
Status : "success" ,
648
704
Data : json .RawMessage (`"test"` ),
649
705
ErrorType : ErrTimeout ,
650
706
Error : "timed out" ,
651
707
},
652
- err : & Error {
708
+ expectedErr : & Error {
653
709
Type : ErrBadResponse ,
654
710
Msg : "inconsistent body for response code" ,
655
711
},
656
- code : statusAPIError ,
657
712
},
658
713
{
714
+ code : http .StatusOK ,
659
715
response : & apiResponse {
660
716
Status : "error" ,
661
717
Data : json .RawMessage (`"test"` ),
662
718
ErrorType : ErrTimeout ,
663
719
Error : "timed out" ,
664
720
},
665
- err : & Error {
721
+ expectedErr : & Error {
666
722
Type : ErrBadResponse ,
667
723
Msg : "inconsistent body for response code" ,
668
724
},
669
- code : http .StatusOK ,
670
725
},
671
726
}
672
727
@@ -677,30 +732,37 @@ func TestAPIClientDo(t *testing.T) {
677
732
}
678
733
client := & apiClient {tc }
679
734
680
- for _ , test := range tests {
681
-
682
- tc .ch <- test
683
-
684
- _ , body , err := client .Do (context .Background (), tc .req )
685
-
686
- if test .err != nil {
687
- if err == nil {
688
- t .Errorf ("expected error %q but got none" , test .err )
689
- continue
735
+ for i , test := range tests {
736
+ t .Run (fmt .Sprintf ("%d" , i ), func (t * testing.T ) {
737
+
738
+ tc .ch <- test
739
+
740
+ _ , body , err := client .Do (context .Background (), tc .req )
741
+
742
+ if test .expectedErr != nil {
743
+ if err == nil {
744
+ t .Fatalf ("expected error %q but got none" , test .expectedErr )
745
+ }
746
+ if test .expectedErr .Error () != err .Error () {
747
+ t .Errorf ("unexpected error: want %q, got %q" , test .expectedErr , err )
748
+ }
749
+ if test .expectedErr .Detail != "" {
750
+ apiErr := err .(* Error )
751
+ if apiErr .Detail != test .expectedErr .Detail {
752
+ t .Errorf ("unexpected error details: want %q, got %q" , test .expectedErr .Detail , apiErr .Detail )
753
+ }
754
+ }
755
+ return
690
756
}
691
- if test . err . Error () != err . Error () {
692
- t .Errorf ( "unexpected error: want %q, got %q" , test . err , err )
757
+ if err != nil {
758
+ t .Fatalf ( "unexpeceted error %s" , err )
693
759
}
694
- continue
695
- }
696
- if err != nil {
697
- t .Errorf ("unexpeceted error %s" , err )
698
- continue
699
- }
700
760
701
- want , got := test .expected , string (body )
702
- if want != got {
703
- t .Errorf ("unexpected body: want %q, got %q" , want , got )
704
- }
761
+ want , got := test .expectedBody , string (body )
762
+ if want != got {
763
+ t .Errorf ("unexpected body: want %q, got %q" , want , got )
764
+ }
765
+ })
766
+
705
767
}
706
768
}
0 commit comments