From 64c689b9b487428ba2005a918b924082ade4ca8b Mon Sep 17 00:00:00 2001 From: Tullio Sebastiani Date: Mon, 9 Dec 2024 11:50:40 +0100 Subject: [PATCH] unit tests (#16) Signed-off-by: Tullio Sebastiani --- cmd/graph.go | 3 + cmd/query_status.go | 23 +- cmd/run.go | 12 +- internal/config/config.go | 1 - internal/config/config.json | 1 - ...ctory_test.go => provider_factory_test.go} | 0 pkg/scenario_orchestrator/common_functions.go | 5 +- .../docker/scenario_orchestrator.go | 8 +- .../docker/scenario_orchestrator_test.go | 37 ++- .../factory/factory_test.go | 28 ++ .../podman/scenario_orchestrator.go | 13 +- .../podman/scenario_orchestrator_test.go | 61 ++++- .../test/common_test_functions.go | 206 ++++++++++++++- pkg/scenario_orchestrator/utils/errors.go | 11 + pkg/scenario_orchestrator/utils/utils.go | 76 +++--- pkg/scenario_orchestrator/utils/utils_test.go | 247 ++++++++++++++++++ tests/containerfiles/dummyscenario/run.sh | 2 +- tests/data/kubeconfig | 32 +++ tests/data/test_ca | 19 ++ tests/data/test_cert | 19 ++ tests/data/test_key | 27 ++ tests/data/wrong_kubeconfig | 33 +++ 22 files changed, 788 insertions(+), 76 deletions(-) rename pkg/provider/factory/{provide_factory_test.go => provider_factory_test.go} (100%) create mode 100644 pkg/scenario_orchestrator/factory/factory_test.go create mode 100644 pkg/scenario_orchestrator/utils/errors.go create mode 100644 tests/data/kubeconfig create mode 100644 tests/data/test_ca create mode 100644 tests/data/test_cert create mode 100644 tests/data/test_key create mode 100644 tests/data/wrong_kubeconfig diff --git a/cmd/graph.go b/cmd/graph.go index e4fd9d8..53984cd 100644 --- a/cmd/graph.go +++ b/cmd/graph.go @@ -73,6 +73,9 @@ func NewGraphRunCommand(factory *providerfactory.ProviderFactory, scenarioOrches if err != nil { return err } + if kubeconfigPath == nil { + return fmt.Errorf("kubeconfig not found: %s", kubeconfig) + } volumes[*kubeconfigPath] = config.KubeconfigPath if metricsProfile != "" { diff --git a/cmd/query_status.go b/cmd/query_status.go index d10656b..2a6580a 100644 --- a/cmd/query_status.go +++ b/cmd/query_status.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" "github.com/krkn-chaos/krknctl/internal/config" provider_models "github.com/krkn-chaos/krknctl/pkg/provider/models" @@ -47,7 +48,7 @@ func resolveContainerIdOrName(orchestrator scenario_orchestrator.ScenarioOrchest fmt.Println(buf.String()) if scenarioContainer.Container.ExitStatus != 0 { - return utils.StatusCodeToError(scenarioContainer.Container.ExitStatus, conf) + return &utils.ExitError{ExitStatus: int(scenarioContainer.Container.ExitStatus)} } return nil } @@ -78,7 +79,7 @@ func resolveGraphFile(orchestrator scenario_orchestrator.ScenarioOrchestrator, f if (*containerScenario).Container != nil { containers = append(containers, *(*containerScenario).Container) if (*containerScenario).Container.ExitStatus != 0 { - statusCodeError = utils.StatusCodeToError((*containerScenario).Container.ExitStatus, orchestrator.GetConfig()) + return &utils.ExitError{ExitStatus: int((*containerScenario).Container.ExitStatus)} } } } @@ -115,8 +116,11 @@ func NewQueryStatusCommand(scenarioOrchestrator *scenario_orchestrator.ScenarioO } if len(args) > 0 { err = resolveContainerIdOrName(*scenarioOrchestrator, args[0], conn, config) - if exit := utils.ErrorToStatusCode(err, config); exit != nil { - os.Exit(int(*exit)) + var staterr *utils.ExitError + if errors.As(err, &staterr) { + if staterr.ExitStatus != 0 { + os.Exit(staterr.ExitStatus) + } } return err } @@ -135,10 +139,13 @@ func NewQueryStatusCommand(scenarioOrchestrator *scenario_orchestrator.ScenarioO } err = resolveGraphFile(*scenarioOrchestrator, graphPath, conn, config) - if exit := utils.ErrorToStatusCode(err, config); exit != nil { - // since multiple errors of different values might be set - // on graph it exits with a generic 1 - os.Exit(1) + // since multiple errors of different values might be set + // on graph it exits with a generic 1 + var staterr *utils.ExitError + if errors.As(err, &staterr) { + if staterr.ExitStatus != 0 { + os.Exit(1) + } } if err != nil { diff --git a/cmd/run.go b/cmd/run.go index 156659c..839894c 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -1,6 +1,7 @@ package cmd import ( + "errors" "fmt" "github.com/fatih/color" "github.com/krkn-chaos/krknctl/internal/config" @@ -143,6 +144,9 @@ func NewRunCommand(factory *factory.ProviderFactory, scenarioOrchestrator *scena if err != nil { return err } + if kubeconfigPath == nil { + return fmt.Errorf("kubeconfig not found: %s", *foundKubeconfig) + } volumes[*kubeconfigPath] = config.KubeconfigPath if metricsProfile != nil { volumes[*metricsProfile] = config.MetricsProfilePath @@ -218,11 +222,11 @@ func NewRunCommand(factory *factory.ProviderFactory, scenarioOrchestrator *scena _, err = (*scenarioOrchestrator).RunAttached(quayImageUri+":"+scenarioDetail.Name, containerName, environment, false, volumes, os.Stdout, os.Stderr, &commChan, conn, debug) if err != nil { - if exit := utils.ErrorToStatusCode(err, config); exit != nil { - os.Exit(int(*exit)) - } else { - return err + var staterr *utils.ExitError + if errors.As(err, &staterr) { + os.Exit(staterr.ExitStatus) } + return err } scenarioDuration := time.Since(startTime) fmt.Println(fmt.Sprintf("%s ran for %s", scenarioDetail.Name, scenarioDuration.String())) diff --git a/internal/config/config.go b/internal/config/config.go index ec7a4ec..9c4e5f3 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -16,7 +16,6 @@ type Config struct { KubeconfigPrefix string `json:"kubeconfig_prefix"` PodmanDarwinSocketTemplate string `json:"podman_darwin_socket_template"` PodmanLinuxSocketTemplate string `json:"podman_linux_socket_template"` - ContainerExitStatusPrefix string `json:"container_exit_status_prefix"` PodmanSocketRoot string `json:"podman_socket_root_linux"` PodmanRunningState string `json:"podman_running_state"` DockerSocketRoot string `json:"docker_socket_root"` diff --git a/internal/config/config.json b/internal/config/config.json index d6d1f1c..25fefa9 100644 --- a/internal/config/config.json +++ b/internal/config/config.json @@ -9,7 +9,6 @@ "krknctl_logs": "krknct-log", "podman_darwin_socket_template": "unix://%s/.local/share/containers/podman/machine/podman.sock", "podman_linux_socket_template": "unix://run/user/%d/podman/podman.sock", - "container_exit_status_prefix": "!#KRKN_EXIT_STATUS", "podman_socket_root_linux": "unix://run/podman/podman.sock", "podman_running_state": "running", "docker_socket_root": "unix:///var/run/docker.sock", diff --git a/pkg/provider/factory/provide_factory_test.go b/pkg/provider/factory/provider_factory_test.go similarity index 100% rename from pkg/provider/factory/provide_factory_test.go rename to pkg/provider/factory/provider_factory_test.go diff --git a/pkg/scenario_orchestrator/common_functions.go b/pkg/scenario_orchestrator/common_functions.go index c996a34..921da60 100644 --- a/pkg/scenario_orchestrator/common_functions.go +++ b/pkg/scenario_orchestrator/common_functions.go @@ -94,7 +94,7 @@ func CommonRunAttached(image string, containerName string, env map[string]string } // if there is an error exit status it is propagated via error to the cmd if containerStatus.Container.ExitStatus > 0 { - return containerId, utils.StatusCodeToError(containerStatus.Container.ExitStatus, c.GetConfig()) + return containerId, &utils.ExitError{ExitStatus: int(containerStatus.Container.ExitStatus)} } return containerId, nil @@ -133,6 +133,9 @@ func CommonListRunningScenarios(c ScenarioOrchestrator, ctx context.Context) (*[ if err != nil { return nil, err } + if scenario == nil { + continue + } runningScenarios = append(runningScenarios, *scenario) } diff --git a/pkg/scenario_orchestrator/docker/scenario_orchestrator.go b/pkg/scenario_orchestrator/docker/scenario_orchestrator.go index 67c0b56..a275709 100644 --- a/pkg/scenario_orchestrator/docker/scenario_orchestrator.go +++ b/pkg/scenario_orchestrator/docker/scenario_orchestrator.go @@ -309,8 +309,9 @@ func (c *ScenarioOrchestrator) ListRunningContainers(ctx context.Context) (*map[ if err != nil { return nil, err } + containerName := strings.Replace(container.Names[0], "/", "", 1) scenarios[index] = orchestratormodels.Container{ - Name: container.Names[0], + Name: containerName, Id: container.ID, Image: container.Image, Started: index, @@ -335,9 +336,12 @@ func (c *ScenarioOrchestrator) InspectScenario(container orchestratormodels.Cont } inspectData, err := cli.ContainerInspect(ctx, container.Id) if err != nil { + if strings.Contains(err.Error(), "No such container") { + return nil, nil + } return nil, err } - container.Name = inspectData.Name + container.Name = strings.Replace(inspectData.Name, "/", "", 1) container.Status = inspectData.State.Status container.ExitStatus = int32(inspectData.State.ExitCode) diff --git a/pkg/scenario_orchestrator/docker/scenario_orchestrator_test.go b/pkg/scenario_orchestrator/docker/scenario_orchestrator_test.go index 27f5bfe..a7bb76c 100644 --- a/pkg/scenario_orchestrator/docker/scenario_orchestrator_test.go +++ b/pkg/scenario_orchestrator/docker/scenario_orchestrator_test.go @@ -94,7 +94,9 @@ func TestScenarioOrchestrator_Docker_AttachWait(t *testing.T) { } func TestScenarioOrchestrator_Docker_Kill(t *testing.T) { - + config := test.CommonGetConfig(t) + sodocker := ScenarioOrchestrator{Config: config, ContainerRuntime: models.Docker} + test.CommonTestScenarioOrchestratorKillContainers(t, &sodocker, config) } func TestScenarioOrchestrator_Docker_ListRunningContainers(t *testing.T) { @@ -104,22 +106,43 @@ func TestScenarioOrchestrator_Docker_ListRunningContainers(t *testing.T) { } func TestScenarioOrchestrator_Docker_ListRunningScenarios(t *testing.T) { - + config := test.CommonGetConfig(t) + sodocker := ScenarioOrchestrator{Config: config, ContainerRuntime: models.Docker} + test.CommonTestScenarioOrchestratorListRunningScenarios(t, &sodocker, config) } func TestScenarioOrchestrator_Docker_InspectRunningScenario(t *testing.T) { + config := test.CommonGetConfig(t) + sodocker := ScenarioOrchestrator{Config: config, ContainerRuntime: models.Docker} + test.CommonTestScenarioOrchestratorInspectRunningScenario(t, &sodocker, config) } func TestScenarioOrchestrator_Docker_GetContainerRuntimeSocket(t *testing.T) { + config := test.CommonGetConfig(t) + sodocker := ScenarioOrchestrator{Config: config, ContainerRuntime: models.Docker} + var uid *int = nil + envuid := os.Getenv("USERID") + if envuid != "" { + _uid, err := strconv.Atoi(envuid) + assert.Nil(t, err) + uid = &_uid + fmt.Println("USERID -> ", *uid) + } else { + _uid := 1337 + uid = &_uid + } + assert.NotNil(t, uid) -} - -func TestScenarioOrchestrator_Docker_GetContainerRuntime(t *testing.T) { + socket, err := sodocker.GetContainerRuntimeSocket(uid) + assert.Nil(t, err) + assert.Equal(t, config.DockerSocketRoot, *socket) } -func TestScenarioOrchestrator_Docker_PrintContainerRuntime(t *testing.T) { - +func TestScenarioOrchestrator_Docker_GetContainerRuntime(t *testing.T) { + config := test.CommonGetTestConfig(t) + sopodman := ScenarioOrchestrator{Config: config, ContainerRuntime: models.Docker} + assert.Equal(t, sopodman.GetContainerRuntime(), models.Docker) } func TestScenarioOrchestrator_Docker_ResolveContainerId(t *testing.T) { diff --git a/pkg/scenario_orchestrator/factory/factory_test.go b/pkg/scenario_orchestrator/factory/factory_test.go new file mode 100644 index 0000000..07b89f0 --- /dev/null +++ b/pkg/scenario_orchestrator/factory/factory_test.go @@ -0,0 +1,28 @@ +package factory + +import ( + "github.com/krkn-chaos/krknctl/internal/config" + "github.com/krkn-chaos/krknctl/pkg/scenario_orchestrator/docker" + "github.com/krkn-chaos/krknctl/pkg/scenario_orchestrator/models" + "github.com/krkn-chaos/krknctl/pkg/scenario_orchestrator/podman" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestScenarioOrchestratorFactory_NewInstance(t *testing.T) { + typeProviderPodman := &podman.ScenarioOrchestrator{} + typeProviderDocker := &docker.ScenarioOrchestrator{} + conf, err := config.LoadConfig() + assert.Nil(t, err) + assert.NotNil(t, conf) + factory := NewScenarioOrchestratorFactory(conf) + assert.NotNil(t, factory) + scenarioDocker := factory.NewInstance(models.Docker) + assert.NotNil(t, scenarioDocker) + assert.IsType(t, scenarioDocker, typeProviderDocker) + + scenarioPodman := factory.NewInstance(models.Podman) + assert.NotNil(t, scenarioPodman) + assert.IsType(t, scenarioPodman, typeProviderPodman) + +} diff --git a/pkg/scenario_orchestrator/podman/scenario_orchestrator.go b/pkg/scenario_orchestrator/podman/scenario_orchestrator.go index 635fc1b..04281ce 100644 --- a/pkg/scenario_orchestrator/podman/scenario_orchestrator.go +++ b/pkg/scenario_orchestrator/podman/scenario_orchestrator.go @@ -3,10 +3,12 @@ package podman import ( "context" "encoding/json" + "errors" "fmt" "github.com/containers/podman/v5/pkg/bindings" "github.com/containers/podman/v5/pkg/bindings/containers" "github.com/containers/podman/v5/pkg/bindings/images" + "github.com/containers/podman/v5/pkg/errorhandling" "github.com/containers/podman/v5/pkg/specgen" "github.com/docker/docker/api/types/mount" "github.com/krkn-chaos/krknctl/internal/config" @@ -227,12 +229,15 @@ func (c *ScenarioOrchestrator) InspectScenario(container orchestratormodels.Cont scenario.Volumes = make(map[string]string) scenario.Env = make(map[string]string) runningScenario.Container = &container + inspectData, err := containers.Inspect(ctx, container.Id, nil) if err != nil { - return nil, err - } - if inspectData == nil { - return nil, fmt.Errorf("container %s not found", container.Id) + var customErr *errorhandling.ErrorModel + if errors.As(err, &customErr) { + if customErr.ResponseCode == 404 { + return nil, nil + } + } } container.Name = inspectData.Name diff --git a/pkg/scenario_orchestrator/podman/scenario_orchestrator_test.go b/pkg/scenario_orchestrator/podman/scenario_orchestrator_test.go index eab89ad..efb2661 100644 --- a/pkg/scenario_orchestrator/podman/scenario_orchestrator_test.go +++ b/pkg/scenario_orchestrator/podman/scenario_orchestrator_test.go @@ -8,8 +8,9 @@ import ( "github.com/krkn-chaos/krknctl/pkg/scenario_orchestrator/models" "github.com/krkn-chaos/krknctl/pkg/scenario_orchestrator/test" "github.com/stretchr/testify/assert" - "os" + operating_system "os" "regexp" + "runtime" "strconv" "strings" "testing" @@ -41,7 +42,7 @@ func TestScenarioOrchestrator_Podman_RunGraph(t *testing.T) { func findContainers(t *testing.T, config config.Config) (int, context.Context) { _true := true - envuid := os.Getenv("USERID") + envuid := operating_system.Getenv("USERID") var uid *int = nil if envuid != "" { _uid, err := strconv.Atoi(envuid) @@ -93,35 +94,69 @@ func TestScenarioOrchestrator_Podman_AttachWait(t *testing.T) { } func TestScenarioOrchestrator_Podman_Kill(t *testing.T) { + config := test.CommonGetConfig(t) + sopodman := ScenarioOrchestrator{Config: config, ContainerRuntime: models.Podman} + test.CommonTestScenarioOrchestratorKillContainers(t, &sopodman, config) + } func TestScenarioOrchestrator_Podman_ListRunningContainers(t *testing.T) { config := test.CommonGetConfig(t) - sodocker := ScenarioOrchestrator{Config: config, ContainerRuntime: models.Podman} - test.CommonTestScenarioOrchestratorListRunningContainers(t, &sodocker, config) + sopodman := ScenarioOrchestrator{Config: config, ContainerRuntime: models.Podman} + test.CommonTestScenarioOrchestratorListRunningContainers(t, &sopodman, config) } func TestScenarioOrchestrator_Podman_ListRunningScenarios(t *testing.T) { - + config := test.CommonGetConfig(t) + sopodman := ScenarioOrchestrator{Config: config, ContainerRuntime: models.Podman} + test.CommonTestScenarioOrchestratorListRunningScenarios(t, &sopodman, config) } func TestScenarioOrchestrator_Podman_InspectRunningScenario(t *testing.T) { - + config := test.CommonGetConfig(t) + sodocker := ScenarioOrchestrator{Config: config, ContainerRuntime: models.Docker} + test.CommonTestScenarioOrchestratorInspectRunningScenario(t, &sodocker, config) } func TestScenarioOrchestrator_Podman_GetContainerRuntimeSocket(t *testing.T) { + config := test.CommonGetConfig(t) + sodocker := ScenarioOrchestrator{Config: config, ContainerRuntime: models.Docker} + var uid *int = nil + envuid := operating_system.Getenv("USERID") + if envuid != "" { + _uid, err := strconv.Atoi(envuid) + assert.Nil(t, err) + uid = &_uid + fmt.Println("USERID -> ", *uid) + } else { + _uid := 1337 + uid = &_uid + } + assert.NotNil(t, uid) -} - -func TestScenarioOrchestrator_Podman_GetContainerRuntime(t *testing.T) { + socket, err := sodocker.GetContainerRuntimeSocket(uid) + assert.Nil(t, err) + switch os := runtime.GOOS; os { + case "darwin": + home, err := operating_system.UserHomeDir() + assert.Nil(t, err) + assert.NotNil(t, home) + assert.Equal(t, fmt.Sprintf(config.PodmanDarwinSocketTemplate, home), *socket) + case "linux": + assert.Equal(t, fmt.Sprintf(config.PodmanLinuxSocketTemplate, *uid), *socket) + default: + panic("😱") + } } -func TestScenarioOrchestrator_Podman_PrintContainerRuntime(t *testing.T) { - +func TestScenarioOrchestrator_Podman_GetContainerRuntime(t *testing.T) { + config := test.CommonGetTestConfig(t) + sopodman := ScenarioOrchestrator{Config: config, ContainerRuntime: models.Podman} + assert.Equal(t, sopodman.GetContainerRuntime(), models.Podman) } func TestScenarioOrchestrator_Podman_ResolveContainerId(t *testing.T) { config := test.CommonGetTestConfig(t) - sodocker := ScenarioOrchestrator{Config: config, ContainerRuntime: models.Podman} - test.CommonTestScenarioOrchestratorResolveContainerName(t, &sodocker, config, 3) + sopodman := ScenarioOrchestrator{Config: config, ContainerRuntime: models.Podman} + test.CommonTestScenarioOrchestratorResolveContainerName(t, &sopodman, config, 3) } diff --git a/pkg/scenario_orchestrator/test/common_test_functions.go b/pkg/scenario_orchestrator/test/common_test_functions.go index 2dd360a..f2eafa5 100644 --- a/pkg/scenario_orchestrator/test/common_test_functions.go +++ b/pkg/scenario_orchestrator/test/common_test_functions.go @@ -2,6 +2,7 @@ package test import ( "encoding/json" + "errors" "fmt" krknctlconfig "github.com/krkn-chaos/krknctl/internal/config" "github.com/krkn-chaos/krknctl/pkg/dependencygraph" @@ -14,6 +15,7 @@ import ( "os" "os/user" "strconv" + "strings" "testing" "time" ) @@ -124,9 +126,9 @@ func CommonTestScenarioOrchestratorRunAttached(t *testing.T, so scenario_orchest assert.NotNil(t, containerId) // Testing exit status > 0 - exitStatus := "3" + exitStatus := 3 env["END"] = fmt.Sprintf("%d", duration) - env["EXIT_STATUS"] = exitStatus + env["EXIT_STATUS"] = fmt.Sprintf("%d", exitStatus) containerName2 := utils.GenerateContainerName(conf, scenario.Name, nil) containerId, err = so.RunAttached(registryUri+":"+scenario.Name, containerName2, env, false, map[string]string{}, os.Stdout, os.Stderr, nil, ctx, false) if err != nil { @@ -134,7 +136,10 @@ func CommonTestScenarioOrchestratorRunAttached(t *testing.T, so scenario_orchest } assert.NotNil(t, err) assert.NotNil(t, containerId) - assert.Equal(t, fmt.Sprintf("%s %s", conf.ContainerExitStatusPrefix, exitStatus), err.Error()) + var staterr *utils.ExitError + assert.True(t, errors.As(err, &staterr)) + assert.NotNil(t, staterr) + assert.Equal(t, staterr.ExitStatus, exitStatus) return *containerId } @@ -421,3 +426,198 @@ func CommonTestScenarioOrchestratorResolveContainerName(t *testing.T, so scenari assert.Nil(t, err) } + +func CommonTestScenarioOrchestratorKillContainers(t *testing.T, so scenario_orchestrator.ScenarioOrchestrator, conf krknctlconfig.Config) { + env := map[string]string{ + "END": "20", + } + + currentUser, err := user.Current() + fmt.Println("Current user: " + (*currentUser).Name) + fmt.Println("current user id" + (*currentUser).Uid) + quayProvider := quay.ScenarioProvider{Config: &conf} + registryUri, err := conf.GetQuayImageUri() + assert.Nil(t, err) + + apiUri, err := conf.GetQuayRepositoryApiUri() + assert.Nil(t, err) + + scenario, err := quayProvider.GetScenarioDetail("dummy-scenario", apiUri) + assert.Nil(t, err) + assert.NotNil(t, scenario) + kubeconfig, err := utils.PrepareKubeconfig(nil, conf) + assert.Nil(t, err) + assert.NotNil(t, kubeconfig) + fmt.Println("KUBECONFIG PARSED -> " + *kubeconfig) + + envuid := os.Getenv("USERID") + var uid *int = nil + if envuid != "" { + _uid, err := strconv.Atoi(envuid) + assert.Nil(t, err) + uid = &_uid + fmt.Println("USERID -> ", *uid) + } + socket, err := so.GetContainerRuntimeSocket(uid) + assert.Nil(t, err) + assert.NotNil(t, socket) + ctx, err := so.Connect(*socket) + assert.Nil(t, err) + assert.NotNil(t, ctx) + + fmt.Println("CONTAINER SOCKET -> " + *socket) + timestamp := time.Now().Unix() + containerName := fmt.Sprintf("%s-%s-kill-%d", conf.ContainerPrefix, scenario.Name, timestamp) + containerId, err := so.Run(registryUri+":"+scenario.Name, containerName, env, false, map[string]string{}, nil, ctx, false) + time.Sleep(2 * time.Second) + containers, err := so.ListRunningContainers(ctx) + assert.Nil(t, err) + found := false + for _, v := range *containers { + if strings.Contains(v.Name, "kill") { + found = true + } + } + assert.True(t, found) + + err = so.Kill(containerId, ctx) + assert.Nil(t, err) + time.Sleep(2 * time.Second) + containers, err = so.ListRunningContainers(ctx) + assert.Nil(t, err) + found = false + for _, v := range *containers { + if strings.Contains(v.Name, "kill") { + found = true + } + } + assert.False(t, found) + end := time.Now().Unix() + assert.True(t, end-timestamp < 20) +} + +func CommonTestScenarioOrchestratorListRunningScenarios(t *testing.T, so scenario_orchestrator.ScenarioOrchestrator, conf krknctlconfig.Config) { + env := map[string]string{ + "END": "20", + } + + currentUser, err := user.Current() + fmt.Println("Current user: " + (*currentUser).Name) + fmt.Println("current user id" + (*currentUser).Uid) + quayProvider := quay.ScenarioProvider{Config: &conf} + registryUri, err := conf.GetQuayImageUri() + assert.Nil(t, err) + + apiUri, err := conf.GetQuayRepositoryApiUri() + assert.Nil(t, err) + + scenario, err := quayProvider.GetScenarioDetail("dummy-scenario", apiUri) + assert.Nil(t, err) + assert.NotNil(t, scenario) + kubeconfig, err := utils.PrepareKubeconfig(nil, conf) + assert.Nil(t, err) + assert.NotNil(t, kubeconfig) + fmt.Println("KUBECONFIG PARSED -> " + *kubeconfig) + + envuid := os.Getenv("USERID") + var uid *int = nil + if envuid != "" { + _uid, err := strconv.Atoi(envuid) + assert.Nil(t, err) + uid = &_uid + fmt.Println("USERID -> ", *uid) + } + socket, err := so.GetContainerRuntimeSocket(uid) + assert.Nil(t, err) + assert.NotNil(t, socket) + ctx, err := so.Connect(*socket) + assert.Nil(t, err) + assert.NotNil(t, ctx) + + fmt.Println("CONTAINER SOCKET -> " + *socket) + + containerName1 := utils.GenerateContainerName(conf, scenario.Name, nil) + containerName2 := utils.GenerateContainerName(conf, scenario.Name, nil) + + //starting containers in inverted order to check if lisRunningScenarios returns them sorted + sortedContainers := make(map[int]string) + _, err = so.Run(registryUri+":"+scenario.Name, containerName2, env, false, map[string]string{}, nil, ctx, false) + _, err = so.Run(registryUri+":"+scenario.Name, containerName1, env, false, map[string]string{}, nil, ctx, false) + time.Sleep(1 * time.Second) + + assert.Nil(t, err) + runningContainers, err := so.ListRunningScenarios(ctx) + assert.Nil(t, err) + assert.NotNil(t, runningContainers) + i := 0 + for _, r := range *runningContainers { + if r.Container.Name == containerName1 || r.Container.Name == containerName2 { + sortedContainers[i] = r.Container.Name + i++ + } + } + assert.Nil(t, err) + fmt.Println(sortedContainers) + assert.True(t, len(*runningContainers) >= 2) + assert.Equal(t, sortedContainers[0], containerName1) + assert.Equal(t, sortedContainers[1], containerName2) +} + +func CommonTestScenarioOrchestratorInspectRunningScenario(t *testing.T, so scenario_orchestrator.ScenarioOrchestrator, conf krknctlconfig.Config) { + env := map[string]string{ + "END": "20", + } + + currentUser, err := user.Current() + fmt.Println("Current user: " + (*currentUser).Name) + fmt.Println("current user id" + (*currentUser).Uid) + quayProvider := quay.ScenarioProvider{Config: &conf} + registryUri, err := conf.GetQuayImageUri() + assert.Nil(t, err) + + apiUri, err := conf.GetQuayRepositoryApiUri() + assert.Nil(t, err) + + scenario, err := quayProvider.GetScenarioDetail("dummy-scenario", apiUri) + assert.Nil(t, err) + assert.NotNil(t, scenario) + kubeconfig, err := utils.PrepareKubeconfig(nil, conf) + assert.Nil(t, err) + assert.NotNil(t, kubeconfig) + fmt.Println("KUBECONFIG PARSED -> " + *kubeconfig) + + envuid := os.Getenv("USERID") + var uid *int = nil + if envuid != "" { + _uid, err := strconv.Atoi(envuid) + assert.Nil(t, err) + uid = &_uid + fmt.Println("USERID -> ", *uid) + } + socket, err := so.GetContainerRuntimeSocket(uid) + assert.Nil(t, err) + assert.NotNil(t, socket) + ctx, err := so.Connect(*socket) + assert.Nil(t, err) + assert.NotNil(t, ctx) + + fmt.Println("CONTAINER SOCKET -> " + *socket) + + containerName1 := utils.GenerateContainerName(conf, scenario.Name, nil) + containerId1, err := so.Run(registryUri+":"+scenario.Name, containerName1, env, false, map[string]string{}, nil, ctx, false) + assert.Nil(t, err) + time.Sleep(1 * time.Second) + + inspectData, err := so.InspectScenario(models.Container{Id: *containerId1}, ctx) + assert.Nil(t, err) + assert.NotNil(t, inspectData) + + assert.Equal(t, inspectData.Container.Name, containerName1) + assert.Equal(t, inspectData.Container.Id, *containerId1) + assert.Equal(t, inspectData.Scenario.Name, scenario.Name) + + inspectData, err = so.InspectScenario(models.Container{Id: "mimmo"}, ctx) + assert.Nil(t, err) + assert.Nil(t, inspectData) + +} diff --git a/pkg/scenario_orchestrator/utils/errors.go b/pkg/scenario_orchestrator/utils/errors.go new file mode 100644 index 0000000..3598eb3 --- /dev/null +++ b/pkg/scenario_orchestrator/utils/errors.go @@ -0,0 +1,11 @@ +package utils + +import "fmt" + +type ExitError struct { + ExitStatus int +} + +func (e *ExitError) Error() string { + return fmt.Sprintf("Krkn exited with exit status: %d", e.ExitStatus) +} diff --git a/pkg/scenario_orchestrator/utils/utils.go b/pkg/scenario_orchestrator/utils/utils.go index 503dec0..2637b54 100644 --- a/pkg/scenario_orchestrator/utils/utils.go +++ b/pkg/scenario_orchestrator/utils/utils.go @@ -10,12 +10,12 @@ import ( "github.com/krkn-chaos/krknctl/internal/config" orchestatormodels "github.com/krkn-chaos/krknctl/pkg/scenario_orchestrator/models" "github.com/krkn-chaos/krknctl/pkg/text" + "io/fs" "k8s.io/client-go/tools/clientcmd" "os" "path/filepath" "regexp" "runtime" - "strconv" "strings" "time" ) @@ -27,25 +27,36 @@ type SigTermChannel struct { func PrepareKubeconfig(kubeconfigPath *string, config config.Config) (*string, error) { var configPath string - + var configFolder string if kubeconfigPath == nil || *kubeconfigPath == "" { configPath = clientcmd.NewDefaultClientConfigLoadingRules().GetDefaultFilename() } else { - path, err := ExpandHomeFolder(*kubeconfigPath) + path, err := ExpandFolder(*kubeconfigPath, nil) if err != nil { return nil, err } configPath = *path } + configFolder = filepath.Dir(configPath) + kubeconfig, err := clientcmd.LoadFromFile(configPath) if err != nil { + var fserr *fs.PathError + if errors.As(err, &fserr) { + return nil, nil + } return nil, fmt.Errorf("failed to load kubeconfig: %v", err) } for clusterName, cluster := range kubeconfig.Clusters { if cluster.CertificateAuthorityData == nil && cluster.CertificateAuthority != "" { - certData, err := os.ReadFile(cluster.CertificateAuthority) + path, err := ExpandFolder(cluster.CertificateAuthority, &configFolder) + if err != nil { + return nil, err + } + + certData, err := os.ReadFile(*path) if err != nil { return nil, fmt.Errorf("failed to load cluster certificate '%s': %v", clusterName, err) } @@ -56,7 +67,11 @@ func PrepareKubeconfig(kubeconfigPath *string, config config.Config) (*string, e for authName, auth := range kubeconfig.AuthInfos { if auth.ClientCertificateData == nil && auth.ClientCertificate != "" { - certData, err := os.ReadFile(auth.ClientCertificate) + path, err := ExpandFolder(auth.ClientCertificate, &configFolder) + if err != nil { + return nil, err + } + certData, err := os.ReadFile(*path) if err != nil { return nil, fmt.Errorf("failed to load user certificate '%s': %v", authName, err) } @@ -65,7 +80,11 @@ func PrepareKubeconfig(kubeconfigPath *string, config config.Config) (*string, e } if auth.ClientKeyData == nil && auth.ClientKey != "" { - keyData, err := os.ReadFile(auth.ClientKey) + path, err := ExpandFolder(auth.ClientKey, &configFolder) + if err != nil { + return nil, err + } + keyData, err := os.ReadFile(*path) if err != nil { return nil, fmt.Errorf("failed to load user key '%s': %v", authName, err) } @@ -142,7 +161,7 @@ func CleanLogFiles(config config.Config) (*int, error) { return &deletedFiles, nil } -func ExpandHomeFolder(folder string) (*string, error) { +func ExpandFolder(folder string, basePath *string) (*string, error) { if strings.HasPrefix(folder, "~/") { home, err := os.UserHomeDir() if err != nil { @@ -152,6 +171,19 @@ func ExpandHomeFolder(folder string) (*string, error) { expandedPath := filepath.Join(home, replacedHome) return &expandedPath, nil } + if filepath.IsAbs(folder) == false { + if basePath != nil { + path := filepath.Join(*basePath, folder) + return &path, nil + } else { + path, err := filepath.Abs(folder) + if err != nil { + return nil, err + } + return &path, nil + } + + } return &folder, nil } @@ -223,10 +255,14 @@ func DetectContainerRuntime(config config.Config) (*orchestatormodels.ContainerR } func GenerateContainerName(config config.Config, scenarioName string, graphNodeName *string) string { + // sleep is needed to avoid the same timestamp to two different containers + // and break all the logic related to the container name timestamp + + time.Sleep(1 * time.Nanosecond) if graphNodeName != nil { - return fmt.Sprintf("%s-%s-%d", config.ContainerPrefix, *graphNodeName, time.Now().Unix()) + return fmt.Sprintf("%s-%s-%d", config.ContainerPrefix, *graphNodeName, time.Now().Nanosecond()) } - return fmt.Sprintf("%s-%s-%d", config.ContainerPrefix, scenarioName, time.Now().Unix()) + return fmt.Sprintf("%s-%s-%d", config.ContainerPrefix, scenarioName, time.Now().Nanosecond()) } func EnvironmentFromString(s string) orchestatormodels.ContainerRuntime { @@ -241,25 +277,3 @@ func EnvironmentFromString(s string) orchestatormodels.ContainerRuntime { panic(fmt.Sprintf("unknown container environment: %q", s)) } } - -func ErrorToStatusCode(err error, conf config.Config) *int32 { - if err == nil { - return nil - } - if strings.Contains(err.Error(), conf.ContainerExitStatusPrefix) { - exit := strings.Split(err.Error(), " ") - if len(exit) == 2 { - status, err := strconv.ParseInt(exit[1], 10, 32) - if err != nil { - return nil - } - status32 := int32(status) - return &status32 - } - } - return nil -} - -func StatusCodeToError(statusCode int32, conf config.Config) error { - return fmt.Errorf("%s %d", conf.ContainerExitStatusPrefix, statusCode) -} diff --git a/pkg/scenario_orchestrator/utils/utils_test.go b/pkg/scenario_orchestrator/utils/utils_test.go index d2c22de..6d1ffe5 100644 --- a/pkg/scenario_orchestrator/utils/utils_test.go +++ b/pkg/scenario_orchestrator/utils/utils_test.go @@ -1,9 +1,256 @@ package utils import ( + "fmt" + krknctlconfig "github.com/krkn-chaos/krknctl/internal/config" + "github.com/krkn-chaos/krknctl/pkg/scenario_orchestrator/models" + "github.com/stretchr/testify/assert" + "io/fs" + "k8s.io/client-go/tools/clientcmd" + "os" + "path/filepath" + "regexp" + "runtime" "testing" ) func TestFlatten(t *testing.T) { + conf, err := krknctlconfig.LoadConfig() + assert.Nil(t, err) + + not_existing_kubeconfig := "tests/data/not_existing" + flat_kubeconfig_path, err := PrepareKubeconfig(¬_existing_kubeconfig, conf) + assert.Nil(t, err) + assert.Nil(t, flat_kubeconfig_path) + + wrong_kubeconfig := "tests/data/not_existing" + wrong_kubeconfig_path, err := PrepareKubeconfig(&wrong_kubeconfig, conf) + assert.Nil(t, err) + assert.Nil(t, wrong_kubeconfig_path) + + kubeconfig_path := "../../../tests/data/kubeconfig" + flat_kubeconfig_path, err = PrepareKubeconfig(&kubeconfig_path, conf) + assert.Nil(t, err) + assert.NotNil(t, flat_kubeconfig_path) + + kubeconfig, err := clientcmd.LoadFromFile(*flat_kubeconfig_path) + assert.Nil(t, err) + assert.NotNil(t, kubeconfig) + + assert.NotEmpty(t, kubeconfig.Clusters) + ca, err := os.ReadFile("../../../tests/data/test_ca") + cert, err := os.ReadFile("../../../tests/data/test_cert") + key, err := os.ReadFile("../../../tests/data/test_key") + assert.Nil(t, err) + + for _, v := range kubeconfig.Clusters { + assert.NotEmpty(t, v.CertificateAuthorityData) + assert.Equal(t, ca, v.CertificateAuthorityData) + } + + for _, auth := range kubeconfig.AuthInfos { + assert.NotEmpty(t, auth.ClientCertificateData) + assert.Equal(t, cert, auth.ClientCertificateData) + assert.NotEmpty(t, auth.ClientKeyData) + assert.Equal(t, key, auth.ClientKeyData) + } + +} + +func TestExpandFolder(t *testing.T) { + + currentfolder, err := os.Getwd() + parentfolder := filepath.Dir(currentfolder) + grandParentFolder := filepath.Dir(parentfolder) + baseFolder := "/usr/local/bin" + homeFolder, err := os.UserHomeDir() + assert.Nil(t, err) + expectedHomeFolder := filepath.Join(homeFolder, "tests", "data") + expectedParentFolder := filepath.Join(parentfolder, "krknctl") + expectedGrandParentFolder := filepath.Join(grandParentFolder, "krknctl") + expectedCurrentFolder := filepath.Join(currentfolder, "krknctl") + expectedParentFolderWithBase := "/usr/local/krknctl" + + resultParentFolder, err := ExpandFolder("../krknctl", nil) + assert.Nil(t, err) + assert.Equal(t, expectedParentFolder, *resultParentFolder) + + resultGrandParentFolder, err := ExpandFolder("../../krknctl", nil) + assert.Nil(t, err) + assert.Equal(t, expectedGrandParentFolder, *resultGrandParentFolder) + + resultCurrentFolder, err := ExpandFolder("./krknctl", nil) + assert.Nil(t, err) + assert.Equal(t, expectedCurrentFolder, *resultCurrentFolder) + + resultHomeFolder, err := ExpandFolder("~/tests/data", nil) + assert.Nil(t, err) + assert.Equal(t, expectedHomeFolder, *resultHomeFolder) + + resultSameAbsoluteFolder, err := ExpandFolder(currentfolder, nil) + assert.Nil(t, err) + assert.Equal(t, currentfolder, *resultSameAbsoluteFolder) + + resultParentFolderWithBase, err := ExpandFolder("../krknctl", &baseFolder) + assert.Nil(t, err) + assert.Equal(t, expectedParentFolderWithBase, *resultParentFolderWithBase) + +} + +func TestCleanKubeconfigFiles(t *testing.T) { + cwd, err := os.Getwd() + assert.Nil(t, err) + conf, err := krknctlconfig.LoadConfig() + assert.Nil(t, err) + kubeconfig_path := "../../../tests/data/kubeconfig" + flat_kubeconfig_path, err := PrepareKubeconfig(&kubeconfig_path, conf) + assert.Nil(t, err) + assert.NotNil(t, flat_kubeconfig_path) + root := os.DirFS(cwd) + mdFiles, err := fs.Glob(root, "krknctl-kubeconfig-*") + assert.Nil(t, err) + assert.Greater(t, len(mdFiles), 0) + num, err := CleanKubeconfigFiles(conf) + assert.Nil(t, err) + assert.Equal(t, *num, len(mdFiles)) + + mdFiles, err = fs.Glob(root, "krkctl-kubeconifig-*") + assert.Nil(t, err) + assert.Equal(t, len(mdFiles), 0) +} + +func TestCleanLogFiles(t *testing.T) { + cwd, err := os.Getwd() + assert.Nil(t, err) + conf, err := krknctlconfig.LoadConfig() + assert.Nil(t, err) + nodename1 := "dummy-random" + containername1 := GenerateContainerName(conf, "dummy-scenario", &nodename1) + containername2 := GenerateContainerName(conf, "dummy-scenario", nil) + filename1 := fmt.Sprintf("%s.log", containername1) + filename2 := fmt.Sprintf("%s.log", containername2) + // this one will be kept + filename3 := "random-log.log" + + file, err := os.Create(filename1) + file.Close() + file, err = os.Create(filename2) + file.Close() + file, err = os.Create(filename3) + file.Close() + + root := os.DirFS(cwd) + mdFiles, err := fs.Glob(root, "*.log") + assert.GreaterOrEqual(t, len(mdFiles), 3) + num, err := CleanLogFiles(conf) + assert.Nil(t, err) + assert.Equal(t, *num, len(mdFiles)-1) + +} + +func TestGetSocketByContainerEnvironment(t *testing.T) { + conf, err := krknctlconfig.LoadConfig() + uid := 1337 + root := 0 + assert.Nil(t, err) + if runtime.GOOS == "linux" { + + // not testing nil because might be root or user depending on the test environment + socket, err := GetSocketByContainerEnvironment(models.Podman, conf, &uid) + assert.Nil(t, err) + assert.Equal(t, *socket, fmt.Sprintf(conf.PodmanLinuxSocketTemplate, uid)) + socket, err = GetSocketByContainerEnvironment(models.Podman, conf, &root) + assert.Nil(t, err) + assert.Equal(t, *socket, conf.PodmanSocketRoot) + + socket, err = GetSocketByContainerEnvironment(models.Docker, conf, nil) + assert.Nil(t, err) + assert.Equal(t, *socket, conf.DockerSocketRoot) + socket, err = GetSocketByContainerEnvironment(models.Docker, conf, &uid) + assert.Nil(t, err) + assert.Equal(t, *socket, conf.DockerSocketRoot) + socket, err = GetSocketByContainerEnvironment(models.Docker, conf, &root) + assert.Nil(t, err) + assert.Equal(t, *socket, conf.DockerSocketRoot) + + socket, err = GetSocketByContainerEnvironment(models.Both, conf, &root) + assert.NotNil(t, err) + + } else if runtime.GOOS == "darwin" { + home, err := os.UserHomeDir() + assert.Nil(t, err) + + socket, err := GetSocketByContainerEnvironment(models.Podman, conf, &uid) + assert.Nil(t, err) + assert.Equal(t, *socket, fmt.Sprintf(conf.PodmanDarwinSocketTemplate, home)) + + socket, err = GetSocketByContainerEnvironment(models.Podman, conf, &root) + assert.Nil(t, err) + assert.Equal(t, *socket, fmt.Sprintf(conf.PodmanDarwinSocketTemplate, home)) + + socket, err = GetSocketByContainerEnvironment(models.Docker, conf, &uid) + assert.Nil(t, err) + assert.Equal(t, *socket, conf.DockerSocketRoot) + + socket, err = GetSocketByContainerEnvironment(models.Docker, conf, &root) + assert.Nil(t, err) + assert.Equal(t, *socket, conf.DockerSocketRoot) + + socket, err = GetSocketByContainerEnvironment(models.Both, conf, &root) + assert.NotNil(t, err) + + } else { + assert.False(t, true, "😱") + } +} + +func TestDetectContainerRuntime(t *testing.T) { + // **** WARNING + // Works only on Github Action where both the platforms are installed + // or on systems where both the platform are installed + conf, err := krknctlconfig.LoadConfig() + assert.Nil(t, err) + + cont, err := DetectContainerRuntime(conf) + assert.Nil(t, err) + assert.Equal(t, *cont, models.Both) +} + +func TestGenerateContainerName(t *testing.T) { + conf, err := krknctlconfig.LoadConfig() + assert.Nil(t, err) + nodename := "dummy-random" + scenarioname := "dummy-scenario" + renode, err := regexp.Compile(fmt.Sprintf("%s-%s-[0-9]+", conf.ContainerPrefix, nodename)) + assert.Nil(t, err) + rescenario, err := regexp.Compile(fmt.Sprintf("%s-%s-[0-9]+", conf.ContainerPrefix, scenarioname)) + assert.Nil(t, err) + + containerscenario := GenerateContainerName(conf, scenarioname, nil) + assert.True(t, rescenario.MatchString(containerscenario)) + + containernode := GenerateContainerName(conf, scenarioname, &nodename) + assert.True(t, renode.MatchString(containernode)) + +} + +func TestEnvironmentFromString(t *testing.T) { + + defer func() { + if r := recover(); r == nil { + assert.Fail(t, "unknown string did not panic") + } + }() + + podman := EnvironmentFromString("podman") + assert.Equal(t, podman, models.Podman) + + docker := EnvironmentFromString("docker") + assert.Equal(t, docker, models.Docker) + + both := EnvironmentFromString("both") + assert.Equal(t, both, models.Both) + + EnvironmentFromString("unknown") } diff --git a/tests/containerfiles/dummyscenario/run.sh b/tests/containerfiles/dummyscenario/run.sh index 8e512d8..7714157 100755 --- a/tests/containerfiles/dummyscenario/run.sh +++ b/tests/containerfiles/dummyscenario/run.sh @@ -1,5 +1,5 @@ +EXIT_STATUS=${EXIT_STATUS:=0} [ -z $END ] && echo '$END variable not exported' && exit 1 -[ -z $EXIT_STATUS ] && echo '$EXIT_STATUS variable not exported' && exit 1 if [[ $DEBUG == 'True' ]]; then echo "DEBUG MODE ON!" fi diff --git a/tests/data/kubeconfig b/tests/data/kubeconfig new file mode 100644 index 0000000..26ce946 --- /dev/null +++ b/tests/data/kubeconfig @@ -0,0 +1,32 @@ +apiVersion: v1 +clusters: +- cluster: + certificate-authority: ./test_ca + extensions: + - extension: + last-update: Thu, 28 Nov 2024 11:50:15 CET + provider: minikube.sigs.k8s.io + version: v1.34.0 + name: cluster_info + server: https://127.0.0.1:53279 + name: minikube +contexts: +- context: + cluster: minikube + extensions: + - extension: + last-update: Thu, 28 Nov 2024 11:50:15 CET + provider: minikube.sigs.k8s.io + version: v1.34.0 + name: context_info + namespace: default + user: minikube + name: minikube +current-context: minikube +kind: Config +preferences: {} +users: +- name: minikube + user: + client-certificate: ./test_cert + client-key: ./test_key \ No newline at end of file diff --git a/tests/data/test_ca b/tests/data/test_ca new file mode 100644 index 0000000..580fa76 --- /dev/null +++ b/tests/data/test_ca @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwptaW5p +a3ViZUNBMB4XDTI0MTAyMTA4MTIzNloXDTM0MTAyMDA4MTIzNlowFTETMBEGA1UE +AxMKbWluaWt1YmVDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANG4 +wLzUuP8RrpWwl8hJVfyTE2HDg0/bn5lSIeDQ2khAcdPrYdF5vpUJzr28qxwAH1rP +ipxzW8WaUJ9psUV82WU6Ij104ipwojiC28qGEPEcbOBfqYKJ1vnUT0BHXXvrPZJ3 +PDrcncnsqAOcD4F1HnYIVz7g0Drh49NUtdmMkYPhXM4uDPtJBacMGlXlqVU07AE/ +5Dp1n6zdliCgooXOmEb8u97ZRcVppqUa9/E1KdycoafB6yVLxe5hmCU2Yfy0QF1L +xu39UpJZ7VWz+aUAdQ0q7IA5SXmuWzjFKc8ovUzzrkJ8hG+0+/2dnmXuQNdX9HE7 +J1qdFMncRmp1UtVN/i0CAwEAAaNhMF8wDgYDVR0PAQH/BAQDAgKkMB0GA1UdJQQW +MBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBRlLh2lkN4vyZ2zcYqjG45Ig2A3WDANBgkqhkiG9w0BAQsFAAOCAQEAD66Q2xY0 +oWAw35lM1C+XEWBD9+ujengEYC9nlQRrqGOzupUoHCsAthwH86WmynB3y8QjqC8y +1uwtWUuY6WAK0NGFuXdgPKaijrPhWwOy8Bz7GmDMNXxegEApZP4gRJ9LsUwE1XHf +BSAdzeKag4XmuvUeMiwVV4TEkyQQ2TqGjZD2uZqTiuBGF/+C4+6+oea86pNwYbr0 +amfaB97io7028YkBJNJhm0rToKqU3/hk/He0WtKs2YHDA6TYn8BFqYpcET8iJWSf +M959M3EjOIRTaPCdkMFVgmSqWkRaZWSuZTNpMJdyRBPk/R3qhyCaIGYFxd/vv0mq +6cBGVBSkJazsqw== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/tests/data/test_cert b/tests/data/test_cert new file mode 100644 index 0000000..2734c04 --- /dev/null +++ b/tests/data/test_cert @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDITCCAgmgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwptaW5p +a3ViZUNBMB4XDTI0MTAyODA5MDMxNloXDTI3MTAyOTA5MDMxNlowMTEXMBUGA1UE +ChMOc3lzdGVtOm1hc3RlcnMxFjAUBgNVBAMTDW1pbmlrdWJlLXVzZXIwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRur0yLzvOiQQDhub8Ij2mliAasfcp +jt6a9J2dX9OKJ6DMNIScO8bK5LTpYFVtOrZVz48Y1M8u1pPwMKBGVDm1hdW7lRLF +w4KahO5BpOEvsemFJnDOmOQ6WP5jpNtFD8XLSFiikG/BLPWm+lj/HmP54z65p6vD +5TxNJNVIx5dbv+6K94viVh+Y6b/ceCeL1jfrh6g75G3Q75FPwGjmCVK4nVDLVJgJ +reaeTvwdjrMzD8fOtAwui63Ye5yPwIGa28b7sdY9L2Gf9Ytz/xQEVvdy39VdQ5SM +sSCm/kzs1oL3gs2CbcIcdr4ErjSOeDU+5WuSPwkoW9MAKV4jX3fHWhZfAgMBAAGj +YDBeMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUH +AwIwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBRlLh2lkN4vyZ2zcYqjG45Ig2A3 +WDANBgkqhkiG9w0BAQsFAAOCAQEAghjyC9PPrVGqvKRUlJYPQm2aXOh0eCZcvD7G +VFYn7cvwbesEhgaSZPmbVkawPe6bkY1qjoE1SiwGcn1gGx6CRoLRha6qhJ0CN3kn +bMMaGXUMyTOkoD5IwTkf+hEWZpp0s2ZA1LlARFhwca4xJvLN6E0asvuUWg4NRknc +x6Bn83Po/sDK+8DM940EN3qtVdG6bbblxGbiv0aCS0zXcq6xsuRtyFTJLrKmAWXh +/zFPeFglp2naeF9JEJiLALJsxizHo9yIrVpJD6RU/+ZO+zNWKHN8JMlPHEB9At2e +8PHsXMnx/SwdfvuevYgscYGehYLyqzo/G0kCWindpfqlNUT8bg== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/tests/data/test_key b/tests/data/test_key new file mode 100644 index 0000000..eeba295 --- /dev/null +++ b/tests/data/test_key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA0bq9Mi87zokEA4bm/CI9ppYgGrH3KY7emvSdnV/TiiegzDSE +nDvGyuS06WBVbTq2Vc+PGNTPLtaT8DCgRlQ5tYXVu5USxcOCmoTuQaThL7HphSZw +zpjkOlj+Y6TbRQ/Fy0hYopBvwSz1pvpY/x5j+eM+uaerw+U8TSTVSMeXW7/uiveL +4lYfmOm/3Hgni9Y364eoO+Rt0O+RT8Bo5glSuJ1Qy1SYCa3mnk78HY6zMw/HzrQM +Lout2Hucj8CBmtvG+7HWPS9hn/WLc/8UBFb3ct/VXUOUjLEgpv5M7NaC94LNgm3C +HHa+BK40jng1PuVrkj8JKFvTACleI193x1oWXwIDAQABAoIBAGvnPavyLT0HtW7z +GyghncJ1frL9WQKipNjofacYREfSN6KYapnPD2oX3RQtIgZ+rIzdquvFoYqhj5+G +BQ/qCX7hCqPmALCK9Ej3l3VilRDq4hBFRMimVNXIL6moib+wa704zZFl6nli3kg4 +iU1In3tTdVQjdfXlnO67wpgdSDxFRsyuDgCzjR6p4DMLO0W6TwA9qXm7+3ONn2Tx +ISSbd5XOwY+D33+sthvuTa67wPaBgC6+MKT/Peuz8boR8JLBwMcrEl4ndljD4154 +0jxHLNKh2NCVNA+H6qIKs5U7yBNKZ4kZbMR7HT8XfAiJaKhj0VU81OhZV39Ml14x +xUWARwECgYEA6pDeSO0cDa0dajwBqGS9wcnxfJl6xH92hLhw24Fc69pPYq1guJlS +MQBJQbK8Pmc87buSi8auOTYNvxfGdNY6+fQxF2SjP39yJIEcL8xz+lU4lgojNe3Z +9JAtVH+VG06PPxrU1bgLxYgLYcdW+dLu7iwaWUDWUrUzWZsi2yLPCR8CgYEA5OTh +Ctguh+uX3VN6/S3TWZwrDyrlxc7znQoahsZSciA0JrVlBaHMWgh25zg7EP/60/+8 +sc7VdiFvgmfOuQyWFX/MO4TKHR1DEDIJzf6hH8D13PRbsQ2RaYMHKu6LHfXMQHcM +VCKjahzn3CWNjRokylEoHibqfwcRuY8bWJr3CsECgYEAj7o2yh6nquWheX/NUD5y +W3T/CGcO56pml8pgNNAefNInBILSGiqwRyAywxPe7qnZlp3xnL4f8SRi5e2Oh/bg +6lmrXvcmZHkWGrIV8F/pzME9TApoKtpUS9uwOu92EOZhNbyeH1qHtAC5YK+BZtDN +4JibiIcHDGTFUymRAQ9iJucCgYAZ2if4u5X10Awk+UrI0aYvVs4eNnAhOVCWig+Y +7UlejniVbqNsUWvtN0uGrfkt4FuKGjZLttqxLvGTPvpAOEWzQ+3jQwo445cxexVU +aM/18CtUu1yn0Kp9ykjC9pJL3fklxsxjrE3crEsbuDoWl79UAnqPfUG6+ydrV9h0 +13vTgQKBgQCJPKjV6/EoD5PdpYEQ/9zJ6jicMey1mZDhuVGbeUkoCvpguQkty7F5 +6dkHQy/Y/3xarJOxn+f1yVcvGcRmhB67CQiGXUmDpk+pRg9x3Cr51hF36W/QmONl +qAnJ0YSlWlsb4zmpJ14V2BShyeglM6tqF9GCdZbfrA1HtYtp3gvkaw== +-----END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/tests/data/wrong_kubeconfig b/tests/data/wrong_kubeconfig new file mode 100644 index 0000000..212285f --- /dev/null +++ b/tests/data/wrong_kubeconfig @@ -0,0 +1,33 @@ + +{apiVersion: v1 +clusters: +- cluster: + certificate-authority: ./test_ca + extensions:} + - extension: + last-update: Thu, 28 Nov 2024 11:50:15 CET + {provider: minikube.sigs.k8s.io + version: v1.34.0} + name: cluster_info + server: https://127.0.0.1:53279 + {name: minikube +contexts: +- context: + cluster: minikube + extensions:}# + - extension:!! + last-update: Thu, 28 Nov 2024 11:50:15 CET + provider: minikube.sigs.k8s.io + version: v1.34.0 + name: context_info + namespace: default + user: minikube + name: minikube +current-context: minikube +kind: Config +preferences: {} +users: +- name: minikube + user: + client-certificate: ./test_cert + client-key: ./test_key \ No newline at end of file