k8s.io/apiserver@v0.31.1/plugin/pkg/authenticator/token/webhook/metrics_test.go (about)

     1  /*
     2  Copyright 2021 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package webhook
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  )
    23  
    24  func TestAuthenticatorMetrics(t *testing.T) {
    25  	scenarios := []struct {
    26  		name                            string
    27  		clientCert, clientKey, clientCA []byte
    28  		serverCert, serverKey, serverCA []byte
    29  		authnFakeServiceStatusCode      int
    30  		authFakeServiceDeny             bool
    31  		expectedRegisteredStatusCode    string
    32  		wantErr                         bool
    33  	}{
    34  		{
    35  			name:       "happy path",
    36  			clientCert: clientCert, clientKey: clientKey, clientCA: caCert,
    37  			serverCert: serverCert, serverKey: serverKey, serverCA: caCert,
    38  			expectedRegisteredStatusCode: "200",
    39  		},
    40  
    41  		{
    42  			name:       "an internal error returned from the webhook",
    43  			clientCert: clientCert, clientKey: clientKey, clientCA: caCert,
    44  			serverCert: serverCert, serverKey: serverKey, serverCA: caCert,
    45  			authnFakeServiceStatusCode:   500,
    46  			expectedRegisteredStatusCode: "500",
    47  		},
    48  
    49  		{
    50  			name:       "incorrect client certificate used, the webhook not called, an error is recorded",
    51  			clientCert: clientCert, clientKey: clientKey, clientCA: caCert,
    52  			serverCert: serverCert, serverKey: serverKey, serverCA: badCACert,
    53  			expectedRegisteredStatusCode: "<error>",
    54  			wantErr:                      true,
    55  		},
    56  	}
    57  
    58  	for _, scenario := range scenarios {
    59  		t.Run(scenario.name, func(t *testing.T) {
    60  			service := new(mockV1Service)
    61  			service.statusCode = scenario.authnFakeServiceStatusCode
    62  			if service.statusCode == 0 {
    63  				service.statusCode = 200
    64  			}
    65  			service.allow = !scenario.authFakeServiceDeny
    66  
    67  			server, err := NewV1TestServer(service, scenario.serverCert, scenario.serverKey, scenario.serverCA)
    68  			if err != nil {
    69  				t.Errorf("%s: failed to create server: %v", scenario.name, err)
    70  				return
    71  			}
    72  			defer server.Close()
    73  
    74  			fakeAuthnMetrics := &fakeAuthenticatorMetrics{}
    75  			authnMetrics := AuthenticatorMetrics{
    76  				RecordRequestTotal:   fakeAuthnMetrics.RequestTotal,
    77  				RecordRequestLatency: fakeAuthnMetrics.RequestLatency,
    78  			}
    79  			wh, err := newV1TokenAuthenticator(server.URL, scenario.clientCert, scenario.clientKey, scenario.clientCA, 0, nil, authnMetrics)
    80  			if err != nil {
    81  				t.Error("failed to create client")
    82  				return
    83  			}
    84  
    85  			_, _, err = wh.AuthenticateToken(context.Background(), "t0k3n")
    86  			if scenario.wantErr {
    87  				if err == nil {
    88  					t.Errorf("expected error making authorization request: %v", err)
    89  				}
    90  			}
    91  
    92  			if fakeAuthnMetrics.totalCode != scenario.expectedRegisteredStatusCode {
    93  				t.Errorf("incorrect status code recorded for RecordRequestTotal method, expected = %v, got %v", scenario.expectedRegisteredStatusCode, fakeAuthnMetrics.totalCode)
    94  			}
    95  
    96  			if fakeAuthnMetrics.latencyCode != scenario.expectedRegisteredStatusCode {
    97  				t.Errorf("incorrect status code recorded for RecordRequestLatency method, expected = %v, got %v", scenario.expectedRegisteredStatusCode, fakeAuthnMetrics.latencyCode)
    98  			}
    99  		})
   100  	}
   101  }
   102  
   103  type fakeAuthenticatorMetrics struct {
   104  	totalCode string
   105  
   106  	latency     float64
   107  	latencyCode string
   108  }
   109  
   110  func (f *fakeAuthenticatorMetrics) RequestTotal(_ context.Context, code string) {
   111  	f.totalCode = code
   112  }
   113  
   114  func (f *fakeAuthenticatorMetrics) RequestLatency(_ context.Context, code string, latency float64) {
   115  	f.latency = latency
   116  	f.latencyCode = code
   117  }