From b3431e34c07d58b8f8b1b0dd38fd1228b313a138 Mon Sep 17 00:00:00 2001 From: David Simansky Date: Thu, 5 Aug 2021 15:12:53 +0200 Subject: [PATCH] Fix unit tests clash with local kubeconfig (#1418) * Fix unit tests clash with local kubeconfig * Add unit tests * Format source code * Add more tests to cover types.go * Add more tests to cover namespaced.go --- pkg/kn/commands/namespaced_test.go | 83 +++++++++++++++++++++++ pkg/kn/commands/revision/revision_test.go | 23 +++++++ pkg/kn/commands/types_test.go | 33 +++++++-- 3 files changed, 135 insertions(+), 4 deletions(-) diff --git a/pkg/kn/commands/namespaced_test.go b/pkg/kn/commands/namespaced_test.go index 33655d948..ac26a8e2e 100644 --- a/pkg/kn/commands/namespaced_test.go +++ b/pkg/kn/commands/namespaced_test.go @@ -15,8 +15,15 @@ package commands import ( + "io/ioutil" + "os" + "path/filepath" "testing" + "knative.dev/client/lib/test" + + "k8s.io/client-go/tools/clientcmd" + "github.com/spf13/cobra" "gotest.tools/v3/assert" ) @@ -47,6 +54,8 @@ func TestGetNamespaceSample(t *testing.T) { t.Fatalf("Incorrect namespace retrieved: %v, expected: %v", actualNamespace, expectedNamespace) } kp = &KnParams{} + // Mock ClientConfig to avoid clash with real kubeconfig on host OS + kp.ClientConfig, _ = clientcmd.NewClientConfigFromBytes([]byte(BASIC_KUBECONFIG)) testCmd = testCommandGenerator(false) actualNamespace, err = kp.GetNamespace(testCmd) assert.NilError(t, err) @@ -128,3 +137,77 @@ func TestGetNamespaceAllNamespacesNotDefined(t *testing.T) { t.Fatalf("Incorrect namespace retrieved: %v, expected: %v", actualNamespace, expectedNamespace) } } + +func TestGetNamespaceFallback(t *testing.T) { + tempDir, err := ioutil.TempDir("", "kn-unit-tests") + defer os.RemoveAll(tempDir) + assert.NilError(t, err) + + tempFile := filepath.Join(tempDir, "mock") + err = ioutil.WriteFile(tempFile, []byte(BASIC_KUBECONFIG), test.FileModeReadWrite) + assert.NilError(t, err) + + testCmd := testCommandGenerator(true) + kp := &KnParams{KubeCfgPath: tempFile} + testCmd.Execute() + actual, err := kp.GetNamespace(testCmd) + assert.NilError(t, err) + assert.Assert(t, actual == "default") + + tempFile = filepath.Join(tempDir, "empty") + err = ioutil.WriteFile(tempFile, []byte(""), test.FileModeReadWrite) + assert.NilError(t, err) + + testCmd = testCommandGenerator(true) + kp = &KnParams{KubeCfgPath: tempFile} + testCmd.Execute() + actual, err = kp.GetNamespace(testCmd) + assert.NilError(t, err) + assert.Assert(t, actual == "default") + + testCmd = testCommandGenerator(true) + kp = &KnParams{KubeCfgPath: filepath.Join(tempDir, "missing")} + testCmd.Execute() + actual, err = kp.GetNamespace(testCmd) + assert.ErrorContains(t, err, "can not be found") + assert.Assert(t, actual == "") +} + +func TestCurrentNamespace(t *testing.T) { + tempDir, err := ioutil.TempDir("", "kn-unit-tests") + defer os.RemoveAll(tempDir) + assert.NilError(t, err) + + tempFile := filepath.Join(tempDir, "empty") + err = ioutil.WriteFile(tempFile, []byte(""), test.FileModeReadWrite) + assert.NilError(t, err) + + // Invalid kubeconfig + kp := &KnParams{KubeCfgPath: tempFile} + actual, err := kp.CurrentNamespace() + assert.Assert(t, err != nil) + assert.Assert(t, clientcmd.IsConfigurationInvalid(err)) + assert.Assert(t, actual == "") + + // Missing kubeconfig + kp = &KnParams{KubeCfgPath: filepath.Join(tempDir, "missing")} + actual, err = kp.CurrentNamespace() + assert.Assert(t, err != nil) + assert.ErrorContains(t, err, "can not be found") + assert.Assert(t, actual == "") + + // Variable namespace override + kp = &KnParams{fixedCurrentNamespace: FakeNamespace} + actual, err = kp.CurrentNamespace() + assert.NilError(t, err) + assert.Equal(t, actual, FakeNamespace) + + // Fallback to "default" namespace from mock kubeconfig + tempFile = filepath.Join(tempDir, "mock") + err = ioutil.WriteFile(tempFile, []byte(BASIC_KUBECONFIG), test.FileModeReadWrite) + assert.NilError(t, err) + kp = &KnParams{KubeCfgPath: tempFile} + actual, err = kp.CurrentNamespace() + assert.NilError(t, err) + assert.Equal(t, actual, "default") +} diff --git a/pkg/kn/commands/revision/revision_test.go b/pkg/kn/commands/revision/revision_test.go index b5c8bafba..3bf77b6bc 100644 --- a/pkg/kn/commands/revision/revision_test.go +++ b/pkg/kn/commands/revision/revision_test.go @@ -33,6 +33,29 @@ import ( // Helper methods var blankConfig clientcmd.ClientConfig +const kubeConfig = `kind: Config +version: v1 +users: +- name: u +clusters: +- name: c + cluster: + server: example.com +contexts: +- name: x + context: + user: u + cluster: c +current-context: x` + +func init() { + var err error + blankConfig, err = clientcmd.NewClientConfigFromBytes([]byte(kubeConfig)) + if err != nil { + panic(err) + } +} + func TestExtractTrafficAndTag(t *testing.T) { service := &servingv1.Service{ diff --git a/pkg/kn/commands/types_test.go b/pkg/kn/commands/types_test.go index 8216c7906..932624714 100644 --- a/pkg/kn/commands/types_test.go +++ b/pkg/kn/commands/types_test.go @@ -16,10 +16,14 @@ package commands import ( "fmt" + "io/ioutil" "os" + "path/filepath" "strings" "testing" + "knative.dev/client/lib/test" + "gotest.tools/v3/assert" "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" @@ -55,9 +59,7 @@ current-context: a func TestPrepareConfig(t *testing.T) { basic, err := clientcmd.NewClientConfigFromBytes([]byte(BASIC_KUBECONFIG)) - if err != nil { - t.Error(err) - } + assert.NilError(t, err) for i, tc := range []configTestCase{ { clientcmd.NewDefaultClientConfig(clientcmdapi.Config{}, &clientcmd.ConfigOverrides{}), @@ -96,9 +98,16 @@ func TestPrepareConfig(t *testing.T) { } } } - _, err = (&KnParams{}).RestConfig() + kpEmptyConfig := &KnParams{} + kpEmptyConfig.ClientConfig, err = clientcmd.NewClientConfigFromBytes([]byte("")) + assert.NilError(t, err) + _, err = kpEmptyConfig.RestConfig() assert.ErrorContains(t, err, "no kubeconfig") + kpEmptyConfig = &KnParams{} + kpEmptyConfig.KubeCfgPath = filepath.Join("non", "existing", "file") + _, err = kpEmptyConfig.RestConfig() + assert.ErrorContains(t, err, "can not be found") } type typeTestCase struct { @@ -111,6 +120,14 @@ type typeTestCase struct { func TestGetClientConfig(t *testing.T) { multiConfigs := fmt.Sprintf("%s%s%s", "/testing/assets/kube-config-01.yml", string(os.PathListSeparator), "/testing/assets/kube-config-02.yml") + + tempDir, err := ioutil.TempDir("", "kn-unit-tests") + defer os.RemoveAll(tempDir) + assert.NilError(t, err) + tempFile := filepath.Join(tempDir, "mock") + err = ioutil.WriteFile(tempFile, []byte(BASIC_KUBECONFIG), test.FileModeReadWrite) + assert.NilError(t, err) + for _, tc := range []typeTestCase{ { "", @@ -119,6 +136,13 @@ func TestGetClientConfig(t *testing.T) { clientcmd.NewDefaultClientConfigLoadingRules().ExplicitPath, "", }, + { + tempFile, + "", + "", + tempFile, + "", + }, { "/testing/assets/kube-config-01.yml", "foo", @@ -137,6 +161,7 @@ func TestGetClientConfig(t *testing.T) { p := &KnParams{ KubeCfgPath: tc.kubeCfgPath, KubeContext: tc.kubeContext, + KubeCluster: tc.kubeCluster, } clientConfig, err := p.GetClientConfig()