Files
higress/pkg/ingress/kube/secret/controller_test.go
2023-01-29 17:43:42 +08:00

161 lines
4.1 KiB
Go

// Copyright (c) 2022 Alibaba Group Holding Ltd.
//
// 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 secret
import (
"context"
"reflect"
"sync"
"testing"
"time"
"istio.io/istio/pilot/pkg/model"
kubeclient "istio.io/istio/pkg/kube"
"istio.io/istio/pkg/test/util/retry"
corev1 "k8s.io/api/core/v1"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/cache"
"github.com/alibaba/higress/pkg/ingress/kube/util"
)
const (
secretFakeName = "fake-secret"
secretFakeKey = "fake-key"
secretInitValue = "init-value"
secretUpdatedValue = "updated-value"
)
var period = time.Second
func TestController(t *testing.T) {
client := kubeclient.NewFakeClient()
ctrl := NewController(client, "fake-cluster")
stop := make(chan struct{})
t.Cleanup(func() {
close(stop)
})
client.RunAndWait(stop)
// store secret
store := sync.Map{}
// add event handler
ctrl.AddEventHandler(func(name util.ClusterNamespacedName) {
t.Logf("event recived, clusterId: %s, namespacedName: %s", name.ClusterId, name.NamespacedName.String())
retry.UntilSuccessOrFail(t, func() error {
secret, err := ctrl.Lister().Secrets(name.NamespacedName.Namespace).Get(name.NamespacedName.Name)
if err != nil && !kerrors.IsNotFound(err) {
t.Logf("get secret %s error: %v", name.NamespacedName.String(), err)
return err
}
store.Store(name.NamespacedName.String(), secret.Data)
return nil
})
})
// start controller
go ctrl.Run(stop)
// wait for cache sync
cache.WaitForCacheSync(stop, ctrl.Informer().HasSynced)
// init secret
secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: secretFakeName,
},
Type: corev1.SecretTypeOpaque,
Data: map[string][]byte{
secretFakeKey: []byte(secretInitValue),
},
}
testCases := []struct {
name string
do func() error
expect string
}{
{
name: "create secret",
do: func() error {
_, err := client.CoreV1().Secrets(metav1.NamespaceDefault).Create(context.Background(),
secret, metav1.CreateOptions{})
return err
},
expect: secretInitValue,
},
{
name: "update secret",
do: func() error {
var getSecret *corev1.Secret
// get or create secret
getSecret, err := ctrl.Lister().Secrets(metav1.NamespaceDefault).Get(secretFakeName)
if err != nil {
if !kerrors.IsNotFound(err) {
return err
}
getSecret, err = client.CoreV1().Secrets(metav1.NamespaceDefault).Create(context.Background(),
secret, metav1.CreateOptions{})
if err != nil {
return err
}
}
// update secret
getSecret.Data[secretFakeKey] = []byte(secretUpdatedValue)
_, err = client.CoreV1().Secrets(metav1.NamespaceDefault).Update(context.Background(),
getSecret, metav1.UpdateOptions{})
return err
},
expect: secretUpdatedValue,
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
if err := testCase.do(); err != nil {
t.Fatalf("do %s error: %v", testCase.name, err)
}
// controller Run() with setting period time to 1s.
time.Sleep(period)
secretFullName := model.NamespacedName{
Namespace: metav1.NamespaceDefault,
Name: secretFakeName,
}.String()
valAny, ok := store.Load(secretFullName)
if !ok {
t.Fatalf("secret %s not found", secretFullName)
}
val, ok := valAny.(map[string][]byte)
if !ok {
t.Fatalf("assert secret %s data type error", secretFullName)
}
if !reflect.DeepEqual(val[secretFakeKey], []byte(testCase.expect)) {
t.Fatalf("secret %s data error, expect: %s, got: %s",
secretFullName, testCase.expect, string(val[secretFakeKey]))
}
})
}
}