mirror of
https://github.com/ahmetb/kubectx.git
synced 2025-09-02 17:14:42 +00:00
Unit tests
This commit is contained in:
@@ -62,10 +62,16 @@ func Test_parseArgs_new(t *testing.T) {
|
||||
want: UnsupportedOp{fmt.Errorf("'-d' needs arguments")}},
|
||||
{name: "delete - current context",
|
||||
args: []string{"-d", "."},
|
||||
want: DeleteOp{[]string{"."}}},
|
||||
want: DeleteOp{[]string{"."}, false}},
|
||||
{name: "delete - multiple contexts",
|
||||
args: []string{"-d", ".", "a", "b"},
|
||||
want: DeleteOp{[]string{".", "a", "b"}}},
|
||||
want: DeleteOp{[]string{".", "a", "b"}, false}},
|
||||
{name: "delete cascading- current context",
|
||||
args: []string{"-D", "."},
|
||||
want: DeleteOp{[]string{"."}, true}},
|
||||
{name: "delete cascading - multiple contexts",
|
||||
args: []string{"-D", ".", "a", "b"},
|
||||
want: DeleteOp{[]string{".", "a", "b"}, true}},
|
||||
{name: "rename context",
|
||||
args: []string{"a=b"},
|
||||
want: RenameOp{"a", "b"}},
|
||||
|
124
internal/kubeconfig/clusters_test.go
Normal file
124
internal/kubeconfig/clusters_test.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package kubeconfig
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
|
||||
"github.com/ahmetb/kubectx/internal/testutil"
|
||||
)
|
||||
|
||||
func TestKubeconfig_ClusterOfContext_ctxNotFound(t *testing.T) {
|
||||
kc := new(Kubeconfig).WithLoader(WithMockKubeconfigLoader(testutil.KC().
|
||||
WithCtxs(testutil.Ctx("c1")).ToYAML(t)))
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err := kc.ClusterOfContext("c2")
|
||||
if err == nil {
|
||||
t.Fatal("expected err")
|
||||
}
|
||||
}
|
||||
|
||||
func TestKubeconfig_ClusterOfContext(t *testing.T) {
|
||||
kc := new(Kubeconfig).WithLoader(WithMockKubeconfigLoader(testutil.KC().
|
||||
WithCtxs(
|
||||
testutil.Ctx("c1").Cluster("c1c1"),
|
||||
testutil.Ctx("c2").Cluster("c2c2")).ToYAML(t)))
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
v1, err := kc.ClusterOfContext("c1")
|
||||
if err != nil {
|
||||
t.Fatal("unexpected err", err)
|
||||
}
|
||||
if expected := `c1c1`; v1 != expected {
|
||||
t.Fatalf("c1: expected=\"%s\" got=\"%s\"", expected, v1)
|
||||
}
|
||||
|
||||
v2, err := kc.ClusterOfContext("c2")
|
||||
if err != nil {
|
||||
t.Fatal("unexpected err", err)
|
||||
}
|
||||
if expected := `c2c2`; v2 != expected {
|
||||
t.Fatalf("c2: expected=\"%s\" got=\"%s\"", expected, v2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKubeconfig_DeleteClusterEntry_errors(t *testing.T) {
|
||||
kc := new(Kubeconfig).WithLoader(WithMockKubeconfigLoader(`[1, 2, 3]`))
|
||||
_ = kc.Parse()
|
||||
err := kc.DeleteClusterEntry("foo")
|
||||
if err == nil {
|
||||
t.Fatal("supposed to fail on non-mapping nodes")
|
||||
}
|
||||
|
||||
kc = new(Kubeconfig).WithLoader(WithMockKubeconfigLoader(`a: b`))
|
||||
_ = kc.Parse()
|
||||
err = kc.DeleteClusterEntry("foo")
|
||||
if err == nil {
|
||||
t.Fatal("supposed to fail if clusters key does not exist")
|
||||
}
|
||||
|
||||
kc = new(Kubeconfig).WithLoader(WithMockKubeconfigLoader(`clusters: "some string"`))
|
||||
_ = kc.Parse()
|
||||
err = kc.DeleteClusterEntry("foo")
|
||||
if err == nil {
|
||||
t.Fatal("supposed to fail if clusters key is not an array")
|
||||
}
|
||||
}
|
||||
|
||||
func TestKubeconfig_DeleteClusterEntry(t *testing.T) {
|
||||
test := WithMockKubeconfigLoader(
|
||||
testutil.KC().WithClusters(
|
||||
testutil.Cluster("c1"),
|
||||
testutil.Cluster("c2"),
|
||||
testutil.Cluster("c3")).ToYAML(t))
|
||||
kc := new(Kubeconfig).WithLoader(test)
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := kc.DeleteClusterEntry("c1"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := kc.Save(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
expected := testutil.KC().WithClusters(
|
||||
testutil.Cluster("c2"),
|
||||
testutil.Cluster("c3")).ToYAML(t)
|
||||
out := test.Output()
|
||||
if diff := cmp.Diff(expected, out); diff != "" {
|
||||
t.Fatalf("diff: %s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKubeconfig_CountClusterReferences_errors(t *testing.T) {
|
||||
kc := new(Kubeconfig).WithLoader(WithMockKubeconfigLoader(testutil.KC().
|
||||
WithCtxs(
|
||||
testutil.Ctx("c1").Cluster("c1c1"),
|
||||
testutil.Ctx("c2").Cluster("c2c2"),
|
||||
testutil.Ctx("c3").Cluster("c1c1")).ToYAML(t)))
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
count1, err := kc.CountClusterReferences("c1c1")
|
||||
if err != nil {
|
||||
t.Fatal("unexpected err", err)
|
||||
}
|
||||
if expected := 2; count1 != expected {
|
||||
t.Fatalf("c1: expected=\"%d\" got=\"%d\"", expected, count1)
|
||||
}
|
||||
|
||||
count2, err := kc.CountClusterReferences("c2c2")
|
||||
if err != nil {
|
||||
t.Fatal("unexpected err", err)
|
||||
}
|
||||
if expected := 1; count2 != expected {
|
||||
t.Fatalf("c1: expected=\"%d\" got=\"%d\"", expected, count2)
|
||||
}
|
||||
}
|
124
internal/kubeconfig/users_test.go
Normal file
124
internal/kubeconfig/users_test.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package kubeconfig
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
|
||||
"github.com/ahmetb/kubectx/internal/testutil"
|
||||
)
|
||||
|
||||
func TestKubeconfig_UserOfContext_ctxNotFound(t *testing.T) {
|
||||
kc := new(Kubeconfig).WithLoader(WithMockKubeconfigLoader(testutil.KC().
|
||||
WithCtxs(testutil.Ctx("c1")).ToYAML(t)))
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err := kc.UserOfContext("c2")
|
||||
if err == nil {
|
||||
t.Fatal("expected err")
|
||||
}
|
||||
}
|
||||
|
||||
func TestKubeconfig_UserOfContext(t *testing.T) {
|
||||
kc := new(Kubeconfig).WithLoader(WithMockKubeconfigLoader(testutil.KC().
|
||||
WithCtxs(
|
||||
testutil.Ctx("c1").User("c1u1"),
|
||||
testutil.Ctx("c2").User("c2u2")).ToYAML(t)))
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
v1, err := kc.UserOfContext("c1")
|
||||
if err != nil {
|
||||
t.Fatal("unexpected err", err)
|
||||
}
|
||||
if expected := `c1u1`; v1 != expected {
|
||||
t.Fatalf("c1: expected=\"%s\" got=\"%s\"", expected, v1)
|
||||
}
|
||||
|
||||
v2, err := kc.UserOfContext("c2")
|
||||
if err != nil {
|
||||
t.Fatal("unexpected err", err)
|
||||
}
|
||||
if expected := `c2u2`; v2 != expected {
|
||||
t.Fatalf("c2: expected=\"%s\" got=\"%s\"", expected, v2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKubeconfig_DeleteUserEntry_errors(t *testing.T) {
|
||||
kc := new(Kubeconfig).WithLoader(WithMockKubeconfigLoader(`[1, 2, 3]`))
|
||||
_ = kc.Parse()
|
||||
err := kc.DeleteUserEntry("foo")
|
||||
if err == nil {
|
||||
t.Fatal("supposed to fail on non-mapping nodes")
|
||||
}
|
||||
|
||||
kc = new(Kubeconfig).WithLoader(WithMockKubeconfigLoader(`a: b`))
|
||||
_ = kc.Parse()
|
||||
err = kc.DeleteUserEntry("foo")
|
||||
if err == nil {
|
||||
t.Fatal("supposed to fail if users key does not exist")
|
||||
}
|
||||
|
||||
kc = new(Kubeconfig).WithLoader(WithMockKubeconfigLoader(`users: "some string"`))
|
||||
_ = kc.Parse()
|
||||
err = kc.DeleteUserEntry("foo")
|
||||
if err == nil {
|
||||
t.Fatal("supposed to fail if users key is not an array")
|
||||
}
|
||||
}
|
||||
|
||||
func TestKubeconfig_DeleteUserEntry(t *testing.T) {
|
||||
test := WithMockKubeconfigLoader(
|
||||
testutil.KC().WithUsers(
|
||||
testutil.User("u1"),
|
||||
testutil.User("u2"),
|
||||
testutil.User("u3")).ToYAML(t))
|
||||
kc := new(Kubeconfig).WithLoader(test)
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := kc.DeleteUserEntry("u1"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := kc.Save(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
expected := testutil.KC().WithUsers(
|
||||
testutil.User("u2"),
|
||||
testutil.User("u3")).ToYAML(t)
|
||||
out := test.Output()
|
||||
if diff := cmp.Diff(expected, out); diff != "" {
|
||||
t.Fatalf("diff: %s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKubeconfig_CountUserReferences_errors(t *testing.T) {
|
||||
kc := new(Kubeconfig).WithLoader(WithMockKubeconfigLoader(testutil.KC().
|
||||
WithCtxs(
|
||||
testutil.Ctx("c1").User("c1u1"),
|
||||
testutil.Ctx("c2").User("c2u2"),
|
||||
testutil.Ctx("c3").User("c1u1")).ToYAML(t)))
|
||||
if err := kc.Parse(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
count1, err := kc.CountUserReferences("c1u1")
|
||||
if err != nil {
|
||||
t.Fatal("unexpected err", err)
|
||||
}
|
||||
if expected := 2; count1 != expected {
|
||||
t.Fatalf("c1: expected=\"%d\" got=\"%d\"", expected, count1)
|
||||
}
|
||||
|
||||
count2, err := kc.CountUserReferences("c2u2")
|
||||
if err != nil {
|
||||
t.Fatal("unexpected err", err)
|
||||
}
|
||||
if expected := 1; count2 != expected {
|
||||
t.Fatalf("c1: expected=\"%d\" got=\"%d\"", expected, count2)
|
||||
}
|
||||
}
|
@@ -21,15 +21,31 @@ import (
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type Context struct {
|
||||
type ContextObj struct {
|
||||
Name string `yaml:"name,omitempty"`
|
||||
Context struct {
|
||||
Namespace string `yaml:"namespace,omitempty"`
|
||||
User string `yaml:"user,omitempty"`
|
||||
Cluster string `yaml:"cluster,omitempty"`
|
||||
} `yaml:"context,omitempty"`
|
||||
}
|
||||
|
||||
func Ctx(name string) *Context { return &Context{Name: name} }
|
||||
func (c *Context) Ns(ns string) *Context { c.Context.Namespace = ns; return c }
|
||||
func Ctx(name string) *ContextObj { return &ContextObj{Name: name} }
|
||||
func (c *ContextObj) Ns(ns string) *ContextObj { c.Context.Namespace = ns; return c }
|
||||
func (c *ContextObj) User(user string) *ContextObj { c.Context.User = user; return c }
|
||||
func (c *ContextObj) Cluster(cluster string) *ContextObj { c.Context.Cluster = cluster; return c }
|
||||
|
||||
type UserObj struct {
|
||||
Name string `yaml:"name,omitempty"`
|
||||
}
|
||||
|
||||
func User(name string) *UserObj { return &UserObj{Name: name} }
|
||||
|
||||
type ClusterObj struct {
|
||||
Name string `yaml:"name,omitempty"`
|
||||
}
|
||||
|
||||
func Cluster(name string) *ClusterObj { return &ClusterObj{Name: name} }
|
||||
|
||||
type Kubeconfig map[string]interface{}
|
||||
|
||||
@@ -41,7 +57,9 @@ func KC() *Kubeconfig {
|
||||
|
||||
func (k *Kubeconfig) Set(key string, v interface{}) *Kubeconfig { (*k)[key] = v; return k }
|
||||
func (k *Kubeconfig) WithCurrentCtx(s string) *Kubeconfig { (*k)["current-context"] = s; return k }
|
||||
func (k *Kubeconfig) WithCtxs(c ...*Context) *Kubeconfig { (*k)["contexts"] = c; return k }
|
||||
func (k *Kubeconfig) WithCtxs(c ...*ContextObj) *Kubeconfig { (*k)["contexts"] = c; return k }
|
||||
func (k *Kubeconfig) WithUsers(u ...*UserObj) *Kubeconfig { (*k)["users"] = u; return k }
|
||||
func (k *Kubeconfig) WithClusters(c ...*ClusterObj) *Kubeconfig { (*k)["clusters"] = c; return k }
|
||||
|
||||
func (k *Kubeconfig) ToYAML(t *testing.T) string {
|
||||
t.Helper()
|
||||
|
Reference in New Issue
Block a user