github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/runtime/kubernetes/api/api_test.go (about) 1 // Licensed under the Apache License, Version 2.0 (the "License"); 2 // you may not use this file except in compliance with the License. 3 // You may obtain a copy of the License at 4 // 5 // https://www.apache.org/licenses/LICENSE-2.0 6 // 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, 9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 // See the License for the specific language governing permissions and 11 // limitations under the License. 12 // 13 // Original source: github.com/micro/go-micro/v3/util/kubernetes/api/api_test.go 14 15 package api 16 17 import ( 18 "encoding/json" 19 "net/http" 20 "net/http/httptest" 21 "reflect" 22 "testing" 23 ) 24 25 type testcase struct { 26 Token string 27 ReqFn func(opts *Options) *Request 28 Method string 29 URI string 30 Body interface{} 31 Header map[string]string 32 Assert func(req *http.Request) bool 33 } 34 35 type assertFn func(req *http.Request) bool 36 37 var tests = []testcase{ 38 testcase{ 39 ReqFn: func(opts *Options) *Request { 40 return NewRequest(opts).Get().Resource("service") 41 }, 42 Method: "GET", 43 URI: "/api/v1/namespaces/default/services/", 44 }, 45 testcase{ 46 ReqFn: func(opts *Options) *Request { 47 return NewRequest(opts).Get().Resource("service").Name("foo") 48 }, 49 Method: "GET", 50 URI: "/api/v1/namespaces/default/services/foo", 51 }, 52 testcase{ 53 ReqFn: func(opts *Options) *Request { 54 return NewRequest(opts).Get().Resource("service").Namespace("test").Name("bar") 55 }, 56 Method: "GET", 57 URI: "/api/v1/namespaces/test/services/bar", 58 }, 59 testcase{ 60 ReqFn: func(opts *Options) *Request { 61 return NewRequest(opts).Get().Resource("deployment").Name("foo") 62 }, 63 Method: "GET", 64 URI: "/apis/apps/v1/namespaces/default/deployments/foo", 65 }, 66 testcase{ 67 ReqFn: func(opts *Options) *Request { 68 return NewRequest(opts).Get().Resource("deployment").Namespace("test").Name("foo") 69 }, 70 Method: "GET", 71 URI: "/apis/apps/v1/namespaces/test/deployments/foo", 72 }, 73 testcase{ 74 ReqFn: func(opts *Options) *Request { 75 return NewRequest(opts).Get().Resource("pod").Params(&Params{LabelSelector: map[string]string{"foo": "bar"}}) 76 }, 77 Method: "GET", 78 URI: "/api/v1/namespaces/default/pods/?labelSelector=foo%3Dbar", 79 }, 80 testcase{ 81 ReqFn: func(opts *Options) *Request { 82 return NewRequest(opts).Post().Resource("service").Name("foo").Body(map[string]string{"foo": "bar"}) 83 }, 84 Method: "POST", 85 URI: "/api/v1/namespaces/default/services/foo", 86 Body: map[string]string{"foo": "bar"}, 87 }, 88 testcase{ 89 ReqFn: func(opts *Options) *Request { 90 return NewRequest(opts).Post().Resource("deployment").Namespace("test").Name("foo").Body(map[string]string{"foo": "bar"}) 91 }, 92 Method: "POST", 93 URI: "/apis/apps/v1/namespaces/test/deployments/foo", 94 Body: map[string]string{"foo": "bar"}, 95 }, 96 testcase{ 97 ReqFn: func(opts *Options) *Request { 98 return NewRequest(opts).Put().Resource("endpoint").Name("baz").Body(map[string]string{"bam": "bar"}) 99 }, 100 Method: "PUT", 101 URI: "/api/v1/namespaces/default/endpoints/baz", 102 Body: map[string]string{"bam": "bar"}, 103 }, 104 testcase{ 105 ReqFn: func(opts *Options) *Request { 106 return NewRequest(opts).Patch().Resource("endpoint").Name("baz").Body(map[string]string{"bam": "bar"}) 107 }, 108 Method: "PATCH", 109 URI: "/api/v1/namespaces/default/endpoints/baz", 110 Body: map[string]string{"bam": "bar"}, 111 }, 112 testcase{ 113 ReqFn: func(opts *Options) *Request { 114 return NewRequest(opts).Patch().Resource("endpoint").Name("baz").SetHeader("foo", "bar") 115 }, 116 Method: "PATCH", 117 URI: "/api/v1/namespaces/default/endpoints/baz", 118 Header: map[string]string{"foo": "bar"}, 119 }, 120 testcase{ 121 ReqFn: func(opts *Options) *Request { 122 return NewRequest(opts).Patch().Resource("deployment").Name("baz").SetHeader("foo", "bar") 123 }, 124 Method: "PATCH", 125 URI: "/apis/apps/v1/namespaces/default/deployments/baz", 126 Header: map[string]string{"foo": "bar"}, 127 }, 128 testcase{ 129 ReqFn: func(opts *Options) *Request { 130 return NewRequest(opts). 131 Get(). 132 Resource("pod"). 133 SubResource("log"). 134 Name("foolog") 135 }, 136 Method: "GET", 137 URI: "/api/v1/namespaces/default/pods/foolog/log", 138 }, 139 } 140 141 var wrappedHandler = func(test *testcase, t *testing.T) http.HandlerFunc { 142 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 143 auth := r.Header.Get("Authorization") 144 if len(test.Token) > 0 && (len(auth) == 0 || auth != "Bearer "+test.Token) { 145 t.Errorf("test case token (%s) did not match expected token (%s)", "Bearer "+test.Token, auth) 146 } 147 148 if len(test.Method) > 0 && test.Method != r.Method { 149 t.Errorf("test case Method (%s) did not match expected Method (%s)", test.Method, r.Method) 150 } 151 152 if len(test.URI) > 0 && test.URI != r.URL.RequestURI() { 153 t.Errorf("test case URI (%s) did not match expected URI (%s)", test.URI, r.URL.RequestURI()) 154 } 155 156 if test.Body != nil { 157 var res map[string]string 158 decoder := json.NewDecoder(r.Body) 159 if err := decoder.Decode(&res); err != nil { 160 t.Errorf("decoding body failed: %v", err) 161 } 162 if !reflect.DeepEqual(res, test.Body) { 163 t.Error("body did not match") 164 } 165 } 166 167 if test.Header != nil { 168 for k, v := range test.Header { 169 if r.Header.Get(k) != v { 170 t.Error("header did not exist") 171 } 172 } 173 } 174 175 w.WriteHeader(http.StatusOK) 176 }) 177 } 178 179 func TestRequest(t *testing.T) { 180 for _, test := range tests { 181 ts := httptest.NewServer(wrappedHandler(&test, t)) 182 req := test.ReqFn(&Options{ 183 Host: ts.URL, 184 Client: &http.Client{}, 185 BearerToken: &test.Token, 186 Namespace: "default", 187 }) 188 res := req.Do() 189 if res.Error() != nil { 190 t.Errorf("request failed with %v", res.Error()) 191 } 192 ts.Close() 193 } 194 }