// SPDX-License-Identifier: Apache-2.0 // Copyright Authors of K9s package client_test import ( "errors" "log/slog" "os" "testing" "time" "github.com/derailed/k9s/internal/client" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "k8s.io/cli-runtime/pkg/genericclioptions" ) var kubeConfig = "./testdata/config" func init() { slog.SetDefault(slog.New(slog.DiscardHandler)) } func TestCallTimeout(t *testing.T) { uu := map[string]struct { t string e time.Duration }{ "custom": { t: "1m", e: 1 * time.Minute, }, "default": { e: client.DefaultCallTimeoutDuration, }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { flags := genericclioptions.NewConfigFlags(false) flags.Timeout = &u.t cfg := client.NewConfig(flags) assert.Equal(t, u.e, cfg.CallTimeout()) }) } } func TestConfigCurrentContext(t *testing.T) { uu := map[string]struct { context string e string }{ "default": { e: "fred", }, "custom": { context: "blee", e: "blee", }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { flags := genericclioptions.NewConfigFlags(false) flags.KubeConfig = &kubeConfig if u.context != "" { flags.Context = &u.context } cfg := client.NewConfig(flags) ctx, err := cfg.CurrentContextName() require.NoError(t, err) assert.Equal(t, u.e, ctx) }) } } func TestConfigCurrentCluster(t *testing.T) { name := "blee" uu := map[string]struct { flags *genericclioptions.ConfigFlags cluster string }{ "default": { flags: &genericclioptions.ConfigFlags{ KubeConfig: &kubeConfig, }, cluster: "zorg", }, "custom": { flags: &genericclioptions.ConfigFlags{ KubeConfig: &kubeConfig, Context: &name, }, cluster: "blee", }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { cfg := client.NewConfig(u.flags) ct, err := cfg.CurrentClusterName() require.NoError(t, err) assert.Equal(t, u.cluster, ct) }) } } func TestConfigCurrentUser(t *testing.T) { name := "blee" uu := map[string]struct { flags *genericclioptions.ConfigFlags user string }{ "default": { flags: &genericclioptions.ConfigFlags{KubeConfig: &kubeConfig}, user: "fred", }, "custom": { flags: &genericclioptions.ConfigFlags{KubeConfig: &kubeConfig, AuthInfoName: &name}, user: "blee", }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { cfg := client.NewConfig(u.flags) ctx, err := cfg.CurrentUserName() require.NoError(t, err) assert.Equal(t, u.user, ctx) }) } } func TestConfigCurrentNamespace(t *testing.T) { bleeNS, bleeCTX := "blee", "blee" uu := map[string]struct { flags *genericclioptions.ConfigFlags namespace string }{ "default": { flags: &genericclioptions.ConfigFlags{KubeConfig: &kubeConfig}, namespace: "", }, "withContext": { flags: &genericclioptions.ConfigFlags{KubeConfig: &kubeConfig, Context: &bleeCTX}, namespace: "zorg", }, "withNS": { flags: &genericclioptions.ConfigFlags{KubeConfig: &kubeConfig, Namespace: &bleeNS}, namespace: "blee", }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { cfg := client.NewConfig(u.flags) ns, err := cfg.CurrentNamespaceName() if ns != "" { require.NoError(t, err) } assert.Equal(t, u.namespace, ns) }) } } func TestConfigGetContext(t *testing.T) { uu := map[string]struct { cluster string err error }{ "default": { cluster: "blee", }, "custom": { cluster: "bozo", err: errors.New(`getcontext - invalid context specified: "bozo"`), }, } flags := &genericclioptions.ConfigFlags{KubeConfig: &kubeConfig} cfg := client.NewConfig(flags) for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { ctx, err := cfg.GetContext(u.cluster) if err != nil { assert.Equal(t, u.err, err) } else { assert.NotNil(t, ctx) assert.Equal(t, u.cluster, ctx.Cluster) } }) } } func TestConfigSwitchContext(t *testing.T) { cluster := "duh" flags := genericclioptions.ConfigFlags{ KubeConfig: &kubeConfig, Context: &cluster, } cfg := client.NewConfig(&flags) err := cfg.SwitchContext("blee") require.NoError(t, err) ctx, err := cfg.CurrentContextName() require.NoError(t, err) assert.Equal(t, "blee", ctx) } func TestConfigAccess(t *testing.T) { context := "duh" flags := genericclioptions.ConfigFlags{ KubeConfig: &kubeConfig, Context: &context, } cfg := client.NewConfig(&flags) acc, err := cfg.ConfigAccess() require.NoError(t, err) assert.NotEmpty(t, acc.GetDefaultFilename()) } func TestConfigContextNames(t *testing.T) { cluster := "duh" flags := genericclioptions.ConfigFlags{ KubeConfig: &kubeConfig, Context: &cluster, } cfg := client.NewConfig(&flags) cc, err := cfg.ContextNames() require.NoError(t, err) assert.Len(t, cc, 3) } func TestConfigContexts(t *testing.T) { context := "duh" flags := genericclioptions.ConfigFlags{ KubeConfig: &kubeConfig, Context: &context, } cfg := client.NewConfig(&flags) cc, err := cfg.Contexts() require.NoError(t, err) assert.Len(t, cc, 3) } func TestConfigDelContext(t *testing.T) { require.NoError(t, cp("./testdata/config.2", "./testdata/config.1")) context, kubeCfg := "duh", "./testdata/config.1" flags := genericclioptions.ConfigFlags{ KubeConfig: &kubeCfg, Context: &context, } cfg := client.NewConfig(&flags) err := cfg.DelContext("fred") require.NoError(t, err) cc, err := cfg.ContextNames() require.NoError(t, err) assert.Len(t, cc, 1) _, ok := cc["blee"] assert.True(t, ok) } func TestConfigRestConfig(t *testing.T) { flags := genericclioptions.ConfigFlags{ KubeConfig: &kubeConfig, } cfg := client.NewConfig(&flags) rc, err := cfg.RESTConfig() require.NoError(t, err) assert.Equal(t, "https://localhost:3002", rc.Host) } func TestConfigBadConfig(t *testing.T) { kubeConfig := "./testdata/bork_config" flags := genericclioptions.ConfigFlags{ KubeConfig: &kubeConfig, } cfg := client.NewConfig(&flags) _, err := cfg.RESTConfig() assert.Error(t, err) } // Helpers... func cp(src, dst string) error { data, err := os.ReadFile(src) if err != nil { return err } return os.WriteFile(dst, data, 0600) }