Skip to content

Commit

Permalink
Add tests for task package
Browse files Browse the repository at this point in the history
  • Loading branch information
HappyTetrahedron committed Jun 27, 2024
1 parent a9e95a0 commit 22a6f4a
Show file tree
Hide file tree
Showing 7 changed files with 340 additions and 20 deletions.
32 changes: 20 additions & 12 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,21 @@ type GitlabConfig struct {
BaseURL string
}

type GitlabClient struct {
type GitlabClient interface {
GetConfigFileForMR(mr *gitlab.MergeRequest, filePath string) (*[]byte, error)
ListMrsWithLabel(label string) ([]*gitlab.MergeRequest, error)
RefreshMr(mr *gitlab.MergeRequest) (*gitlab.MergeRequest, error)
MergeMr(mr *gitlab.MergeRequest) error
Comment(mr *gitlab.MergeRequest, comment string) error
}

type gitlabClientImpl struct {
client *gitlab.Client
me *gitlab.User
config *GitlabConfig
}

func NewGitlabClient(config GitlabConfig) (*GitlabClient, error) {
func NewGitlabClient(config GitlabConfig) (GitlabClient, error) {
git, err := gitlab.NewClient(config.AccessToken, gitlab.WithBaseURL(config.BaseURL))
if err != nil {
return nil, fmt.Errorf("failed to authenticate to GitLab: %w", err)
Expand All @@ -28,14 +36,14 @@ func NewGitlabClient(config GitlabConfig) (*GitlabClient, error) {
if err != nil {
return nil, fmt.Errorf("failed to get current user information from GitLab: %w", err)
}
return &GitlabClient{
return &gitlabClientImpl{
client: git,
me: me,
config: &config,
}, nil
}

func (g *GitlabClient) GetConfigFileForMR(mr *gitlab.MergeRequest, filePath string) (*[]byte, error) {
func (g *gitlabClientImpl) GetConfigFileForMR(mr *gitlab.MergeRequest, filePath string) (*[]byte, error) {
opts := &gitlab.GetRawFileOptions{Ref: &mr.SourceBranch}
file, _, err := g.client.RepositoryFiles.GetRawFile(mr.ProjectID, filePath, opts)
if err != nil {
Expand All @@ -44,7 +52,7 @@ func (g *GitlabClient) GetConfigFileForMR(mr *gitlab.MergeRequest, filePath stri
return &file, nil
}

func (g *GitlabClient) ListMrsWithLabel(label string) ([]*gitlab.MergeRequest, error) {
func (g *gitlabClientImpl) ListMrsWithLabel(label string) ([]*gitlab.MergeRequest, error) {
labels := gitlab.LabelOptions{label}
opts := &gitlab.ListMergeRequestsOptions{
ListOptions: gitlab.ListOptions{
Expand Down Expand Up @@ -72,7 +80,7 @@ func (g *GitlabClient) ListMrsWithLabel(label string) ([]*gitlab.MergeRequest, e
return allMrs, nil
}

func (g *GitlabClient) RefreshMr(mr *gitlab.MergeRequest) (*gitlab.MergeRequest, error) {
func (g *gitlabClientImpl) RefreshMr(mr *gitlab.MergeRequest) (*gitlab.MergeRequest, error) {
opts := &gitlab.GetMergeRequestsOptions{}
mr, _, err := g.client.MergeRequests.GetMergeRequest(mr.ProjectID, mr.IID, opts)
if err != nil {
Expand All @@ -82,7 +90,7 @@ func (g *GitlabClient) RefreshMr(mr *gitlab.MergeRequest) (*gitlab.MergeRequest,
return mr, nil
}

func (g *GitlabClient) MergeMr(mr *gitlab.MergeRequest) error {
func (g *gitlabClientImpl) MergeMr(mr *gitlab.MergeRequest) error {
opts := &gitlab.AcceptMergeRequestOptions{ShouldRemoveSourceBranch: gitlab.Ptr(true)}
_, _, err := g.client.MergeRequests.AcceptMergeRequest(mr.ProjectID, mr.IID, opts)
if err != nil {
Expand All @@ -91,11 +99,7 @@ func (g *GitlabClient) MergeMr(mr *gitlab.MergeRequest) error {
return nil
}

func IsMergeable(mr *gitlab.MergeRequest) bool {
return mr.DetailedMergeStatus == MR_MERGE_STATUS_MERGEABLE
}

func (g *GitlabClient) Comment(mr *gitlab.MergeRequest, comment string) error {
func (g *gitlabClientImpl) Comment(mr *gitlab.MergeRequest, comment string) error {
nopts := &gitlab.ListMergeRequestNotesOptions{}
notes, _, err := g.client.Notes.ListMergeRequestNotes(mr.ProjectID, mr.IID, nopts)
if err != nil {
Expand All @@ -120,3 +124,7 @@ func (g *GitlabClient) Comment(mr *gitlab.MergeRequest, comment string) error {
}
return nil
}

func IsMergeable(mr *gitlab.MergeRequest) bool {
return mr.DetailedMergeStatus == MR_MERGE_STATUS_MERGEABLE
}
113 changes: 113 additions & 0 deletions client/mock/client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,21 @@ go 1.22.2
require (
github.com/robfig/cron/v3 v3.0.1
github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.8.1
github.com/xanzy/go-gitlab v0.106.0
go.uber.org/mock v0.4.0
go.uber.org/multierr v1.11.0
gopkg.in/yaml.v3 v3.0.1
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.2 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/net v0.8.0 // indirect
golang.org/x/oauth2 v0.6.0 // indirect
Expand Down
9 changes: 9 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
Expand Down Expand Up @@ -28,11 +29,18 @@ github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/xanzy/go-gitlab v0.106.0 h1:EDfD03K74cIlQo2EducfiupVrip+Oj02bq9ofw5F8sA=
github.com/xanzy/go-gitlab v0.106.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI=
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
Expand All @@ -56,5 +64,6 @@ google.golang.org/protobuf v1.29.1 h1:7QBf+IK2gx70Ap/hDsOmam3GE0v9HicjfEdAxE62Uo
google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func main() {
}

func setupCronTask(
client *client.GitlabClient,
client client.GitlabClient,
crontab string,
scheduledLabel string,
configFilePath string,
Expand Down
34 changes: 27 additions & 7 deletions task/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ type TaskConfig struct {

type Task struct {
config TaskConfig
client *client.GitlabClient
client client.GitlabClient
clock Clock
}

type RepositoryConfig struct {
Expand All @@ -36,10 +37,29 @@ type MergeSchedule struct {
Location string `yaml:"location"`
}

func NewTask(client *client.GitlabClient, config TaskConfig) Task {
type Clock interface {
Now() time.Time
}

type realClock struct{}

func (realClock) Now() time.Time {
return time.Now()
}

func NewTask(client client.GitlabClient, config TaskConfig) Task {
return Task{
config: config,
client: client,
clock: realClock{},
}
}

func NewTaskWithClock(client client.GitlabClient, config TaskConfig, clock Clock) Task {
return Task{
config: config,
client: client,
clock: clock,
}
}

Expand Down Expand Up @@ -71,16 +91,16 @@ func (t Task) processMR(mr *gitlab.MergeRequest) error {
err = yaml.Unmarshal(*file, &config)

if err != nil {
return t.client.Comment(mr, "Failed to schedule merge: error while parsing config file.")
return t.client.Comment(mr, fmt.Sprintf("Failed to schedule merge: Error while parsing config file.\n\n%s", err.Error()))
}

now := time.Now()
now := t.clock.Now()
var earliestMergeWindow *MergeWindow = nil
earliestMergeWindowTime := now.Add(1000000 * time.Hour)
for _, w := range config.MergeWindows {
nextActiveStartTime, err := w.getNextActiveWindowStartTime(now)
if err != nil {
return t.client.Comment(mr, "Failed to schedule merge: error while parsing merge windows.")
return t.client.Comment(mr, fmt.Sprintf("Failed to schedule merge: Error while parsing merge windows.\n\n%s", err.Error()))
}
if nextActiveStartTime.Before(now) {
return t.mergeMR(mr)
Expand Down Expand Up @@ -113,7 +133,7 @@ func (t Task) mergeMR(mr *gitlab.MergeRequest) error {
// We need to recheck MRs - we might in the interim have merged other things that led to conflicts
rmr, err := t.client.RefreshMr(mr)
if err != nil {
return t.client.Comment(mr, "Failed to merge: error while refreshing merge request data.")
return t.client.Comment(mr, fmt.Sprintf("Failed to merge: error while refreshing merge request data.\n\n%s", err.Error()))
}

if !client.IsMergeable(rmr) {
Expand All @@ -122,7 +142,7 @@ func (t Task) mergeMR(mr *gitlab.MergeRequest) error {

err = t.client.MergeMr(rmr)
if err != nil {
return t.client.Comment(mr, "Failed to merge: error while merging.")
return t.client.Comment(mr, fmt.Sprintf("Failed to merge: Error while merging.\n\n%s", err.Error()))
}

return nil
Expand Down
Loading

0 comments on commit 22a6f4a

Please sign in to comment.