1// Copyright 2018 Envoyproxy Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package server_test 16 17import ( 18 "context" 19 "io" 20 "net/http" 21 "net/http/httptest" 22 "strings" 23 "testing" 24 "testing/iotest" 25 26 "github.com/envoyproxy/go-control-plane/pkg/cache/types" 27 "github.com/envoyproxy/go-control-plane/pkg/cache/v2" 28 "github.com/envoyproxy/go-control-plane/pkg/resource/v2" 29 "github.com/envoyproxy/go-control-plane/pkg/server/v2" 30) 31 32type logger struct { 33 t *testing.T 34} 35 36func (log logger) Debugf(format string, args ...interface{}) { log.t.Logf(format, args...) } 37func (log logger) Infof(format string, args ...interface{}) { log.t.Logf(format, args...) } 38func (log logger) Warnf(format string, args ...interface{}) { log.t.Logf(format, args...) } 39func (log logger) Errorf(format string, args ...interface{}) { log.t.Logf(format, args...) } 40 41func TestGateway(t *testing.T) { 42 config := makeMockConfigWatcher() 43 config.responses = map[string][]cache.Response{ 44 resource.ClusterType: []cache.Response{{ 45 Version: "2", 46 Resources: []types.Resource{cluster}, 47 }}, 48 resource.RouteType: []cache.Response{{ 49 Version: "3", 50 Resources: []types.Resource{route}, 51 }}, 52 resource.ListenerType: []cache.Response{{ 53 Version: "4", 54 Resources: []types.Resource{listener}, 55 }}, 56 } 57 gtw := server.HTTPGateway{Log: logger{t: t}, Server: server.NewServer(context.Background(), config, nil)} 58 59 failCases := []struct { 60 path string 61 body io.Reader 62 expect int 63 }{ 64 { 65 path: "/hello/", 66 expect: http.StatusNotFound, 67 }, 68 { 69 path: "/v2/discovery:endpoints", 70 expect: http.StatusBadRequest, 71 }, 72 { 73 path: "/v2/discovery:endpoints", 74 body: iotest.TimeoutReader(strings.NewReader("hello")), 75 expect: http.StatusBadRequest, 76 }, 77 { 78 path: "/v2/discovery:endpoints", 79 body: strings.NewReader("hello"), 80 expect: http.StatusBadRequest, 81 }, 82 { 83 // missing response 84 path: "/v2/discovery:endpoints", 85 body: strings.NewReader("{\"node\": {\"id\": \"test\"}}"), 86 expect: http.StatusInternalServerError, 87 }, 88 } 89 for _, cs := range failCases { 90 rr := httptest.NewRecorder() 91 req, err := http.NewRequest(http.MethodPost, cs.path, cs.body) 92 if err != nil { 93 t.Fatal(err) 94 } 95 gtw.ServeHTTP(rr, req) 96 if status := rr.Code; status != cs.expect { 97 t.Errorf("handler returned wrong status: %d, want %d", status, cs.expect) 98 } 99 } 100 101 for _, path := range []string{"/v2/discovery:clusters", "/v2/discovery:routes", "/v2/discovery:listeners"} { 102 rr := httptest.NewRecorder() 103 req, err := http.NewRequest(http.MethodPost, path, strings.NewReader("{\"node\": {\"id\": \"test\"}}")) 104 if err != nil { 105 t.Fatal(err) 106 } 107 gtw.ServeHTTP(rr, req) 108 if status := rr.Code; status != 200 { 109 t.Errorf("handler returned wrong status: %d, want %d", status, 200) 110 } 111 } 112} 113