all: fix generic comparisons on protobuf messages

External counterpart of cl/282460381.

Change-Id: I1b01326214083b7d994d1b2f91bb754a6d182ca2
Reviewed-on: https://code-review.googlesource.com/c/gocloud/+/48894
Reviewed-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Joe Tsai <joetsai@google.com>
Reviewed-by: Tyler Bui-Palsulich <tbp@google.com>
diff --git a/bigtable/bttest/inmem_test.go b/bigtable/bttest/inmem_test.go
index 469b3c1..5e7dd5d 100644
--- a/bigtable/bttest/inmem_test.go
+++ b/bigtable/bttest/inmem_test.go
@@ -30,7 +30,6 @@
 	"github.com/golang/protobuf/proto"
 	"github.com/golang/protobuf/ptypes/wrappers"
 	"github.com/google/go-cmp/cmp"
-	"github.com/google/go-cmp/cmp/cmpopts"
 	btapb "google.golang.org/genproto/googleapis/bigtable/admin/v2"
 	btpb "google.golang.org/genproto/googleapis/bigtable/v2"
 	"google.golang.org/grpc"
@@ -1050,8 +1049,13 @@
 			// bttest for some reason undeterministically returns:
 			//      RowStatus: &bigtable.ReadRowsResponse_CellChunk_CommitRow{CommitRow: true},
 			// so we'll ignore that field during comparison.
-			ignore := cmpopts.IgnoreFields(btpb.ReadRowsResponse_CellChunk{}, "RowStatus")
-			diff := cmp.Diff(gotCellChunks, wantCellChunks, ignore)
+			scrubRowStatus := func(cs []*btpb.ReadRowsResponse_CellChunk) []*btpb.ReadRowsResponse_CellChunk {
+				for _, c := range cs {
+					c.RowStatus = nil
+				}
+				return cs
+			}
+			diff := cmp.Diff(scrubRowStatus(gotCellChunks), scrubRowStatus(wantCellChunks), cmp.Comparer(proto.Equal))
 			if diff != "" {
 				t.Fatalf("unexpected response: %s", diff)
 			}
@@ -1146,7 +1150,17 @@
 		},
 	}
 
-	diff := cmp.Diff(got, want, cmpopts.IgnoreFields(btpb.Cell{}, "TimestampMicros"))
+	scrubTimestamp := func(resp *btpb.ReadModifyWriteRowResponse) *btpb.ReadModifyWriteRowResponse {
+		for _, fam := range resp.GetRow().GetFamilies() {
+			for _, col := range fam.GetColumns() {
+				for _, cell := range col.GetCells() {
+					cell.TimestampMicros = 0
+				}
+			}
+		}
+		return resp
+	}
+	diff := cmp.Diff(scrubTimestamp(got), scrubTimestamp(want), cmp.Comparer(proto.Equal))
 	if diff != "" {
 		t.Errorf("unexpected response: %s", diff)
 	}
@@ -1592,7 +1606,7 @@
 			},
 		},
 	}
-	if diff := cmp.Diff(got, want); diff != "" {
+	if diff := cmp.Diff(got, want, cmp.Comparer(proto.Equal)); diff != "" {
 		t.Fatalf("Response mismatch: got: + want -\n%s", diff)
 	}
 }
@@ -1689,7 +1703,7 @@
 			},
 		},
 	}
-	if diff := cmp.Diff(gotChunks, wantChunks); diff != "" {
+	if diff := cmp.Diff(gotChunks, wantChunks, cmp.Comparer(proto.Equal)); diff != "" {
 		t.Fatalf("Response chunks mismatch: got: + want -\n%s", diff)
 	}
 }
diff --git a/bigtable/retry_test.go b/bigtable/retry_test.go
index 31f6d93..8e7f82a 100644
--- a/bigtable/retry_test.go
+++ b/bigtable/retry_test.go
@@ -283,7 +283,11 @@
 		status.Errorf(codes.FailedPrecondition, ""),
 		status.Errorf(codes.Aborted, ""),
 	}
-	if !testutil.Equal(want, errors) {
+	if !testutil.Equal(want, errors,
+		cmp.Comparer(func(x, y error) bool {
+			return x == y || (x != nil && y != nil && x.Error() == y.Error())
+		}),
+	) {
 		t.Errorf("unretryable errors: got: %v, want: %v", errors, want)
 	}
 }
diff --git a/firestore/conformance_test.go b/firestore/conformance_test.go
index df2a8c4..26e66d3 100644
--- a/firestore/conformance_test.go
+++ b/firestore/conformance_test.go
@@ -210,7 +210,7 @@
 		got, err := nSnapshots(iter, len(typedTestcase.Listen.Snapshots))
 		if err != nil {
 			return err
-		} else if diff := cmp.Diff(got, typedTestcase.Listen.Snapshots); diff != "" {
+		} else if diff := cmp.Diff(got, typedTestcase.Listen.Snapshots, cmp.Comparer(proto.Equal)); diff != "" {
 			return errors.New(diff)
 		}
 		if typedTestcase.Listen.IsError {