[gold] /json/triage RPC: If set, use image matching algorithm name as change author.
Bug: skia:9527
Change-Id: I63ad7715cb44efa1e0fc81b095ac056a3dcad055
Reviewed-on: https://skia-review.googlesource.com/c/buildbot/+/289632
Commit-Queue: Leandro Lovisolo <lovisolo@google.com>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
diff --git a/gold-client/go/goldclient/goldclient.go b/gold-client/go/goldclient/goldclient.go
index cedec00..65036d6 100644
--- a/gold-client/go/goldclient/goldclient.go
+++ b/gold-client/go/goldclient/goldclient.go
@@ -791,8 +791,9 @@
func (c *CloudClient) TriageAsPositive(testName types.TestName, digest types.Digest, changeListId string) error {
// Build TriageRequest struct and encode it into JSON.
triageRequest := &frontend.TriageRequest{
- TestDigestStatus: map[types.TestName]map[types.Digest]string{testName: {digest: expectations.Positive.String()}},
- ChangeListID: changeListId,
+ TestDigestStatus: map[types.TestName]map[types.Digest]string{testName: {digest: expectations.Positive.String()}},
+ ChangeListID: changeListId,
+ ImageMatchingAlgorithm: "", // TODO(lovisolo): Pipe through the image matching algorithm name.
}
jsonTriageRequest, err := json.Marshal(triageRequest)
if err != nil {
diff --git a/gold-client/go/goldclient/goldclient_test.go b/gold-client/go/goldclient/goldclient_test.go
index b7a2d85..e29819a 100644
--- a/gold-client/go/goldclient/goldclient_test.go
+++ b/gold-client/go/goldclient/goldclient_test.go
@@ -2004,7 +2004,7 @@
url := "https://testing-gold.skia.org/json/triage"
contentType := "application/json"
- body := bytes.NewReader([]byte(`{"testDigestStatus":{"MyTest":{"deadbeefcafefe771d61bf0ed3d84bc2":"positive"}},"issue":"123456"}`))
+ body := bytes.NewReader([]byte(`{"testDigestStatus":{"MyTest":{"deadbeefcafefe771d61bf0ed3d84bc2":"positive"}},"issue":"123456","imageMatchingAlgorithm":""}`))
httpClient.On("Post", url, contentType, body).Return(httpResponse([]byte{}, "200 OK", http.StatusOK), nil)
err = goldClient.TriageAsPositive("MyTest", "deadbeefcafefe771d61bf0ed3d84bc2", "123456")
@@ -2033,7 +2033,7 @@
url := "https://testing-gold.skia.org/json/triage"
contentType := "application/json"
- body := bytes.NewReader([]byte(`{"testDigestStatus":{"MyTest":{"deadbeefcafefe771d61bf0ed3d84bc2":"positive"}},"issue":"123456"}`))
+ body := bytes.NewReader([]byte(`{"testDigestStatus":{"MyTest":{"deadbeefcafefe771d61bf0ed3d84bc2":"positive"}},"issue":"123456","imageMatchingAlgorithm":""}`))
httpClient.On("Post", url, contentType, body).Return(httpResponse([]byte{}, "500 Internal Server Error", http.StatusInternalServerError), nil)
err = goldClient.TriageAsPositive("MyTest", "deadbeefcafefe771d61bf0ed3d84bc2", "123456")
diff --git a/golden/go/web/frontend/types.go b/golden/go/web/frontend/types.go
index 8d75f60..36bb6a9 100644
--- a/golden/go/web/frontend/types.go
+++ b/golden/go/web/frontend/types.go
@@ -95,6 +95,15 @@
// ChangeListID is the id of the ChangeList for which we want to change the expectations.
// "issue" is the JSON field for backwards compatibility.
ChangeListID string `json:"issue"`
+
+ // ImageMatchingAlgorithm is the name of the non-exact image matching algorithm requesting the
+ // triage (see http://go/gold-non-exact-matching). If set, the algorithm name will be used as
+ // the author of the triage action.
+ //
+ // An empty image matching algorithm indicates this is a manual triage operation, in which case
+ // the username that initiated the triage operation via Gold's UI will be used as the author of
+ // the operation.
+ ImageMatchingAlgorithm string `json:"imageMatchingAlgorithm"`
}
// TriageDelta represents one changed digest and the label that was
diff --git a/golden/go/web/web.go b/golden/go/web/web.go
index 920d980..e5d41d0 100644
--- a/golden/go/web/web.go
+++ b/golden/go/web/web.go
@@ -934,6 +934,11 @@
expStore = wh.ExpectationsStore.ForChangeList(req.ChangeListID, wh.ChangeListStore.System())
}
+ // If set, use the image matching algorithm's name as the author of this change.
+ if req.ImageMatchingAlgorithm != "" {
+ user = req.ImageMatchingAlgorithm
+ }
+
// Add the change.
if err := expStore.AddChange(ctx, tc, user); err != nil {
return skerr.Wrapf(err, "Failed to store the updated expectations.")
diff --git a/golden/go/web/web_test.go b/golden/go/web/web_test.go
index c87472c..200b719 100644
--- a/golden/go/web/web_test.go
+++ b/golden/go/web/web_test.go
@@ -550,15 +550,15 @@
}
}
-// TestTriage_SingleDigestOnMaster_SunnyDay_Success tests a common case of a developer triaging a
-// single test on the master branch.
-func TestTriage_SingleDigestOnMaster_SunnyDay_Success(t *testing.T) {
+// TestTriage_SingleDigestOnMaster_Success tests a common case of a developer triaging a single
+// test on the master branch.
+func TestTriage_SingleDigestOnMaster_Success(t *testing.T) {
unittest.SmallTest(t)
mes := &mock_expectations.Store{}
defer mes.AssertExpectations(t)
- user := "user@example.com"
+ const user = "user@example.com"
mes.On("AddChange", testutils.AnyContext, []expectations.Delta{
{
@@ -587,9 +587,46 @@
assert.NoError(t, err)
}
-// TestTriage_SingleDigestOnCL_SunnyDay_Success tests a common case of a developer triaging a single
-// test on a ChangeList.
-func TestTriage_SingleDigestOnCL_SunnyDay_Success(t *testing.T) {
+func TestTriage_SingleDigestOnMaster_ImageMatchingAlgorithmSet_UsesAlgorithmNameAsAuthor(t *testing.T) {
+ unittest.SmallTest(t)
+
+ mes := &mock_expectations.Store{}
+ defer mes.AssertExpectations(t)
+
+ const user = "user@example.com"
+ const algorithmName = "fuzzy"
+
+ mes.On("AddChange", testutils.AnyContext, []expectations.Delta{
+ {
+ Grouping: bug_revert.TestOne,
+ Digest: bug_revert.BravoUntriagedDigest,
+ Label: expectations.Negative,
+ },
+ }, algorithmName).Return(nil)
+
+ wh := Handlers{
+ HandlersConfig: HandlersConfig{
+ ExpectationsStore: mes,
+ },
+ }
+
+ tr := frontend.TriageRequest{
+ ChangeListID: "",
+ TestDigestStatus: map[types.TestName]map[types.Digest]string{
+ bug_revert.TestOne: {
+ bug_revert.BravoUntriagedDigest: expectations.Negative.String(),
+ },
+ },
+ ImageMatchingAlgorithm: algorithmName,
+ }
+
+ err := wh.triage(context.Background(), user, tr)
+ assert.NoError(t, err)
+}
+
+// TestTriage_SingleDigestOnCL_Success tests a common case of a developer triaging a single test on
+// a ChangeList.
+func TestTriage_SingleDigestOnCL_Success(t *testing.T) {
unittest.SmallTest(t)
mes := &mock_expectations.Store{}
@@ -599,9 +636,9 @@
defer clExp.AssertExpectations(t)
defer mcs.AssertExpectations(t)
- clID := "12345"
- crs := "github"
- user := "user@example.com"
+ const clID = "12345"
+ const crs = "github"
+ const user = "user@example.com"
mes.On("ForChangeList", clID, crs).Return(clExp)
@@ -635,6 +672,54 @@
assert.NoError(t, err)
}
+func TestTriage_SingleDigestOnCL_ImageMatchingAlgorithmSet_UsesAlgorithmNameAsAuthor(t *testing.T) {
+ unittest.SmallTest(t)
+
+ mes := &mock_expectations.Store{}
+ clExp := &mock_expectations.Store{}
+ mcs := &mock_clstore.Store{}
+ defer mes.AssertExpectations(t)
+ defer clExp.AssertExpectations(t)
+ defer mcs.AssertExpectations(t)
+
+ const clID = "12345"
+ const crs = "github"
+ const user = "user@example.com"
+ const algorithmName = "fuzzy"
+
+ mes.On("ForChangeList", clID, crs).Return(clExp)
+
+ clExp.On("AddChange", testutils.AnyContext, []expectations.Delta{
+ {
+ Grouping: bug_revert.TestOne,
+ Digest: bug_revert.BravoUntriagedDigest,
+ Label: expectations.Negative,
+ },
+ }, algorithmName).Return(nil)
+
+ mcs.On("System").Return(crs)
+
+ wh := Handlers{
+ HandlersConfig: HandlersConfig{
+ ExpectationsStore: mes,
+ ChangeListStore: mcs,
+ },
+ }
+
+ tr := frontend.TriageRequest{
+ ChangeListID: clID,
+ TestDigestStatus: map[types.TestName]map[types.Digest]string{
+ bug_revert.TestOne: {
+ bug_revert.BravoUntriagedDigest: expectations.Negative.String(),
+ },
+ },
+ ImageMatchingAlgorithm: algorithmName,
+ }
+
+ err := wh.triage(context.Background(), user, tr)
+ assert.NoError(t, err)
+}
+
// TestTriage_BulkTriageOnMaster_SunnyDay_Success tests the case of a developer triaging multiple
// tests at once (via bulk triage).
func TestTriage_BulkTriageOnMaster_SunnyDay_Success(t *testing.T) {
@@ -643,7 +728,7 @@
mes := &mock_expectations.Store{}
defer mes.AssertExpectations(t)
- user := "user@example.com"
+ const user = "user@example.com"
matcher := mock.MatchedBy(func(delta []expectations.Delta) bool {
assert.Contains(t, delta, expectations.Delta{
@@ -703,7 +788,7 @@
mes := &mock_expectations.Store{}
defer mes.AssertExpectations(t)
- user := "user@example.com"
+ const user = "user@example.com"
mes.On("AddChange", testutils.AnyContext, []expectations.Delta{
{