kubernetes requestheader_controller_test 源码
kubernetes requestheader_controller_test 代码
文件路径:/staging/src/k8s.io/apiserver/pkg/authentication/request/headerrequest/requestheader_controller_test.go
/*
Copyright 2020 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package headerrequest
import (
"context"
"encoding/json"
"k8s.io/apimachinery/pkg/api/equality"
"testing"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"
corev1listers "k8s.io/client-go/listers/core/v1"
"k8s.io/client-go/tools/cache"
)
const (
defConfigMapName = "extension-apiserver-authentication"
defConfigMapNamespace = "kube-system"
defUsernameHeadersKey = "user-key"
defGroupHeadersKey = "group-key"
defExtraHeaderPrefixesKey = "extra-key"
defAllowedClientNamesKey = "names-key"
)
type expectedHeadersHolder struct {
usernameHeaders []string
groupHeaders []string
extraHeaderPrefixes []string
allowedClientNames []string
}
func TestRequestHeaderAuthRequestController(t *testing.T) {
scenarios := []struct {
name string
cm *corev1.ConfigMap
expectedHeader expectedHeadersHolder
expectErr bool
}{
{
name: "happy-path: headers values are populated form a config map",
cm: defaultConfigMap(t, []string{"user-val"}, []string{"group-val"}, []string{"extra-val"}, []string{"names-val"}),
expectedHeader: expectedHeadersHolder{
usernameHeaders: []string{"user-val"},
groupHeaders: []string{"group-val"},
extraHeaderPrefixes: []string{"extra-val"},
allowedClientNames: []string{"names-val"},
},
},
{
name: "passing an empty config map doesn't break the controller",
cm: func() *corev1.ConfigMap {
c := defaultConfigMap(t, nil, nil, nil, nil)
c.Data = map[string]string{}
return c
}(),
},
{
name: "an invalid config map produces an error",
cm: func() *corev1.ConfigMap {
c := defaultConfigMap(t, nil, nil, nil, nil)
c.Data = map[string]string{
defUsernameHeadersKey: "incorrect-json-array",
}
return c
}(),
expectErr: true,
},
}
for _, scenario := range scenarios {
t.Run(scenario.name, func(t *testing.T) {
// test data
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{})
if err := indexer.Add(scenario.cm); err != nil {
t.Fatal(err.Error())
}
target := newDefaultTarget()
target.configmapLister = corev1listers.NewConfigMapLister(indexer).ConfigMaps(defConfigMapNamespace)
// act
err := target.sync()
if err != nil && !scenario.expectErr {
t.Errorf("got unexpected error %v", err)
}
if err == nil && scenario.expectErr {
t.Error("expected an error but didn't get one")
}
// validate
validateExpectedHeaders(t, target, scenario.expectedHeader)
})
}
}
func TestRequestHeaderAuthRequestControllerPreserveState(t *testing.T) {
scenarios := []struct {
name string
cm *corev1.ConfigMap
expectedHeader expectedHeadersHolder
expectErr bool
}{
{
name: "scenario 1: headers values are populated form a config map",
cm: defaultConfigMap(t, []string{"user-val"}, []string{"group-val"}, []string{"extra-val"}, []string{"names-val"}),
expectedHeader: expectedHeadersHolder{
usernameHeaders: []string{"user-val"},
groupHeaders: []string{"group-val"},
extraHeaderPrefixes: []string{"extra-val"},
allowedClientNames: []string{"names-val"},
},
},
{
name: "scenario 2: an invalid config map produces an error but doesn't destroy the state (scenario 1)",
cm: func() *corev1.ConfigMap {
c := defaultConfigMap(t, nil, nil, nil, nil)
c.Data = map[string]string{
defUsernameHeadersKey: "incorrect-json-array",
}
return c
}(),
expectErr: true,
expectedHeader: expectedHeadersHolder{
usernameHeaders: []string{"user-val"},
groupHeaders: []string{"group-val"},
extraHeaderPrefixes: []string{"extra-val"},
allowedClientNames: []string{"names-val"},
},
},
{
name: "scenario 3: some headers values have changed (prev set by scenario 1)",
cm: defaultConfigMap(t, []string{"user-val"}, []string{"group-val-scenario-3"}, []string{"extra-val"}, []string{"names-val"}),
expectedHeader: expectedHeadersHolder{
usernameHeaders: []string{"user-val"},
groupHeaders: []string{"group-val-scenario-3"},
extraHeaderPrefixes: []string{"extra-val"},
allowedClientNames: []string{"names-val"},
},
},
{
name: "scenario 4: all headers values have changed (prev set by scenario 3)",
cm: defaultConfigMap(t, []string{"user-val-scenario-4"}, []string{"group-val-scenario-4"}, []string{"extra-val-scenario-4"}, []string{"names-val-scenario-4"}),
expectedHeader: expectedHeadersHolder{
usernameHeaders: []string{"user-val-scenario-4"},
groupHeaders: []string{"group-val-scenario-4"},
extraHeaderPrefixes: []string{"extra-val-scenario-4"},
allowedClientNames: []string{"names-val-scenario-4"},
},
},
}
target := newDefaultTarget()
for _, scenario := range scenarios {
t.Run(scenario.name, func(t *testing.T) {
// test data
if scenario.cm != nil {
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{})
if err := indexer.Add(scenario.cm); err != nil {
t.Fatal(err.Error())
}
target.configmapLister = corev1listers.NewConfigMapLister(indexer).ConfigMaps(defConfigMapNamespace)
}
// act
err := target.sync()
if err != nil && !scenario.expectErr {
t.Errorf("got unexpected error %v", err)
}
if err == nil && scenario.expectErr {
t.Error("expected an error but didn't get one")
}
// validate
validateExpectedHeaders(t, target, scenario.expectedHeader)
})
}
}
func TestRequestHeaderAuthRequestControllerSyncOnce(t *testing.T) {
scenarios := []struct {
name string
cm *corev1.ConfigMap
expectedHeader expectedHeadersHolder
expectErr bool
}{
{
name: "headers values are populated form a config map",
cm: defaultConfigMap(t, []string{"user-val"}, []string{"group-val"}, []string{"extra-val"}, []string{"names-val"}),
expectedHeader: expectedHeadersHolder{
usernameHeaders: []string{"user-val"},
groupHeaders: []string{"group-val"},
extraHeaderPrefixes: []string{"extra-val"},
allowedClientNames: []string{"names-val"},
},
},
}
for _, scenario := range scenarios {
t.Run(scenario.name, func(t *testing.T) {
// test data
target := newDefaultTarget()
fakeKubeClient := fake.NewSimpleClientset(scenario.cm)
target.client = fakeKubeClient
// act
ctx := context.TODO()
err := target.RunOnce(ctx)
if err != nil && !scenario.expectErr {
t.Errorf("got unexpected error %v", err)
}
if err == nil && scenario.expectErr {
t.Error("expected an error but didn't get one")
}
// validate
validateExpectedHeaders(t, target, scenario.expectedHeader)
})
}
}
func defaultConfigMap(t *testing.T, usernameHeaderVal, groupHeadersVal, extraHeaderPrefixesVal, allowedClientNamesVal []string) *corev1.ConfigMap {
encode := func(val []string) string {
encodedVal, err := json.Marshal(val)
if err != nil {
t.Fatalf("unable to marshal %q , due to %v", usernameHeaderVal, err)
}
return string(encodedVal)
}
return &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: defConfigMapName,
Namespace: defConfigMapNamespace,
},
Data: map[string]string{
defUsernameHeadersKey: encode(usernameHeaderVal),
defGroupHeadersKey: encode(groupHeadersVal),
defExtraHeaderPrefixesKey: encode(extraHeaderPrefixesVal),
defAllowedClientNamesKey: encode(allowedClientNamesVal),
},
}
}
func newDefaultTarget() *RequestHeaderAuthRequestController {
return &RequestHeaderAuthRequestController{
configmapName: defConfigMapName,
configmapNamespace: defConfigMapNamespace,
usernameHeadersKey: defUsernameHeadersKey,
groupHeadersKey: defGroupHeadersKey,
extraHeaderPrefixesKey: defExtraHeaderPrefixesKey,
allowedClientNamesKey: defAllowedClientNamesKey,
}
}
func validateExpectedHeaders(t *testing.T, target *RequestHeaderAuthRequestController, expected expectedHeadersHolder) {
if !equality.Semantic.DeepEqual(target.UsernameHeaders(), expected.usernameHeaders) {
t.Fatalf("incorrect usernameHeaders, got %v, wanted %v", target.UsernameHeaders(), expected.usernameHeaders)
}
if !equality.Semantic.DeepEqual(target.GroupHeaders(), expected.groupHeaders) {
t.Fatalf("incorrect groupHeaders, got %v, wanted %v", target.GroupHeaders(), expected.groupHeaders)
}
if !equality.Semantic.DeepEqual(target.ExtraHeaderPrefixes(), expected.extraHeaderPrefixes) {
t.Fatalf("incorrect extraheaderPrefixes, got %v, wanted %v", target.ExtraHeaderPrefixes(), expected.extraHeaderPrefixes)
}
if !equality.Semantic.DeepEqual(target.AllowedClientNames(), expected.allowedClientNames) {
t.Fatalf("incorrect expectedAllowedClientNames, got %v, wanted %v", target.AllowedClientNames(), expected.allowedClientNames)
}
}
相关信息
相关文章
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦