mirror of
https://git.vectorsigma.ru/public/atlantis.git
synced 2026-07-28 22:18:30 +00:00
* Initial build out of redis backend * Regenerate locking mocks and matchers * More test cleanup * More test fixes * Added tests for redis * Test fix * Linting fix * Dcos update * Update redis.go * Update server.go * Adding nolint to RedisDB struct
287 lines
8.9 KiB
Go
287 lines
8.9 KiB
Go
// Copyright 2017 HootSuite Media Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the License);
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an AS IS BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
// Modified hereafter by contributors to runatlantis/atlantis.
|
|
|
|
package events_test
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"testing"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/runatlantis/atlantis/server/core/db"
|
|
"github.com/runatlantis/atlantis/server/jobs"
|
|
"github.com/stretchr/testify/assert"
|
|
bolt "go.etcd.io/bbolt"
|
|
|
|
. "github.com/petergtz/pegomock"
|
|
lockmocks "github.com/runatlantis/atlantis/server/core/locking/mocks"
|
|
"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/mocks/matchers"
|
|
"github.com/runatlantis/atlantis/server/events/models"
|
|
"github.com/runatlantis/atlantis/server/events/models/fixtures"
|
|
vcsmocks "github.com/runatlantis/atlantis/server/events/vcs/mocks"
|
|
loggermocks "github.com/runatlantis/atlantis/server/logging/mocks"
|
|
. "github.com/runatlantis/atlantis/testing"
|
|
)
|
|
|
|
func TestCleanUpPullWorkspaceErr(t *testing.T) {
|
|
t.Log("when workspace.Delete returns an error, we return it")
|
|
RegisterMockTestingT(t)
|
|
w := mocks.NewMockWorkingDir()
|
|
tmp, cleanup := TempDir(t)
|
|
defer cleanup()
|
|
db, err := db.New(tmp)
|
|
Ok(t, err)
|
|
pce := events.PullClosedExecutor{
|
|
WorkingDir: w,
|
|
PullClosedTemplate: &events.PullClosedEventTemplate{},
|
|
Backend: db,
|
|
}
|
|
err = errors.New("err")
|
|
When(w.Delete(fixtures.GithubRepo, fixtures.Pull)).ThenReturn(err)
|
|
actualErr := pce.CleanUpPull(fixtures.GithubRepo, fixtures.Pull)
|
|
Equals(t, "cleaning workspace: err", actualErr.Error())
|
|
}
|
|
|
|
func TestCleanUpPullUnlockErr(t *testing.T) {
|
|
t.Log("when locker.UnlockByPull returns an error, we return it")
|
|
RegisterMockTestingT(t)
|
|
w := mocks.NewMockWorkingDir()
|
|
l := lockmocks.NewMockLocker()
|
|
tmp, cleanup := TempDir(t)
|
|
defer cleanup()
|
|
db, err := db.New(tmp)
|
|
Ok(t, err)
|
|
pce := events.PullClosedExecutor{
|
|
Locker: l,
|
|
WorkingDir: w,
|
|
Backend: db,
|
|
PullClosedTemplate: &events.PullClosedEventTemplate{},
|
|
}
|
|
err = errors.New("err")
|
|
When(l.UnlockByPull(fixtures.GithubRepo.FullName, fixtures.Pull.Num)).ThenReturn(nil, err)
|
|
actualErr := pce.CleanUpPull(fixtures.GithubRepo, fixtures.Pull)
|
|
Equals(t, "cleaning up locks: err", actualErr.Error())
|
|
}
|
|
|
|
func TestCleanUpPullNoLocks(t *testing.T) {
|
|
t.Log("when there are no locks to clean up, we don't comment")
|
|
RegisterMockTestingT(t)
|
|
w := mocks.NewMockWorkingDir()
|
|
l := lockmocks.NewMockLocker()
|
|
cp := vcsmocks.NewMockClient()
|
|
tmp, cleanup := TempDir(t)
|
|
defer cleanup()
|
|
db, err := db.New(tmp)
|
|
Ok(t, err)
|
|
pce := events.PullClosedExecutor{
|
|
Locker: l,
|
|
VCSClient: cp,
|
|
WorkingDir: w,
|
|
Backend: db,
|
|
}
|
|
When(l.UnlockByPull(fixtures.GithubRepo.FullName, fixtures.Pull.Num)).ThenReturn(nil, nil)
|
|
err = pce.CleanUpPull(fixtures.GithubRepo, fixtures.Pull)
|
|
Ok(t, err)
|
|
cp.VerifyWasCalled(Never()).CreateComment(matchers.AnyModelsRepo(), AnyInt(), AnyString(), AnyString())
|
|
}
|
|
|
|
func TestCleanUpPullComments(t *testing.T) {
|
|
t.Log("should comment correctly")
|
|
RegisterMockTestingT(t)
|
|
cases := []struct {
|
|
Description string
|
|
Locks []models.ProjectLock
|
|
Exp string
|
|
}{
|
|
{
|
|
"single lock, empty path",
|
|
[]models.ProjectLock{
|
|
{
|
|
Project: models.NewProject("owner/repo", ""),
|
|
Workspace: "default",
|
|
},
|
|
},
|
|
"- dir: `.` workspace: `default`",
|
|
},
|
|
{
|
|
"single lock, non-empty path",
|
|
[]models.ProjectLock{
|
|
{
|
|
Project: models.NewProject("owner/repo", "path"),
|
|
Workspace: "default",
|
|
},
|
|
},
|
|
"- dir: `path` workspace: `default`",
|
|
},
|
|
{
|
|
"single path, multiple workspaces",
|
|
[]models.ProjectLock{
|
|
{
|
|
Project: models.NewProject("owner/repo", "path"),
|
|
Workspace: "workspace1",
|
|
},
|
|
{
|
|
Project: models.NewProject("owner/repo", "path"),
|
|
Workspace: "workspace2",
|
|
},
|
|
},
|
|
"- dir: `path` workspaces: `workspace1`, `workspace2`",
|
|
},
|
|
{
|
|
"multiple paths, multiple workspaces",
|
|
[]models.ProjectLock{
|
|
{
|
|
Project: models.NewProject("owner/repo", "path"),
|
|
Workspace: "workspace1",
|
|
},
|
|
{
|
|
Project: models.NewProject("owner/repo", "path"),
|
|
Workspace: "workspace2",
|
|
},
|
|
{
|
|
Project: models.NewProject("owner/repo", "path2"),
|
|
Workspace: "workspace1",
|
|
},
|
|
{
|
|
Project: models.NewProject("owner/repo", "path2"),
|
|
Workspace: "workspace2",
|
|
},
|
|
},
|
|
"- dir: `path` workspaces: `workspace1`, `workspace2`\n- dir: `path2` workspaces: `workspace1`, `workspace2`",
|
|
},
|
|
}
|
|
for _, c := range cases {
|
|
func() {
|
|
w := mocks.NewMockWorkingDir()
|
|
cp := vcsmocks.NewMockClient()
|
|
l := lockmocks.NewMockLocker()
|
|
tmp, cleanup := TempDir(t)
|
|
defer cleanup()
|
|
db, err := db.New(tmp)
|
|
Ok(t, err)
|
|
pce := events.PullClosedExecutor{
|
|
Locker: l,
|
|
VCSClient: cp,
|
|
WorkingDir: w,
|
|
Backend: db,
|
|
}
|
|
t.Log("testing: " + c.Description)
|
|
When(l.UnlockByPull(fixtures.GithubRepo.FullName, fixtures.Pull.Num)).ThenReturn(c.Locks, nil)
|
|
err = pce.CleanUpPull(fixtures.GithubRepo, fixtures.Pull)
|
|
Ok(t, err)
|
|
_, _, comment, _ := cp.VerifyWasCalledOnce().CreateComment(matchers.AnyModelsRepo(), AnyInt(), AnyString(), AnyString()).GetCapturedArguments()
|
|
|
|
expected := "Locks and plans deleted for the projects and workspaces modified in this pull request:\n\n" + c.Exp
|
|
Equals(t, expected, comment)
|
|
}()
|
|
}
|
|
}
|
|
|
|
func TestCleanUpLogStreaming(t *testing.T) {
|
|
RegisterMockTestingT(t)
|
|
|
|
t.Run("Should Clean Up Log Streaming Resources When PR is closed", func(t *testing.T) {
|
|
|
|
// Create Log streaming resources
|
|
prjCmdOutput := make(chan *jobs.ProjectCmdOutputLine)
|
|
prjCmdOutHandler := jobs.NewAsyncProjectCommandOutputHandler(prjCmdOutput, logger)
|
|
ctx := command.ProjectContext{
|
|
BaseRepo: fixtures.GithubRepo,
|
|
Pull: fixtures.Pull,
|
|
ProjectName: *fixtures.Project.Name,
|
|
Workspace: "default",
|
|
}
|
|
|
|
go prjCmdOutHandler.Handle()
|
|
prjCmdOutHandler.Send(ctx, "Test Message", false)
|
|
|
|
// Create boltdb and add pull request.
|
|
var lockBucket = "bucket"
|
|
var configBucket = "configBucket"
|
|
var pullsBucketName = "pulls"
|
|
|
|
f, err := ioutil.TempFile("", "")
|
|
if err != nil {
|
|
panic(errors.Wrap(err, "failed to create temp file"))
|
|
}
|
|
path := f.Name()
|
|
f.Close() // nolint: errcheck
|
|
|
|
// Open the database.
|
|
boltDB, err := bolt.Open(path, 0600, nil)
|
|
if err != nil {
|
|
panic(errors.Wrap(err, "could not start bolt DB"))
|
|
}
|
|
if err := boltDB.Update(func(tx *bolt.Tx) error {
|
|
if _, err := tx.CreateBucketIfNotExists([]byte(pullsBucketName)); err != nil {
|
|
return errors.Wrap(err, "failed to create bucket")
|
|
}
|
|
return nil
|
|
}); err != nil {
|
|
panic(errors.Wrap(err, "could not create bucket"))
|
|
}
|
|
db, _ := db.NewWithDB(boltDB, lockBucket, configBucket)
|
|
result := []command.ProjectResult{
|
|
{
|
|
RepoRelDir: fixtures.GithubRepo.FullName,
|
|
Workspace: "default",
|
|
ProjectName: *fixtures.Project.Name,
|
|
},
|
|
}
|
|
|
|
// Create a new record for pull
|
|
_, err = db.UpdatePullWithResults(fixtures.Pull, result)
|
|
Ok(t, err)
|
|
|
|
workingDir := mocks.NewMockWorkingDir()
|
|
locker := lockmocks.NewMockLocker()
|
|
client := vcsmocks.NewMockClient()
|
|
logger := loggermocks.NewMockSimpleLogging()
|
|
|
|
pullClosedExecutor := events.PullClosedExecutor{
|
|
Locker: locker,
|
|
WorkingDir: workingDir,
|
|
Backend: db,
|
|
VCSClient: client,
|
|
PullClosedTemplate: &events.PullClosedEventTemplate{},
|
|
LogStreamResourceCleaner: prjCmdOutHandler,
|
|
Logger: logger,
|
|
}
|
|
|
|
locks := []models.ProjectLock{
|
|
{
|
|
Project: models.NewProject(fixtures.GithubRepo.FullName, ""),
|
|
Workspace: "default",
|
|
},
|
|
}
|
|
When(locker.UnlockByPull(fixtures.GithubRepo.FullName, fixtures.Pull.Num)).ThenReturn(locks, nil)
|
|
|
|
// Clean up.
|
|
err = pullClosedExecutor.CleanUpPull(fixtures.GithubRepo, fixtures.Pull)
|
|
Ok(t, err)
|
|
|
|
close(prjCmdOutput)
|
|
_, _, comment, _ := client.VerifyWasCalledOnce().CreateComment(matchers.AnyModelsRepo(), AnyInt(), AnyString(), AnyString()).GetCapturedArguments()
|
|
expectedComment := "Locks and plans deleted for the projects and workspaces modified in this pull request:\n\n" + "- dir: `.` workspace: `default`"
|
|
Equals(t, expectedComment, comment)
|
|
|
|
// Assert log streaming resources are cleaned up.
|
|
dfPrjCmdOutputHandler := prjCmdOutHandler.(*jobs.AsyncProjectCommandOutputHandler)
|
|
assert.Empty(t, dfPrjCmdOutputHandler.GetProjectOutputBuffer(ctx.PullInfo()))
|
|
assert.Empty(t, dfPrjCmdOutputHandler.GetReceiverBufferForPull(ctx.PullInfo()))
|
|
})
|
|
}
|