Repository: diggerhq/digger
Pull request #174 (2023-04-27 08:59:00)

add some tests


Patch:
diff --git a/pkg/configuration/digger_config.go b/pkg/configuration/digger_config.go
index fa54583b..83bddedc 100644
--- a/pkg/configuration/digger_config.go
+++ b/pkg/configuration/digger_config.go
@@ -199,15 +199,6 @@ func ConvertDiggerYamlToConfig(diggerYaml *DiggerConfigYaml, workingDir string,
 		}
 	}
 
-	projectNames := make(map[string]bool)
-
-	for _, project := range diggerConfig.Projects {
-		if projectNames[project.Name] {
-			return nil, fmt.Errorf("project name '%s' is duplicated", project.Name)
-		}
-		projectNames[project.Name] = true
-	}
-
 	return &diggerConfig, nil
 }
 
diff --git a/pkg/digger/digger.go b/pkg/digger/digger.go
index edf2fd25..b0405022 100644
--- a/pkg/digger/digger.go
+++ b/pkg/digger/digger.go
@@ -375,7 +375,8 @@ func (d DiggerExecutor) Plan(prNumber int) error {
 			}
 			if step.Action == "run" {
 				stdout, stderr, err := d.commandRunner.Run(step.Value)
-				log.Printf("Running %v for **%v**\n%v%v", step.Value, d.lock.LockId(), stdout, stderr)
+				comment := "Running " + step.Value + " for **" + d.lock.LockId() + "**\n" + stdout + stderr
+				d.prManager.PublishComment(prNumber, comment)
 				if err != nil {
 					return fmt.Errorf("error running command: %v", err)
 				}
@@ -455,7 +456,8 @@ func (d DiggerExecutor) Apply(prNumber int) error {
 				}
 				if step.Action == "run" {
 					stdout, stderr, err := d.commandRunner.Run(step.Value)
-					log.Printf("Running %v for **%v**\n%v%v", step.Value, d.lock.LockId(), stdout, stderr)
+					comment := "Running " + step.Value + " for **" + d.lock.LockId() + "**\n" + stdout + stderr
+					d.prManager.PublishComment(prNumber, comment)
 					if err != nil {
 						return fmt.Errorf("error running command: %v", err)
 					}
diff --git a/pkg/terraform/utils.go b/pkg/terraform/utils.go
index bb3dde81..ece62b4f 100644
--- a/pkg/terraform/utils.go
+++ b/pkg/terraform/utils.go
@@ -126,3 +126,22 @@ workflows:
 		log.Fatal(err2)
 	}
 }
+
+func CreateCustomDiggerYmlFile(dir string, diggerYaml string) {
+	f, err := os.Create(dir + "/digger.yml")
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	defer func(f *os.File) {
+		err := f.Close()
+		if err != nil {
+
+		}
+	}(f)
+
+	_, err2 := f.WriteString(diggerYaml)
+	if err2 != nil {
+		log.Fatal(err2)
+	}
+}
diff --git a/pkg/utils/io.go b/pkg/utils/io.go
index d33fe212..52c3cc5b 100644
--- a/pkg/utils/io.go
+++ b/pkg/utils/io.go
@@ -5,7 +5,6 @@ import (
 	"bytes"
 	"io"
 	"io/ioutil"
-	"strings"
 )
 
 type Zip interface {
@@ -21,12 +20,12 @@ func (z *Zipper) GetFileFromZip(zipFile string, filename string) (string, error)
 		return "", err
 	}
 	defer reader.Close()
+
 	for _, file := range reader.File {
 		if file.FileInfo().IsDir() {
 			continue
 		}
-
-		if strings.HasSuffix(file.Name, filename) {
+		if file.Name == filename {
 			rc, err := file.Open()
 			if err != nil {
 				return "", err


Test patch:
diff --git a/pkg/configuration/digger_config_test.go b/pkg/configuration/digger_config_test.go
index 5fe0e794..55930eb4 100644
--- a/pkg/configuration/digger_config_test.go
+++ b/pkg/configuration/digger_config_test.go
@@ -92,6 +92,30 @@ projects:
 	assert.Equal(t, "path/to/module", dg.GetDirectory("dev"))
 }
 
+func TestCustomCommandsConfiguration(t *testing.T) {
+	tempDir, teardown := setUp()
+	defer teardown()
+
+	diggerCfg := `
+projects:
+- name: dev
+  dir: infra/dev
+  workflow: myworkflow
+
+workflows:
+  myworkflow:
+    plan:
+      steps:
+      - run: echo "hello"
+`
+	deleteFile := createFile(path.Join(tempDir, "digger.yaml"), diggerCfg)
+	defer deleteFile()
+
+	dg, err := NewDiggerConfig(tempDir, &FileSystemDirWalker{})
+	assert.NoError(t, err, "expected error to be nil")
+	assert.Equal(t, Step{Action: "run", Value: "echo \"hello\""}, dg.Workflows["myworkflow"].Plan.Steps[0], "parsed struct does not match expected struct")
+}
+
 func TestDefaultValuesForWorkflowConfiguration(t *testing.T) {
 	tempDir, teardown := setUp()
 	defer teardown()
diff --git a/pkg/digger/digger_test.go b/pkg/digger/digger_test.go
index f49fc58b..b1ba052b 100644
--- a/pkg/digger/digger_test.go
+++ b/pkg/digger/digger_test.go
@@ -2,13 +2,12 @@ package digger
 
 import (
 	"digger/pkg/configuration"
+	"github.com/stretchr/testify/assert"
 	"sort"
 	"strconv"
 	"strings"
 	"testing"
 	"time"
-
-	"github.com/stretchr/testify/assert"
 )
 
 type RunInfo struct {
@@ -156,7 +155,7 @@ func TestCorrectCommandExecutionWhenApplying(t *testing.T) {
 
 	commandStrings := allCommandsInOrderWithParams(terraformExecutor, commandRunner, prManager, lock)
 
-	assert.Equal(t, []string{"DownloadLatestPlans 1", "IsMergeable 1", "Lock 1", "Init ", "Apply  plan", "LockId ", "PublishComment 1 Apply for ****\n```terraform\n\n```", "Unlock 1", "Run echo", "LockId "}, commandStrings)
+	assert.Equal(t, []string{"DownloadLatestPlans 1", "IsMergeable 1", "Lock 1", "Init ", "Apply  plan", "LockId ", "PublishComment 1 Apply for ****\n```terraform\n\n```", "Unlock 1", "Run echo", "LockId ", "PublishComment 1 Running echo for ****\n"}, commandStrings)
 }
 
 func TestCorrectCommandExecutionWhenPlanning(t *testing.T) {
@@ -197,7 +196,7 @@ func TestCorrectCommandExecutionWhenPlanning(t *testing.T) {
 
 	commandStrings := allCommandsInOrderWithParams(terraformExecutor, commandRunner, prManager, lock)
 
-	assert.Equal(t, []string{"Lock 1", "Init ", "Plan -out .tfplan", "LockId ", "PublishComment 1 Plan for ****\n```terraform\n\n```", "Run echo", "LockId "}, commandStrings)
+	assert.Equal(t, []string{"Lock 1", "Init ", "Plan -out .tfplan", "LockId ", "PublishComment 1 Plan for ****\n```terraform\n\n```", "Run echo", "LockId ", "PublishComment 1 Running echo for ****\n"}, commandStrings)
 }
 
 func allCommandsInOrderWithParams(terraformExecutor *MockTerraformExecutor, commandRunner *MockCommandRunner, prManager *MockPRManager, lock *MockProjectLock) []string {
diff --git a/pkg/integration/integration_test.go b/pkg/integration/integration_test.go
index abde35c6..b8565165 100644
--- a/pkg/integration/integration_test.go
+++ b/pkg/integration/integration_test.go
@@ -328,6 +328,11 @@ var githubContextUnknownEventJson = `{
 }`
 
 func TestHappyPath(t *testing.T) {
+	/*
+		to be able to run this test following env vars should be configured:
+		AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION, GITHUB_TOKEN
+	*/
+
 	SkipCI(t)
 
 	dir := terraform.CreateTestTerraformProject()
@@ -658,3 +663,153 @@ func TestNonExistentGitHubEvent(t *testing.T) {
 	assert.Error(t, err)
 	assert.Equal(t, "error parsing GitHub context JSON: unknown GitHub event: non_existent_event", err.Error())
 }
+
+func TestCustomCommandHappyPath(t *testing.T) {
+	SkipCI(t)
+	diggerCfg := `
+projects:
+- name: dev
+  dir: infra/dev
+  workflow: myworkflow
+
+workflows:
+  myworkflow:
+    plan:
+      steps:
+      - run: echo "hello"
+`
+
+	dir := terraform.CreateTestTerraformProject()
+
+	defer func(name string) {
+		err := os.RemoveAll(name)
+		if err != nil {
+			log.Fatal(err)
+		}
+	}(dir)
+
+	terraform.CreateValidTerraformTestFile(dir)
+	terraform.CreateCustomDiggerYmlFile(dir, diggerCfg)
+
+	diggerConfig, err := configuration.NewDiggerConfig(dir, &configuration.FileSystemDirWalker{})
+	assert.NoError(t, err)
+
+	assert.NotNil(t, diggerConfig.Workflows)
+	assert.NotNil(t, diggerConfig.Workflows["myworkflow"])
+	assert.NotNil(t, diggerConfig.Workflows["myworkflow"].Configuration)
+	assert.NotNil(t, diggerConfig.Workflows["myworkflow"].Configuration.OnCommitToDefault)
+
+	lock, err := utils.GetLock()
+	assert.NoError(t, err)
+	assert.NotNil(t, lock, "failed to create lock")
+
+	ghToken := os.Getenv("GITHUB_TOKEN")
+	assert.NotEmpty(t, ghToken)
+
+	println("--- new pull request ---")
+	newPullRequestContext := githubContextNewPullRequestMinJson
+	parsedNewPullRequestContext, err := digger.GetGitHubContext(newPullRequestContext)
+	assert.NoError(t, err)
+
+	diggerPlanCommentContext := githubContextDiggerPlanCommentMinJson
+	parsedDiggerPlanCommentContext, err := digger.GetGitHubContext(diggerPlanCommentContext)
+	assert.NoError(t, err)
+
+	diggerApplyCommentContext := githubContextDiggerApplyCommentMinJson
+	parsedDiggerApplyCommentContext, err := digger.GetGitHubContext(diggerApplyCommentContext)
+	assert.NoError(t, err)
+
+	diggerUnlockCommentContext := githubContextDiggerUnlockCommentMinJson
+	parsedDiggerUnlockCommentContext, err := digger.GetGitHubContext(diggerUnlockCommentContext)
+	assert.NoError(t, err)
+
+	ghEvent := parsedNewPullRequestContext.Event
+	eventName := parsedNewPullRequestContext.EventName
+	repoOwner := parsedNewPullRequestContext.RepositoryOwner
+	repositoryName := parsedNewPullRequestContext.Repository
+	githubPrService := github.NewGithubPullRequestService(ghToken, repositoryName, repoOwner)
+
+	assert.Equal(t, "pull_request", parsedNewPullRequestContext.EventName)
+
+	//  new pr should lock the project
+	impactedProjects, prNumber, err := digger.ProcessGitHubEvent(ghEvent, diggerConfig, githubPrService)
+	assert.NoError(t, err)
+	commandsToRunPerProject, err := digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, map[string]configuration.Workflow{})
+	assert.NoError(t, err)
+	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, dir)
+	assert.NoError(t, err)
+
+	projectLock := &utils.ProjectLockImpl{
+		InternalLock: lock,
+		PrManager:    githubPrService,
+		ProjectName:  "dev",
+		RepoName:     repositoryName,
+		RepoOwner:    repoOwner,
+	}
+	resource := repositoryName + "#" + projectLock.ProjectName
+	transactionId, err := projectLock.InternalLock.GetLock(resource)
+	assert.NoError(t, err)
+	assert.NotNil(t, transactionId)
+	assert.Equal(t, 42, *transactionId, "TransactionId")
+
+	println("--- digger plan comment ---")
+	ghEvent = parsedDiggerPlanCommentContext.Event
+	eventName = parsedDiggerPlanCommentContext.EventName
+	repoOwner = parsedDiggerPlanCommentContext.RepositoryOwner
+	repositoryName = parsedDiggerPlanCommentContext.Repository
+
+	// 'digger plan' comment should trigger terraform execution
+	impactedProjects, prNumber, err = digger.ProcessGitHubEvent(ghEvent, diggerConfig, githubPrService)
+	assert.NoError(t, err)
+	commandsToRunPerProject, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, map[string]configuration.Workflow{})
+	assert.NoError(t, err)
+	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, dir)
+	assert.NoError(t, err)
+
+	println("--- digger apply comment ---")
+	ghEvent = parsedDiggerApplyCommentContext.Event
+	eventName = parsedDiggerApplyCommentContext.EventName
+	repoOwner = parsedDiggerApplyCommentContext.RepositoryOwner
+	repositoryName = parsedDiggerApplyCommentContext.Repository
+
+	// 'digger apply' comment should trigger terraform execution and unlock the project
+	impactedProjects, prNumber, err = digger.ProcessGitHubEvent(ghEvent, diggerConfig, githubPrService)
+	assert.NoError(t, err)
+	commandsToRunPerProject, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, map[string]configuration.Workflow{})
+	assert.NoError(t, err)
+	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, dir)
+	assert.NoError(t, err)
+
+	projectLock = &utils.ProjectLockImpl{
+		InternalLock: lock,
+		PrManager:    githubPrService,
+		ProjectName:  "dev",
+		RepoName:     repositoryName,
+		RepoOwner:    repoOwner,
+	}
+	transactionId, err = projectLock.InternalLock.GetLock(resource)
+	assert.NoError(t, err)
+
+	println("--- digger unlock comment ---")
+	ghEvent = parsedDiggerUnlockCommentContext.Event
+	eventName = parsedDiggerUnlockCommentContext.EventName
+	repoOwner = parsedDiggerUnlockCommentContext.RepositoryOwner
+	repositoryName = parsedDiggerUnlockCommentContext.Repository
+
+	impactedProjects, prNumber, err = digger.ProcessGitHubEvent(ghEvent, diggerConfig, githubPrService)
+	assert.NoError(t, err)
+	commandsToRunPerProject, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, map[string]configuration.Workflow{})
+	assert.NoError(t, err)
+	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, dir)
+	assert.NoError(t, err)
+
+	projectLock = &utils.ProjectLockImpl{
+		InternalLock: lock,
+		PrManager:    githubPrService,
+		ProjectName:  "dev",
+		RepoName:     repositoryName,
+		RepoOwner:    repoOwner,
+	}
+	transactionId, err = projectLock.InternalLock.GetLock(resource)
+	assert.NoError(t, err)
+}