@@ -22,19 +22,22 @@ package elasticsearch
2222import (
2323 "encoding/base64"
2424 "errors"
25- "github.com/elastic/go-elasticsearch/v7/estransport"
2625 "io/ioutil"
2726 "net/http"
27+ "net/http/httptest"
2828 "net/url"
2929 "os"
30+ "reflect"
3031 "regexp"
3132 "strings"
3233 "testing"
34+
35+ "github.com/elastic/go-elasticsearch/v7/estransport"
3336)
3437
3538var called bool
3639
37- type mockTransp struct {
40+ type mockTransp struct {
3841 RoundTripFunc func (* http.Request ) (* http.Response , error )
3942}
4043
@@ -64,7 +67,6 @@ func (t *mockTransp) RoundTrip(req *http.Request) (*http.Response, error) {
6467 return t .RoundTripFunc (req )
6568}
6669
67-
6870func TestClientConfiguration (t * testing.T ) {
6971 t .Parallel ()
7072
@@ -219,7 +221,7 @@ func TestClientConfiguration(t *testing.T) {
219221 }, nil
220222 },
221223 },
222- })
224+ })
223225 if err != nil {
224226 t .Errorf ("Unexpected error, got: %+v" , err )
225227 }
@@ -444,7 +446,7 @@ func TestParseElasticsearchVersion(t *testing.T) {
444446 wantErr : true ,
445447 },
446448 }
447- for _ , tt := range tests {
449+ for _ , tt := range tests {
448450 t .Run (tt .name , func (t * testing.T ) {
449451 got , got1 , got2 , err := ParseElasticsearchVersion (tt .version )
450452 if (err != nil ) != tt .wantErr {
@@ -556,7 +558,7 @@ func TestGenuineCheckHeader(t *testing.T) {
556558 wantErr : true ,
557559 },
558560 {
559- name : "Unavailable product header" ,
561+ name : "Unavailable product header" ,
560562 headers : http.Header {},
561563 wantErr : true ,
562564 },
@@ -575,49 +577,56 @@ func TestResponseCheckOnly(t *testing.T) {
575577 name string
576578 useResponseCheckOnly bool
577579 response * http.Response
580+ requestErr error
578581 wantErr bool
579- } {
582+ }{
580583 {
581- name : "Valid answer with header" ,
584+ name : "Valid answer with header" ,
582585 useResponseCheckOnly : false ,
583586 response : & http.Response {
584587 Header : http.Header {"X-Elastic-Product" : []string {"Elasticsearch" }},
585- Body : ioutil .NopCloser (strings .NewReader ("{}" )),
588+ Body : ioutil .NopCloser (strings .NewReader ("{}" )),
586589 },
587- wantErr : false ,
590+ wantErr : false ,
588591 },
589592 {
590- name : "Valid answer without header" ,
593+ name : "Valid answer without header" ,
591594 useResponseCheckOnly : false ,
592595 response : & http.Response {
593596 Body : ioutil .NopCloser (strings .NewReader ("{}" )),
594597 },
595- wantErr : true ,
598+ wantErr : true ,
596599 },
597600 {
598- name : "Valid answer with header and response check" ,
601+ name : "Valid answer with header and response check" ,
599602 useResponseCheckOnly : true ,
600603 response : & http.Response {
601604 Header : http.Header {"X-Elastic-Product" : []string {"Elasticsearch" }},
602- Body : ioutil .NopCloser (strings .NewReader ("{}" )),
605+ Body : ioutil .NopCloser (strings .NewReader ("{}" )),
603606 },
604- wantErr : false ,
607+ wantErr : false ,
605608 },
606609 {
607- name : "Valid answer withouth header and response check" ,
610+ name : "Valid answer without header and response check" ,
608611 useResponseCheckOnly : true ,
609612 response : & http.Response {
610613 Body : ioutil .NopCloser (strings .NewReader ("{}" )),
611614 },
612- wantErr : true ,
615+ wantErr : true ,
616+ },
617+ {
618+ name : "Request failed" ,
619+ useResponseCheckOnly : true ,
620+ response : nil ,
621+ requestErr : errors .New ("request failed" ),
622+ wantErr : true ,
613623 },
614-
615624 }
616625 for _ , tt := range tests {
617626 t .Run (tt .name , func (t * testing.T ) {
618627 c , _ := NewClient (Config {
619628 Transport : & mockTransp {RoundTripFunc : func (request * http.Request ) (* http.Response , error ) {
620- return tt .response , nil
629+ return tt .response , tt . requestErr
621630 }},
622631 UseResponseCheckOnly : tt .useResponseCheckOnly ,
623632 })
@@ -628,3 +637,33 @@ func TestResponseCheckOnly(t *testing.T) {
628637 })
629638 }
630639}
640+
641+ func TestProductCheckError (t * testing.T ) {
642+ var requestPaths []string
643+ server := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
644+ requestPaths = append (requestPaths , r .URL .Path )
645+ if len (requestPaths ) == 1 {
646+ // Simulate transient error from a proxy on the first request.
647+ // This must not be cached by the client.
648+ w .WriteHeader (http .StatusBadGateway )
649+ return
650+ }
651+ w .Header ().Set ("X-Elastic-Product" , "Elasticsearch" )
652+ w .Write ([]byte ("{}" ))
653+ }))
654+ defer server .Close ()
655+
656+ c , _ := NewClient (Config {Addresses : []string {server .URL }, DisableRetry : true })
657+ if _ , err := c .Cat .Indices (); err == nil {
658+ t .Fatal ("expected error" )
659+ }
660+ if _ , err := c .Cat .Indices (); err != nil {
661+ t .Fatalf ("unexpected error: %s" , err )
662+ }
663+ if n := len (requestPaths ); n != 3 {
664+ t .Fatalf ("expected 3 requests, got %d" , n )
665+ }
666+ if ! reflect .DeepEqual (requestPaths , []string {"/" , "/" , "/_cat/indices" }) {
667+ t .Fatalf ("unexpected request paths: %s" , requestPaths )
668+ }
669+ }
0 commit comments