[autoroll] Support projects without Commit Queue
Bug: skia:9529
Change-Id: I922f6b3b94ae40e5c78b8eb3c7484f597727c586
Reviewed-on: https://skia-review.googlesource.com/c/buildbot/+/250318
Commit-Queue: Eric Boren <borenet@google.com>
Reviewed-by: Ravi Mistry <rmistry@google.com>
diff --git a/autoroll/go/codereview/config.go b/autoroll/go/codereview/config.go
index daf30c2..f805b06 100644
--- a/autoroll/go/codereview/config.go
+++ b/autoroll/go/codereview/config.go
@@ -20,17 +20,22 @@
// GERRIT_CONFIG_ANGLE is a Gerrit server configuration used by ANGLE.
GERRIT_CONFIG_ANGLE = "angle"
- // GERIT_CONFIG_CHROMIUM is a Gerrit server configuration used by
+ // GERRIT_CONFIG_CHROMIUM is a Gerrit server configuration used by
// Chromium and related projects.
GERRIT_CONFIG_CHROMIUM = "chromium"
+
+ // GERRIT_CONFIG_CHROMIUM_NO_CQ is a Gerrit server configuration used by
+ // Chromium for projects with no Commit Queue.
+ GERRIT_CONFIG_CHROMIUM_NO_CQ = "chromium-no-cq"
)
var (
// GERRIT_CONFIGS maps Gerrit config names to gerrit.Configs.
GERRIT_CONFIGS = map[string]*gerrit.Config{
- GERRIT_CONFIG_ANDROID: gerrit.CONFIG_ANDROID,
- GERRIT_CONFIG_ANGLE: gerrit.CONFIG_ANGLE,
- GERRIT_CONFIG_CHROMIUM: gerrit.CONFIG_CHROMIUM,
+ GERRIT_CONFIG_ANDROID: gerrit.CONFIG_ANDROID,
+ GERRIT_CONFIG_ANGLE: gerrit.CONFIG_ANGLE,
+ GERRIT_CONFIG_CHROMIUM: gerrit.CONFIG_CHROMIUM,
+ GERRIT_CONFIG_CHROMIUM_NO_CQ: gerrit.CONFIG_CHROMIUM_NO_CQ,
}
)
diff --git a/autoroll/go/codereview/roll_test.go b/autoroll/go/codereview/roll_test.go
index db67843..7f32993 100644
--- a/autoroll/go/codereview/roll_test.go
+++ b/autoroll/go/codereview/roll_test.go
@@ -428,6 +428,10 @@
RollingTo: "def456",
Subject: "roll the deps",
}
+ if !cfg.HasCq {
+ expect.CqFinished = true
+ expect.Result = autoroll.ROLL_RESULT_FAILURE
+ }
deepequal.AssertDeepEqual(t, expect, a)
// CQ failed.
@@ -481,6 +485,11 @@
expect.CqFinished = false
expect.IsDryRun = true
expect.Result = autoroll.ROLL_RESULT_DRY_RUN_IN_PROGRESS
+ if !cfg.HasCq {
+ expect.DryRunFinished = true
+ expect.DryRunSuccess = true
+ expect.Result = autoroll.ROLL_RESULT_DRY_RUN_SUCCESS
+ }
a.IsDryRun = true
require.NoError(t, updateIssueFromGerritChangeInfo(a, ci, cfg))
deepequal.AssertDeepEqual(t, expect, a)
@@ -500,6 +509,10 @@
Status: autoroll.TRYBOT_STATUS_COMPLETED,
},
}
+ if !cfg.HasCq {
+ expect.DryRunSuccess = true
+ expect.Result = autoroll.ROLL_RESULT_DRY_RUN_SUCCESS
+ }
a.TryResults = expect.TryResults
require.NoError(t, updateIssueFromGerritChangeInfo(a, ci, cfg))
deepequal.AssertDeepEqual(t, expect, a)
@@ -510,6 +523,7 @@
ci.Status = gerrit.CHANGE_STATUS_ABANDONED
expect.Closed = true
expect.DryRunFinished = true
+ expect.DryRunSuccess = false
expect.Result = autoroll.ROLL_RESULT_DRY_RUN_FAILURE
require.NoError(t, updateIssueFromGerritChangeInfo(a, ci, cfg))
deepequal.AssertDeepEqual(t, expect, a)
@@ -553,6 +567,10 @@
testUpdateFromGerritChangeInfo(t, gerrit.CONFIG_CHROMIUM)
}
+func TestUpdateFromGerritChangeInfoChromiumNoCQ(t *testing.T) {
+ testUpdateFromGerritChangeInfo(t, gerrit.CONFIG_CHROMIUM_NO_CQ)
+}
+
func TestUpdateFromGitHubPullRequest(t *testing.T) {
unittest.SmallTest(t)
diff --git a/autoroll/go/repo_manager/no_checkout_deps_repo_manager_test.go b/autoroll/go/repo_manager/no_checkout_deps_repo_manager_test.go
index 3375e34..1a0177c 100644
--- a/autoroll/go/repo_manager/no_checkout_deps_repo_manager_test.go
+++ b/autoroll/go/repo_manager/no_checkout_deps_repo_manager_test.go
@@ -23,7 +23,7 @@
"go.skia.org/infra/go/testutils/unittest"
)
-func setupNoCheckout(t *testing.T, cfg *NoCheckoutDEPSRepoManagerConfig, strategy string) (context.Context, string, RepoManager, *git_testutils.GitBuilder, *git_testutils.GitBuilder, *gitiles_testutils.MockRepo, *gitiles_testutils.MockRepo, []string, *mockhttpclient.URLMock, func()) {
+func setupNoCheckout(t *testing.T, cfg *NoCheckoutDEPSRepoManagerConfig, strategy string, gerritCfg *gerrit.Config) (context.Context, string, RepoManager, *git_testutils.GitBuilder, *git_testutils.GitBuilder, *gitiles_testutils.MockRepo, *gitiles_testutils.MockRepo, []string, *mockhttpclient.URLMock, func()) {
unittest.LargeTest(t)
wd, err := ioutil.TempDir("", "")
@@ -68,7 +68,7 @@
require.NoError(t, err)
serialized = append([]byte("abcd\n"), serialized...)
urlmock.MockOnce(gUrl+"/a/accounts/self/detail", mockhttpclient.MockGetDialogue(serialized))
- g, err := gerrit.NewGerrit(gUrl, gitcookies, urlmock.Client())
+ g, err := gerrit.NewGerritWithConfig(gerritCfg, gUrl, gitcookies, urlmock.Client())
require.NoError(t, err)
cfg.ChildRepo = child.RepoUrl()
@@ -111,7 +111,7 @@
func TestNoCheckoutDEPSRepoManagerUpdate(t *testing.T) {
cfg := noCheckoutDEPSCfg()
- ctx, _, rm, _, parentRepo, mockChild, mockParent, childCommits, _, cleanup := setupNoCheckout(t, cfg, strategy.ROLL_STRATEGY_BATCH)
+ ctx, _, rm, _, parentRepo, mockChild, mockParent, childCommits, _, cleanup := setupNoCheckout(t, cfg, strategy.ROLL_STRATEGY_BATCH, gerrit.CONFIG_CHROMIUM)
defer cleanup()
mockParent.MockGetCommit(ctx, "master")
@@ -148,7 +148,7 @@
func TestNoCheckoutDEPSRepoManagerStrategies(t *testing.T) {
cfg := noCheckoutDEPSCfg()
- ctx, _, rm, _, parentRepo, mockChild, mockParent, childCommits, _, cleanup := setupNoCheckout(t, cfg, strategy.ROLL_STRATEGY_SINGLE)
+ ctx, _, rm, _, parentRepo, mockChild, mockParent, childCommits, _, cleanup := setupNoCheckout(t, cfg, strategy.ROLL_STRATEGY_SINGLE, gerrit.CONFIG_CHROMIUM)
defer cleanup()
mockParent.MockGetCommit(ctx, "master")
@@ -179,9 +179,9 @@
require.Equal(t, childCommits[1], rm.NextRollRev().Id)
}
-func TestNoCheckoutDEPSRepoManagerCreateNewRoll(t *testing.T) {
+func testNoCheckoutDEPSRepoManagerCreateNewRoll(t *testing.T, gerritCfg *gerrit.Config) {
cfg := noCheckoutDEPSCfg()
- ctx, _, rm, childRepo, parentRepo, mockChild, mockParent, childCommits, urlmock, cleanup := setupNoCheckout(t, cfg, strategy.ROLL_STRATEGY_BATCH)
+ ctx, _, rm, childRepo, parentRepo, mockChild, mockParent, childCommits, urlmock, cleanup := setupNoCheckout(t, cfg, strategy.ROLL_STRATEGY_BATCH, gerritCfg)
defer cleanup()
mockParent.MockGetCommit(ctx, "master")
@@ -284,20 +284,35 @@
urlmock.MockOnce("https://fake-skia-review.googlesource.com/a/changes/123/ready", mockhttpclient.MockPostDialogue("application/json", reqBody, []byte("")))
// Mock the request to set the CQ.
- reqBody = []byte(`{"labels":{"Code-Review":1,"Commit-Queue":2},"message":"","reviewers":[{"reviewer":"me@google.com"}]}`)
+ if gerritCfg.HasCq {
+ reqBody = []byte(`{"labels":{"Code-Review":1,"Commit-Queue":2},"message":"","reviewers":[{"reviewer":"me@google.com"}]}`)
+ } else {
+ reqBody = []byte(`{"labels":{"Code-Review":1},"message":"","reviewers":[{"reviewer":"me@google.com"}]}`)
+ }
urlmock.MockOnce("https://fake-skia-review.googlesource.com/a/changes/123/revisions/ps1/review", mockhttpclient.MockPostDialogue("application/json", reqBody, []byte("")))
+ if !gerritCfg.HasCq {
+ urlmock.MockOnce("https://fake-skia-review.googlesource.com/a/changes/123/submit", mockhttpclient.MockPostDialogue("application/json", []byte("{}"), []byte("")))
+ }
issue, err := rm.CreateNewRoll(ctx, rm.LastRollRev(), rm.NextRollRev(), []string{"me@google.com"}, "", false)
require.NoError(t, err)
require.NotEqual(t, 0, issue)
}
+func TestNoCheckoutDEPSRepoManagerCreateNewRoll(t *testing.T) {
+ testNoCheckoutDEPSRepoManagerCreateNewRoll(t, gerrit.CONFIG_CHROMIUM)
+}
+
+func TestNoCheckoutDEPSRepoManagerCreateNewRollNoCQ(t *testing.T) {
+ testNoCheckoutDEPSRepoManagerCreateNewRoll(t, gerrit.CONFIG_CHROMIUM_NO_CQ)
+}
+
func TestNoCheckoutDEPSRepoManagerCreateNewRollTransitive(t *testing.T) {
cfg := noCheckoutDEPSCfg()
cfg.TransitiveDeps = map[string]string{
"child/dep": "parent/dep",
}
- ctx, _, rm, childRepo, parentRepo, mockChild, mockParent, childCommits, urlmock, cleanup := setupNoCheckout(t, cfg, strategy.ROLL_STRATEGY_BATCH)
+ ctx, _, rm, childRepo, parentRepo, mockChild, mockParent, childCommits, urlmock, cleanup := setupNoCheckout(t, cfg, strategy.ROLL_STRATEGY_BATCH, gerrit.CONFIG_CHROMIUM)
defer cleanup()
mockParent.MockGetCommit(ctx, "master")
diff --git a/autoroll/go/repo_manager/no_checkout_repo_manager.go b/autoroll/go/repo_manager/no_checkout_repo_manager.go
index c934988..60b151b 100644
--- a/autoroll/go/repo_manager/no_checkout_repo_manager.go
+++ b/autoroll/go/repo_manager/no_checkout_repo_manager.go
@@ -134,6 +134,14 @@
return 0, fmt.Errorf("Failed to set review: %s", err)
}
+ // Manually submit if necessary.
+ if !rm.g.Config().HasCq {
+ if err := rm.g.Submit(ctx, ci); err != nil {
+ // TODO(borenet): Should we try to abandon the CL?
+ return 0, fmt.Errorf("Failed to submit: %s", err)
+ }
+ }
+
return ci.Issue, nil
}
diff --git a/go/autoroll/autoroll.go b/go/autoroll/autoroll.go
index 40b5602..5590be7 100644
--- a/go/autoroll/autoroll.go
+++ b/go/autoroll/autoroll.go
@@ -236,7 +236,9 @@
continue
}
if !t.Succeeded() {
- sklog.Infof(" ...failed")
+ if t.Finished() {
+ sklog.Infof(" ...failed")
+ }
return false
}
}
diff --git a/go/gerrit/config.go b/go/gerrit/config.go
index c3f5b00..154b2d1 100644
--- a/go/gerrit/config.go
+++ b/go/gerrit/config.go
@@ -5,6 +5,7 @@
SelfApproveLabels: map[string]int{
CODEREVIEW_LABEL: CODEREVIEW_LABEL_SELF_APPROVE,
},
+ HasCq: true,
SetCqLabels: map[string]int{
AUTOSUBMIT_LABEL: AUTOSUBMIT_LABEL_SUBMIT,
PRESUBMIT_READY_LABEL: PRESUBMIT_READY_LABEL_ENABLE,
@@ -44,6 +45,7 @@
SelfApproveLabels: map[string]int{
CODEREVIEW_LABEL: CODEREVIEW_LABEL_SELF_APPROVE,
},
+ HasCq: true,
SetCqLabels: map[string]int{
COMMITQUEUE_LABEL: COMMITQUEUE_LABEL_SUBMIT,
},
@@ -70,6 +72,7 @@
SelfApproveLabels: map[string]int{
CODEREVIEW_LABEL: CODEREVIEW_LABEL_APPROVE,
},
+ HasCq: true,
SetCqLabels: map[string]int{
COMMITQUEUE_LABEL: COMMITQUEUE_LABEL_SUBMIT,
},
@@ -91,6 +94,25 @@
DryRunFailureLabels: map[string]int{},
DryRunUsesTryjobResults: true,
}
+
+ CONFIG_CHROMIUM_NO_CQ = &Config{
+ SelfApproveLabels: map[string]int{
+ CODEREVIEW_LABEL: CODEREVIEW_LABEL_APPROVE,
+ },
+ HasCq: false,
+ SetCqLabels: map[string]int{},
+ SetDryRunLabels: map[string]int{},
+ NoCqLabels: map[string]int{
+ COMMITQUEUE_LABEL: COMMITQUEUE_LABEL_NONE,
+ },
+ CqActiveLabels: map[string]int{},
+ CqSuccessLabels: map[string]int{},
+ CqFailureLabels: map[string]int{},
+ DryRunActiveLabels: map[string]int{},
+ DryRunSuccessLabels: map[string]int{},
+ DryRunFailureLabels: map[string]int{},
+ DryRunUsesTryjobResults: false,
+ }
)
type Config struct {
@@ -98,6 +120,9 @@
// same as a normal approval.
SelfApproveLabels map[string]int
+ // Whether or not this project has a Commit Queue.
+ HasCq bool
+
// Labels to set to run the Commit Queue.
SetCqLabels map[string]int
// Labels to set to run the Commit Queue in dry run mode.
@@ -164,6 +189,9 @@
// CqRunning returns true if the commit queue is still running. Returns false if
// the change is merged or abandoned.
func (c *Config) CqRunning(ci *ChangeInfo) bool {
+ if !c.HasCq {
+ return false
+ }
if ci.IsClosed() {
return false
}
@@ -184,6 +212,9 @@
// DryRunRunning returns true if the dry run is still running. Returns false if
// the change is merged or abandoned.
func (c *Config) DryRunRunning(ci *ChangeInfo) bool {
+ if !c.HasCq {
+ return false
+ }
if ci.IsClosed() {
return false
}
@@ -203,6 +234,12 @@
if ci.IsClosed() {
return ci.IsMerged()
}
+ if !c.HasCq {
+ // DryRunSuccess indicates that the CL has passed all of the
+ // checks required for submission; if there are no checks, then
+ // it has passed all of them by default.
+ return true
+ }
if len(c.DryRunSuccessLabels) > 0 && all(ci, c.DryRunSuccessLabels) {
return true
}
diff --git a/go/gerrit/config_test.go b/go/gerrit/config_test.go
index bfaff91..e562e2a 100644
--- a/go/gerrit/config_test.go
+++ b/go/gerrit/config_test.go
@@ -21,17 +21,32 @@
require.False(t, cfg.CqRunning(ci))
require.False(t, cfg.CqSuccess(ci))
require.False(t, cfg.DryRunRunning(ci))
- // Have to use false here because ANGLE and Chromium configs do not use
- // CQ success/failure labels, so we can't distinguish between "dry run
- // finished" and "dry run never started".
- require.False(t, cfg.DryRunSuccess(ci, false))
+ if cfg.HasCq {
+ // Have to use false here because ANGLE and Chromium configs do not use
+ // CQ success/failure labels, so we can't distinguish between "dry run
+ // finished" and "dry run never started".
+ require.False(t, cfg.DryRunSuccess(ci, false))
+ } else {
+ // DryRunSuccess is always true with no CQ.
+ require.True(t, cfg.DryRunSuccess(ci, false))
+ }
// CQ in progress.
SetLabels(ci, cfg.SetCqLabels)
- require.True(t, cfg.CqRunning(ci))
- require.False(t, cfg.CqSuccess(ci))
- require.False(t, cfg.DryRunRunning(ci))
- require.False(t, cfg.DryRunSuccess(ci, true))
+ if cfg.HasCq {
+ require.True(t, cfg.CqRunning(ci))
+ require.False(t, cfg.CqSuccess(ci))
+ require.False(t, cfg.DryRunRunning(ci))
+ require.False(t, cfg.DryRunSuccess(ci, true))
+ } else {
+ // CQ and DryRun are never running with no CQ. CqSuccess is only
+ // true if the change is merged, and DryRunSuccess is always
+ // true.
+ require.False(t, cfg.CqRunning(ci))
+ require.False(t, cfg.CqSuccess(ci))
+ require.False(t, cfg.DryRunRunning(ci))
+ require.True(t, cfg.DryRunSuccess(ci, true))
+ }
// CQ success.
if len(cfg.CqSuccessLabels) > 0 {
@@ -39,10 +54,20 @@
}
UnsetLabels(ci, cfg.CqActiveLabels)
ci.Status = CHANGE_STATUS_MERGED
- require.False(t, cfg.CqRunning(ci))
- require.True(t, cfg.CqSuccess(ci))
- require.False(t, cfg.DryRunRunning(ci))
- require.True(t, cfg.DryRunSuccess(ci, false))
+ if cfg.HasCq {
+ require.False(t, cfg.CqRunning(ci))
+ require.True(t, cfg.CqSuccess(ci))
+ require.False(t, cfg.DryRunRunning(ci))
+ require.True(t, cfg.DryRunSuccess(ci, false))
+ } else {
+ // CQ and DryRun are never running with no CQ. CqSuccess is only
+ // true if the change is merged, and DryRunSuccess is always
+ // true.
+ require.False(t, cfg.CqRunning(ci))
+ require.True(t, cfg.CqSuccess(ci))
+ require.False(t, cfg.DryRunRunning(ci))
+ require.True(t, cfg.DryRunSuccess(ci, true))
+ }
// CQ failed.
if len(cfg.CqSuccessLabels) > 0 {
@@ -52,10 +77,20 @@
SetLabels(ci, cfg.CqFailureLabels)
}
ci.Status = ""
- require.False(t, cfg.CqRunning(ci))
- require.False(t, cfg.CqSuccess(ci))
- require.False(t, cfg.DryRunRunning(ci))
- require.False(t, cfg.DryRunSuccess(ci, false))
+ if cfg.HasCq {
+ require.False(t, cfg.CqRunning(ci))
+ require.False(t, cfg.CqSuccess(ci))
+ require.False(t, cfg.DryRunRunning(ci))
+ require.False(t, cfg.DryRunSuccess(ci, false))
+ } else {
+ // CQ and DryRun are never running with no CQ. CqSuccess is only
+ // true if the change is merged, and DryRunSuccess is always
+ // true.
+ require.False(t, cfg.CqRunning(ci))
+ require.False(t, cfg.CqSuccess(ci))
+ require.False(t, cfg.DryRunRunning(ci))
+ require.True(t, cfg.DryRunSuccess(ci, true))
+ }
// Dry run in progress.
if len(cfg.CqFailureLabels) > 0 {
@@ -63,10 +98,20 @@
}
UnsetLabels(ci, cfg.SetCqLabels)
SetLabels(ci, cfg.SetDryRunLabels)
- require.False(t, cfg.CqRunning(ci))
- require.False(t, cfg.CqSuccess(ci))
- require.True(t, cfg.DryRunRunning(ci))
- require.False(t, cfg.DryRunSuccess(ci, true))
+ if cfg.HasCq {
+ require.False(t, cfg.CqRunning(ci))
+ require.False(t, cfg.CqSuccess(ci))
+ require.True(t, cfg.DryRunRunning(ci))
+ require.False(t, cfg.DryRunSuccess(ci, true))
+ } else {
+ // CQ and DryRun are never running with no CQ. CqSuccess is only
+ // true if the change is merged, and DryRunSuccess is always
+ // true.
+ require.False(t, cfg.CqRunning(ci))
+ require.False(t, cfg.CqSuccess(ci))
+ require.False(t, cfg.DryRunRunning(ci))
+ require.True(t, cfg.DryRunSuccess(ci, true))
+ }
// Dry run success.
if len(cfg.DryRunSuccessLabels) > 0 {
@@ -85,10 +130,20 @@
if len(cfg.DryRunFailureLabels) > 0 {
SetLabels(ci, cfg.DryRunFailureLabels)
}
- require.False(t, cfg.CqRunning(ci))
- require.False(t, cfg.CqSuccess(ci))
- require.False(t, cfg.DryRunRunning(ci))
- require.False(t, cfg.DryRunSuccess(ci, false))
+ if cfg.HasCq {
+ require.False(t, cfg.CqRunning(ci))
+ require.False(t, cfg.CqSuccess(ci))
+ require.False(t, cfg.DryRunRunning(ci))
+ require.False(t, cfg.DryRunSuccess(ci, false))
+ } else {
+ // CQ and DryRun are never running with no CQ. CqSuccess is only
+ // true if the change is merged, and DryRunSuccess is always
+ // true.
+ require.False(t, cfg.CqRunning(ci))
+ require.False(t, cfg.CqSuccess(ci))
+ require.False(t, cfg.DryRunRunning(ci))
+ require.True(t, cfg.DryRunSuccess(ci, true))
+ }
}
func TestConfigAndroid(t *testing.T) {
@@ -102,3 +157,7 @@
func TestConfigChromium(t *testing.T) {
testConfig(t, CONFIG_CHROMIUM)
}
+
+func TestConfigChromiumNoCQ(t *testing.T) {
+ testConfig(t, CONFIG_CHROMIUM_NO_CQ)
+}
diff --git a/go/gerrit/gerrit.go b/go/gerrit/gerrit.go
index 9b501b1..5a28246 100644
--- a/go/gerrit/gerrit.go
+++ b/go/gerrit/gerrit.go
@@ -239,6 +239,7 @@
SetReadyForReview(context.Context, *ChangeInfo) error
SetReview(context.Context, *ChangeInfo, string, map[string]int, []string) error
SetTopic(context.Context, string, int64) error
+ Submit(context.Context, *ChangeInfo) error
TurnOnAuthenticatedGets()
Url(int64) string
}
@@ -937,6 +938,11 @@
return false, nil
}
+// Submit submits the Change.
+func (g *Gerrit) Submit(ctx context.Context, ci *ChangeInfo) error {
+ return g.post(ctx, fmt.Sprintf("/a/changes/%d/submit", ci.Issue), []byte("{}"))
+}
+
// CodeReviewCache is an LRU cache for Gerrit Issues that polls in the background to determine if
// issues have been updated. If so it expells them from the cache to force a reload.
type CodeReviewCache struct {
diff --git a/go/gerrit/mocks/GerritInterface.go b/go/gerrit/mocks/GerritInterface.go
index 36a988f..c300a3b 100644
--- a/go/gerrit/mocks/GerritInterface.go
+++ b/go/gerrit/mocks/GerritInterface.go
@@ -542,6 +542,20 @@
return r0
}
+// Submit provides a mock function with given fields: _a0, _a1
+func (_m *GerritInterface) Submit(_a0 context.Context, _a1 *gerrit.ChangeInfo) error {
+ ret := _m.Called(_a0, _a1)
+
+ var r0 error
+ if rf, ok := ret.Get(0).(func(context.Context, *gerrit.ChangeInfo) error); ok {
+ r0 = rf(_a0, _a1)
+ } else {
+ r0 = ret.Error(0)
+ }
+
+ return r0
+}
+
// TurnOnAuthenticatedGets provides a mock function with given fields:
func (_m *GerritInterface) TurnOnAuthenticatedGets() {
_m.Called()
diff --git a/go/gerrit/mocks/simple_mock_gerrit.go b/go/gerrit/mocks/simple_mock_gerrit.go
index 411eda9..f474572 100644
--- a/go/gerrit/mocks/simple_mock_gerrit.go
+++ b/go/gerrit/mocks/simple_mock_gerrit.go
@@ -126,5 +126,9 @@
return nil
}
+func (g *SimpleGerritInterface) Submit(ctx context.Context, ci *gerrit.ChangeInfo) error {
+ return nil
+}
+
// Make sure MockGerrit fulfills GerritInterface
var _ gerrit.GerritInterface = (*SimpleGerritInterface)(nil)