mirror of
https://git.vectorsigma.ru/public/atlantis.git
synced 2026-07-29 16:48:21 +00:00
* Add pre and post workflow hook status * fix missing mocks * fix pre/post workflow hooks tests * add cmd output to file * fix typo * add cmd output to file on pre workflow hooks * Add hooks output to web UI * Remove unnecessary dependencies * Clean the code and make tests work again * Make lint happy * Small fixes, create dedicated UUID generator and docs * Add missing commentary * Use matchers instead of mocking for tests and fix e2e tests * Change 'OUTPUT_FILE' to 'OUTPUT_STATUS_FILE' * Reduce SendWorkflowHook calls on hooks * Apply suggestions from code review Co-authored-by: PePe Amengual <jose.amengual@gmail.com> Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com>
271 lines
8.5 KiB
Go
271 lines
8.5 KiB
Go
package events_test
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
|
|
. "github.com/petergtz/pegomock"
|
|
"github.com/runatlantis/atlantis/server/core/config/valid"
|
|
runtime_mocks "github.com/runatlantis/atlantis/server/core/runtime/mocks"
|
|
runtimematchers "github.com/runatlantis/atlantis/server/core/runtime/mocks/matchers"
|
|
"github.com/runatlantis/atlantis/server/events"
|
|
"github.com/runatlantis/atlantis/server/events/command"
|
|
"github.com/runatlantis/atlantis/server/events/mocks"
|
|
"github.com/runatlantis/atlantis/server/events/models"
|
|
"github.com/runatlantis/atlantis/server/events/models/fixtures"
|
|
vcsmocks "github.com/runatlantis/atlantis/server/events/vcs/mocks"
|
|
"github.com/runatlantis/atlantis/server/logging"
|
|
. "github.com/runatlantis/atlantis/testing"
|
|
)
|
|
|
|
var preWh events.DefaultPreWorkflowHooksCommandRunner
|
|
var preWhWorkingDir *mocks.MockWorkingDir
|
|
var preWhWorkingDirLocker *mocks.MockWorkingDirLocker
|
|
var whPreWorkflowHookRunner *runtime_mocks.MockPreWorkflowHookRunner
|
|
var preCommitStatusUpdater *mocks.MockCommitStatusUpdater
|
|
|
|
func preWorkflowHooksSetup(t *testing.T) {
|
|
RegisterMockTestingT(t)
|
|
vcsClient := vcsmocks.NewMockClient()
|
|
preWhWorkingDir = mocks.NewMockWorkingDir()
|
|
preWhWorkingDirLocker = mocks.NewMockWorkingDirLocker()
|
|
whPreWorkflowHookRunner = runtime_mocks.NewMockPreWorkflowHookRunner()
|
|
preCommitStatusUpdater = mocks.NewMockCommitStatusUpdater()
|
|
preWorkflowHookURLGenerator := mocks.NewMockPreWorkflowHookURLGenerator()
|
|
|
|
preWh = events.DefaultPreWorkflowHooksCommandRunner{
|
|
VCSClient: vcsClient,
|
|
WorkingDirLocker: preWhWorkingDirLocker,
|
|
WorkingDir: preWhWorkingDir,
|
|
PreWorkflowHookRunner: whPreWorkflowHookRunner,
|
|
CommitStatusUpdater: preCommitStatusUpdater,
|
|
Router: preWorkflowHookURLGenerator,
|
|
}
|
|
}
|
|
|
|
func newBool(b bool) *bool {
|
|
return &b
|
|
}
|
|
|
|
func TestRunPreHooks_Clone(t *testing.T) {
|
|
|
|
log := logging.NewNoopLogger(t)
|
|
|
|
var newPull = fixtures.Pull
|
|
newPull.BaseRepo = fixtures.GithubRepo
|
|
|
|
ctx := &command.Context{
|
|
Pull: newPull,
|
|
HeadRepo: fixtures.GithubRepo,
|
|
User: fixtures.User,
|
|
Log: log,
|
|
}
|
|
|
|
testHook := valid.WorkflowHook{
|
|
StepName: "test",
|
|
RunCommand: "some command",
|
|
}
|
|
|
|
repoDir := "path/to/repo"
|
|
result := "some result"
|
|
runtimeDesc := ""
|
|
|
|
pCtx := models.WorkflowHookCommandContext{
|
|
BaseRepo: fixtures.GithubRepo,
|
|
HeadRepo: fixtures.GithubRepo,
|
|
Pull: newPull,
|
|
Log: log,
|
|
User: fixtures.User,
|
|
Verbose: false,
|
|
}
|
|
|
|
t.Run("success hooks in cfg", func(t *testing.T) {
|
|
preWorkflowHooksSetup(t)
|
|
|
|
var unlockCalled = newBool(false)
|
|
unlockFn := func() {
|
|
unlockCalled = newBool(true)
|
|
}
|
|
|
|
globalCfg := valid.GlobalCfg{
|
|
Repos: []valid.Repo{
|
|
{
|
|
ID: fixtures.GithubRepo.ID(),
|
|
PreWorkflowHooks: []*valid.WorkflowHook{
|
|
&testHook,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
preWh.GlobalCfg = globalCfg
|
|
|
|
When(preWhWorkingDirLocker.TryLock(fixtures.GithubRepo.FullName, newPull.Num, events.DefaultWorkspace, events.DefaultRepoRelDir)).ThenReturn(unlockFn, nil)
|
|
When(preWhWorkingDir.Clone(log, fixtures.GithubRepo, newPull, events.DefaultWorkspace)).ThenReturn(repoDir, false, nil)
|
|
When(whPreWorkflowHookRunner.Run(runtimematchers.AnyModelsWorkflowHookCommandContext(), EqString(testHook.RunCommand), EqString(repoDir))).ThenReturn(result, runtimeDesc, nil)
|
|
|
|
err := preWh.RunPreHooks(ctx, nil)
|
|
|
|
Ok(t, err)
|
|
whPreWorkflowHookRunner.VerifyWasCalledOnce().Run(runtimematchers.AnyModelsWorkflowHookCommandContext(), EqString(testHook.RunCommand), EqString(repoDir))
|
|
Assert(t, *unlockCalled == true, "unlock function called")
|
|
})
|
|
|
|
t.Run("success hooks not in cfg", func(t *testing.T) {
|
|
preWorkflowHooksSetup(t)
|
|
globalCfg := valid.GlobalCfg{
|
|
Repos: []valid.Repo{
|
|
// one with hooks but mismatched id
|
|
{
|
|
ID: "id1",
|
|
PreWorkflowHooks: []*valid.WorkflowHook{
|
|
&testHook,
|
|
},
|
|
},
|
|
// one with the correct id but no hooks
|
|
{
|
|
ID: fixtures.GithubRepo.ID(),
|
|
PreWorkflowHooks: []*valid.WorkflowHook{},
|
|
},
|
|
},
|
|
}
|
|
|
|
preWh.GlobalCfg = globalCfg
|
|
|
|
err := preWh.RunPreHooks(ctx, nil)
|
|
|
|
Ok(t, err)
|
|
|
|
whPreWorkflowHookRunner.VerifyWasCalled(Never()).Run(runtimematchers.AnyModelsWorkflowHookCommandContext(), EqString(testHook.RunCommand), EqString(repoDir))
|
|
preWhWorkingDirLocker.VerifyWasCalled(Never()).TryLock(fixtures.GithubRepo.FullName, newPull.Num, events.DefaultWorkspace)
|
|
preWhWorkingDir.VerifyWasCalled(Never()).Clone(log, fixtures.GithubRepo, newPull, events.DefaultWorkspace)
|
|
})
|
|
|
|
t.Run("error locking work dir", func(t *testing.T) {
|
|
preWorkflowHooksSetup(t)
|
|
|
|
globalCfg := valid.GlobalCfg{
|
|
Repos: []valid.Repo{
|
|
{
|
|
ID: fixtures.GithubRepo.ID(),
|
|
PreWorkflowHooks: []*valid.WorkflowHook{
|
|
&testHook,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
preWh.GlobalCfg = globalCfg
|
|
|
|
When(preWhWorkingDirLocker.TryLock(fixtures.GithubRepo.FullName, newPull.Num, events.DefaultWorkspace, events.DefaultRepoRelDir)).ThenReturn(func() {}, errors.New("some error"))
|
|
|
|
err := preWh.RunPreHooks(ctx, nil)
|
|
|
|
Assert(t, err != nil, "error not nil")
|
|
preWhWorkingDir.VerifyWasCalled(Never()).Clone(log, fixtures.GithubRepo, newPull, events.DefaultWorkspace)
|
|
whPreWorkflowHookRunner.VerifyWasCalled(Never()).Run(runtimematchers.AnyModelsWorkflowHookCommandContext(), EqString(testHook.RunCommand), EqString(repoDir))
|
|
})
|
|
|
|
t.Run("error cloning", func(t *testing.T) {
|
|
preWorkflowHooksSetup(t)
|
|
|
|
var unlockCalled = newBool(false)
|
|
unlockFn := func() {
|
|
unlockCalled = newBool(true)
|
|
}
|
|
|
|
globalCfg := valid.GlobalCfg{
|
|
Repos: []valid.Repo{
|
|
{
|
|
ID: fixtures.GithubRepo.ID(),
|
|
PreWorkflowHooks: []*valid.WorkflowHook{
|
|
&testHook,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
preWh.GlobalCfg = globalCfg
|
|
|
|
When(preWhWorkingDirLocker.TryLock(fixtures.GithubRepo.FullName, newPull.Num, events.DefaultWorkspace, events.DefaultRepoRelDir)).ThenReturn(unlockFn, nil)
|
|
When(preWhWorkingDir.Clone(log, fixtures.GithubRepo, newPull, events.DefaultWorkspace)).ThenReturn(repoDir, false, errors.New("some error"))
|
|
|
|
err := preWh.RunPreHooks(ctx, nil)
|
|
|
|
Assert(t, err != nil, "error not nil")
|
|
|
|
whPreWorkflowHookRunner.VerifyWasCalled(Never()).Run(runtimematchers.AnyModelsWorkflowHookCommandContext(), EqString(testHook.RunCommand), EqString(repoDir))
|
|
Assert(t, *unlockCalled == true, "unlock function called")
|
|
})
|
|
|
|
t.Run("error running pre hook", func(t *testing.T) {
|
|
preWorkflowHooksSetup(t)
|
|
|
|
var unlockCalled = newBool(false)
|
|
unlockFn := func() {
|
|
unlockCalled = newBool(true)
|
|
}
|
|
|
|
globalCfg := valid.GlobalCfg{
|
|
Repos: []valid.Repo{
|
|
{
|
|
ID: fixtures.GithubRepo.ID(),
|
|
PreWorkflowHooks: []*valid.WorkflowHook{
|
|
&testHook,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
preWh.GlobalCfg = globalCfg
|
|
|
|
When(preWhWorkingDirLocker.TryLock(fixtures.GithubRepo.FullName, newPull.Num, events.DefaultWorkspace, events.DefaultRepoRelDir)).ThenReturn(unlockFn, nil)
|
|
When(preWhWorkingDir.Clone(log, fixtures.GithubRepo, newPull, events.DefaultWorkspace)).ThenReturn(repoDir, false, nil)
|
|
When(whPreWorkflowHookRunner.Run(runtimematchers.AnyModelsWorkflowHookCommandContext(), EqString(testHook.RunCommand), EqString(repoDir))).ThenReturn(result, runtimeDesc, errors.New("some error"))
|
|
|
|
err := preWh.RunPreHooks(ctx, nil)
|
|
|
|
Assert(t, err != nil, "error not nil")
|
|
Assert(t, *unlockCalled == true, "unlock function called")
|
|
})
|
|
|
|
t.Run("comment args passed to webhooks", func(t *testing.T) {
|
|
preWorkflowHooksSetup(t)
|
|
|
|
var unlockCalled = newBool(false)
|
|
unlockFn := func() {
|
|
unlockCalled = newBool(true)
|
|
}
|
|
|
|
globalCfg := valid.GlobalCfg{
|
|
Repos: []valid.Repo{
|
|
{
|
|
ID: fixtures.GithubRepo.ID(),
|
|
PreWorkflowHooks: []*valid.WorkflowHook{
|
|
&testHook,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
cmd := &events.CommentCommand{
|
|
Flags: []string{"comment", "args"},
|
|
}
|
|
|
|
expectedCtx := pCtx
|
|
expectedCtx.EscapedCommentArgs = []string{"\\c\\o\\m\\m\\e\\n\\t", "\\a\\r\\g\\s"}
|
|
|
|
preWh.GlobalCfg = globalCfg
|
|
|
|
When(preWhWorkingDirLocker.TryLock(fixtures.GithubRepo.FullName, newPull.Num, events.DefaultWorkspace, events.DefaultRepoRelDir)).ThenReturn(unlockFn, nil)
|
|
When(preWhWorkingDir.Clone(log, fixtures.GithubRepo, newPull, events.DefaultWorkspace)).ThenReturn(repoDir, false, nil)
|
|
When(whPreWorkflowHookRunner.Run(runtimematchers.AnyModelsWorkflowHookCommandContext(), EqString(testHook.RunCommand), EqString(repoDir))).ThenReturn(result, runtimeDesc, nil)
|
|
|
|
err := preWh.RunPreHooks(ctx, cmd)
|
|
|
|
Ok(t, err)
|
|
whPreWorkflowHookRunner.VerifyWasCalledOnce().Run(runtimematchers.AnyModelsWorkflowHookCommandContext(), EqString(testHook.RunCommand), EqString(repoDir))
|
|
Assert(t, *unlockCalled == true, "unlock function called")
|
|
})
|
|
}
|