istio.io/istio@v0.0.0-20240520182934-d79c90f27776/istioctl/pkg/admin/istiodconfig_test.go (about) 1 // Copyright Istio 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 15 package admin 16 17 import ( 18 "net/http" 19 "net/http/httptest" 20 "net/url" 21 "os" 22 "reflect" 23 "testing" 24 ) 25 26 func Test_newScopeLevelPair(t *testing.T) { 27 validationPattern := `^\w+:(debug|error|warn|info|debug)` 28 type args struct { 29 slp string 30 validationPattern string 31 } 32 tests := []struct { 33 name string 34 args args 35 want *ScopeLevelPair 36 wantErr bool 37 }{ 38 { 39 name: "Fail when logs scope-level pair don't match pattern", 40 args: args{validationPattern: validationPattern, slp: "invalid:pattern"}, 41 wantErr: true, 42 }, 43 } 44 for _, tt := range tests { 45 t.Run(tt.name, func(t *testing.T) { 46 got, err := newScopeLevelPair(tt.args.slp, tt.args.validationPattern) 47 if (err != nil) != tt.wantErr { 48 t.Errorf("newScopeLevelPair() error = %v, wantErr %v", err, tt.wantErr) 49 return 50 } 51 if !reflect.DeepEqual(got, tt.want) { 52 t.Errorf("newScopeLevelPair() got = %v, want %v", got, tt.want) 53 } 54 }) 55 } 56 } 57 58 func Test_newScopeStackTraceLevelPair(t *testing.T) { 59 validationPattern := `^\w+:(debug|error|warn|info|debug)` 60 type args struct { 61 sslp string 62 validationPattern string 63 } 64 tests := []struct { 65 name string 66 args args 67 want *scopeStackTraceLevelPair 68 wantErr bool 69 }{ 70 { 71 name: "Fail when logs scope-level pair don't match pattern", 72 args: args{validationPattern: validationPattern, sslp: "invalid:pattern"}, 73 wantErr: true, 74 }, 75 } 76 for _, tt := range tests { 77 t.Run(tt.name, func(t *testing.T) { 78 got, err := newScopeStackTraceLevelPair(tt.args.sslp, tt.args.validationPattern) 79 if (err != nil) != tt.wantErr { 80 t.Errorf("newScopeStackTraceLevelPair() error = %v, wantErr %v", err, tt.wantErr) 81 return 82 } 83 if !reflect.DeepEqual(got, tt.want) { 84 t.Errorf("newScopeStackTraceLevelPair() got = %v, want %v", got, tt.want) 85 } 86 }) 87 } 88 } 89 90 func Test_chooseClientFlag(t *testing.T) { 91 url, _ := url.Parse("http://localhost/scopej/resource") 92 93 ctrzClient := &ControlzClient{ 94 baseURL: url, 95 httpClient: &http.Client{}, 96 } 97 98 type args struct { 99 ctrzClient *ControlzClient 100 reset bool 101 outputLogLevel string 102 stackTraceLevel string 103 outputFormat string 104 } 105 tests := []struct { 106 name string 107 args args 108 want *istiodConfigLog 109 }{ 110 { 111 name: "given --reset flag return reset command", 112 args: args{ 113 ctrzClient: ctrzClient, 114 reset: true, 115 outputLogLevel: "", 116 stackTraceLevel: "", 117 outputFormat: "", 118 }, 119 want: &istiodConfigLog{state: &resetState{ 120 client: ctrzClient, 121 }}, 122 }, 123 { 124 name: "given --level flag return outputLogLevel command", 125 args: args{ 126 ctrzClient: ctrzClient, 127 reset: false, 128 outputLogLevel: "resource:info", 129 stackTraceLevel: "", 130 outputFormat: "", 131 }, 132 want: &istiodConfigLog{state: &logLevelState{ 133 client: ctrzClient, 134 outputLogLevel: "resource:info", 135 }}, 136 }, 137 { 138 name: "given --stack-trace-level flag return stackTraceLevelState", 139 args: args{ 140 ctrzClient: ctrzClient, 141 reset: false, 142 outputLogLevel: "", 143 stackTraceLevel: "resource:info", 144 outputFormat: "", 145 }, 146 want: &istiodConfigLog{ 147 state: &stackTraceLevelState{ 148 client: ctrzClient, 149 stackTraceLevel: "resource:info", 150 }, 151 }, 152 }, 153 } 154 for _, tt := range tests { 155 t.Run(tt.name, func(t *testing.T) { 156 if got := chooseClientFlag(tt.args.ctrzClient, tt.args.reset, tt.args.outputLogLevel, 157 tt.args.stackTraceLevel, tt.args.outputFormat); !reflect.DeepEqual(got, tt.want) { 158 t.Errorf("chooseClientFlag() = %v, want %v", got, tt.want) 159 } 160 }) 161 } 162 } 163 164 func resourceHandler(writer http.ResponseWriter, request *http.Request) { 165 const getResponse = `{"name":"resource","description":"Core resource model scope","output_level":"info","stack_trace_level":"none","log_callers":false}` 166 167 switch request.Method { 168 case http.MethodGet: 169 _, _ = writer.Write([]byte(getResponse)) 170 } 171 } 172 173 func adsHandler(writer http.ResponseWriter, request *http.Request) { 174 const getResponse = `{"name":"ads","description":"ads debugging","output_level":"info","stack_trace_level":"none","log_callers":false}` 175 176 switch request.Method { 177 case http.MethodGet: 178 _, _ = writer.Write([]byte(getResponse)) 179 } 180 } 181 182 func setupHTTPServer() (*httptest.Server, *url.URL) { 183 handler := http.NewServeMux() 184 handler.HandleFunc("/scopej/ads", adsHandler) 185 handler.HandleFunc("/scopej/resource", resourceHandler) 186 server := httptest.NewServer(handler) 187 url, _ := url.Parse(server.URL) 188 return server, url 189 } 190 191 func Test_flagState_run(t *testing.T) { 192 server, url := setupHTTPServer() 193 defer server.Close() 194 195 ctrzClientNoScopejHandler := &ControlzClient{ 196 baseURL: url, 197 httpClient: &http.Client{}, 198 } 199 tests := []struct { 200 name string 201 state flagState 202 want string 203 wantErr bool 204 }{ 205 { 206 name: "resetState.run() should throw an error if the /scopej endpoint is missing", 207 state: &resetState{client: ctrzClientNoScopejHandler}, 208 wantErr: true, 209 }, 210 { 211 name: "logLevelState.run() should throw an error if the /scopej endpoint is missing", 212 state: &logLevelState{ 213 client: ctrzClientNoScopejHandler, 214 outputLogLevel: "test:debug", 215 }, 216 wantErr: true, 217 }, 218 { 219 name: "stackTraceLevelState.run() should throw an error if the /scopej endpoint is missing", 220 state: &stackTraceLevelState{ 221 client: ctrzClientNoScopejHandler, 222 stackTraceLevel: "test:debug", 223 }, 224 wantErr: true, 225 }, 226 } 227 for _, tt := range tests { 228 t.Run(tt.name, func(t *testing.T) { 229 err := tt.state.run(os.Stdout) 230 if (err != nil) != tt.wantErr { 231 t.Errorf("run() error = %v, wantErr %v", err, tt.wantErr) 232 return 233 } 234 }) 235 } 236 }