diff --git a/src/helm/helm_test.go b/src/helm/helm_test.go new file mode 100644 index 0000000..3f97030 --- /dev/null +++ b/src/helm/helm_test.go @@ -0,0 +1,17 @@ +package helm + + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestHelm(t *testing.T) { + cmd := HelmCommand{} + cmd.New() + + assert.NotNilf(t, cmd.Exec, "TestHelm %s", "New") + + cmd.Exec("pwd") +} diff --git a/src/kubectl/context.go b/src/kubectl/context.go index 579ef72..554e719 100644 --- a/src/kubectl/context.go +++ b/src/kubectl/context.go @@ -4,15 +4,11 @@ import ( "fmt" "strings" "errors" - "os/exec" "encoding/json" + log "oc-deploy/log_wrapper" ) -// type KubeContext struct { -// Bin string // Chemin vers le binaire -// } - type kubeConfig struct { CurrentContext string `json:"current-context"` @@ -43,7 +39,7 @@ type kubeConfigClusters struct { func (this KubectlCommand) GetCurrentContext() (string, error) { bin := this.Bin - msg := fmt.Sprintf("%s get config current-context", bin) + msg := fmt.Sprintf("%s config current-context", bin) log.Log().Debug().Msg(msg) cmd_args := strings.Split(msg, " ") @@ -56,8 +52,7 @@ func (this KubectlCommand) GetCurrentContext() (string, error) { return res, err } -// Current Context -// namespace, server +// currentContext, currentNamespace, currentServer func (this KubectlCommand) GetContext() (string, string, string, error) { bin := this.Bin @@ -101,9 +96,14 @@ func (this KubectlCommand) GetContext() (string, string, string, error) { func (this KubectlCommand) UseContext(newContext string) (error) { - cmd := exec.Command(this.Bin, "config", "use-context", newContext) - stdout, err := cmd.CombinedOutput() + bin := this.Bin + msg := fmt.Sprintf("%s config use-context %s", bin, newContext) + log.Log().Debug().Msg(msg) + + cmd_args := strings.Split(msg, " ") + cmd := this.Exec(cmd_args[0], cmd_args[1:]...) + stdout, err := cmd.CombinedOutput() if err != nil { log.Log().Debug().Msg(string(stdout)) return errors.New(string(stdout)) diff --git a/src/kubectl/context_test.go b/src/kubectl/context_test.go new file mode 100644 index 0000000..d30d74c --- /dev/null +++ b/src/kubectl/context_test.go @@ -0,0 +1,86 @@ +package kubectl + + +import ( + "os" + "path/filepath" + "errors" + + "testing" + + "github.com/stretchr/testify/assert" +) + +var MOCK_ENABLE = true + +func TestKubectCurrentContext(t *testing.T) { + + cmd := getCmdKubectl(MOCK_ENABLE, "minikube") + + res, err := cmd.GetCurrentContext() + + assert.Nilf(t, err, "error message %s", err) + assert.Equal(t, "minikube", res, "TestKubectCurrentContext error") +} + +func TestKubectContext(t *testing.T) { + + fileName := filepath.Join(TEST_SRC_DIR, "context.json") + cmd_json, _ := os.ReadFile(fileName) + + cmd := getCmdKubectl(MOCK_ENABLE, string(cmd_json)) + + currentContext, currentNamespace, currentServer, err := cmd.GetContext() + + assert.Nilf(t, err, "error message %s", err) + assert.Equal(t, "minikube", currentContext, "TestKubectContext error") + assert.Equal(t, "default", currentNamespace, "TestKubectContext error") + assert.Equal(t, "https://127.0.0.1:38039", currentServer, "TestKubectContext error") +} + +func TestKubectUseContext(t *testing.T) { + + cmd := getCmdKubectl(MOCK_ENABLE, `Switched to context "minikube".`) + + err := cmd.UseContext("minikube") + + assert.Nilf(t, err, "error message %s", err) +} + +func TestKubectUseContextErr(t *testing.T) { + + error := errors.New("exit 1") + cmd := getCmdKubectlError(MOCK_ENABLE, `error: no context exists with the name: "minikube2"`, error) + + err := cmd.UseContext("minikube2") + + assert.NotNilf(t, err, "error message %s", err) +} + +func TestKubectCheck(t *testing.T) { + + cmd_txt := ` + Kubernetes control plane is running at https://127.0.0.1:38039 +CoreDNS is running at https://127.0.0.1:38039/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy + +To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. +` + // error := errors.New("exit 1") + cmd := getCmdKubectl(MOCK_ENABLE, cmd_txt) + + err := cmd.Check() + + assert.Nilf(t, err, "error message %s", err) +} + +func TestKubectCheckErr(t *testing.T) { + + cmd_txt := "" + + error := errors.New("exit 1") + cmd := getCmdKubectlError(MOCK_ENABLE, cmd_txt, error) + + err := cmd.Check() + + assert.NotNilf(t, err, "error message %s", "TestKubectCheckErr") +} diff --git a/src/kubectl/kubectl_test.go b/src/kubectl/kubectl_test.go new file mode 100644 index 0000000..5eb1a28 --- /dev/null +++ b/src/kubectl/kubectl_test.go @@ -0,0 +1,17 @@ +package kubectl + + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestKubectl(t *testing.T) { + cmd := KubectlCommand{} + cmd.New() + + assert.NotNilf(t, cmd.Exec, "TestKubectl %s", "New") + + cmd.Exec("pwd") +} diff --git a/src/kubectl/main_test.go b/src/kubectl/main_test.go index c93bd3d..bffba13 100644 --- a/src/kubectl/main_test.go +++ b/src/kubectl/main_test.go @@ -30,15 +30,16 @@ type MockCommandExecutor struct { // Used to stub the return of the Output method // Could add other properties depending on testing needs output string + err error } // Implements the commandExecutor interface func (m *MockCommandExecutor) Output() ([]byte, error) { - return []byte(m.output), nil + return []byte(m.output), m.err } func (m *MockCommandExecutor) CombinedOutput() ([]byte, error) { - return []byte(m.output), nil + return []byte(m.output), m.err } // @@ -74,7 +75,26 @@ func getCmdsKubectl(mock bool, outputs map[string]string) (KubectlCommand) { cmd := KubectlCommand{Bin: "mock", Exec: mock} return cmd } else { - bin := filepath.Join(TEST_BIN_DIR, "Kubectl") + bin := filepath.Join(TEST_BIN_DIR, "kubectl") + os.Chmod(bin, 0700) + + cmd := KubectlCommand{Bin: bin} + cmd.New() + return cmd + } +} + +func getCmdKubectlError(mock bool, output string, err error) (KubectlCommand) { + if mock == true { + + mock := func(name string, args ...string) commandExecutor { + return &MockCommandExecutor{output: output, err: err} + } + + cmd := KubectlCommand{Bin: "mock", Exec: mock} + return cmd + } else { + bin := filepath.Join(TEST_BIN_DIR, "kubectl") os.Chmod(bin, 0700) cmd := KubectlCommand{Bin: bin} diff --git a/src/kubectl/object.go b/src/kubectl/object.go index d8994dd..aba7c5e 100644 --- a/src/kubectl/object.go +++ b/src/kubectl/object.go @@ -1,9 +1,9 @@ package kubectl import ( - "fmt" - "time" - "errors" + "fmt" + "time" + "errors" log "oc-deploy/log_wrapper" ) @@ -20,14 +20,14 @@ type getOutput struct { } type getStatusOutput struct { - Replicas int `json:"replicas"` - UnavailableReplicas int `json:"unavailableReplicas"` + Replicas int `json:"replicas"` + UnavailableReplicas int `json:"unavailableReplicas"` } func (this KubectlCommand) Get(data KubectlObject) (map[string]any, error) { - if data.Kind == "Deployment" {return this.getDeployment(data)} - if data.Kind == "StatefulSet" {return this.getStatefulSet(data)} - return make(map[string]any), fmt.Errorf("Kind %s inconnu", data.Kind) + if data.Kind == "Deployment" {return this.getDeployment(data)} + if data.Kind == "StatefulSet" {return this.getStatefulSet(data)} + return make(map[string]any), fmt.Errorf("Kind %s inconnu", data.Kind) } func (this KubectlCommand) Wait(data KubectlObject) (error) { @@ -35,22 +35,22 @@ func (this KubectlCommand) Wait(data KubectlObject) (error) { boucle := 10 sleep := 10000 * time.Millisecond - for _ = range boucle { + for _ = range boucle { - log.Log().Debug().Msg(fmt.Sprintf("Check Deployement %s", data.Name)) + log.Log().Debug().Msg(fmt.Sprintf("Check Deployement %s", data.Name)) - m, err := this.Get(data) - if err != nil { - return err - } - ko := m["UnavailableReplicas"].(int) - if ko == 0 { - return nil - } + m, err := this.Get(data) + if err != nil { + return err + } + ko := m["UnavailableReplicas"].(int) + if ko == 0 { + return nil + } - log.Log().Info().Msg(fmt.Sprintf(" >> %s (Unavailable : %d)...", data.Name, ko)) - time.Sleep(sleep) + log.Log().Info().Msg(fmt.Sprintf(" >> %s (Unavailable : %d)...", data.Name, ko)) + time.Sleep(sleep) - } - return errors.New("Temps d'attente dépassé") + } + return errors.New("Temps d'attente dépassé") } \ No newline at end of file diff --git a/src/log_wrapper/log_wrapper.go b/src/log_wrapper/log_wrapper.go index 1029052..c2f8ecb 100644 --- a/src/log_wrapper/log_wrapper.go +++ b/src/log_wrapper/log_wrapper.go @@ -3,7 +3,9 @@ package log_wrapper // https://github.com/rs/zerolog/issues/150 import ( + "fmt" "os" + "path/filepath" "github.com/rs/zerolog" ) @@ -28,9 +30,11 @@ func Log() *zerolog.Logger { return &mainLogVar } -func InitLog(serverName string) bool { +func InitLog(filename string) bool { - fAll, _ := os.OpenFile("./" + serverName + ".log", os.O_APPEND|os.O_CREATE|os.O_RDWR, 0644) + ficlog := filepath.Join(filename + ".log") + fAll, _ := os.OpenFile(ficlog, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0644) + fmt.Println("ficlog", ficlog) output := zerolog.ConsoleWriter{Out: os.Stdout} writerInfo := zerolog.MultiLevelWriter(output) diff --git a/src/log_wrapper/log_wrapper_test.go b/src/log_wrapper/log_wrapper_test.go new file mode 100644 index 0000000..91e03fd --- /dev/null +++ b/src/log_wrapper/log_wrapper_test.go @@ -0,0 +1,21 @@ +package log_wrapper + +import ( + // "os" + "path/filepath" + // "errors" + + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestLogWrapper(t *testing.T) { + ficlog := filepath.Join(TEST_DEST_DIR, "test") + InitLog(ficlog) + + Log().Info().Msg("KKK") + Log().Error().Msg("KKK") + + assert.FileExists(t, ficlog + ".log", "TestLogWrapper") +} diff --git a/src/log_wrapper/main_test.go b/src/log_wrapper/main_test.go new file mode 100644 index 0000000..68906d4 --- /dev/null +++ b/src/log_wrapper/main_test.go @@ -0,0 +1,21 @@ +package log_wrapper + +import ( + "os" + "testing" +) + +var TEST_DEST_DIR = "../wrk_log" + +func TestMain(m *testing.M) { + folderPath := TEST_DEST_DIR + + os.RemoveAll(folderPath) + os.MkdirAll(folderPath, os.ModePerm) + + // call flag.Parse() here if TestMain uses flags + exitCode := m.Run() + + os.RemoveAll(folderPath) + os.Exit(exitCode) +} diff --git a/test/kubectl/context.json b/test/kubectl/context.json new file mode 100644 index 0000000..d45e66b --- /dev/null +++ b/test/kubectl/context.json @@ -0,0 +1,54 @@ +{ + "kind": "Config", + "apiVersion": "v1", + "preferences": {}, + "clusters": [ + { + "name": "minikube", + "cluster": { + "server": "https://127.0.0.1:38039", + "certificate-authority": "/home/admeju/.minikube/ca.crt", + "extensions": [ + { + "name": "cluster_info", + "extension": { + "last-update": "Tue, 10 Sep 2024 10:32:04 UTC", + "provider": "minikube.sigs.k8s.io", + "version": "v1.33.1" + } + } + ] + } + } + ], + "users": [ + { + "name": "minikube", + "user": { + "client-certificate": "/home/admeju/.minikube/profiles/minikube/client.crt", + "client-key": "/home/admeju/.minikube/profiles/minikube/client.key" + } + } + ], + "contexts": [ + { + "name": "minikube", + "context": { + "cluster": "minikube", + "user": "minikube", + "namespace": "default", + "extensions": [ + { + "name": "context_info", + "extension": { + "last-update": "Tue, 10 Sep 2024 10:32:04 UTC", + "provider": "minikube.sigs.k8s.io", + "version": "v1.33.1" + } + } + ] + } + } + ], + "current-context": "minikube" +}