diff --git a/generator/basic_test.go b/generator/basic_test.go deleted file mode 100644 index 1c649a8..0000000 --- a/generator/basic_test.go +++ /dev/null @@ -1,57 +0,0 @@ -package generator - -import ( - "log" - "os" - "testing" - - "sigs.k8s.io/yaml" -) - -func setup(content string) string { - // write the _compose_file in temporary directory - tmpDir, err := os.MkdirTemp("", "katenary") - if err != nil { - panic(err) - } - os.WriteFile(tmpDir+"/compose.yml", []byte(content), 0o644) - return tmpDir -} - -func teardown(tmpDir string) { - // remove the temporary directory - log.Println("Removing temporary directory: ", tmpDir) - if err := os.RemoveAll(tmpDir); err != nil { - panic(err) - } -} - -func TestGenerate(t *testing.T) { - _compose_file := ` -services: - web: - image: nginx:1.29 -` - tmpDir := setup(_compose_file) - defer teardown(tmpDir) - - currentDir, _ := os.Getwd() - os.Chdir(tmpDir) - defer os.Chdir(currentDir) - - output := _compile_test(t) - - dt := DeploymentTest{} - if err := yaml.Unmarshal([]byte(output), &dt); err != nil { - t.Errorf("Failed to unmarshal the output: %s", err) - } - - if dt.Spec.Replicas != 1 { - t.Errorf("Expected replicas to be 1, got %d", dt.Spec.Replicas) - t.Errorf("Output: %s", output) - } - - if dt.Spec.Template.Spec.Containers[0].Image != "nginx:1.29" { - t.Errorf("Expected image to be nginx:1.29, got %s", dt.Spec.Template.Spec.Containers[0].Image) - } -} diff --git a/generator/configMap_test.go b/generator/configMap_test.go new file mode 100644 index 0000000..29fc922 --- /dev/null +++ b/generator/configMap_test.go @@ -0,0 +1,42 @@ +package generator + +import ( + "os" + "testing" + + v1 "k8s.io/api/core/v1" + "sigs.k8s.io/yaml" +) + +func TestEnvInConfigMap(t *testing.T) { + composeFile := ` +services: + web: + image: nginx:1.29 + environment: + - FOO=bar + - BAR=baz +` + tmpDir := setup(composeFile) + defer teardown(tmpDir) + + currentDir, _ := os.Getwd() + os.Chdir(tmpDir) + defer os.Chdir(currentDir) + + output := _compile_test(t, "-s", "templates/web/configmap.yaml") + configMap := v1.ConfigMap{} + if err := yaml.Unmarshal([]byte(output), &configMap); err != nil { + t.Errorf("Failed to unmarshal the output: %s", err) + } + data := configMap.Data + if len(data) != 2 { + t.Errorf("Expected 2 data, got %d", len(data)) + } + if data["FOO"] != "bar" { + t.Errorf("Expected FOO to be bar, got %s", data["FOO"]) + } + if data["BAR"] != "baz" { + t.Errorf("Expected BAR to be baz, got %s", data["BAR"]) + } +} diff --git a/generator/deployment_test.go b/generator/deployment_test.go new file mode 100644 index 0000000..b6a57e8 --- /dev/null +++ b/generator/deployment_test.go @@ -0,0 +1,69 @@ +package generator + +import ( + "os" + "testing" + + v1 "k8s.io/api/apps/v1" + "sigs.k8s.io/yaml" +) + +func TestGenerate(t *testing.T) { + _compose_file := ` +services: + web: + image: nginx:1.29 +` + tmpDir := setup(_compose_file) + defer teardown(tmpDir) + + currentDir, _ := os.Getwd() + os.Chdir(tmpDir) + defer os.Chdir(currentDir) + + output := _compile_test(t, "-s", "templates/web/deployment.yaml") + + // dt := DeploymentTest{} + dt := v1.Deployment{} + if err := yaml.Unmarshal([]byte(output), &dt); err != nil { + t.Errorf("Failed to unmarshal the output: %s", err) + } + + if *dt.Spec.Replicas != 1 { + t.Errorf("Expected replicas to be 1, got %d", dt.Spec.Replicas) + t.Errorf("Output: %s", output) + } + + if dt.Spec.Template.Spec.Containers[0].Image != "nginx:1.29" { + t.Errorf("Expected image to be nginx:1.29, got %s", dt.Spec.Template.Spec.Containers[0].Image) + } +} + +func TestGenerateWithBoundVolume(t *testing.T) { + _compose_file := ` +services: + web: + image: nginx:1.29 + volumes: + - data:/var/www +volumes: + data: +` + tmpDir := setup(_compose_file) + defer teardown(tmpDir) + + currentDir, _ := os.Getwd() + os.Chdir(tmpDir) + defer os.Chdir(currentDir) + + output := _compile_test(t, "-s", "templates/web/deployment.yaml") + + dt := v1.Deployment{} + if err := yaml.Unmarshal([]byte(output), &dt); err != nil { + t.Errorf("Failed to unmarshal the output: %s", err) + } + + if dt.Spec.Template.Spec.Containers[0].VolumeMounts[0].Name != "data" { + t.Errorf("Expected volume name to be data: %v", dt) + } +} diff --git a/generator/ingress_test.go b/generator/ingress_test.go new file mode 100644 index 0000000..0e05b93 --- /dev/null +++ b/generator/ingress_test.go @@ -0,0 +1,44 @@ +package generator + +import ( + "fmt" + "os" + "testing" + + v1 "k8s.io/api/networking/v1" + "sigs.k8s.io/yaml" +) + +func TestSimpleIngress(t *testing.T) { + composeFile := ` +services: + web: + image: nginx:1.29 + ports: + - 80:80 + - 443:443 + labels: + %singress: |- + host: my.test.tld + port: 80 +` + composeFile = fmt.Sprintf(composeFile, KATENARY_PREFIX) + tmpDir := setup(composeFile) + defer teardown(tmpDir) + + currentDir, _ := os.Getwd() + os.Chdir(tmpDir) + defer os.Chdir(currentDir) + + output := _compile_test(t, "-s", "templates/web/ingress.yaml", "--set", "web.ingress.enabled=true") + ingress := v1.Ingress{} + if err := yaml.Unmarshal([]byte(output), &ingress); err != nil { + t.Errorf("Failed to unmarshal the output: %s", err) + } + if len(ingress.Spec.Rules) != 1 { + t.Errorf("Expected 1 rule, got %d", len(ingress.Spec.Rules)) + } + if ingress.Spec.Rules[0].Host != "my.test.tld" { + t.Errorf("Expected host to be my.test.tld, got %s", ingress.Spec.Rules[0].Host) + } +} diff --git a/generator/secret_test.go b/generator/secret_test.go new file mode 100644 index 0000000..1399a0c --- /dev/null +++ b/generator/secret_test.go @@ -0,0 +1,45 @@ +package generator + +import ( + "fmt" + "os" + "testing" + + v1 "k8s.io/api/core/v1" + "sigs.k8s.io/yaml" +) + +func TestCreateSecretFromEnvironment(t *testing.T) { + composeFile := ` +services: + web: + image: nginx:1.29 + environment: + - FOO=bar + - BAR=baz + labels: + %ssecrets: |- + - BAR +` + composeFile = fmt.Sprintf(composeFile, KATENARY_PREFIX) + tmpDir := setup(composeFile) + defer teardown(tmpDir) + + currentDir, _ := os.Getwd() + os.Chdir(tmpDir) + defer os.Chdir(currentDir) + + output := _compile_test(t, "-s", "templates/web/secret.yaml") + secret := v1.Secret{} + if err := yaml.Unmarshal([]byte(output), &secret); err != nil { + t.Errorf("Failed to unmarshal the output: %s", err) + } + data := secret.Data + if len(data) != 1 { + t.Errorf("Expected 1 data, got %d", len(data)) + } + // v1.Secret.Data is decoded, no problem + if string(data["BAR"]) != "baz" { + t.Errorf("Expected BAR to be baz, got %s", data["BAR"]) + } +} diff --git a/generator/service_test.go b/generator/service_test.go new file mode 100644 index 0000000..4b5ab24 --- /dev/null +++ b/generator/service_test.go @@ -0,0 +1,49 @@ +package generator + +import ( + "os" + "testing" + + v1 "k8s.io/api/core/v1" + "sigs.k8s.io/yaml" +) + +func TestBasicService(t *testing.T) { + composeFile := ` +services: + web: + image: nginx:1.29 + ports: + - 80:80 + - 443:443 + ` + tmpDir := setup(composeFile) + defer teardown(tmpDir) + + currentDir, _ := os.Getwd() + os.Chdir(tmpDir) + defer os.Chdir(currentDir) + + output := _compile_test(t, "-s", "templates/web/service.yaml") + service := v1.Service{} + if err := yaml.Unmarshal([]byte(output), &service); err != nil { + t.Errorf("Failed to unmarshal the output: %s", err) + } + + if len(service.Spec.Ports) != 2 { + t.Errorf("Expected 2 ports, got %d", len(service.Spec.Ports)) + } + + foundPort := 0 + for _, port := range service.Spec.Ports { + if port.Port == 80 && port.TargetPort.StrVal == "http" { + foundPort++ + } + if port.Port == 443 && port.TargetPort.StrVal == "https" { + foundPort++ + } + } + if foundPort != 2 { + t.Errorf("Expected 2 ports, got %d", foundPort) + } +} diff --git a/generator/tools_test.go b/generator/tools_test.go index 02b0f25..7d8caad 100644 --- a/generator/tools_test.go +++ b/generator/tools_test.go @@ -1,29 +1,36 @@ package generator import ( + "log" + "os" "os/exec" "testing" "katenary/parser" ) -type DeploymentTest struct { - Spec struct { - Replicas int `yaml:"replicas"` - Template struct { - Spec struct { - Containers []struct { - Image string `yaml:"image"` - } `yaml:"containers"` - } `yaml:"spec"` - } `yaml:"template"` - } `yaml:"spec"` +func setup(content string) string { + // write the _compose_file in temporary directory + tmpDir, err := os.MkdirTemp("", "katenary") + if err != nil { + panic(err) + } + os.WriteFile(tmpDir+"/compose.yml", []byte(content), 0o644) + return tmpDir } -func _compile_test(t *testing.T) string { +func teardown(tmpDir string) { + // remove the temporary directory + log.Println("Removing temporary directory: ", tmpDir) + if err := os.RemoveAll(tmpDir); err != nil { + panic(err) + } +} + +func _compile_test(t *testing.T, options ...string) string { _, err := parser.Parse(nil, "compose.yml") if err != nil { - t.Errorf("Failed to parse the project: %s", err) + t.Fatalf("Failed to parse the project: %s", err) } force := false @@ -47,15 +54,18 @@ func _compile_test(t *testing.T) string { } // try with helm template var output string - if output, err = helmTemplate(convertOptions); err != nil { + if output, err = helmTemplate(convertOptions, options...); err != nil { t.Errorf("Failed to template the generated chart") - t.Errorf("Output: %s", output) + t.Fatalf("Output %s", output) } return output } -func helmTemplate(options ConvertOptions) (string, error) { - cmd := exec.Command("helm", "template", options.OutputDir) +func helmTemplate(options ConvertOptions, arguments ...string) (string, error) { + args := []string{"template", options.OutputDir} + args = append(args, arguments...) + + cmd := exec.Command("helm", args...) output, err := cmd.CombinedOutput() if err != nil { return string(output), err