From 24cdc5cb3176ccb5e849814cf9e837823bb40ffe Mon Sep 17 00:00:00 2001 From: Kim Oliver Drechsel Date: Sun, 4 Aug 2024 14:11:20 +0200 Subject: [PATCH] feat: add tests --- .github/workflows/test.yaml | 26 ++++ Makefile | 2 +- internal/config/deploy_config.go | 6 +- internal/config/deploy_config_test.go | 112 ++++++++++++++++++ internal/docker/compose_test.go | 164 ++++++++++++++++++++++++++ 5 files changed, 308 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/test.yaml create mode 100644 internal/config/deploy_config_test.go create mode 100644 internal/docker/compose_test.go diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..aceea3f --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,26 @@ +name: Tests + +on: + workflow_dispatch: + push: + paths-ignore: + - 'README.md' + - 'docs/**' + +permissions: + contents: read + +jobs: + test: + name: Run Acceptance Tests + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + with: + go-version-file: 'go.mod' + cache: true + - run: go mod download + - run: go test -v -cover ./internal/... + timeout-minutes: 5 diff --git a/Makefile b/Makefile index ca2cc2d..7d9c93d 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ BINARY_NAME=docker-compose-webhook test: @echo "Running tests..." - @go test -v ./... -timeout 30m + @go test -p 1 -v ./... -timeout 5m build: mkdir -p $(BINARY_DIR) diff --git a/internal/config/deploy_config.go b/internal/config/deploy_config.go index 19567b0..ad003fe 100644 --- a/internal/config/deploy_config.go +++ b/internal/config/deploy_config.go @@ -74,7 +74,11 @@ func GetDeployConfig(repoDir, name string) (*DeployConfig, error) { for _, configFile := range DefaultDeploymentConfigFileNames { config, err := getDeployConfigFile(repoDir, files, configFile) if err != nil { - continue + if errors.Is(err, ErrConfigFileNotFound) { + continue + } else { + return nil, err + } } if config != nil { diff --git a/internal/config/deploy_config_test.go b/internal/config/deploy_config_test.go new file mode 100644 index 0000000..9b59231 --- /dev/null +++ b/internal/config/deploy_config_test.go @@ -0,0 +1,112 @@ +package config + +import ( + "fmt" + "os" + "path/filepath" + "reflect" + "testing" +) + +var projectName = "test" + +func createTestFile(fileName string, content string) error { + err := os.WriteFile(fileName, []byte(content), 0o644) + if err != nil { + return err + } + + return nil +} + +func createTmpDir(t *testing.T) string { + dirName, err := os.MkdirTemp(os.TempDir(), "test-*") + if err != nil { + t.Fatal(err) + } + + return dirName +} + +func TestGetDeployConfig(t *testing.T) { + fileName := ".compose-deploy.yaml" + reference := "refs/heads/test" + workingDirectory := "/test" + composeFiles := []string{"test.compose.yaml"} + + deployConfig := fmt.Sprintf(`name: %s +reference: %s +working_dir: %s +compose_files: + - %s +`, projectName, reference, workingDirectory, composeFiles[0]) + + dirName := createTmpDir(t) + defer func(path string) { + err := os.RemoveAll(path) + if err != nil { + t.Fatal(err) + } + }(dirName) + + filePath := filepath.Join(dirName, fileName) + + err := createTestFile(filePath, deployConfig) + if err != nil { + t.Fatal(err) + } + + config, err := GetDeployConfig(dirName, projectName) + if err != nil { + t.Fatal(err) + } + + if config.Name != projectName { + t.Errorf("expected name to be %v, got %s", projectName, config.Name) + } + + if config.Reference != reference { + t.Errorf("expected reference to be %v, got %s", reference, config.Reference) + } + + if config.WorkingDirectory != workingDirectory { + t.Errorf("expected working directory to be '%v', got '%s'", workingDirectory, config.WorkingDirectory) + } + + if !reflect.DeepEqual(config.ComposeFiles, composeFiles) { + t.Errorf("expected compose files to be %v, got %v", composeFiles, config.ComposeFiles) + } +} + +func TestGetDeployConfig_Default(t *testing.T) { + defaultConfig := DefaultDeployConfig(projectName) + + dirName := createTmpDir(t) + defer func(path string) { + err := os.RemoveAll(path) + if err != nil { + t.Fatal(err) + } + }(dirName) + + config, err := GetDeployConfig(dirName, projectName) + if err != nil { + t.Fatal(err) + } + + if config.Name != projectName { + t.Errorf("expected name to be %v, got %s", projectName, config.Name) + } + + if config.Reference != defaultConfig.Reference { + t.Errorf("expected reference to be %s, got %s", defaultConfig.Reference, config.Reference) + } + + if config.WorkingDirectory != defaultConfig.WorkingDirectory { + t.Errorf("expected working directory to be %s, got %s", defaultConfig.WorkingDirectory, config.WorkingDirectory) + } + + if !reflect.DeepEqual(config.ComposeFiles, defaultConfig.ComposeFiles) { + t.Errorf("expected compose files to be %v, got %v", defaultConfig.ComposeFiles, config.ComposeFiles) + } +} diff --git a/internal/docker/compose_test.go b/internal/docker/compose_test.go new file mode 100644 index 0000000..4fe8f20 --- /dev/null +++ b/internal/docker/compose_test.go @@ -0,0 +1,164 @@ +package docker + +import ( + "context" + "fmt" + "os" + "path/filepath" + "testing" + + "github.com/docker/compose/v2/pkg/api" + "github.com/docker/compose/v2/pkg/compose" + "github.com/kimdre/docker-compose-webhook/internal/config" +) + +func createTmpDir(t *testing.T) string { + dirName, err := os.MkdirTemp(os.TempDir(), "test-*") + if err != nil { + t.Fatal(err) + } + + return dirName +} + +func createComposeFile(t *testing.T, filePath, content string) { + err := os.WriteFile(filePath, []byte(content), 0o644) + if err != nil { + t.Fatal(err) + } +} + +func createTestFile(fileName string, content string) error { + err := os.WriteFile(fileName, []byte(content), 0o644) + if err != nil { + return err + } + + return nil +} + +var ( + projectName = "test" + composeContents = `services: + test: + image: nginx:latest + environment: + TZ: Europe/Berlin +` +) + +func TestVerifySocketConnection(t *testing.T) { + err := VerifySocketConnection() + if err != nil { + t.Fatal(err) + } +} + +func TestLoadCompose(t *testing.T) { + ctx := context.Background() + + dirName := createTmpDir(t) + defer func(path string) { + err := os.RemoveAll(path) + if err != nil { + t.Fatal(err) + } + }(dirName) + + filePath := filepath.Join(dirName, "test.compose.yaml") + + t.Log("Load compose file") + createComposeFile(t, filePath, composeContents) + + project, err := LoadCompose(ctx, dirName, projectName, []string{filePath}) + if err != nil { + t.Fatal(err) + } + + if len(project.Services) != 1 { + t.Fatalf("expected 1 service, got %d", len(project.Services)) + } +} + +func TestDeployCompose(t *testing.T) { + t.Log("Verify socket connection") + + err := VerifySocketConnection() + if err != nil { + t.Fatal(err) + } + + ctx := context.Background() + + dirName := createTmpDir(t) + defer func(path string) { + err := os.RemoveAll(path) + if err != nil { + t.Fatal(err) + } + }(dirName) + + filePath := filepath.Join(dirName, "test.compose.yaml") + + t.Log("Load compose file") + createComposeFile(t, filePath, composeContents) + + project, err := LoadCompose(ctx, dirName, projectName, []string{filePath}) + if err != nil { + t.Fatal(err) + } + + t.Log("Deploy compose") + + dockerCli, err := CreateDockerCli() + if err != nil { + t.Fatal(err) + } + + fileName := ".compose-deploy.yaml" + reference := "refs/heads/test" + workingDirectory := "/test" + composeFiles := []string{"test.compose.yaml"} + + deployConfig := fmt.Sprintf(`name: %s +reference: %s +working_dir: %s +compose_files: + - %s +`, projectName, reference, workingDirectory, composeFiles[0]) + + filePath = filepath.Join(dirName, fileName) + + err = createTestFile(filePath, deployConfig) + if err != nil { + t.Fatal(err) + } + + deployConf, err := config.GetDeployConfig(dirName, projectName) + if err != nil { + t.Fatal(err) + } + + service := compose.NewComposeService(dockerCli) + + // Remove test container after test + defer func() { + downOpts := api.DownOptions{ + RemoveOrphans: true, + Images: "all", + Volumes: true, + } + + t.Log("Remove test container") + + err = service.Down(ctx, project.Name, downOpts) + if err != nil { + t.Fatal(err) + } + }() + + err = DeployCompose(ctx, dockerCli, project, deployConf) + if err != nil { + t.Fatal(err) + } +}