fix: KUBECONFIG unit test interference (#1387)

* fix: clear KUBECONFIG when testing

* fix nil pointer when no config exists

* update comments

* comments and cleanup
This commit is contained in:
Luke Kingland 2022-10-31 19:04:13 +09:00 committed by GitHub
parent d0448adb82
commit 55383b7e24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 166 additions and 54 deletions

View File

@ -242,7 +242,6 @@ func TestDeploy_BuilderPersists(t *testing.T) {
func testBuilderPersists(cmdFn commandConstructor, t *testing.T) {
t.Helper()
t.Setenv("KUBECONFIG", fmt.Sprintf("%s/testdata/kubeconfig_deploy_namespace", cwd()))
root := fromTempDirectory(t)
if err := fn.New().Create(fn.Function{Runtime: "go", Root: root}); err != nil {
@ -557,8 +556,6 @@ func Test_ImageWithDigestErrors(t *testing.T) {
},
}
t.Setenv("KUBECONFIG", fmt.Sprintf("%s/testdata/kubeconfig_deploy_namespace", cwd()))
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Move into a new temp directory
@ -641,19 +638,19 @@ func Test_namespace(t *testing.T) {
confNamespace: "",
funcNamespace: "",
context: true,
expected: "test-ns-deploy", // see ./testdata
expected: "mynamespace", // see ./testdata/Test_namespace/kubeconfig
},
{
name: "default",
confNamespace: "",
funcNamespace: "",
context: false,
expected: "",
expected: "func", // see ./testdata/default_kubeconfig
},
}
// contains a kube config with active namespace "test-ns-deploy"
contextPath := fmt.Sprintf("%s/testdata/kubeconfig_deploy_namespace", cwd())
contextPath := fmt.Sprintf("%s/testdata/Test_namespace/kubeconfig", cwd())
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
@ -663,8 +660,6 @@ func Test_namespace(t *testing.T) {
// if running with an active kubeconfig
if test.context {
t.Setenv("KUBECONFIG", contextPath)
} else {
t.Setenv("KUBECONFIG", cwd())
}
// Creat a funcction which may be already deployed
@ -838,8 +833,10 @@ func TestDeploy_GitURLBranch(t *testing.T) {
// TestDeploy_NamespaceDefaults ensures that when not specified, a users's
// active kubernetes context is used for the namespace if available.
func TestDeploy_NamespaceDefaults(t *testing.T) {
t.Setenv("KUBECONFIG", filepath.Join(cwd(), "testdata", "kubeconfig_deploy_namespace"))
root := fromTempDirectory(t)
kubeconfig := filepath.Join(cwd(), "testdata", "TestDeploy_NamespaceDefaults/kubeconfig")
expected := "mynamespace"
root := fromTempDirectory(t) // clears envs and cds to empty root
t.Setenv("KUBECONFIG", kubeconfig)
// Create a new function
if err := fn.New().Create(fn.Function{Runtime: "go", Root: root}); err != nil {
@ -849,6 +846,9 @@ func TestDeploy_NamespaceDefaults(t *testing.T) {
// Assert it has no default namespace set
f, err := fn.NewFunction(root)
if err != nil {
t.Fatal(err)
}
if f.Deploy.Namespace != "" {
t.Fatalf("newly created functions should not have a namespace set until deployed. Got '%v'", f.Deploy.Namespace)
}
@ -874,8 +874,8 @@ func TestDeploy_NamespaceDefaults(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if f.Deploy.Namespace != "test-ns-deploy" { // from testdata/kubeconfig_deploy_namespace
t.Fatalf("expected function to have active namespace 'test-ns-deploy' by default. got '%v'", f.Deploy.Namespace)
if f.Deploy.Namespace != expected { // see ./testdata/TestDeploy_NamespaceDefaults
t.Fatalf("expected function to have active namespace '%v'. got '%v'", expected, f.Deploy.Namespace)
}
// See the knative package's tests for an example of tests which require
// the knative or kubernetes API dependency.
@ -946,14 +946,15 @@ func TestDeploy_NamespaceUpdateWarning(t *testing.T) {
// not instructed otherwise.
func TestDeploy_NamespaceRedeployWarning(t *testing.T) {
// Change profile to one whose current profile is 'test-ns-deploy'
t.Setenv("KUBECONFIG", filepath.Join(cwd(), "testdata", "kubeconfig_deploy_namespace"))
kubeconfig := filepath.Join(cwd(), "testdata", "TestDeploy_NamespaceRedeployWarning/kubeconfig")
root := fromTempDirectory(t)
t.Setenv("KUBECONFIG", kubeconfig)
// Create a Function which appears to have been deployed to 'myns'
// Create a Function which appears to have been deployed to 'funcns'
f := fn.Function{
Runtime: "go",
Root: root,
Deploy: fn.DeploySpec{Namespace: "myns"},
Deploy: fn.DeploySpec{Namespace: "funcns"},
}
if err := fn.New().Create(f); err != nil {
t.Fatal(err)
@ -974,7 +975,7 @@ func TestDeploy_NamespaceRedeployWarning(t *testing.T) {
t.Fatal(err)
}
expected := "Warning: Function is in namespace 'myns', but currently active namespace is 'test-ns-deploy'. Continuing with redeployment to 'myns'."
expected := "Warning: Function is in namespace 'funcns', but currently active namespace is 'mynamespace'. Continuing with redeployment to 'funcns'."
// Ensure output contained warning if changing namespace
if !strings.Contains(stderr.String(), expected) {
@ -982,12 +983,12 @@ func TestDeploy_NamespaceRedeployWarning(t *testing.T) {
t.Fatalf("Expected warning not found:\n%v", expected)
}
// Ensure the function was saved as having been deployed to
// Ensure the function was saved as having been deployed to the correct ns
f, err := fn.NewFunction(root)
if err != nil {
t.Fatal(err)
}
if f.Deploy.Namespace != "myns" {
t.Fatalf("expected function to be updated with namespace 'myns'. got '%v'", f.Deploy.Namespace)
if f.Deploy.Namespace != "funcns" {
t.Fatalf("expected function to be namespace 'funcns'. got '%v'", f.Deploy.Namespace)
}
}

View File

@ -5,6 +5,7 @@ import (
"fmt"
"io"
"os"
"path/filepath"
"reflect"
"strings"
"testing"
@ -295,15 +296,25 @@ func piped(t *testing.T) func() string {
}
}
// fromTempDirectory is a cli-specific test helper which
// - creates a temp directory and changes to it as the new working directory
// - creates a temp directory and uses it for XDG_CONFIG_HOME
// - removes temp directories on cleanup
// - resets viper on cleanup (the reason this is "cli-specific")
// fromTempDirectory is a cli-specific test helper which endeavors to create
// an environment clean of developer's settings for use during CLI testing.
func fromTempDirectory(t *testing.T) string {
t.Helper()
// We have to define KUBECONFIG, or the file at ~/.kube/config (if extant)
// will be used (disrupting tests by using the current user's environment).
// The test kubeconfig set below has the current namespace set to 'func'
// NOTE: the below settings affect unit tests only, and we do explicitly
// want all unit tests to start in an empty environment with tests "opting in"
// to config, not opting out.
t.Setenv("KUBECONFIG", filepath.Join(cwd(), "testdata", "default_kubeconfig"))
// By default unit tests presum no config exists unless provided in testdata.
t.Setenv("XDG_CONFIG_HOME", t.TempDir())
d, done := Mktemp(t) // creates and CDs to 'tmp'
// creates and CDs to a temp directory
d, done := Mktemp(t)
// Return to original directory and resets viper.
t.Cleanup(func() { done(); viper.Reset() })
return d
}

View File

@ -0,0 +1,25 @@
apiVersion: v1
clusters:
- cluster:
insecure-skip-tls-verify: true
server: https://cluster.example.com:6443
name: cluster-example-com:6443
contexts:
- context:
cluster: cluster-example-com:6443
namespace: default
user: kube:admin/cluster-example-com:6443
name: default/cluster-example-com:6443/kube:admin
- context:
cluster: cluster-example-com:6443
namespace: mynamespace
user: kube:admin/cluster-example-com:6443
name: mynamespace/cluster-example-com:6443/kube:admin
current-context: mynamespace/cluster-example-com:6443/kube:admin
kind: Config
preferences: {}
users:
- name: kubeadmin
user:
token: sha256~XXXXexample-test-hash

View File

@ -0,0 +1,25 @@
apiVersion: v1
clusters:
- cluster:
insecure-skip-tls-verify: true
server: https://cluster.example.com:6443
name: cluster-example-com:6443
contexts:
- context:
cluster: cluster-example-com:6443
namespace: default
user: kube:admin/cluster-example-com:6443
name: default/cluster-example-com:6443/kube:admin
- context:
cluster: cluster-example-com:6443
namespace: mynamespace
user: kube:admin/cluster-example-com:6443
name: mynamespace/cluster-example-com:6443/kube:admin
current-context: mynamespace/cluster-example-com:6443/kube:admin
kind: Config
preferences: {}
users:
- name: kubeadmin
user:
token: sha256~XXXXexample-test-hash

View File

@ -0,0 +1,25 @@
apiVersion: v1
clusters:
- cluster:
insecure-skip-tls-verify: true
server: https://cluster.example.com:6443
name: cluster-example-com:6443
contexts:
- context:
cluster: cluster-example-com:6443
namespace: default
user: kube:admin/cluster-example-com:6443
name: default/cluster-example-com:6443/kube:admin
- context:
cluster: cluster-example-com:6443
namespace: mynamespace
user: kube:admin/cluster-example-com:6443
name: mynamespace/cluster-example-com:6443/kube:admin
current-context: mynamespace/cluster-example-com:6443/kube:admin
kind: Config
preferences: {}
users:
- name: kubeadmin
user:
token: sha256~XXXXexample-test-hash

25
cmd/testdata/Test_namespace/kubeconfig vendored Normal file
View File

@ -0,0 +1,25 @@
apiVersion: v1
clusters:
- cluster:
insecure-skip-tls-verify: true
server: https://cluster.example.com:6443
name: cluster-example-com:6443
contexts:
- context:
cluster: cluster-example-com:6443
namespace: default
user: kube:admin/cluster-example-com:6443
name: default/cluster-example-com:6443/kube:admin
- context:
cluster: cluster-example-com:6443
namespace: mynamespace
user: kube:admin/cluster-example-com:6443
name: mynamespace/cluster-example-com:6443/kube:admin
current-context: mynamespace/cluster-example-com:6443/kube:admin
kind: Config
preferences: {}
users:
- name: kubeadmin
user:
token: sha256~XXXXexample-test-hash

25
cmd/testdata/default_kubeconfig vendored Normal file
View File

@ -0,0 +1,25 @@
apiVersion: v1
clusters:
- cluster:
insecure-skip-tls-verify: true
server: https://cluster.example.com:6443
name: cluster-example-com:6443
contexts:
- context:
cluster: cluster-example-com:6443
namespace: default
user: kube:admin/cluster-example-com:6443
name: default/cluster-example-com:6443/kube:admin
- context:
cluster: cluster-example-com:6443
namespace: func
user: kube:admin/cluster-example-com:6443
name: func/cluster-example-com:6443/kube:admin
current-context: func/cluster-example-com:6443/kube:admin
kind: Config
preferences: {}
users:
- name: kubeadmin
user:
token: sha256~XXXXexample-test-hash

View File

@ -1,25 +0,0 @@
apiVersion: v1
clusters:
- cluster:
insecure-skip-tls-verify: true
server: https://example-cluster.serverless.devcluster.openshift.com:6443
name: example-cluster-serverless-devcluster-openshift-com:6443
contexts:
- context:
cluster: example-cluster-serverless-devcluster-openshift-com:6443
namespace: default
user: kube:admin/example-cluster-serverless-devcluster-openshift-com:6443
name: default/example-cluster-serverless-devcluster-openshift-com:6443/kube:admin
- context:
cluster: example-cluster-serverless-devcluster-openshift-com:6443
namespace: test-ns-deploy
user: kube:admin/example-cluster-serverless-devcluster-openshift-com:6443
name: test-ns-deploy/example-cluster-serverless-devcluster-openshift-com:6443/kube:admin
current-context: test-ns-deploy/example-cluster-serverless-devcluster-openshift-com:6443/kube:admin
kind: Config
preferences: {}
users:
- name: kubeadmin
user:
token: sha256~XXXXexample-test-hash

View File

@ -134,11 +134,11 @@ func GetDockerCredentialLoaders() []creds.CredentialsCallback {
if !ok {
return nil
}
authInfo := rawConf.AuthInfos[cc.AuthInfo]
var credentials docker.Credentials
credentials := docker.Credentials{
Username: "openshift",
Password: authInfo.Token,
if authInfo := rawConf.AuthInfos[cc.AuthInfo]; authInfo != nil {
credentials.Username = "openshift"
credentials.Password = authInfo.Token
}
return []creds.CredentialsCallback{