Files
atlantis/server/events/project_command_builder_internal_test.go
Nish Krishnan 7ac8106f8a Add structured logger (#54) (#1467)
This is two changes:

Replacing all usages of SimpleLogger with it's interface SimpleLogging which makes it easier to swap out loggers going forward
Nukes SimpleLogger in favor of StructuredLogger which allows us to better analyze logs in our log management system we choose.
2021-04-06 12:02:25 -07:00

1041 lines
27 KiB
Go

package events
import (
"io/ioutil"
"path/filepath"
"testing"
version "github.com/hashicorp/go-version"
. "github.com/petergtz/pegomock"
"github.com/runatlantis/atlantis/server/events/matchers"
"github.com/runatlantis/atlantis/server/events/models"
vcsmocks "github.com/runatlantis/atlantis/server/events/vcs/mocks"
"github.com/runatlantis/atlantis/server/events/yaml"
"github.com/runatlantis/atlantis/server/events/yaml/valid"
"github.com/runatlantis/atlantis/server/logging"
logging_matchers "github.com/runatlantis/atlantis/server/logging/mocks/matchers"
. "github.com/runatlantis/atlantis/testing"
)
// Test different permutations of global and repo config.
func TestBuildProjectCmdCtx(t *testing.T) {
logger := logging.NewNoopLogger(t)
emptyPolicySets := valid.PolicySets{
Version: nil,
PolicySets: []valid.PolicySet{},
}
baseRepo := models.Repo{
FullName: "owner/repo",
VCSHost: models.VCSHost{
Hostname: "github.com",
},
}
pull := models.PullRequest{
BaseRepo: baseRepo,
}
cases := map[string]struct {
globalCfg string
repoCfg string
expErr string
expCtx models.ProjectCommandContext
expPlanSteps []string
expApplySteps []string
}{
// Test that if we've set global defaults and no project config
// that the global defaults are used.
"global defaults": {
globalCfg: `
repos:
- id: /.*/
workflow: default
workflows:
default:
plan:
steps:
- init
- plan
apply:
steps:
- apply`,
repoCfg: "",
expCtx: models.ProjectCommandContext{
ApplyCmd: "atlantis apply -d project1 -w myworkspace",
BaseRepo: baseRepo,
EscapedCommentArgs: []string{`\f\l\a\g`},
AutomergeEnabled: false,
AutoplanEnabled: true,
HeadRepo: models.Repo{},
Log: logger,
PullMergeable: true,
Pull: pull,
ProjectName: "",
ApplyRequirements: []string{},
RePlanCmd: "atlantis plan -d project1 -w myworkspace -- flag",
RepoRelDir: "project1",
User: models.User{},
Verbose: true,
Workspace: "myworkspace",
PolicySets: emptyPolicySets,
},
expPlanSteps: []string{"init", "plan"},
expApplySteps: []string{"apply"},
},
// Test that if we've set global defaults, that they are used but the
// allowed project config values also come through.
"global defaults with repo cfg": {
globalCfg: `
repos:
- id: /.*/
workflow: default
workflows:
default:
plan:
steps:
- init
- plan
apply:
steps:
- apply`,
repoCfg: `
version: 3
automerge: true
projects:
- dir: project1
workspace: myworkspace
autoplan:
enabled: true
when_modified: [../modules/**/*.tf]
terraform_version: v10.0
`,
expCtx: models.ProjectCommandContext{
ApplyCmd: "atlantis apply -d project1 -w myworkspace",
BaseRepo: baseRepo,
EscapedCommentArgs: []string{`\f\l\a\g`},
AutomergeEnabled: true,
AutoplanEnabled: true,
HeadRepo: models.Repo{},
Log: logger,
PullMergeable: true,
Pull: pull,
ProjectName: "",
ApplyRequirements: []string{},
RepoConfigVersion: 3,
RePlanCmd: "atlantis plan -d project1 -w myworkspace -- flag",
RepoRelDir: "project1",
TerraformVersion: mustVersion("10.0"),
User: models.User{},
Verbose: true,
Workspace: "myworkspace",
PolicySets: emptyPolicySets,
},
expPlanSteps: []string{"init", "plan"},
expApplySteps: []string{"apply"},
},
// Set a global apply req that should be used.
"global apply_requirements": {
globalCfg: `
repos:
- id: /.*/
workflow: default
apply_requirements: [approved, mergeable]
workflows:
default:
plan:
steps:
- init
- plan
apply:
steps:
- apply`,
repoCfg: `
version: 3
automerge: true
projects:
- dir: project1
workspace: myworkspace
autoplan:
enabled: true
when_modified: [../modules/**/*.tf]
terraform_version: v10.0
`,
expCtx: models.ProjectCommandContext{
ApplyCmd: "atlantis apply -d project1 -w myworkspace",
BaseRepo: baseRepo,
EscapedCommentArgs: []string{`\f\l\a\g`},
AutomergeEnabled: true,
AutoplanEnabled: true,
HeadRepo: models.Repo{},
Log: logger,
PullMergeable: true,
Pull: pull,
ProjectName: "",
ApplyRequirements: []string{"approved", "mergeable"},
RepoConfigVersion: 3,
RePlanCmd: "atlantis plan -d project1 -w myworkspace -- flag",
RepoRelDir: "project1",
TerraformVersion: mustVersion("10.0"),
User: models.User{},
Verbose: true,
Workspace: "myworkspace",
PolicySets: emptyPolicySets,
},
expPlanSteps: []string{"init", "plan"},
expApplySteps: []string{"apply"},
},
// If we have global config that matches a specific repo, it should be used.
"specific repo": {
globalCfg: `
repos:
- id: /.*/
workflow: default
- id: github.com/owner/repo
workflow: specific
apply_requirements: [approved]
workflows:
default:
plan:
steps:
- init
- plan
apply:
steps:
- apply
specific:
plan:
steps:
- plan
apply:
steps: []`,
repoCfg: `
version: 3
automerge: true
projects:
- dir: project1
workspace: myworkspace
autoplan:
enabled: true
when_modified: [../modules/**/*.tf]
terraform_version: v10.0
`,
expCtx: models.ProjectCommandContext{
ApplyCmd: "atlantis apply -d project1 -w myworkspace",
BaseRepo: baseRepo,
EscapedCommentArgs: []string{`\f\l\a\g`},
AutomergeEnabled: true,
AutoplanEnabled: true,
HeadRepo: models.Repo{},
Log: logger,
PullMergeable: true,
Pull: pull,
ProjectName: "",
ApplyRequirements: []string{"approved"},
RepoConfigVersion: 3,
RePlanCmd: "atlantis plan -d project1 -w myworkspace -- flag",
RepoRelDir: "project1",
TerraformVersion: mustVersion("10.0"),
User: models.User{},
Verbose: true,
Workspace: "myworkspace",
PolicySets: emptyPolicySets,
},
expPlanSteps: []string{"plan"},
expApplySteps: []string{},
},
// We should get an error if the repo sets an apply req when its
// not allowed.
"repo defines apply_requirements": {
globalCfg: `
repos:
- id: /.*/
workflow: default
apply_requirements: [approved, mergeable]
workflows:
default:
plan:
steps:
- init
- plan
apply:
steps:
- apply`,
repoCfg: `
version: 3
automerge: true
projects:
- dir: project1
workspace: myworkspace
apply_requirements: []
`,
expErr: "repo config not allowed to set 'apply_requirements' key: server-side config needs 'allowed_overrides: [apply_requirements]'",
},
// We should get an error if a repo sets a workflow when it's not allowed.
"repo sets its own workflow": {
globalCfg: `
repos:
- id: /.*/
workflow: default
apply_requirements: [approved, mergeable]
workflows:
default:
plan:
steps:
- init
- plan
apply:
steps:
- apply`,
repoCfg: `
version: 3
automerge: true
projects:
- dir: project1
workspace: myworkspace
workflow: default
`,
expErr: "repo config not allowed to set 'workflow' key: server-side config needs 'allowed_overrides: [workflow]'",
},
// We should get an error if a repo defines a workflow when it's not
// allowed.
"repo defines new workflow": {
globalCfg: `
repos:
- id: /.*/
workflow: default
apply_requirements: [approved, mergeable]
workflows:
default:
plan:
steps:
- init
- plan
apply:
steps:
- apply`,
repoCfg: `
version: 3
automerge: true
projects:
- dir: project1
workspace: myworkspace
workflows:
new: ~
`,
expErr: "repo config not allowed to define custom workflows: server-side config needs 'allow_custom_workflows: true'",
},
// If the repos are allowed to set everything then their config should
// come through.
"full repo permissions": {
globalCfg: `
repos:
- id: /.*/
workflow: default
apply_requirements: [approved]
allowed_overrides: [apply_requirements, workflow]
allow_custom_workflows: true
workflows:
default:
plan:
steps: []
apply:
steps: []
`,
repoCfg: `
version: 3
automerge: true
projects:
- dir: project1
workspace: myworkspace
autoplan:
enabled: true
when_modified: [../modules/**/*.tf]
terraform_version: v10.0
apply_requirements: []
workflow: custom
workflows:
custom:
plan:
steps:
- plan
apply:
steps:
- apply
`,
expCtx: models.ProjectCommandContext{
ApplyCmd: "atlantis apply -d project1 -w myworkspace",
BaseRepo: baseRepo,
EscapedCommentArgs: []string{`\f\l\a\g`},
AutomergeEnabled: true,
AutoplanEnabled: true,
HeadRepo: models.Repo{},
Log: logger,
PullMergeable: true,
Pull: pull,
ProjectName: "",
ApplyRequirements: []string{},
RepoConfigVersion: 3,
RePlanCmd: "atlantis plan -d project1 -w myworkspace -- flag",
RepoRelDir: "project1",
TerraformVersion: mustVersion("10.0"),
User: models.User{},
Verbose: true,
Workspace: "myworkspace",
PolicySets: emptyPolicySets,
},
expPlanSteps: []string{"plan"},
expApplySteps: []string{"apply"},
},
// Repos can choose server-side workflows.
"repos choose server-side workflow": {
globalCfg: `
repos:
- id: /.*/
workflow: default
allowed_overrides: [workflow]
workflows:
default:
plan:
steps: []
apply:
steps: []
custom:
plan:
steps: [plan]
apply:
steps: [apply]
`,
repoCfg: `
version: 3
automerge: true
projects:
- dir: project1
workspace: myworkspace
autoplan:
enabled: true
when_modified: [../modules/**/*.tf]
terraform_version: v10.0
workflow: custom
`,
expCtx: models.ProjectCommandContext{
ApplyCmd: "atlantis apply -d project1 -w myworkspace",
BaseRepo: baseRepo,
EscapedCommentArgs: []string{`\f\l\a\g`},
AutomergeEnabled: true,
AutoplanEnabled: true,
HeadRepo: models.Repo{},
Log: logger,
PullMergeable: true,
Pull: pull,
ProjectName: "",
ApplyRequirements: []string{},
RepoConfigVersion: 3,
RePlanCmd: "atlantis plan -d project1 -w myworkspace -- flag",
RepoRelDir: "project1",
TerraformVersion: mustVersion("10.0"),
User: models.User{},
Verbose: true,
Workspace: "myworkspace",
PolicySets: emptyPolicySets,
},
expPlanSteps: []string{"plan"},
expApplySteps: []string{"apply"},
},
// Repo-side workflows with the same name override server-side if
// allowed.
"repo-side workflow override": {
globalCfg: `
repos:
- id: /.*/
workflow: custom
allowed_overrides: [workflow]
allow_custom_workflows: true
workflows:
custom:
plan:
steps: [plan]
apply:
steps: [apply]
`,
repoCfg: `
version: 3
automerge: true
projects:
- dir: project1
workspace: myworkspace
autoplan:
enabled: true
when_modified: [../modules/**/*.tf]
terraform_version: v10.0
workflow: custom
workflows:
custom:
plan:
steps: []
apply:
steps: []
`,
expCtx: models.ProjectCommandContext{
ApplyCmd: "atlantis apply -d project1 -w myworkspace",
BaseRepo: baseRepo,
EscapedCommentArgs: []string{`\f\l\a\g`},
AutomergeEnabled: true,
AutoplanEnabled: true,
HeadRepo: models.Repo{},
Log: logger,
PullMergeable: true,
Pull: pull,
ProjectName: "",
ApplyRequirements: []string{},
RepoConfigVersion: 3,
RePlanCmd: "atlantis plan -d project1 -w myworkspace -- flag",
RepoRelDir: "project1",
TerraformVersion: mustVersion("10.0"),
User: models.User{},
Verbose: true,
Workspace: "myworkspace",
PolicySets: emptyPolicySets,
},
expPlanSteps: []string{},
expApplySteps: []string{},
},
// Test that if we leave keys undefined, that they don't override.
"cascading matches": {
globalCfg: `
repos:
- id: /.*/
apply_requirements: [approved]
- id: github.com/owner/repo
workflow: custom
workflows:
custom:
plan:
steps: [plan]
`,
repoCfg: `
version: 3
projects:
- dir: project1
workspace: myworkspace
`,
expCtx: models.ProjectCommandContext{
ApplyCmd: "atlantis apply -d project1 -w myworkspace",
BaseRepo: baseRepo,
EscapedCommentArgs: []string{`\f\l\a\g`},
AutomergeEnabled: false,
AutoplanEnabled: true,
HeadRepo: models.Repo{},
Log: logger,
PullMergeable: true,
Pull: pull,
ProjectName: "",
ApplyRequirements: []string{"approved"},
RepoConfigVersion: 3,
RePlanCmd: "atlantis plan -d project1 -w myworkspace -- flag",
RepoRelDir: "project1",
User: models.User{},
Verbose: true,
Workspace: "myworkspace",
PolicySets: emptyPolicySets,
},
expPlanSteps: []string{"plan"},
expApplySteps: []string{"apply"},
},
}
for name, c := range cases {
t.Run(name, func(t *testing.T) {
tmp, cleanup := DirStructure(t, map[string]interface{}{
"project1": map[string]interface{}{
"main.tf": nil,
},
"modules": map[string]interface{}{
"module": map[string]interface{}{
"main.tf": nil,
},
},
})
defer cleanup()
workingDir := NewMockWorkingDir()
When(workingDir.Clone(matchers.AnyPtrToLoggingSimpleLogger(), matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest(), AnyString())).ThenReturn(tmp, false, nil)
vcsClient := vcsmocks.NewMockClient()
When(vcsClient.GetModifiedFiles(matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest())).ThenReturn([]string{"modules/module/main.tf"}, nil)
// Write and parse the global config file.
globalCfgPath := filepath.Join(tmp, "global.yaml")
Ok(t, ioutil.WriteFile(globalCfgPath, []byte(c.globalCfg), 0600))
parser := &yaml.ParserValidator{}
globalCfg, err := parser.ParseGlobalCfg(globalCfgPath, valid.NewGlobalCfg(false, false, false))
Ok(t, err)
if c.repoCfg != "" {
Ok(t, ioutil.WriteFile(filepath.Join(tmp, "atlantis.yaml"), []byte(c.repoCfg), 0600))
}
builder := NewProjectCommandBuilder(
false,
parser,
&DefaultProjectFinder{},
vcsClient,
workingDir,
NewDefaultWorkingDirLocker(),
globalCfg,
&DefaultPendingPlanFinder{},
&CommentParser{},
false,
false,
)
// We run a test for each type of command.
for _, cmd := range []models.CommandName{models.PlanCommand, models.ApplyCommand} {
t.Run(cmd.String(), func(t *testing.T) {
ctxs, err := builder.buildProjectCommandCtx(&CommandContext{
Log: logger,
Pull: models.PullRequest{
BaseRepo: baseRepo,
},
PullMergeable: true,
}, cmd, "", []string{"flag"}, tmp, "project1", "myworkspace", true)
if c.expErr != "" {
ErrEquals(t, c.expErr, err)
return
}
ctx := ctxs[0]
Ok(t, err)
// Construct expected steps.
var stepNames []string
switch cmd {
case models.PlanCommand:
stepNames = c.expPlanSteps
case models.ApplyCommand:
stepNames = c.expApplySteps
}
var expSteps []valid.Step
for _, stepName := range stepNames {
expSteps = append(expSteps, valid.Step{
StepName: stepName,
})
}
c.expCtx.CommandName = cmd
// Init fields we couldn't in our cases map.
c.expCtx.Steps = expSteps
ctx.PolicySets = emptyPolicySets
Equals(t, c.expCtx, ctx)
// Equals() doesn't compare TF version properly so have to
// use .String().
if c.expCtx.TerraformVersion != nil {
Equals(t, c.expCtx.TerraformVersion.String(), ctx.TerraformVersion.String())
}
})
}
})
}
}
func TestBuildProjectCmdCtx_WithRegExpCmdEnabled(t *testing.T) {
emptyPolicySets := valid.PolicySets{
Version: nil,
PolicySets: []valid.PolicySet{},
}
baseRepo := models.Repo{
FullName: "owner/repo",
VCSHost: models.VCSHost{
Hostname: "github.com",
},
}
pull := models.PullRequest{
BaseRepo: baseRepo,
}
cases := map[string]struct {
globalCfg string
repoCfg string
expErr string
expCtx models.ProjectCommandContext
expPlanSteps []string
expApplySteps []string
}{
// Test that if we've set global defaults, that they are used but the
// allowed project config values also come through.
"global defaults with repo cfg": {
globalCfg: `
repos:
- id: /.*/
workflow: default
workflows:
default:
plan:
steps:
- init
- plan
apply:
steps:
- apply`,
repoCfg: `
version: 3
automerge: true
projects:
- name: myproject_1
dir: project1
workspace: myworkspace
autoplan:
enabled: true
when_modified: [../modules/**/*.tf]
terraform_version: v10.0
- name: myproject_2
dir: project2
workspace: myworkspace
autoplan:
enabled: true
when_modified: [../modules/**/*.tf]
terraform_version: v10.0
- name: myproject_3
dir: project3
workspace: myworkspace
autoplan:
enabled: true
when_modified: [../modules/**/*.tf]
terraform_version: v10.0
`,
expCtx: models.ProjectCommandContext{
ApplyCmd: "atlantis apply -p myproject_1",
BaseRepo: baseRepo,
EscapedCommentArgs: []string{`\f\l\a\g`},
AutomergeEnabled: true,
AutoplanEnabled: true,
HeadRepo: models.Repo{},
Log: logging.NewNoopLogger(t),
PullMergeable: true,
Pull: pull,
ProjectName: "myproject_1",
ApplyRequirements: []string{},
RepoConfigVersion: 3,
RePlanCmd: "atlantis plan -p myproject_1 -- flag",
RepoRelDir: "project1",
TerraformVersion: mustVersion("10.0"),
User: models.User{},
Verbose: true,
Workspace: "myworkspace",
PolicySets: emptyPolicySets,
},
expPlanSteps: []string{"init", "plan"},
expApplySteps: []string{"apply"},
},
}
for name, c := range cases {
t.Run(name, func(t *testing.T) {
tmp, cleanup := DirStructure(t, map[string]interface{}{
"project1": map[string]interface{}{
"main.tf": nil,
},
"modules": map[string]interface{}{
"module": map[string]interface{}{
"main.tf": nil,
},
},
})
defer cleanup()
workingDir := NewMockWorkingDir()
When(workingDir.Clone(logging_matchers.AnyPtrToLoggingSimpleLogger(), matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest(), AnyString())).ThenReturn(tmp, false, nil)
vcsClient := vcsmocks.NewMockClient()
When(vcsClient.GetModifiedFiles(matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest())).ThenReturn([]string{"modules/module/main.tf"}, nil)
// Write and parse the global config file.
globalCfgPath := filepath.Join(tmp, "global.yaml")
Ok(t, ioutil.WriteFile(globalCfgPath, []byte(c.globalCfg), 0600))
parser := &yaml.ParserValidator{}
globalCfg, err := parser.ParseGlobalCfg(globalCfgPath, valid.NewGlobalCfg(false, false, false))
Ok(t, err)
if c.repoCfg != "" {
Ok(t, ioutil.WriteFile(filepath.Join(tmp, "atlantis.yaml"), []byte(c.repoCfg), 0600))
}
builder := NewProjectCommandBuilder(
false,
parser,
&DefaultProjectFinder{},
vcsClient,
workingDir,
NewDefaultWorkingDirLocker(),
globalCfg,
&DefaultPendingPlanFinder{},
&CommentParser{},
false,
true,
)
// We run a test for each type of command, again specific projects
for _, cmd := range []models.CommandName{models.PlanCommand, models.ApplyCommand} {
t.Run(cmd.String(), func(t *testing.T) {
ctxs, err := builder.buildProjectCommandCtx(&CommandContext{
Pull: models.PullRequest{
BaseRepo: baseRepo,
},
Log: logging.NewNoopLogger(t),
PullMergeable: true,
}, cmd, "myproject_[1-2]", []string{"flag"}, tmp, "project1", "myworkspace", true)
if c.expErr != "" {
ErrEquals(t, c.expErr, err)
return
}
ctx := ctxs[0]
Ok(t, err)
Equals(t, 2, len(ctxs))
// Construct expected steps.
var stepNames []string
switch cmd {
case models.PlanCommand:
stepNames = c.expPlanSteps
case models.ApplyCommand:
stepNames = c.expApplySteps
}
var expSteps []valid.Step
for _, stepName := range stepNames {
expSteps = append(expSteps, valid.Step{
StepName: stepName,
})
}
c.expCtx.CommandName = cmd
// Init fields we couldn't in our cases map.
c.expCtx.Steps = expSteps
ctx.PolicySets = emptyPolicySets
Equals(t, c.expCtx, ctx)
// Equals() doesn't compare TF version properly so have to
// use .String().
if c.expCtx.TerraformVersion != nil {
Equals(t, c.expCtx.TerraformVersion.String(), ctx.TerraformVersion.String())
}
})
}
})
}
}
func TestBuildProjectCmdCtx_WithPolicCheckEnabled(t *testing.T) {
logger := logging.NewNoopLogger(t)
emptyPolicySets := valid.PolicySets{
Version: nil,
PolicySets: []valid.PolicySet{},
}
baseRepo := models.Repo{
FullName: "owner/repo",
VCSHost: models.VCSHost{
Hostname: "github.com",
},
}
pull := models.PullRequest{
BaseRepo: baseRepo,
}
cases := map[string]struct {
globalCfg string
repoCfg string
expErr string
expCtx models.ProjectCommandContext
expPolicyCheckSteps []string
}{
// Test that if we've set global defaults and no project config
// that the global defaults are used.
"global defaults": {
globalCfg: `
repos:
- id: /.*/
`,
repoCfg: "",
expCtx: models.ProjectCommandContext{
ApplyCmd: "atlantis apply -d project1 -w myworkspace",
BaseRepo: baseRepo,
EscapedCommentArgs: []string{`\f\l\a\g`},
AutomergeEnabled: false,
AutoplanEnabled: true,
HeadRepo: models.Repo{},
Log: logger,
PullMergeable: true,
Pull: pull,
ProjectName: "",
ApplyRequirements: []string{},
RePlanCmd: "atlantis plan -d project1 -w myworkspace -- flag",
RepoRelDir: "project1",
User: models.User{},
Verbose: true,
Workspace: "myworkspace",
PolicySets: emptyPolicySets,
},
expPolicyCheckSteps: []string{"show", "policy_check"},
},
// If the repos are allowed to set everything then their config should
// come through.
"full repo permissions": {
globalCfg: `
repos:
- id: /.*/
workflow: default
apply_requirements: [approved]
allowed_overrides: [apply_requirements, workflow]
allow_custom_workflows: true
workflows:
default:
policy_check:
steps: []
`,
repoCfg: `
version: 3
automerge: true
projects:
- dir: project1
workspace: myworkspace
autoplan:
enabled: true
when_modified: [../modules/**/*.tf]
terraform_version: v10.0
apply_requirements: []
workflow: custom
workflows:
custom:
policy_check:
steps:
- policy_check
`,
expCtx: models.ProjectCommandContext{
ApplyCmd: "atlantis apply -d project1 -w myworkspace",
BaseRepo: baseRepo,
EscapedCommentArgs: []string{`\f\l\a\g`},
AutomergeEnabled: true,
AutoplanEnabled: true,
HeadRepo: models.Repo{},
Log: logger,
PullMergeable: true,
Pull: pull,
ProjectName: "",
ApplyRequirements: []string{},
RepoConfigVersion: 3,
RePlanCmd: "atlantis plan -d project1 -w myworkspace -- flag",
RepoRelDir: "project1",
TerraformVersion: mustVersion("10.0"),
User: models.User{},
Verbose: true,
Workspace: "myworkspace",
PolicySets: emptyPolicySets,
},
expPolicyCheckSteps: []string{"policy_check"},
},
}
for name, c := range cases {
t.Run(name, func(t *testing.T) {
tmp, cleanup := DirStructure(t, map[string]interface{}{
"project1": map[string]interface{}{
"main.tf": nil,
},
"modules": map[string]interface{}{
"module": map[string]interface{}{
"main.tf": nil,
},
},
})
defer cleanup()
workingDir := NewMockWorkingDir()
When(workingDir.Clone(matchers.AnyPtrToLoggingSimpleLogger(), matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest(), AnyString())).ThenReturn(tmp, false, nil)
vcsClient := vcsmocks.NewMockClient()
When(vcsClient.GetModifiedFiles(matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest())).ThenReturn([]string{"modules/module/main.tf"}, nil)
// Write and parse the global config file.
globalCfgPath := filepath.Join(tmp, "global.yaml")
Ok(t, ioutil.WriteFile(globalCfgPath, []byte(c.globalCfg), 0600))
parser := &yaml.ParserValidator{}
globalCfg, err := parser.ParseGlobalCfg(globalCfgPath, valid.NewGlobalCfg(false, false, false))
Ok(t, err)
if c.repoCfg != "" {
Ok(t, ioutil.WriteFile(filepath.Join(tmp, "atlantis.yaml"), []byte(c.repoCfg), 0600))
}
builder := NewProjectCommandBuilder(
true,
parser,
&DefaultProjectFinder{},
vcsClient,
workingDir,
NewDefaultWorkingDirLocker(),
globalCfg,
&DefaultPendingPlanFinder{},
&CommentParser{},
false,
false,
)
cmd := models.PolicyCheckCommand
t.Run(cmd.String(), func(t *testing.T) {
ctxs, err := builder.buildProjectCommandCtx(&CommandContext{
Log: logger,
Pull: models.PullRequest{
BaseRepo: baseRepo,
},
PullMergeable: true,
}, models.PlanCommand, "", []string{"flag"}, tmp, "project1", "myworkspace", true)
if c.expErr != "" {
ErrEquals(t, c.expErr, err)
return
}
ctx := ctxs[1]
Ok(t, err)
// Construct expected steps.
var stepNames []string
var expSteps []valid.Step
stepNames = c.expPolicyCheckSteps
for _, stepName := range stepNames {
expSteps = append(expSteps, valid.Step{
StepName: stepName,
})
}
c.expCtx.CommandName = cmd
// Init fields we couldn't in our cases map.
c.expCtx.Steps = expSteps
ctx.PolicySets = emptyPolicySets
Equals(t, c.expCtx, ctx)
// Equals() doesn't compare TF version properly so have to
// use .String().
if c.expCtx.TerraformVersion != nil {
Equals(t, c.expCtx.TerraformVersion.String(), ctx.TerraformVersion.String())
}
})
})
}
}
func mustVersion(v string) *version.Version {
vers, err := version.NewVersion(v)
if err != nil {
panic(err)
}
return vers
}