blob: c20b323ec818077e035023e9d636418b94f6cde6 [file] [log] [blame]
// Copyright Istio 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 multicluster
import (
"bytes"
"os"
"reflect"
"testing"
"time"
)
import (
"github.com/google/go-cmp/cmp"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/clientcmd/api"
"k8s.io/client-go/tools/clientcmd/api/latest"
)
import (
"github.com/apache/dubbo-go-pixiu/pkg/kube"
)
var fakeKubeconfigData = `apiVersion: v1
kind: Config
clusters:
- cluster:
certificate-authority-data: UEhPTlkK
server: https://192.168.1.1
name: prod0
contexts:
- context:
cluster: prod0
user: prod0
name: prod0
current-context: prod0
users:
- name: prod0
user:
auth-provider:
name: gcp` // nolint:lll
func createFakeKubeconfigFileOrDie(t *testing.T) (string, *api.Config) {
t.Helper()
f, err := os.CreateTemp("", "fakeKubeconfigForEnvironment")
if err != nil {
t.Fatalf("could not create fake kubeconfig file: %v", err)
}
kubeconfigPath := f.Name()
defer func() {
if err := f.Close(); err != nil {
t.Errorf("couldn't close temp file %v: %v", kubeconfigPath, err)
}
}()
if _, err = f.WriteString(fakeKubeconfigData); err != nil {
t.Fatalf("could not write fake kubeconfig data to %v: %v", kubeconfigPath, err)
}
// Temporary workaround until https://github.com/kubernetes/kubernetes/pull/86414 merges
into := &api.Config{
Clusters: map[string]*api.Cluster{},
AuthInfos: map[string]*api.AuthInfo{},
Contexts: map[string]*api.Context{},
Extensions: map[string]runtime.Object{},
}
out, _, err := latest.Codec.Decode([]byte(fakeKubeconfigData), nil, into)
if err != nil {
t.Fatalf("could not decode fake kubeconfig: %v", err)
}
config, ok := out.(*api.Config)
if !ok {
t.Fatalf("decoded kubeconfig is not a valid api.Config (%v)", reflect.TypeOf(out))
}
// fill in missing defaults
config.Contexts[config.CurrentContext].LocationOfOrigin = kubeconfigPath
config.Clusters[config.CurrentContext].LocationOfOrigin = kubeconfigPath
config.AuthInfos[config.CurrentContext].LocationOfOrigin = kubeconfigPath
config.Extensions = make(map[string]runtime.Object)
config.Preferences.Extensions = make(map[string]runtime.Object)
return kubeconfigPath, config
}
type fakeEnvironment struct {
KubeEnvironment
client kube.ExtendedClient
injectClientCreateError error
kubeconfig string
wOut bytes.Buffer
wErr bytes.Buffer
}
func newFakeEnvironmentOrDie(t *testing.T, minor string, config *api.Config, objs ...runtime.Object) *fakeEnvironment {
t.Helper()
var wOut, wErr bytes.Buffer
f := &fakeEnvironment{
KubeEnvironment: KubeEnvironment{
config: config,
stdout: &wOut,
stderr: &wErr,
kubeconfig: "unused",
},
client: kube.NewFakeClientWithVersion(minor, objs...),
kubeconfig: "unused",
wOut: wOut,
wErr: wErr,
}
return f
}
func (f *fakeEnvironment) CreateClient(_ string) (kube.ExtendedClient, error) {
if f.injectClientCreateError != nil {
return nil, f.injectClientCreateError
}
return f.client, nil
}
func (f *fakeEnvironment) Poll(_, _ time.Duration, condition ConditionFunc) error {
// TODO - add hooks to inject fake timeouts
_, _ = condition()
return nil
}
func TestNewEnvironment(t *testing.T) {
context := "" // empty, use current-Context
kubeconfig, wantConfig := createFakeKubeconfigFileOrDie(t)
var wOut, wErr bytes.Buffer
wantEnv := &KubeEnvironment{
config: wantConfig,
stdout: &wOut,
stderr: &wErr,
kubeconfig: kubeconfig,
}
gotEnv, err := NewEnvironment(kubeconfig, context, &wOut, &wErr)
if err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(*wantEnv.GetConfig(), *gotEnv.GetConfig()); diff != "" {
t.Errorf("bad config: \n got %v \nwant %v\ndiff %v", gotEnv, wantEnv, diff)
}
wantEnv.config = nil
gotEnv.config = nil
if !reflect.DeepEqual(wantEnv, gotEnv) {
t.Errorf("bad environment: \n got %v \nwant %v", *gotEnv, *wantEnv)
}
// verify interface
if gotEnv.Stderr() != &wErr {
t.Errorf("Stderr() returned wrong io.writer")
}
if gotEnv.Stdout() != &wOut {
t.Errorf("Stdout() returned wrong io.writer")
}
gotEnv.Printf("stdout %v", "test")
wantOut := "stdout test"
if gotOut := wOut.String(); gotOut != wantOut {
t.Errorf("Printf() printed wrong string: got %v want %v", gotOut, wantOut)
}
gotEnv.Errorf("stderr %v", "test")
wantErr := "stderr test"
if gotErr := wErr.String(); gotErr != wantErr {
t.Errorf("Errorf() printed wrong string: got %v want %v", gotErr, wantErr)
}
}