mirror of
https://github.com/ahmetb/kubectx.git
synced 2025-06-24 14:32:24 +00:00
extract kubeconfig test utils to a type
Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
This commit is contained in:
parent
49539fbcb3
commit
7b96a338a3
@ -8,22 +8,9 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/ahmetb/kubectx/internal/kubeconfig"
|
||||
"github.com/ahmetb/kubectx/internal/testutil"
|
||||
)
|
||||
|
||||
func withTestVar(key, value string) func() {
|
||||
// TODO(ahmetb) this method is currently duplicated
|
||||
// consider extracting to internal/testutil or something
|
||||
|
||||
orig, ok := os.LookupEnv(key)
|
||||
os.Setenv(key, value)
|
||||
return func() {
|
||||
if ok {
|
||||
os.Setenv(key, orig)
|
||||
} else {
|
||||
os.Unsetenv(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_homeDir(t *testing.T) {
|
||||
type env struct{ k, v string }
|
||||
@ -72,7 +59,7 @@ func Test_homeDir(t *testing.T) {
|
||||
t.Run(c.name, func(tt *testing.T) {
|
||||
var unsets []func()
|
||||
for _, e := range c.envs {
|
||||
unsets = append(unsets, withTestVar(e.k, e.v))
|
||||
unsets = append(unsets, testutil.WithEnvVar(e.k, e.v))
|
||||
}
|
||||
|
||||
got := homeDir()
|
||||
@ -87,7 +74,7 @@ func Test_homeDir(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_kubeconfigPath(t *testing.T) {
|
||||
defer withTestVar("HOME", "/x/y/z")()
|
||||
defer testutil.WithEnvVar("HOME", "/x/y/z")()
|
||||
|
||||
expected := filepath.FromSlash("/x/y/z/.kube/config")
|
||||
got, err := kubeconfigPath()
|
||||
@ -100,9 +87,9 @@ func Test_kubeconfigPath(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_kubeconfigPath_noEnvVars(t *testing.T) {
|
||||
defer withTestVar("XDG_CACHE_HOME", "")()
|
||||
defer withTestVar("HOME", "")()
|
||||
defer withTestVar("USERPROFILE", "")()
|
||||
defer testutil.WithEnvVar("XDG_CACHE_HOME", "")()
|
||||
defer testutil.WithEnvVar("HOME", "")()
|
||||
defer testutil.WithEnvVar("USERPROFILE", "")()
|
||||
|
||||
_, err := kubeconfigPath()
|
||||
if err == nil {
|
||||
@ -111,7 +98,7 @@ func Test_kubeconfigPath_noEnvVars(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_kubeconfigPath_envOvveride(t *testing.T) {
|
||||
defer withTestVar("KUBECONFIG", "foo")()
|
||||
defer testutil.WithEnvVar("KUBECONFIG", "foo")()
|
||||
|
||||
v, err := kubeconfigPath()
|
||||
if err != nil {
|
||||
@ -124,7 +111,7 @@ func Test_kubeconfigPath_envOvveride(t *testing.T) {
|
||||
|
||||
func Test_kubeconfigPath_envOvverideDoesNotSupportPathSeparator(t *testing.T) {
|
||||
path := strings.Join([]string{"file1", "file2"}, string(os.PathListSeparator))
|
||||
defer withTestVar("KUBECONFIG", path)()
|
||||
defer testutil.WithEnvVar("KUBECONFIG", path)()
|
||||
|
||||
_, err := kubeconfigPath()
|
||||
if err == nil {
|
||||
@ -133,7 +120,7 @@ func Test_kubeconfigPath_envOvverideDoesNotSupportPathSeparator(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStandardKubeconfigLoader_returnsNotFoundErr(t *testing.T) {
|
||||
defer withTestVar("KUBECONFIG", "foo")()
|
||||
defer testutil.WithEnvVar("KUBECONFIG", "foo")()
|
||||
kc := new(kubeconfig.Kubeconfig).WithLoader(defaultLoader)
|
||||
err := kc.Parse()
|
||||
if err == nil {
|
||||
|
@ -1,28 +1,27 @@
|
||||
package kubeconfig
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
func TestKubeconfig_DeleteContextEntry_errors(t *testing.T) {
|
||||
kc := new(Kubeconfig).WithLoader(&testLoader{in: strings.NewReader(`[1, 2, 3]`)})
|
||||
kc := new(Kubeconfig).WithLoader(WithMockKubeconfigLoader(`[1, 2, 3]`))
|
||||
_ = kc.Parse()
|
||||
err := kc.DeleteContextEntry("foo")
|
||||
if err == nil {
|
||||
t.Fatal("supposed to fail on non-mapping nodes")
|
||||
}
|
||||
|
||||
kc = new(Kubeconfig).WithLoader(&testLoader{in: strings.NewReader(`a: b`)})
|
||||
kc = new(Kubeconfig).WithLoader(WithMockKubeconfigLoader(`a: b`))
|
||||
_ = kc.Parse()
|
||||
err = kc.DeleteContextEntry("foo")
|
||||
if err == nil {
|
||||
t.Fatal("supposed to fail if contexts key does not exist")
|
||||
}
|
||||
|
||||
kc = new(Kubeconfig).WithLoader(&testLoader{in: strings.NewReader(`contexts: "some string"`)})
|
||||
kc = new(Kubeconfig).WithLoader(WithMockKubeconfigLoader(`contexts: "some string"`))
|
||||
_ = kc.Parse()
|
||||
err = kc.DeleteContextEntry("foo")
|
||||
if err == nil {
|
||||
@ -31,8 +30,8 @@ func TestKubeconfig_DeleteContextEntry_errors(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestKubeconfig_DeleteContextEntry(t *testing.T) {
|
||||
test := &testLoader{in: strings.NewReader(
|
||||
`contexts: [{name: c1}, {name: c2}, {name: c3}]`)}
|
||||
test := WithMockKubeconfigLoader(
|
||||
`contexts: [{name: c1}, {name: c2}, {name: c3}]`)
|
||||
kc := new(Kubeconfig).WithLoader(test)
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
@ -45,16 +44,15 @@ func TestKubeconfig_DeleteContextEntry(t *testing.T) {
|
||||
}
|
||||
|
||||
expected := "contexts: [{name: c2}, {name: c3}]\n"
|
||||
out := test.out.String()
|
||||
out := test.Output()
|
||||
if diff := cmp.Diff(expected, out); diff != "" {
|
||||
t.Fatalf("diff: %s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKubeconfig_ModifyCurrentContext_fieldExists(t *testing.T) {
|
||||
test := &testLoader{in: strings.NewReader(
|
||||
`current-context: abc
|
||||
field1: value1`)}
|
||||
test := WithMockKubeconfigLoader(`current-context: abc
|
||||
field1: value1`)
|
||||
kc := new(Kubeconfig).WithLoader(test)
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
@ -68,15 +66,15 @@ field1: value1`)}
|
||||
|
||||
expected := `current-context: foo
|
||||
field1: value1` + "\n"
|
||||
out := test.out.String()
|
||||
out := test.Output()
|
||||
if diff := cmp.Diff(expected, out); diff != "" {
|
||||
t.Fatalf("diff: %s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKubeconfig_ModifyCurrentContext_fieldMissing(t *testing.T) {
|
||||
test := &testLoader{in: strings.NewReader(
|
||||
`field1: value1`)}
|
||||
test := WithMockKubeconfigLoader(
|
||||
`field1: value1`)
|
||||
kc := new(Kubeconfig).WithLoader(test)
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
@ -89,7 +87,7 @@ func TestKubeconfig_ModifyCurrentContext_fieldMissing(t *testing.T) {
|
||||
}
|
||||
|
||||
expected := `field1: value1` + "\n" + "current-context: foo\n"
|
||||
out := test.out.String()
|
||||
out := test.Output()
|
||||
if diff := cmp.Diff(expected, out); diff != "" {
|
||||
t.Fatalf("diff: %s", diff)
|
||||
}
|
||||
@ -97,8 +95,8 @@ func TestKubeconfig_ModifyCurrentContext_fieldMissing(t *testing.T) {
|
||||
|
||||
func TestKubeconfig_ModifyContextName_noContextsEntryError(t *testing.T) {
|
||||
// no context entries
|
||||
test := &testLoader{in: strings.NewReader(
|
||||
`a: b`)}
|
||||
test := WithMockKubeconfigLoader(
|
||||
`a: b`)
|
||||
kc := new(Kubeconfig).WithLoader(test)
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
@ -111,8 +109,8 @@ func TestKubeconfig_ModifyContextName_noContextsEntryError(t *testing.T) {
|
||||
|
||||
func TestKubeconfig_ModifyContextName_contextsEntryNotSequenceError(t *testing.T) {
|
||||
// no context entries
|
||||
test := &testLoader{in: strings.NewReader(
|
||||
`contexts: "hello"`)}
|
||||
test := WithMockKubeconfigLoader(
|
||||
`contexts: "hello"`)
|
||||
kc := new(Kubeconfig).WithLoader(test)
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
@ -124,8 +122,8 @@ func TestKubeconfig_ModifyContextName_contextsEntryNotSequenceError(t *testing.T
|
||||
|
||||
|
||||
func TestKubeconfig_ModifyContextName_noChange(t *testing.T) {
|
||||
test := &testLoader{in: strings.NewReader(
|
||||
`contexts: [{name: c1}, {name: c2}, {name: c3}]`)}
|
||||
test := WithMockKubeconfigLoader(
|
||||
`contexts: [{name: c1}, {name: c2}, {name: c3}]`)
|
||||
kc := new(Kubeconfig).WithLoader(test)
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
@ -136,8 +134,8 @@ func TestKubeconfig_ModifyContextName_noChange(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestKubeconfig_ModifyContextName(t *testing.T) {
|
||||
test := &testLoader{in: strings.NewReader(
|
||||
`contexts: [{name: c1}, {name: c2}, {name: c3}]`)}
|
||||
test := WithMockKubeconfigLoader(
|
||||
`contexts: [{name: c1}, {name: c2}, {name: c3}]`)
|
||||
kc := new(Kubeconfig).WithLoader(test)
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
@ -150,7 +148,7 @@ func TestKubeconfig_ModifyContextName(t *testing.T) {
|
||||
}
|
||||
|
||||
expected := "contexts: [{name: ccc}, {name: c2}, {name: c3}]\n"
|
||||
out := test.out.String()
|
||||
out := test.Output()
|
||||
if diff := cmp.Diff(expected, out); diff != "" {
|
||||
t.Fatalf("diff: %s", diff)
|
||||
}
|
||||
|
@ -1,21 +1,20 @@
|
||||
package kubeconfig
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
func TestKubeconfig_ContextNames(t *testing.T) {
|
||||
tl := &testLoader{in: strings.NewReader(`
|
||||
tl := WithMockKubeconfigLoader(`
|
||||
contexts:
|
||||
- name: abc
|
||||
- name: def
|
||||
field1: value1
|
||||
- name: ghi
|
||||
foo:
|
||||
bar: zoo`)}
|
||||
bar: zoo`)
|
||||
|
||||
kc := new(Kubeconfig).WithLoader(tl)
|
||||
if err := kc.Parse(); err != nil {
|
||||
@ -30,7 +29,7 @@ contexts:
|
||||
}
|
||||
|
||||
func TestKubeconfig_ContextNames_noContextsEntry(t *testing.T) {
|
||||
tl := &testLoader{in: strings.NewReader(`a: b`)}
|
||||
tl := WithMockKubeconfigLoader(`a: b`)
|
||||
kc := new(Kubeconfig).WithLoader(tl)
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
@ -43,7 +42,7 @@ func TestKubeconfig_ContextNames_noContextsEntry(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestKubeconfig_ContextNames_nonArrayContextsEntry(t *testing.T) {
|
||||
tl := &testLoader{in: strings.NewReader(`contexts: "hello"`)}
|
||||
tl := WithMockKubeconfigLoader(`contexts: "hello"`)
|
||||
kc := new(Kubeconfig).WithLoader(tl)
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
@ -56,9 +55,9 @@ func TestKubeconfig_ContextNames_nonArrayContextsEntry(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestKubeconfig_CheckContextExists(t *testing.T) {
|
||||
tl := &testLoader{in: strings.NewReader(`contexts:
|
||||
tl := WithMockKubeconfigLoader(`contexts:
|
||||
- name: c1
|
||||
- name: c2`)}
|
||||
- name: c2`)
|
||||
|
||||
kc := new(Kubeconfig).WithLoader(tl)
|
||||
if err := kc.Parse(); err != nil {
|
||||
|
@ -1,12 +1,11 @@
|
||||
package kubeconfig
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestKubeconfig_GetCurrentContext(t *testing.T) {
|
||||
tl := &testLoader{in: strings.NewReader(`current-context: foo`)}
|
||||
tl := WithMockKubeconfigLoader(`current-context: foo`)
|
||||
kc := new(Kubeconfig).WithLoader(tl)
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
@ -20,7 +19,7 @@ func TestKubeconfig_GetCurrentContext(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestKubeconfig_GetCurrentContext_missingField(t *testing.T) {
|
||||
tl := &testLoader{in: strings.NewReader(`abc: def`)}
|
||||
tl := WithMockKubeconfigLoader(`abc: def`)
|
||||
kc := new(Kubeconfig).WithLoader(tl)
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
@ -34,7 +33,7 @@ func TestKubeconfig_GetCurrentContext_missingField(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestKubeconfig_UnsetCurrentContext(t *testing.T) {
|
||||
tl := &testLoader{in: strings.NewReader(`current-context: foo`)}
|
||||
tl := WithMockKubeconfigLoader(`current-context: foo`)
|
||||
kc := new(Kubeconfig).WithLoader(tl)
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
@ -46,7 +45,7 @@ func TestKubeconfig_UnsetCurrentContext(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
out := tl.out.String()
|
||||
out := tl.Output()
|
||||
expected := `current-context: ""
|
||||
`
|
||||
if out != expected {
|
||||
|
23
internal/kubeconfig/helper_test.go
Normal file
23
internal/kubeconfig/helper_test.go
Normal file
@ -0,0 +1,23 @@
|
||||
package kubeconfig
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type MockKubeconfigLoader struct {
|
||||
in io.Reader
|
||||
out bytes.Buffer
|
||||
}
|
||||
|
||||
func (t *MockKubeconfigLoader) Read(p []byte) (n int, err error) { return t.in.Read(p) }
|
||||
func (t *MockKubeconfigLoader) Write(p []byte) (n int, err error) { return t.out.Write(p) }
|
||||
func (t *MockKubeconfigLoader) Close() error { return nil }
|
||||
func (t *MockKubeconfigLoader) Reset() error { return nil }
|
||||
func (t *MockKubeconfigLoader) Load() (ReadWriteResetCloser, error) { return t, nil }
|
||||
func (t *MockKubeconfigLoader) Output() string { return t.out.String() }
|
||||
|
||||
func WithMockKubeconfigLoader(kubecfg string) *MockKubeconfigLoader {
|
||||
return &MockKubeconfigLoader{in: strings.NewReader(kubecfg)}
|
||||
}
|
@ -1,17 +1,2 @@
|
||||
package kubeconfig
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type testLoader struct {
|
||||
in *strings.Reader
|
||||
out bytes.Buffer
|
||||
}
|
||||
|
||||
func (t *testLoader) Read(p []byte) (n int, err error) { return t.in.Read(p) }
|
||||
func (t *testLoader) Write(p []byte) (n int, err error) { return t.out.Write(p) }
|
||||
func (t *testLoader) Close() error { return nil }
|
||||
func (t *testLoader) Reset() error { return nil }
|
||||
func (t *testLoader) Load() (ReadWriteResetCloser, error) { return t, nil }
|
||||
|
@ -1,24 +1,23 @@
|
||||
package kubeconfig
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
err := new(Kubeconfig).WithLoader(&testLoader{in: strings.NewReader(`a: [1, 2`)}).Parse()
|
||||
err := new(Kubeconfig).WithLoader(WithMockKubeconfigLoader(`a: [1, 2`)).Parse()
|
||||
if err == nil {
|
||||
t.Fatal("expected error from bad yaml")
|
||||
}
|
||||
|
||||
err = new(Kubeconfig).WithLoader(&testLoader{in: strings.NewReader(`[1, 2, 3]`)}).Parse()
|
||||
err = new(Kubeconfig).WithLoader(WithMockKubeconfigLoader(`[1, 2, 3]`)).Parse()
|
||||
if err == nil {
|
||||
t.Fatal("expected error from not-mapping root node")
|
||||
}
|
||||
|
||||
err = new(Kubeconfig).WithLoader(&testLoader{in: strings.NewReader(`current-context: foo`)}).Parse()
|
||||
err = new(Kubeconfig).WithLoader(WithMockKubeconfigLoader(`current-context: foo`)).Parse()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -26,7 +25,7 @@ func TestParse(t *testing.T) {
|
||||
|
||||
func TestSave(t *testing.T) {
|
||||
in := `a: [1, 2, 3]` + "\n"
|
||||
test := &testLoader{in: strings.NewReader(in)}
|
||||
test := WithMockKubeconfigLoader(in)
|
||||
kc := new(Kubeconfig).WithLoader(test)
|
||||
defer kc.Close()
|
||||
if err := kc.Parse(); err != nil {
|
||||
@ -37,7 +36,7 @@ func TestSave(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expected := in+"current-context: hello\n"
|
||||
if diff := cmp.Diff(expected, test.out.String()); diff != "" {
|
||||
if diff := cmp.Diff(expected, test.Output()); diff != "" {
|
||||
t.Fatal(diff)
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +1,20 @@
|
||||
package printer
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
func withTestVar(key, value string) func() {
|
||||
orig, ok := os.LookupEnv(key)
|
||||
os.Setenv(key, value)
|
||||
return func() {
|
||||
if ok {
|
||||
os.Setenv(key, orig)
|
||||
} else {
|
||||
os.Unsetenv(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
"github.com/ahmetb/kubectx/internal/testutil"
|
||||
)
|
||||
|
||||
var (
|
||||
tr, fa = true, false
|
||||
)
|
||||
|
||||
func Test_useColors_forceColors(t *testing.T) {
|
||||
defer withTestVar("_KUBECTX_FORCE_COLOR", "1")()
|
||||
defer withTestVar("NO_COLOR", "1")()
|
||||
defer testutil.WithEnvVar("_KUBECTX_FORCE_COLOR", "1")()
|
||||
defer testutil.WithEnvVar("NO_COLOR", "1")()
|
||||
|
||||
if v := UseColors(); !cmp.Equal(v, &tr) {
|
||||
t.Fatalf("expected UseColors() = true; got = %v", v)
|
||||
@ -33,7 +22,7 @@ func Test_useColors_forceColors(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_useColors_disableColors(t *testing.T) {
|
||||
defer withTestVar("NO_COLOR", "1")()
|
||||
defer testutil.WithEnvVar("NO_COLOR", "1")()
|
||||
|
||||
if v := UseColors(); !cmp.Equal(v, &fa) {
|
||||
t.Fatalf("expected UseColors() = false; got = %v", v)
|
||||
@ -41,8 +30,8 @@ func Test_useColors_disableColors(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_useColors_default(t *testing.T) {
|
||||
defer withTestVar("NO_COLOR", "")()
|
||||
defer withTestVar("_KUBECTX_FORCE_COLOR", "")()
|
||||
defer testutil.WithEnvVar("NO_COLOR", "")()
|
||||
defer testutil.WithEnvVar("_KUBECTX_FORCE_COLOR", "")()
|
||||
|
||||
if v := UseColors(); v != nil {
|
||||
t.Fatalf("expected UseColors() = nil; got=%v", *v)
|
||||
|
2
internal/testutil/kubeconfigloader.go
Normal file
2
internal/testutil/kubeconfigloader.go
Normal file
@ -0,0 +1,2 @@
|
||||
package testutil
|
||||
|
18
internal/testutil/testutil.go
Normal file
18
internal/testutil/testutil.go
Normal file
@ -0,0 +1,18 @@
|
||||
package testutil
|
||||
|
||||
import "os"
|
||||
|
||||
// WithEnvVar sets an env var temporarily. Call its return value
|
||||
// in defer to restore original value in env (if exists).
|
||||
func WithEnvVar(key, value string) func() {
|
||||
orig, ok := os.LookupEnv(key)
|
||||
os.Setenv(key, value)
|
||||
return func() {
|
||||
if ok {
|
||||
os.Setenv(key, orig)
|
||||
} else {
|
||||
os.Unsetenv(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user