package main import ( "bytes" "errors" "log" "testing" "go.uber.org/mock/gomock" "src.opensuse.org/autogits/common" "src.opensuse.org/autogits/common/gitea-generated/models" mock_common "src.opensuse.org/autogits/common/mock" mock_main "src.opensuse.org/workflow-pr/mock" ) func TestRepoCheck(t *testing.T) { var logBuf bytes.Buffer oldOut := log.Writer() log.SetOutput(&logBuf) defer log.SetOutput(oldOut) t.Run("Consistency Check On Start", func(t *testing.T) { c := CreateDefaultStateChecker(true, nil, nil, 100) ctl := gomock.NewController(t) state := mock_main.NewMockStateChecker(ctl) c.i = state state.EXPECT().CheckRepos().Do(func() error { // only checkOnStart has checkInterval = 0 if c.checkInterval != 0 { t.Fail() } c.exitCheckLoop = true return nil }) c.ConsistencyCheckProcess() if c.checkInterval != 100 { t.Fail() } }) t.Run("No consistency Check On Start", func(t *testing.T) { c := CreateDefaultStateChecker(true, nil, nil, 100) ctl := gomock.NewController(t) state := mock_main.NewMockStateChecker(ctl) c.i = state nCalls := 10 state.EXPECT().CheckRepos().Do(func() error { // only checkOnStart has checkInterval = 0 if c.checkInterval != 100 { t.Fail() } nCalls-- if nCalls == 0 { c.exitCheckLoop = true } return nil }).Times(nCalls) c.checkOnStart = false c.ConsistencyCheckProcess() }) t.Run("CheckRepos() calls CheckProjectState() for each project", func(t *testing.T) { ctl := gomock.NewController(t) state := mock_main.NewMockStateChecker(ctl) gitea := mock_common.NewMockGitea(ctl) config1 := &common.AutogitConfig{ GitProjectName: "git_repo1", Organization: "repo1_org", } config2 := &common.AutogitConfig{ GitProjectName: "git_repo2", Organization: "repo2_org", } config3 := &common.AutogitConfig{ GitProjectName: "git_repo3", Organization: "repo3_org", } configs := &RequestProcessor{ configuredRepos: map[string][]*common.AutogitConfig{ "repo1_org": []*common.AutogitConfig{config1}, "repo2_org": []*common.AutogitConfig{config2}, "repo3_org": []*common.AutogitConfig{config3}, }, } r := configs.configuredRepos c := CreateDefaultStateChecker(true, configs, gitea, 100) c.i = state state.EXPECT().VerifyProjectState("repo1_org", r["repo1_org"], 0) state.EXPECT().VerifyProjectState("repo2_org", r["repo2_org"], 0) state.EXPECT().VerifyProjectState("repo3_org", r["repo3_org"], 0) if err := c.CheckRepos(); err != nil { t.Error(err) } }) t.Run("CheckRepos errors", func(t *testing.T) { ctl := gomock.NewController(t) state := mock_main.NewMockStateChecker(ctl) gitea := mock_common.NewMockGitea(ctl) git := mock_common.NewMockGitHandlerGenerator(ctl) config1 := &common.AutogitConfig{ GitProjectName: "git_repo1", Organization: "repo1_org", } configs := &RequestProcessor{ configuredRepos: map[string][]*common.AutogitConfig{ "repo1_org": []*common.AutogitConfig{config1}, }, } //r := configs.configuredRepos c := CreateDefaultStateChecker(true, configs, gitea, 100) c.i = state c.git = git err := errors.New("test error") state.EXPECT().VerifyProjectState("repo1_org", gomock.Any(), 0).Return(err) r := c.CheckRepos() if !errors.Is(r, err) { t.Error(err) } }) } type testGit struct { git *common.GitHandler } func (s *testGit) CreateGitHandler(a, b, c string) (*common.GitHandler, error) { return s.git, nil } func TestVerifyProjectState(t *testing.T) { var logBuf bytes.Buffer oldOut := log.Writer() log.SetOutput(&logBuf) defer log.SetOutput(oldOut) t.Run("Project state with no PRs", func(t *testing.T) { ctl := gomock.NewController(t) gitea := mock_common.NewMockGitea(ctl) git := &common.GitHandler{ DebugLogger: true, GitCommiter: "TestCommiter", GitEmail: "test@testing", GitPath: t.TempDir(), } setupGitForTests(t, git) org := "repo1_org" config1 := &common.AutogitConfig{ GitProjectName: "git_repo1", Organization: "repo1_org", Branch: "testing", Reviewers: []string{"reviewer1", "reviewer2"}, Workflows: []string{"pr"}, } configs := &RequestProcessor{ configuredRepos: map[string][]*common.AutogitConfig{ org: []*common.AutogitConfig{config1}, }, } gitea.EXPECT().CreateRepositoryIfNotExist(gomock.Any(), gomock.Any(), config1.GitProjectName).Return(&models.Repository{ SSHURL: "./prj", }, nil) gitea.EXPECT().GetRecentPullRequests(org, "testRepo") gitea.EXPECT().GetRecentCommits(org, "testRepo", "testing", gomock.Any()) c := CreateDefaultStateChecker(false, configs, gitea, 0) c.git = &testGit{ git: git, } err := c.VerifyProjectState("repo1_org", configs.configuredRepos[org], 0) if err != nil { t.Error(err) } }) t.Run("Project state with 1 PRs that doesn't trigger updates", func(t *testing.T) { ctl := gomock.NewController(t) gitea := mock_common.NewMockGitea(ctl) process := mock_main.NewMockPullRequestProcessor(ctl) git := &common.GitHandler{ DebugLogger: true, GitCommiter: "TestCommiter", GitEmail: "test@testing", GitPath: t.TempDir(), } setupGitForTests(t, git) org := "repo1_org" config1 := &common.AutogitConfig{ GitProjectName: "git_repo1", Organization: "repo1_org", Branch: "testing", Reviewers: []string{"reviewer1", "reviewer2"}, Workflows: []string{"pr"}, } configs := &RequestProcessor{ configuredRepos: map[string][]*common.AutogitConfig{ org: []*common.AutogitConfig{config1}, }, } gitea.EXPECT().CreateRepositoryIfNotExist(gomock.Any(), gomock.Any(), config1.GitProjectName).Return(&models.Repository{ SSHURL: "./prj", }, nil) gitea.EXPECT().GetRecentPullRequests(org, "testRepo").Return([]*models.PullRequest{ &models.PullRequest{ ID: 1234, URL: "url here", Index: 1234, State: "open", Labels: []*models.Label{ &models.Label{ ID: 1, }, }, User: &models.User{}, Base: &models.PRBranchInfo { Name: "one", Ref: "main", Sha: "123", Repo: &models.Repository { Owner: &models.User { }, }, }, Head: &models.PRBranchInfo { Name: "one", Ref: "main", Sha: "123", Repo: &models.Repository { Owner: &models.User { }, }, }, }, }, nil) gitea.EXPECT().GetRecentCommits(org, "testRepo", "testing", gomock.Any()) c := CreateDefaultStateChecker(false, configs, gitea, 0) c.git = &testGit{ git: git, } process.EXPECT().Process(gomock.Any(), gomock.Any(), gomock.Any()) c.processor.Opened = process err := c.VerifyProjectState("repo1_org", configs.configuredRepos[org], 0) if err != nil { t.Error(err) } }) }