Merge changes from topics "remove-notesmigration", "batch-update-factory"
* changes:
NotesMigration: Make config key names private
NoteDbSchemaUpdater: Inline NoteDb config option names
Remove InitNoteDb
NotesMigrationSchemaFactory: Remove NotesMigration check
NotesMigration: Remove readChangeSequence() method
NotesMigration: Remove unused methods
Replace configurable NotesMigration with a stub implementation
Remove unused MutableNotesMigration#failOnLoadForTest
Remove NotesMigration from AbstractChangeNotes.Args
ChangeReviewersByEmailIT: Use enableDb/disableDb helper methods
GetServerInfo: Always report NoteDb as enabled
NoteDbMetrics: Remove unused auto-rebuilding metrics
BatchUpdate: Remove non-assisted Factory
BatchUpdate: Inline newContext method
BatchUpdate: Make remaining protected methods private
Merge NoteDbBatchUpdate into BatchUpdate
* submodules:
* Update plugins/delete-project from branch 'master'
to 5f3fe725b6f943f9acf63270cf8a432f9e7fd97a
- Remove DatabaseDeleteHandler since ReviewDb is gone
Signed-off-by: Edwin Kempin <ekempin@google.com>
Change-Id: I3e362f58b6deb9878e76dcfb225fef086753e4e9
diff --git a/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java b/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
index 3b589b2..cbfd1ca 100644
--- a/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
+++ b/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
@@ -15,15 +15,15 @@
package com.google.gerrit.elasticsearch;
import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.gson.FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES;
import static java.nio.charset.StandardCharsets.UTF_8;
-import static org.apache.commons.codec.binary.Base64.decodeBase64;
import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
+import com.google.common.collect.Streams;
import com.google.common.flogger.FluentLogger;
import com.google.common.io.CharStreams;
import com.google.gerrit.common.Nullable;
@@ -40,6 +40,8 @@
import com.google.gerrit.index.query.FieldBundle;
import com.google.gerrit.index.query.Predicate;
import com.google.gerrit.index.query.QueryParseException;
+import com.google.gerrit.proto.Protos;
+import com.google.gerrit.reviewdb.converter.ProtoConverter;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.index.IndexUtils;
import com.google.gson.Gson;
@@ -48,9 +50,9 @@
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
-import com.google.gwtorm.protobuf.ProtobufCodec;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.ResultSet;
+import com.google.protobuf.MessageLite;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -85,14 +87,22 @@
protected static final String SETTINGS = "settings";
protected static <T> List<T> decodeProtos(
- JsonObject doc, String fieldName, ProtobufCodec<T> codec) {
+ JsonObject doc, String fieldName, ProtoConverter<?, T> converter) {
JsonArray field = doc.getAsJsonArray(fieldName);
if (field == null) {
return null;
}
- return FluentIterable.from(field)
- .transform(i -> codec.decode(decodeBase64(i.toString())))
- .toList();
+ return Streams.stream(field)
+ .map(JsonElement::toString)
+ .map(Base64::decodeBase64)
+ .map(bytes -> parseProtoFrom(bytes, converter))
+ .collect(toImmutableList());
+ }
+
+ private static <P extends MessageLite, T> T parseProtoFrom(
+ byte[] bytes, ProtoConverter<P, T> converter) {
+ P message = Protos.parseUnchecked(converter.getParser(), bytes);
+ return converter.fromProto(message);
}
static String getContent(Response response) throws IOException {
diff --git a/java/com/google/gerrit/elasticsearch/BUILD b/java/com/google/gerrit/elasticsearch/BUILD
index 8d23051..d5c586b 100644
--- a/java/com/google/gerrit/elasticsearch/BUILD
+++ b/java/com/google/gerrit/elasticsearch/BUILD
@@ -9,6 +9,7 @@
"//java/com/google/gerrit/index:query_exception",
"//java/com/google/gerrit/index/project",
"//java/com/google/gerrit/lifecycle",
+ "//java/com/google/gerrit/proto",
"//java/com/google/gerrit/reviewdb:server",
"//java/com/google/gerrit/server",
"//lib:gson",
diff --git a/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java b/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
index 1224c61..9aa65a7 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
@@ -14,9 +14,7 @@
package com.google.gerrit.elasticsearch;
-import static com.google.gerrit.reviewdb.server.ReviewDbCodecs.APPROVAL_CODEC;
import static com.google.gerrit.reviewdb.server.ReviewDbCodecs.CHANGE_CODEC;
-import static com.google.gerrit.reviewdb.server.ReviewDbCodecs.PATCH_SET_CODEC;
import static com.google.gerrit.server.index.change.ChangeIndexRewriter.CLOSED_STATUSES;
import static com.google.gerrit.server.index.change.ChangeIndexRewriter.OPEN_STATUSES;
import static java.nio.charset.StandardCharsets.UTF_8;
@@ -45,6 +43,8 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Change.Id;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.converter.PatchSetApprovalProtoConverter;
+import com.google.gerrit.reviewdb.converter.PatchSetProtoConverter;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ReviewerByEmailSet;
import com.google.gerrit.server.ReviewerSet;
@@ -230,11 +230,14 @@
// Any decoding that is done here must also be done in {@link LuceneChangeIndex}.
// Patch sets.
- cd.setPatchSets(decodeProtos(source, ChangeField.PATCH_SET.getName(), PATCH_SET_CODEC));
+ cd.setPatchSets(
+ decodeProtos(source, ChangeField.PATCH_SET.getName(), PatchSetProtoConverter.INSTANCE));
// Approvals.
if (source.get(ChangeField.APPROVAL.getName()) != null) {
- cd.setCurrentApprovals(decodeProtos(source, ChangeField.APPROVAL.getName(), APPROVAL_CODEC));
+ cd.setCurrentApprovals(
+ decodeProtos(
+ source, ChangeField.APPROVAL.getName(), PatchSetApprovalProtoConverter.INSTANCE));
} else if (fields.contains(ChangeField.APPROVAL.getName())) {
cd.setCurrentApprovals(Collections.emptyList());
}
diff --git a/java/com/google/gerrit/lucene/BUILD b/java/com/google/gerrit/lucene/BUILD
index 9c6ba74..3b18f2c 100644
--- a/java/com/google/gerrit/lucene/BUILD
+++ b/java/com/google/gerrit/lucene/BUILD
@@ -31,11 +31,13 @@
"//java/com/google/gerrit/index:query_exception",
"//java/com/google/gerrit/index/project",
"//java/com/google/gerrit/lifecycle",
+ "//java/com/google/gerrit/proto",
"//java/com/google/gerrit/reviewdb:server",
"//java/com/google/gerrit/server",
"//java/com/google/gerrit/server/logging",
"//lib:guava",
"//lib:gwtorm",
+ "//lib:protobuf",
"//lib/flogger:api",
"//lib/guice",
"//lib/guice:guice-assistedinject",
diff --git a/java/com/google/gerrit/lucene/LuceneChangeIndex.java b/java/com/google/gerrit/lucene/LuceneChangeIndex.java
index b208a31..51e95ed 100644
--- a/java/com/google/gerrit/lucene/LuceneChangeIndex.java
+++ b/java/com/google/gerrit/lucene/LuceneChangeIndex.java
@@ -14,10 +14,9 @@
package com.google.gerrit.lucene;
+import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.gerrit.lucene.AbstractLuceneIndex.sortFieldName;
-import static com.google.gerrit.reviewdb.server.ReviewDbCodecs.APPROVAL_CODEC;
import static com.google.gerrit.reviewdb.server.ReviewDbCodecs.CHANGE_CODEC;
-import static com.google.gerrit.reviewdb.server.ReviewDbCodecs.PATCH_SET_CODEC;
import static com.google.gerrit.server.git.QueueProvider.QueueType.INTERACTIVE;
import static com.google.gerrit.server.index.change.ChangeField.LEGACY_ID;
import static com.google.gerrit.server.index.change.ChangeField.PROJECT;
@@ -42,10 +41,14 @@
import com.google.gerrit.index.query.FieldBundle;
import com.google.gerrit.index.query.Predicate;
import com.google.gerrit.index.query.QueryParseException;
+import com.google.gerrit.proto.Protos;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.converter.PatchSetApprovalProtoConverter;
+import com.google.gerrit.reviewdb.converter.PatchSetProtoConverter;
+import com.google.gerrit.reviewdb.converter.ProtoConverter;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.StarredChangesUtil;
import com.google.gerrit.server.config.GerritServerConfig;
@@ -58,18 +61,17 @@
import com.google.gerrit.server.project.SubmitRuleOptions;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.ChangeDataSource;
-import com.google.gwtorm.protobuf.ProtobufCodec;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.OrmRuntimeException;
import com.google.gwtorm.server.ResultSet;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted;
+import com.google.protobuf.MessageLite;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -511,7 +513,7 @@
}
private void decodePatchSets(ListMultimap<String, IndexableField> doc, ChangeData cd) {
- List<PatchSet> patchSets = decodeProtos(doc, PATCH_SET_FIELD, PATCH_SET_CODEC);
+ List<PatchSet> patchSets = decodeProtos(doc, PATCH_SET_FIELD, PatchSetProtoConverter.INSTANCE);
if (!patchSets.isEmpty()) {
// Will be an empty list for schemas prior to when this field was stored;
// this cannot be valid since a change needs at least one patch set.
@@ -520,7 +522,8 @@
}
private void decodeApprovals(ListMultimap<String, IndexableField> doc, ChangeData cd) {
- cd.setCurrentApprovals(decodeProtos(doc, APPROVAL_FIELD, APPROVAL_CODEC));
+ cd.setCurrentApprovals(
+ decodeProtos(doc, APPROVAL_FIELD, PatchSetApprovalProtoConverter.INSTANCE));
}
private void decodeChangedLines(ListMultimap<String, IndexableField> doc, ChangeData cd) {
@@ -652,18 +655,20 @@
}
private static <T> List<T> decodeProtos(
- ListMultimap<String, IndexableField> doc, String fieldName, ProtobufCodec<T> codec) {
- Collection<IndexableField> fields = doc.get(fieldName);
- if (fields.isEmpty()) {
- return Collections.emptyList();
- }
+ ListMultimap<String, IndexableField> doc, String fieldName, ProtoConverter<?, T> converter) {
+ return doc.get(fieldName)
+ .stream()
+ .map(IndexableField::binaryValue)
+ .map(bytesRef -> parseProtoFrom(bytesRef, converter))
+ .collect(toImmutableList());
+ }
- List<T> result = new ArrayList<>(fields.size());
- for (IndexableField f : fields) {
- BytesRef r = f.binaryValue();
- result.add(codec.decode(r.bytes, r.offset, r.length));
- }
- return result;
+ private static <P extends MessageLite, T> T parseProtoFrom(
+ BytesRef bytesRef, ProtoConverter<P, T> converter) {
+ P message =
+ Protos.parseUnchecked(
+ converter.getParser(), bytesRef.bytes, bytesRef.offset, bytesRef.length);
+ return converter.fromProto(message);
}
private static List<byte[]> copyAsBytes(Collection<IndexableField> fields) {
diff --git a/java/com/google/gerrit/proto/BUILD b/java/com/google/gerrit/proto/BUILD
index 48185d6..b831e92 100644
--- a/java/com/google/gerrit/proto/BUILD
+++ b/java/com/google/gerrit/proto/BUILD
@@ -12,3 +12,13 @@
"//lib/jgit/org.eclipse.jgit:jgit",
],
)
+
+java_library(
+ name = "proto",
+ srcs = ["Protos.java"],
+ visibility = ["//visibility:public"],
+ deps = [
+ "//lib:gwtorm",
+ "//lib:protobuf",
+ ],
+)
diff --git a/java/com/google/gerrit/proto/Protos.java b/java/com/google/gerrit/proto/Protos.java
new file mode 100644
index 0000000..f8c63a3
--- /dev/null
+++ b/java/com/google/gerrit/proto/Protos.java
@@ -0,0 +1,143 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.proto;
+
+import com.google.gwtorm.protobuf.ProtobufCodec;
+import com.google.protobuf.ByteString;
+import com.google.protobuf.CodedOutputStream;
+import com.google.protobuf.MessageLite;
+import com.google.protobuf.Parser;
+import java.io.IOException;
+
+/** Static utilities for dealing with protobuf-based objects. */
+public class Protos {
+ /**
+ * Serializes a proto to a byte array.
+ *
+ * <p>Guarantees deterministic serialization. No matter whether the use case cares about
+ * determinism or not, always use this method in preference to {@link MessageLite#toByteArray()},
+ * which is not guaranteed deterministic.
+ *
+ * @param message the proto message to serialize.
+ * @return a byte array with the message contents.
+ */
+ public static byte[] toByteArray(MessageLite message) {
+ byte[] bytes = new byte[message.getSerializedSize()];
+ CodedOutputStream cout = CodedOutputStream.newInstance(bytes);
+ cout.useDeterministicSerialization();
+ try {
+ message.writeTo(cout);
+ cout.checkNoSpaceLeft();
+ return bytes;
+ } catch (IOException e) {
+ throw new IllegalStateException("exception writing to byte array", e);
+ }
+ }
+
+ /**
+ * Serializes a proto to a {@code ByteString}.
+ *
+ * <p>Guarantees deterministic serialization. No matter whether the use case cares about
+ * determinism or not, always use this method in preference to {@link MessageLite#toByteString()},
+ * which is not guaranteed deterministic.
+ *
+ * @param message the proto message to serialize
+ * @return a {@code ByteString} with the message contents
+ */
+ public static ByteString toByteString(MessageLite message) {
+ try (ByteString.Output bout = ByteString.newOutput(message.getSerializedSize())) {
+ CodedOutputStream outputStream = CodedOutputStream.newInstance(bout);
+ outputStream.useDeterministicSerialization();
+ message.writeTo(outputStream);
+ outputStream.flush();
+ return bout.toByteString();
+ } catch (IOException e) {
+ throw new IllegalStateException("exception writing to ByteString", e);
+ }
+ }
+
+ /**
+ * Serializes an object to a {@link ByteString} using a protobuf codec.
+ *
+ * <p>Guarantees deterministic serialization. No matter whether the use case cares about
+ * determinism or not, always use this method in preference to {@link
+ * ProtobufCodec#encodeToByteString(Object)}, which is not guaranteed deterministic.
+ *
+ * @param object the object to serialize.
+ * @param codec codec for serializing.
+ * @return a {@code ByteString} with the message contents.
+ */
+ public static <T> ByteString toByteString(T object, ProtobufCodec<T> codec) {
+ try (ByteString.Output bout = ByteString.newOutput()) {
+ CodedOutputStream cout = CodedOutputStream.newInstance(bout);
+ cout.useDeterministicSerialization();
+ codec.encode(object, cout);
+ cout.flush();
+ return bout.toByteString();
+ } catch (IOException e) {
+ throw new IllegalStateException("exception writing to ByteString", e);
+ }
+ }
+
+ /**
+ * Parses a byte array to a protobuf message.
+ *
+ * @param parser parser for the proto type.
+ * @param in byte array with the message contents.
+ * @return parsed proto.
+ */
+ public static <M extends MessageLite> M parseUnchecked(Parser<M> parser, byte[] in) {
+ try {
+ return parser.parseFrom(in);
+ } catch (IOException e) {
+ throw new IllegalArgumentException("exception parsing byte array to proto", e);
+ }
+ }
+
+ /**
+ * Parses a specific segment of a byte array to a protobuf message.
+ *
+ * @param parser parser for the proto type
+ * @param in byte array with the message contents
+ * @param offset offset in the byte array to start reading from
+ * @param length amount of read bytes
+ * @return parsed proto
+ */
+ public static <M extends MessageLite> M parseUnchecked(
+ Parser<M> parser, byte[] in, int offset, int length) {
+ try {
+ return parser.parseFrom(in, offset, length);
+ } catch (IOException e) {
+ throw new IllegalArgumentException("exception parsing byte array to proto", e);
+ }
+ }
+
+ /**
+ * Parses a {@code ByteString} to a protobuf message.
+ *
+ * @param parser parser for the proto type
+ * @param byteString {@code ByteString} with the message contents
+ * @return parsed proto
+ */
+ public static <M extends MessageLite> M parseUnchecked(Parser<M> parser, ByteString byteString) {
+ try {
+ return parser.parseFrom(byteString);
+ } catch (IOException e) {
+ throw new IllegalArgumentException("exception parsing ByteString to proto", e);
+ }
+ }
+
+ private Protos() {}
+}
diff --git a/java/com/google/gerrit/proto/testing/BUILD b/java/com/google/gerrit/proto/testing/BUILD
new file mode 100644
index 0000000..5f64c85
--- /dev/null
+++ b/java/com/google/gerrit/proto/testing/BUILD
@@ -0,0 +1,13 @@
+package(default_testonly = 1)
+
+java_library(
+ name = "testing",
+ srcs = glob(["*.java"]),
+ visibility = ["//visibility:public"],
+ deps = [
+ "//java/com/google/gerrit/server/cache/serialize",
+ "//lib:guava",
+ "//lib/commons:lang3",
+ "//lib/truth",
+ ],
+)
diff --git a/java/com/google/gerrit/server/cache/testing/SerializedClassSubject.java b/java/com/google/gerrit/proto/testing/SerializedClassSubject.java
similarity index 90%
rename from java/com/google/gerrit/server/cache/testing/SerializedClassSubject.java
rename to java/com/google/gerrit/proto/testing/SerializedClassSubject.java
index b902c1c..9ca6c9b 100644
--- a/java/com/google/gerrit/server/cache/testing/SerializedClassSubject.java
+++ b/java/com/google/gerrit/proto/testing/SerializedClassSubject.java
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.server.cache.testing;
+package com.google.gerrit.proto.testing;
import static com.google.common.collect.ImmutableMap.toImmutableMap;
import static com.google.common.truth.Truth.assertAbout;
@@ -30,13 +30,14 @@
import org.apache.commons.lang3.reflect.FieldUtils;
/**
- * Subject about classes that are serialized into persistent caches.
+ * Subject about classes that are serialized into persistent caches or indices.
*
* <p>Hand-written {@link com.google.gerrit.server.cache.serialize.CacheSerializer CacheSerializer}
- * implementations depend on the exact representation of the data stored in a class, so it is
- * important to verify any assumptions about the structure of the serialized classes. This class
- * contains assertions about serialized classes, and should be used for every class that has a
- * custom serializer implementation.
+ * and {@link com.google.gerrit.reviewdb.converter.ProtoConverter ProtoConverter} implementations
+ * depend on the exact representation of the data stored in a class, so it is important to verify
+ * any assumptions about the structure of the serialized classes. This class contains assertions
+ * about serialized classes, and should be used for every class that has a custom serializer
+ * implementation.
*
* <p>Changing fields of a serialized class (or abstract methods, in the case of {@code @AutoValue}
* classes) will likely require changes to the serializer implementation, and may require bumping
diff --git a/java/com/google/gerrit/reviewdb/BUILD b/java/com/google/gerrit/reviewdb/BUILD
index 76e35a1..9afa258 100644
--- a/java/com/google/gerrit/reviewdb/BUILD
+++ b/java/com/google/gerrit/reviewdb/BUILD
@@ -10,5 +10,7 @@
"//java/com/google/gerrit/extensions:api",
"//lib:guava",
"//lib:gwtorm",
+ "//lib:protobuf",
+ "//proto:reviewdb_java_proto",
],
)
diff --git a/java/com/google/gerrit/reviewdb/client/PatchSet.java b/java/com/google/gerrit/reviewdb/client/PatchSet.java
index 849fd75..a249a12 100644
--- a/java/com/google/gerrit/reviewdb/client/PatchSet.java
+++ b/java/com/google/gerrit/reviewdb/client/PatchSet.java
@@ -39,7 +39,7 @@
return isChangeRef(name);
}
- static String joinGroups(List<String> groups) {
+ public static String joinGroups(List<String> groups) {
if (groups == null) {
throw new IllegalArgumentException("groups may not be null");
}
diff --git a/java/com/google/gerrit/reviewdb/converter/AccountIdProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/AccountIdProtoConverter.java
new file mode 100644
index 0000000..4209d10
--- /dev/null
+++ b/java/com/google/gerrit/reviewdb/converter/AccountIdProtoConverter.java
@@ -0,0 +1,38 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import com.google.gerrit.proto.reviewdb.Reviewdb;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.protobuf.Parser;
+
+public enum AccountIdProtoConverter implements ProtoConverter<Reviewdb.Account_Id, Account.Id> {
+ INSTANCE;
+
+ @Override
+ public Reviewdb.Account_Id toProto(Account.Id accountId) {
+ return Reviewdb.Account_Id.newBuilder().setId(accountId.get()).build();
+ }
+
+ @Override
+ public Account.Id fromProto(Reviewdb.Account_Id proto) {
+ return new Account.Id(proto.getId());
+ }
+
+ @Override
+ public Parser<Reviewdb.Account_Id> getParser() {
+ return Reviewdb.Account_Id.parser();
+ }
+}
diff --git a/java/com/google/gerrit/reviewdb/converter/ChangeIdProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/ChangeIdProtoConverter.java
new file mode 100644
index 0000000..6eb3359
--- /dev/null
+++ b/java/com/google/gerrit/reviewdb/converter/ChangeIdProtoConverter.java
@@ -0,0 +1,38 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import com.google.gerrit.proto.reviewdb.Reviewdb;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.protobuf.Parser;
+
+public enum ChangeIdProtoConverter implements ProtoConverter<Reviewdb.Change_Id, Change.Id> {
+ INSTANCE;
+
+ @Override
+ public Reviewdb.Change_Id toProto(Change.Id changeId) {
+ return Reviewdb.Change_Id.newBuilder().setId(changeId.get()).build();
+ }
+
+ @Override
+ public Change.Id fromProto(Reviewdb.Change_Id proto) {
+ return new Change.Id(proto.getId());
+ }
+
+ @Override
+ public Parser<Reviewdb.Change_Id> getParser() {
+ return Reviewdb.Change_Id.parser();
+ }
+}
diff --git a/java/com/google/gerrit/reviewdb/converter/ChangeMessageKeyProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/ChangeMessageKeyProtoConverter.java
new file mode 100644
index 0000000..f8667f1
--- /dev/null
+++ b/java/com/google/gerrit/reviewdb/converter/ChangeMessageKeyProtoConverter.java
@@ -0,0 +1,46 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import com.google.gerrit.proto.reviewdb.Reviewdb;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.ChangeMessage;
+import com.google.protobuf.Parser;
+
+public enum ChangeMessageKeyProtoConverter
+ implements ProtoConverter<Reviewdb.ChangeMessage_Key, ChangeMessage.Key> {
+ INSTANCE;
+
+ private final ProtoConverter<Reviewdb.Change_Id, Change.Id> changeIdConverter =
+ ChangeIdProtoConverter.INSTANCE;
+
+ @Override
+ public Reviewdb.ChangeMessage_Key toProto(ChangeMessage.Key messageKey) {
+ return Reviewdb.ChangeMessage_Key.newBuilder()
+ .setChangeId(changeIdConverter.toProto(messageKey.getParentKey()))
+ .setUuid(messageKey.get())
+ .build();
+ }
+
+ @Override
+ public ChangeMessage.Key fromProto(Reviewdb.ChangeMessage_Key proto) {
+ return new ChangeMessage.Key(changeIdConverter.fromProto(proto.getChangeId()), proto.getUuid());
+ }
+
+ @Override
+ public Parser<Reviewdb.ChangeMessage_Key> getParser() {
+ return Reviewdb.ChangeMessage_Key.parser();
+ }
+}
diff --git a/java/com/google/gerrit/reviewdb/converter/ChangeMessageProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/ChangeMessageProtoConverter.java
new file mode 100644
index 0000000..99d9ca7
--- /dev/null
+++ b/java/com/google/gerrit/reviewdb/converter/ChangeMessageProtoConverter.java
@@ -0,0 +1,97 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import com.google.gerrit.proto.reviewdb.Reviewdb;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.ChangeMessage;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.protobuf.Parser;
+import java.sql.Timestamp;
+import java.util.Objects;
+
+public enum ChangeMessageProtoConverter
+ implements ProtoConverter<Reviewdb.ChangeMessage, ChangeMessage> {
+ INSTANCE;
+
+ private final ProtoConverter<Reviewdb.ChangeMessage_Key, ChangeMessage.Key>
+ changeMessageKeyConverter = ChangeMessageKeyProtoConverter.INSTANCE;
+ private final ProtoConverter<Reviewdb.Account_Id, Account.Id> accountIdConverter =
+ AccountIdProtoConverter.INSTANCE;
+ private final ProtoConverter<Reviewdb.PatchSet_Id, PatchSet.Id> patchSetIdConverter =
+ PatchSetIdProtoConverter.INSTANCE;
+
+ @Override
+ public Reviewdb.ChangeMessage toProto(ChangeMessage changeMessage) {
+ Reviewdb.ChangeMessage.Builder builder =
+ Reviewdb.ChangeMessage.newBuilder()
+ .setKey(changeMessageKeyConverter.toProto(changeMessage.getKey()));
+ Account.Id author = changeMessage.getAuthor();
+ if (author != null) {
+ builder.setAuthorId(accountIdConverter.toProto(author));
+ }
+ Timestamp writtenOn = changeMessage.getWrittenOn();
+ if (writtenOn != null) {
+ builder.setWrittenOn(writtenOn.getTime());
+ }
+ String message = changeMessage.getMessage();
+ if (message != null) {
+ builder.setMessage(message);
+ }
+ PatchSet.Id patchSetId = changeMessage.getPatchSetId();
+ if (patchSetId != null) {
+ builder.setPatchset(patchSetIdConverter.toProto(patchSetId));
+ }
+ String tag = changeMessage.getTag();
+ if (tag != null) {
+ builder.setTag(tag);
+ }
+ Account.Id realAuthor = changeMessage.getRealAuthor();
+ // ChangeMessage#getRealAuthor automatically delegates to ChangeMessage#getAuthor if the real
+ // author is not set. However, the previous protobuf representation kept 'realAuthor' empty if
+ // it wasn't set. To ensure binary compatibility, simulate the previous behavior.
+ if (realAuthor != null && !Objects.equals(realAuthor, author)) {
+ builder.setRealAuthor(accountIdConverter.toProto(realAuthor));
+ }
+ return builder.build();
+ }
+
+ @Override
+ public ChangeMessage fromProto(Reviewdb.ChangeMessage proto) {
+ ChangeMessage.Key key =
+ proto.hasKey() ? changeMessageKeyConverter.fromProto(proto.getKey()) : null;
+ Account.Id author =
+ proto.hasAuthorId() ? accountIdConverter.fromProto(proto.getAuthorId()) : null;
+ Timestamp writtenOn = proto.hasWrittenOn() ? new Timestamp(proto.getWrittenOn()) : null;
+ PatchSet.Id patchSetId =
+ proto.hasPatchset() ? patchSetIdConverter.fromProto(proto.getPatchset()) : null;
+ ChangeMessage changeMessage = new ChangeMessage(key, author, writtenOn, patchSetId);
+ if (proto.hasMessage()) {
+ changeMessage.setMessage(proto.getMessage());
+ }
+ if (proto.hasTag()) {
+ changeMessage.setTag(proto.getTag());
+ }
+ if (proto.hasRealAuthor()) {
+ changeMessage.setRealAuthor(accountIdConverter.fromProto(proto.getRealAuthor()));
+ }
+ return changeMessage;
+ }
+
+ @Override
+ public Parser<Reviewdb.ChangeMessage> getParser() {
+ return Reviewdb.ChangeMessage.parser();
+ }
+}
diff --git a/java/com/google/gerrit/reviewdb/converter/LabelIdProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/LabelIdProtoConverter.java
new file mode 100644
index 0000000..7f71f56
--- /dev/null
+++ b/java/com/google/gerrit/reviewdb/converter/LabelIdProtoConverter.java
@@ -0,0 +1,38 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import com.google.gerrit.proto.reviewdb.Reviewdb;
+import com.google.gerrit.reviewdb.client.LabelId;
+import com.google.protobuf.Parser;
+
+public enum LabelIdProtoConverter implements ProtoConverter<Reviewdb.LabelId, LabelId> {
+ INSTANCE;
+
+ @Override
+ public Reviewdb.LabelId toProto(LabelId labelId) {
+ return Reviewdb.LabelId.newBuilder().setId(labelId.get()).build();
+ }
+
+ @Override
+ public LabelId fromProto(Reviewdb.LabelId proto) {
+ return new LabelId(proto.getId());
+ }
+
+ @Override
+ public Parser<Reviewdb.LabelId> getParser() {
+ return Reviewdb.LabelId.parser();
+ }
+}
diff --git a/java/com/google/gerrit/reviewdb/converter/PatchSetApprovalKeyProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/PatchSetApprovalKeyProtoConverter.java
new file mode 100644
index 0000000..a37ddf7
--- /dev/null
+++ b/java/com/google/gerrit/reviewdb/converter/PatchSetApprovalKeyProtoConverter.java
@@ -0,0 +1,56 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import com.google.gerrit.proto.reviewdb.Reviewdb;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.LabelId;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gerrit.reviewdb.client.PatchSetApproval;
+import com.google.protobuf.Parser;
+
+public enum PatchSetApprovalKeyProtoConverter
+ implements ProtoConverter<Reviewdb.PatchSetApproval_Key, PatchSetApproval.Key> {
+ INSTANCE;
+
+ private final ProtoConverter<Reviewdb.PatchSet_Id, PatchSet.Id> patchSetIdConverter =
+ PatchSetIdProtoConverter.INSTANCE;
+ private final ProtoConverter<Reviewdb.Account_Id, Account.Id> accountIdConverter =
+ AccountIdProtoConverter.INSTANCE;
+ private final ProtoConverter<Reviewdb.LabelId, LabelId> labelIdConverter =
+ LabelIdProtoConverter.INSTANCE;
+
+ @Override
+ public Reviewdb.PatchSetApproval_Key toProto(PatchSetApproval.Key key) {
+ return Reviewdb.PatchSetApproval_Key.newBuilder()
+ .setPatchSetId(patchSetIdConverter.toProto(key.getParentKey()))
+ .setAccountId(accountIdConverter.toProto(key.getAccountId()))
+ .setCategoryId(labelIdConverter.toProto(key.getLabelId()))
+ .build();
+ }
+
+ @Override
+ public PatchSetApproval.Key fromProto(Reviewdb.PatchSetApproval_Key proto) {
+ return new PatchSetApproval.Key(
+ patchSetIdConverter.fromProto(proto.getPatchSetId()),
+ accountIdConverter.fromProto(proto.getAccountId()),
+ labelIdConverter.fromProto(proto.getCategoryId()));
+ }
+
+ @Override
+ public Parser<Reviewdb.PatchSetApproval_Key> getParser() {
+ return Reviewdb.PatchSetApproval_Key.parser();
+ }
+}
diff --git a/java/com/google/gerrit/reviewdb/converter/PatchSetApprovalProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/PatchSetApprovalProtoConverter.java
new file mode 100644
index 0000000..fbaff10
--- /dev/null
+++ b/java/com/google/gerrit/reviewdb/converter/PatchSetApprovalProtoConverter.java
@@ -0,0 +1,81 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import com.google.gerrit.proto.reviewdb.Reviewdb;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.PatchSetApproval;
+import com.google.protobuf.Parser;
+import java.sql.Timestamp;
+import java.util.Objects;
+
+public enum PatchSetApprovalProtoConverter
+ implements ProtoConverter<Reviewdb.PatchSetApproval, PatchSetApproval> {
+ INSTANCE;
+
+ private final ProtoConverter<Reviewdb.PatchSetApproval_Key, PatchSetApproval.Key>
+ patchSetApprovalKeyProtoConverter = PatchSetApprovalKeyProtoConverter.INSTANCE;
+ private final ProtoConverter<Reviewdb.Account_Id, Account.Id> accountIdConverter =
+ AccountIdProtoConverter.INSTANCE;
+
+ @Override
+ public Reviewdb.PatchSetApproval toProto(PatchSetApproval patchSetApproval) {
+ Reviewdb.PatchSetApproval.Builder builder =
+ Reviewdb.PatchSetApproval.newBuilder()
+ .setKey(patchSetApprovalKeyProtoConverter.toProto(patchSetApproval.getKey()))
+ .setValue(patchSetApproval.getValue())
+ .setGranted(patchSetApproval.getGranted().getTime())
+ .setPostSubmit(patchSetApproval.isPostSubmit());
+
+ String tag = patchSetApproval.getTag();
+ if (tag != null) {
+ builder.setTag(tag);
+ }
+ Account.Id realAccountId = patchSetApproval.getRealAccountId();
+ // PatchSetApproval#getRealAccountId automatically delegates to PatchSetApproval#getAccountId if
+ // the real author is not set. However, the previous protobuf representation kept
+ // 'realAccountId' empty if it wasn't set. To ensure binary compatibility, simulate the previous
+ // behavior.
+ if (realAccountId != null && !Objects.equals(realAccountId, patchSetApproval.getAccountId())) {
+ builder.setRealAccountId(accountIdConverter.toProto(realAccountId));
+ }
+
+ return builder.build();
+ }
+
+ @Override
+ public PatchSetApproval fromProto(Reviewdb.PatchSetApproval proto) {
+ PatchSetApproval patchSetApproval =
+ new PatchSetApproval(
+ patchSetApprovalKeyProtoConverter.fromProto(proto.getKey()),
+ (short) proto.getValue(),
+ new Timestamp(proto.getGranted()));
+ if (proto.hasTag()) {
+ patchSetApproval.setTag(proto.getTag());
+ }
+ if (proto.hasRealAccountId()) {
+ patchSetApproval.setRealAccountId(accountIdConverter.fromProto(proto.getRealAccountId()));
+ }
+ if (proto.hasPostSubmit()) {
+ patchSetApproval.setPostSubmit(proto.getPostSubmit());
+ }
+ return patchSetApproval;
+ }
+
+ @Override
+ public Parser<Reviewdb.PatchSetApproval> getParser() {
+ return Reviewdb.PatchSetApproval.parser();
+ }
+}
diff --git a/java/com/google/gerrit/reviewdb/converter/PatchSetIdProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/PatchSetIdProtoConverter.java
new file mode 100644
index 0000000..f518a54
--- /dev/null
+++ b/java/com/google/gerrit/reviewdb/converter/PatchSetIdProtoConverter.java
@@ -0,0 +1,45 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import com.google.gerrit.proto.reviewdb.Reviewdb;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.protobuf.Parser;
+
+public enum PatchSetIdProtoConverter implements ProtoConverter<Reviewdb.PatchSet_Id, PatchSet.Id> {
+ INSTANCE;
+
+ private final ProtoConverter<Reviewdb.Change_Id, Change.Id> changeIdConverter =
+ ChangeIdProtoConverter.INSTANCE;
+
+ @Override
+ public Reviewdb.PatchSet_Id toProto(PatchSet.Id patchSetId) {
+ return Reviewdb.PatchSet_Id.newBuilder()
+ .setChangeId(changeIdConverter.toProto(patchSetId.getParentKey()))
+ .setPatchSetId(patchSetId.get())
+ .build();
+ }
+
+ @Override
+ public PatchSet.Id fromProto(Reviewdb.PatchSet_Id proto) {
+ return new PatchSet.Id(changeIdConverter.fromProto(proto.getChangeId()), proto.getPatchSetId());
+ }
+
+ @Override
+ public Parser<Reviewdb.PatchSet_Id> getParser() {
+ return Reviewdb.PatchSet_Id.parser();
+ }
+}
diff --git a/java/com/google/gerrit/reviewdb/converter/PatchSetProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/PatchSetProtoConverter.java
new file mode 100644
index 0000000..ffdc346
--- /dev/null
+++ b/java/com/google/gerrit/reviewdb/converter/PatchSetProtoConverter.java
@@ -0,0 +1,93 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import com.google.gerrit.proto.reviewdb.Reviewdb;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gerrit.reviewdb.client.RevId;
+import com.google.protobuf.Parser;
+import java.sql.Timestamp;
+import java.util.List;
+
+public enum PatchSetProtoConverter implements ProtoConverter<Reviewdb.PatchSet, PatchSet> {
+ INSTANCE;
+
+ private final ProtoConverter<Reviewdb.PatchSet_Id, PatchSet.Id> patchSetIdConverter =
+ PatchSetIdProtoConverter.INSTANCE;
+ private final ProtoConverter<Reviewdb.RevId, RevId> revIdConverter = RevIdProtoConverter.INSTANCE;
+ private final ProtoConverter<Reviewdb.Account_Id, Account.Id> accountIdConverter =
+ AccountIdProtoConverter.INSTANCE;
+
+ @Override
+ public Reviewdb.PatchSet toProto(PatchSet patchSet) {
+ Reviewdb.PatchSet.Builder builder =
+ Reviewdb.PatchSet.newBuilder().setId(patchSetIdConverter.toProto(patchSet.getId()));
+ RevId revision = patchSet.getRevision();
+ if (revision != null) {
+ builder.setRevision(revIdConverter.toProto(revision));
+ }
+ Account.Id uploader = patchSet.getUploader();
+ if (uploader != null) {
+ builder.setUploaderAccountId(accountIdConverter.toProto(uploader));
+ }
+ Timestamp createdOn = patchSet.getCreatedOn();
+ if (createdOn != null) {
+ builder.setCreatedOn(createdOn.getTime());
+ }
+ List<String> groups = patchSet.getGroups();
+ if (!groups.isEmpty()) {
+ builder.setGroups(PatchSet.joinGroups(groups));
+ }
+ String pushCertificate = patchSet.getPushCertificate();
+ if (pushCertificate != null) {
+ builder.setPushCertificate(pushCertificate);
+ }
+ String description = patchSet.getDescription();
+ if (description != null) {
+ builder.setDescription(description);
+ }
+ return builder.build();
+ }
+
+ @Override
+ public PatchSet fromProto(Reviewdb.PatchSet proto) {
+ PatchSet patchSet = new PatchSet(patchSetIdConverter.fromProto(proto.getId()));
+ if (proto.hasRevision()) {
+ patchSet.setRevision(revIdConverter.fromProto(proto.getRevision()));
+ }
+ if (proto.hasUploaderAccountId()) {
+ patchSet.setUploader(accountIdConverter.fromProto(proto.getUploaderAccountId()));
+ }
+ if (proto.hasCreatedOn()) {
+ patchSet.setCreatedOn(new Timestamp(proto.getCreatedOn()));
+ }
+ if (proto.hasGroups()) {
+ patchSet.setGroups(PatchSet.splitGroups(proto.getGroups()));
+ }
+ if (proto.hasPushCertificate()) {
+ patchSet.setPushCertificate(proto.getPushCertificate());
+ }
+ if (proto.hasDescription()) {
+ patchSet.setDescription(proto.getDescription());
+ }
+ return patchSet;
+ }
+
+ @Override
+ public Parser<Reviewdb.PatchSet> getParser() {
+ return Reviewdb.PatchSet.parser();
+ }
+}
diff --git a/java/com/google/gerrit/reviewdb/converter/ProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/ProtoConverter.java
new file mode 100644
index 0000000..568759c
--- /dev/null
+++ b/java/com/google/gerrit/reviewdb/converter/ProtoConverter.java
@@ -0,0 +1,27 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import com.google.protobuf.MessageLite;
+import com.google.protobuf.Parser;
+
+public interface ProtoConverter<P extends MessageLite, C> {
+
+ P toProto(C valueClass);
+
+ C fromProto(P proto);
+
+ Parser<P> getParser();
+}
diff --git a/java/com/google/gerrit/reviewdb/converter/RevIdProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/RevIdProtoConverter.java
new file mode 100644
index 0000000..6402b6b
--- /dev/null
+++ b/java/com/google/gerrit/reviewdb/converter/RevIdProtoConverter.java
@@ -0,0 +1,38 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import com.google.gerrit.proto.reviewdb.Reviewdb;
+import com.google.gerrit.reviewdb.client.RevId;
+import com.google.protobuf.Parser;
+
+public enum RevIdProtoConverter implements ProtoConverter<Reviewdb.RevId, RevId> {
+ INSTANCE;
+
+ @Override
+ public Reviewdb.RevId toProto(RevId revId) {
+ return Reviewdb.RevId.newBuilder().setId(revId.get()).build();
+ }
+
+ @Override
+ public RevId fromProto(Reviewdb.RevId proto) {
+ return new RevId(proto.getId());
+ }
+
+ @Override
+ public Parser<Reviewdb.RevId> getParser() {
+ return Reviewdb.RevId.parser();
+ }
+}
diff --git a/java/com/google/gerrit/reviewdb/server/ReviewDbCodecs.java b/java/com/google/gerrit/reviewdb/server/ReviewDbCodecs.java
index 2958464..7ff2284 100644
--- a/java/com/google/gerrit/reviewdb/server/ReviewDbCodecs.java
+++ b/java/com/google/gerrit/reviewdb/server/ReviewDbCodecs.java
@@ -15,24 +15,12 @@
package com.google.gerrit.reviewdb.server;
import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.reviewdb.client.ChangeMessage;
-import com.google.gerrit.reviewdb.client.PatchSet;
-import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gwtorm.protobuf.CodecFactory;
import com.google.gwtorm.protobuf.ProtobufCodec;
/** {@link ProtobufCodec} instances for ReviewDb types. */
public class ReviewDbCodecs {
- public static final ProtobufCodec<PatchSetApproval> APPROVAL_CODEC =
- CodecFactory.encoder(PatchSetApproval.class);
-
public static final ProtobufCodec<Change> CHANGE_CODEC = CodecFactory.encoder(Change.class);
- public static final ProtobufCodec<ChangeMessage> MESSAGE_CODEC =
- CodecFactory.encoder(ChangeMessage.class);
-
- public static final ProtobufCodec<PatchSet> PATCH_SET_CODEC =
- CodecFactory.encoder(PatchSet.class);
-
private ReviewDbCodecs() {}
}
diff --git a/java/com/google/gerrit/server/BUILD b/java/com/google/gerrit/server/BUILD
index 8401852..df3308c 100644
--- a/java/com/google/gerrit/server/BUILD
+++ b/java/com/google/gerrit/server/BUILD
@@ -40,6 +40,7 @@
"//java/com/google/gerrit/mail",
"//java/com/google/gerrit/metrics",
"//java/com/google/gerrit/prettify:server",
+ "//java/com/google/gerrit/proto",
"//java/com/google/gerrit/reviewdb:server",
"//java/com/google/gerrit/server/cache/serialize",
"//java/com/google/gerrit/server/ioutil",
diff --git a/java/com/google/gerrit/server/account/externalids/AllExternalIds.java b/java/com/google/gerrit/server/account/externalids/AllExternalIds.java
index bb1ade7..bfe46d2 100644
--- a/java/com/google/gerrit/server/account/externalids/AllExternalIds.java
+++ b/java/com/google/gerrit/server/account/externalids/AllExternalIds.java
@@ -21,12 +21,12 @@
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.SetMultimap;
+import com.google.gerrit.proto.Protos;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.server.cache.proto.Cache.AllExternalIdsProto;
import com.google.gerrit.server.cache.proto.Cache.AllExternalIdsProto.ExternalIdProto;
import com.google.gerrit.server.cache.serialize.CacheSerializer;
-import com.google.gerrit.server.cache.serialize.ProtoCacheSerializers;
-import com.google.gerrit.server.cache.serialize.ProtoCacheSerializers.ObjectIdConverter;
+import com.google.gerrit.server.cache.serialize.ObjectIdConverter;
import java.util.Collection;
/** Cache value containing all external IDs. */
@@ -68,7 +68,7 @@
.stream()
.map(extId -> toProto(idConverter, extId))
.forEach(allBuilder::addExternalId);
- return ProtoCacheSerializers.toByteArray(allBuilder.build());
+ return Protos.toByteArray(allBuilder.build());
}
private static ExternalIdProto toProto(ObjectIdConverter idConverter, ExternalId externalId) {
@@ -92,7 +92,7 @@
public AllExternalIds deserialize(byte[] in) {
ObjectIdConverter idConverter = ObjectIdConverter.create();
return create(
- ProtoCacheSerializers.parseUnchecked(AllExternalIdsProto.parser(), in)
+ Protos.parseUnchecked(AllExternalIdsProto.parser(), in)
.getExternalIdList()
.stream()
.map(proto -> toExternalId(idConverter, proto))
diff --git a/java/com/google/gerrit/server/auth/oauth/OAuthTokenCache.java b/java/com/google/gerrit/server/auth/oauth/OAuthTokenCache.java
index 3a6be0c..0980116 100644
--- a/java/com/google/gerrit/server/auth/oauth/OAuthTokenCache.java
+++ b/java/com/google/gerrit/server/auth/oauth/OAuthTokenCache.java
@@ -22,12 +22,12 @@
import com.google.gerrit.extensions.auth.oauth.OAuthToken;
import com.google.gerrit.extensions.auth.oauth.OAuthTokenEncrypter;
import com.google.gerrit.extensions.registration.DynamicItem;
+import com.google.gerrit.proto.Protos;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.server.cache.CacheModule;
import com.google.gerrit.server.cache.proto.Cache.OAuthTokenProto;
import com.google.gerrit.server.cache.serialize.CacheSerializer;
import com.google.gerrit.server.cache.serialize.IntKeyCacheSerializer;
-import com.google.gerrit.server.cache.serialize.ProtoCacheSerializers;
import com.google.inject.Inject;
import com.google.inject.Module;
import com.google.inject.Singleton;
@@ -57,7 +57,7 @@
static class Serializer implements CacheSerializer<OAuthToken> {
@Override
public byte[] serialize(OAuthToken object) {
- return ProtoCacheSerializers.toByteArray(
+ return Protos.toByteArray(
OAuthTokenProto.newBuilder()
.setToken(object.getToken())
.setSecret(object.getSecret())
@@ -69,7 +69,7 @@
@Override
public OAuthToken deserialize(byte[] in) {
- OAuthTokenProto proto = ProtoCacheSerializers.parseUnchecked(OAuthTokenProto.parser(), in);
+ OAuthTokenProto proto = Protos.parseUnchecked(OAuthTokenProto.parser(), in);
return new OAuthToken(
proto.getToken(),
proto.getSecret(),
diff --git a/java/com/google/gerrit/server/cache/serialize/BUILD b/java/com/google/gerrit/server/cache/serialize/BUILD
index 957a153..cd9912c 100644
--- a/java/com/google/gerrit/server/cache/serialize/BUILD
+++ b/java/com/google/gerrit/server/cache/serialize/BUILD
@@ -4,6 +4,7 @@
visibility = ["//visibility:public"],
deps = [
"//java/com/google/gerrit/common:annotations",
+ "//java/com/google/gerrit/proto",
"//lib:guava",
"//lib:gwtorm",
"//lib:protobuf",
diff --git a/java/com/google/gerrit/server/cache/serialize/ObjectIdConverter.java b/java/com/google/gerrit/server/cache/serialize/ObjectIdConverter.java
new file mode 100644
index 0000000..eb946a9
--- /dev/null
+++ b/java/com/google/gerrit/server/cache/serialize/ObjectIdConverter.java
@@ -0,0 +1,56 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.cache.serialize;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH;
+
+import com.google.protobuf.ByteString;
+import org.eclipse.jgit.lib.ObjectId;
+
+/**
+ * Helper for serializing {@link ObjectId} instances to/from protobuf fields.
+ *
+ * <p>Reuse a single instance's {@link #toByteString(ObjectId)} and {@link
+ * #fromByteString(ByteString)} within a single {@link CacheSerializer#serialize} or {@link
+ * CacheSerializer#deserialize} method body to minimize allocation of temporary buffers.
+ *
+ * <p><strong>Note:</strong> This class is not threadsafe. Instances must not be stored in {@link
+ * CacheSerializer} fields if the serializer instances will be used from multiple threads.
+ */
+public class ObjectIdConverter {
+ public static ObjectIdConverter create() {
+ return new ObjectIdConverter();
+ }
+
+ private final byte[] buf = new byte[OBJECT_ID_LENGTH];
+
+ private ObjectIdConverter() {}
+
+ public ByteString toByteString(ObjectId id) {
+ id.copyRawTo(buf, 0);
+ return ByteString.copyFrom(buf);
+ }
+
+ public ObjectId fromByteString(ByteString in) {
+ checkArgument(
+ in.size() == OBJECT_ID_LENGTH,
+ "expected ByteString of length %s: %s",
+ OBJECT_ID_LENGTH,
+ in);
+ in.copyTo(buf, 0);
+ return ObjectId.fromRaw(buf);
+ }
+}
diff --git a/java/com/google/gerrit/server/cache/serialize/ProtoCacheSerializers.java b/java/com/google/gerrit/server/cache/serialize/ProtoCacheSerializers.java
deleted file mode 100644
index 4e0b106..0000000
--- a/java/com/google/gerrit/server/cache/serialize/ProtoCacheSerializers.java
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.server.cache.serialize;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH;
-
-import com.google.gwtorm.protobuf.ProtobufCodec;
-import com.google.protobuf.ByteString;
-import com.google.protobuf.CodedOutputStream;
-import com.google.protobuf.MessageLite;
-import com.google.protobuf.Parser;
-import java.io.IOException;
-import org.eclipse.jgit.lib.ObjectId;
-
-/** Static utilities for writing protobuf-based {@link CacheSerializer} implementations. */
-public class ProtoCacheSerializers {
- /**
- * Serializes a proto to a byte array.
- *
- * <p>Guarantees deterministic serialization and thus is suitable for use in persistent caches.
- * Should be used in preference to {@link MessageLite#toByteArray()}, which is not guaranteed
- * deterministic.
- *
- * @param message the proto message to serialize.
- * @return a byte array with the message contents.
- */
- public static byte[] toByteArray(MessageLite message) {
- byte[] bytes = new byte[message.getSerializedSize()];
- CodedOutputStream cout = CodedOutputStream.newInstance(bytes);
- cout.useDeterministicSerialization();
- try {
- message.writeTo(cout);
- cout.checkNoSpaceLeft();
- return bytes;
- } catch (IOException e) {
- throw new IllegalStateException("exception writing to byte array", e);
- }
- }
-
- /**
- * Serializes an object to a {@link ByteString} using a protobuf codec.
- *
- * <p>Guarantees deterministic serialization and thus is suitable for use in persistent caches.
- * Should be used in preference to {@link ProtobufCodec#encodeToByteString(Object)}, which is not
- * guaranteed deterministic.
- *
- * @param object the object to serialize.
- * @param codec codec for serializing.
- * @return a {@code ByteString} with the message contents.
- */
- public static <T> ByteString toByteString(T object, ProtobufCodec<T> codec) {
- try (ByteString.Output bout = ByteString.newOutput()) {
- CodedOutputStream cout = CodedOutputStream.newInstance(bout);
- cout.useDeterministicSerialization();
- codec.encode(object, cout);
- cout.flush();
- return bout.toByteString();
- } catch (IOException e) {
- throw new IllegalStateException("exception writing to ByteString", e);
- }
- }
-
- /**
- * Parses a byte array to a protobuf message.
- *
- * @param parser parser for the proto type.
- * @param in byte array with the message contents.
- * @return parsed proto.
- */
- public static <M extends MessageLite> M parseUnchecked(Parser<M> parser, byte[] in) {
- try {
- return parser.parseFrom(in);
- } catch (IOException e) {
- throw new IllegalArgumentException("exception parsing byte array to proto", e);
- }
- }
-
- /**
- * Helper for serializing {@link ObjectId} instances to/from protobuf fields.
- *
- * <p>Reuse a single instance's {@link #toByteString(ObjectId)} and {@link
- * #fromByteString(ByteString)} within a single {@link CacheSerializer#serialize} or {@link
- * CacheSerializer#deserialize} method body to minimize allocation of temporary buffers.
- *
- * <p><strong>Note:</strong> This class is not threadsafe. Instances must not be stored in {@link
- * CacheSerializer} fields if the serializer instances will be used from multiple threads.
- */
- public static class ObjectIdConverter {
- public static ObjectIdConverter create() {
- return new ObjectIdConverter();
- }
-
- private final byte[] buf = new byte[OBJECT_ID_LENGTH];
-
- private ObjectIdConverter() {}
-
- public ByteString toByteString(ObjectId id) {
- id.copyRawTo(buf, 0);
- return ByteString.copyFrom(buf);
- }
-
- public ObjectId fromByteString(ByteString in) {
- checkArgument(
- in.size() == OBJECT_ID_LENGTH,
- "expected ByteString of length %s: %s",
- OBJECT_ID_LENGTH,
- in);
- in.copyTo(buf, 0);
- return ObjectId.fromRaw(buf);
- }
- }
-
- private ProtoCacheSerializers() {}
-}
diff --git a/java/com/google/gerrit/server/cache/testing/BUILD b/java/com/google/gerrit/server/cache/testing/BUILD
index 9a9f1ef..f7f7eb6 100644
--- a/java/com/google/gerrit/server/cache/testing/BUILD
+++ b/java/com/google/gerrit/server/cache/testing/BUILD
@@ -5,10 +5,6 @@
srcs = glob(["*.java"]),
visibility = ["//visibility:public"],
deps = [
- "//java/com/google/gerrit/server/cache/serialize",
- "//lib:guava",
"//lib:protobuf",
- "//lib/commons:lang3",
- "//lib/truth",
],
)
diff --git a/java/com/google/gerrit/server/change/ChangeKindCacheImpl.java b/java/com/google/gerrit/server/change/ChangeKindCacheImpl.java
index a6786d8..a57a9a4 100644
--- a/java/com/google/gerrit/server/change/ChangeKindCacheImpl.java
+++ b/java/com/google/gerrit/server/change/ChangeKindCacheImpl.java
@@ -24,6 +24,7 @@
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.client.ChangeKind;
+import com.google.gerrit.proto.Protos;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
@@ -32,8 +33,7 @@
import com.google.gerrit.server.cache.proto.Cache.ChangeKindKeyProto;
import com.google.gerrit.server.cache.serialize.CacheSerializer;
import com.google.gerrit.server.cache.serialize.EnumCacheSerializer;
-import com.google.gerrit.server.cache.serialize.ProtoCacheSerializers;
-import com.google.gerrit.server.cache.serialize.ProtoCacheSerializers.ObjectIdConverter;
+import com.google.gerrit.server.cache.serialize.ObjectIdConverter;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.InMemoryInserter;
@@ -146,7 +146,7 @@
@Override
public byte[] serialize(Key object) {
ObjectIdConverter idConverter = ObjectIdConverter.create();
- return ProtoCacheSerializers.toByteArray(
+ return Protos.toByteArray(
ChangeKindKeyProto.newBuilder()
.setPrior(idConverter.toByteString(object.prior()))
.setNext(idConverter.toByteString(object.next()))
@@ -156,8 +156,7 @@
@Override
public Key deserialize(byte[] in) {
- ChangeKindKeyProto proto =
- ProtoCacheSerializers.parseUnchecked(ChangeKindKeyProto.parser(), in);
+ ChangeKindKeyProto proto = Protos.parseUnchecked(ChangeKindKeyProto.parser(), in);
ObjectIdConverter idConverter = ObjectIdConverter.create();
return create(
idConverter.fromByteString(proto.getPrior()),
diff --git a/java/com/google/gerrit/server/change/MergeabilityCacheImpl.java b/java/com/google/gerrit/server/change/MergeabilityCacheImpl.java
index 131f3a1..1ac558b 100644
--- a/java/com/google/gerrit/server/change/MergeabilityCacheImpl.java
+++ b/java/com/google/gerrit/server/change/MergeabilityCacheImpl.java
@@ -25,13 +25,13 @@
import com.google.common.flogger.FluentLogger;
import com.google.common.util.concurrent.UncheckedExecutionException;
import com.google.gerrit.extensions.client.SubmitType;
+import com.google.gerrit.proto.Protos;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.server.cache.CacheModule;
import com.google.gerrit.server.cache.proto.Cache.MergeabilityKeyProto;
import com.google.gerrit.server.cache.serialize.BooleanCacheSerializer;
import com.google.gerrit.server.cache.serialize.CacheSerializer;
-import com.google.gerrit.server.cache.serialize.ProtoCacheSerializers;
-import com.google.gerrit.server.cache.serialize.ProtoCacheSerializers.ObjectIdConverter;
+import com.google.gerrit.server.cache.serialize.ObjectIdConverter;
import com.google.gerrit.server.git.CodeReviewCommit;
import com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk;
import com.google.gerrit.server.submit.SubmitDryRun;
@@ -143,7 +143,7 @@
@Override
public byte[] serialize(EntryKey object) {
ObjectIdConverter idConverter = ObjectIdConverter.create();
- return ProtoCacheSerializers.toByteArray(
+ return Protos.toByteArray(
MergeabilityKeyProto.newBuilder()
.setCommit(idConverter.toByteString(object.getCommit()))
.setInto(idConverter.toByteString(object.getInto()))
@@ -154,8 +154,7 @@
@Override
public EntryKey deserialize(byte[] in) {
- MergeabilityKeyProto proto =
- ProtoCacheSerializers.parseUnchecked(MergeabilityKeyProto.parser(), in);
+ MergeabilityKeyProto proto = Protos.parseUnchecked(MergeabilityKeyProto.parser(), in);
ObjectIdConverter idConverter = ObjectIdConverter.create();
return new EntryKey(
idConverter.fromByteString(proto.getCommit()),
diff --git a/java/com/google/gerrit/server/git/TagSet.java b/java/com/google/gerrit/server/git/TagSet.java
index ce8814f..57637c89 100644
--- a/java/com/google/gerrit/server/git/TagSet.java
+++ b/java/com/google/gerrit/server/git/TagSet.java
@@ -24,7 +24,7 @@
import com.google.gerrit.server.cache.proto.Cache.TagSetHolderProto.TagSetProto;
import com.google.gerrit.server.cache.proto.Cache.TagSetHolderProto.TagSetProto.CachedRefProto;
import com.google.gerrit.server.cache.proto.Cache.TagSetHolderProto.TagSetProto.TagProto;
-import com.google.gerrit.server.cache.serialize.ProtoCacheSerializers.ObjectIdConverter;
+import com.google.gerrit.server.cache.serialize.ObjectIdConverter;
import com.google.protobuf.ByteString;
import java.io.IOException;
import java.util.BitSet;
diff --git a/java/com/google/gerrit/server/git/TagSetHolder.java b/java/com/google/gerrit/server/git/TagSetHolder.java
index 4c0c035..194283e 100644
--- a/java/com/google/gerrit/server/git/TagSetHolder.java
+++ b/java/com/google/gerrit/server/git/TagSetHolder.java
@@ -17,10 +17,10 @@
import static java.util.stream.Collectors.toList;
import com.google.gerrit.common.Nullable;
+import com.google.gerrit.proto.Protos;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.cache.proto.Cache.TagSetHolderProto;
import com.google.gerrit.server.cache.serialize.CacheSerializer;
-import com.google.gerrit.server.cache.serialize.ProtoCacheSerializers;
import java.util.Collection;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
@@ -111,13 +111,12 @@
if (tags != null) {
b.setTags(tags.toProto());
}
- return ProtoCacheSerializers.toByteArray(b.build());
+ return Protos.toByteArray(b.build());
}
@Override
public TagSetHolder deserialize(byte[] in) {
- TagSetHolderProto proto =
- ProtoCacheSerializers.parseUnchecked(TagSetHolderProto.parser(), in);
+ TagSetHolderProto proto = Protos.parseUnchecked(TagSetHolderProto.parser(), in);
TagSetHolder holder = new TagSetHolder(new Project.NameKey(proto.getProjectName()));
if (proto.hasTags()) {
holder.tags = TagSet.fromProto(proto.getTags());
diff --git a/java/com/google/gerrit/server/git/receive/AsyncReceiveCommits.java b/java/com/google/gerrit/server/git/receive/AsyncReceiveCommits.java
index 882f208..abbba86 100644
--- a/java/com/google/gerrit/server/git/receive/AsyncReceiveCommits.java
+++ b/java/com/google/gerrit/server/git/receive/AsyncReceiveCommits.java
@@ -39,6 +39,7 @@
import com.google.gerrit.server.git.MultiProgressMonitor;
import com.google.gerrit.server.git.ProjectRunnable;
import com.google.gerrit.server.git.TransferConfig;
+import com.google.gerrit.server.git.receive.ResultChangeIds.Key;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackend.RefFilterOptions;
import com.google.gerrit.server.permissions.PermissionBackendException;
@@ -341,17 +342,21 @@
long deltaNanos = System.nanoTime() - startNanos;
int totalChanges = 0;
- for (ResultChangeIds.Key key : ResultChangeIds.Key.values()) {
- List<Change.Id> ids = resultChangeIds.get(key);
- metrics.changes.record(key, ids.size());
- totalChanges += ids.size();
+
+ if (resultChangeIds.isMagicPush()) {
+ List<Change.Id> created = resultChangeIds.get(Key.CREATED);
+ metrics.changes.record(Key.CREATED, created.size());
+ List<Change.Id> replaced = resultChangeIds.get(Key.REPLACED);
+ metrics.changes.record(Key.REPLACED, replaced.size());
+ totalChanges += replaced.size() + created.size();
+ } else {
+ List<Change.Id> autoclosed = resultChangeIds.get(Key.AUTOCLOSED);
+ metrics.changes.record(Key.AUTOCLOSED, autoclosed.size());
}
if (totalChanges > 0) {
metrics.latencyPerChange.record(
- resultChangeIds.get(ResultChangeIds.Key.AUTOCLOSED).isEmpty()
- ? "CREATE_REPLACE"
- : ResultChangeIds.Key.AUTOCLOSED.name(),
+ resultChangeIds.isMagicPush() ? "CREATE_REPLACE" : ResultChangeIds.Key.AUTOCLOSED.name(),
deltaNanos / totalChanges,
NANOSECONDS);
}
diff --git a/java/com/google/gerrit/server/git/receive/ReceiveCommits.java b/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
index 32fbd36..3a9a170 100644
--- a/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
+++ b/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
@@ -631,6 +631,7 @@
private void handleRegularCommands(List<ReceiveCommand> cmds, MultiProgressMonitor progress)
throws PermissionBackendException, IOException, NoSuchProjectException {
+ resultChangeIds.setMagicPush(false);
for (ReceiveCommand cmd : cmds) {
parseRegularCommand(cmd);
}
@@ -1825,6 +1826,7 @@
if (validateConnected(magicBranch.cmd, magicBranch.dest, tip)) {
this.magicBranch = magicBranch;
+ this.resultChangeIds.setMagicPush(true);
}
}
diff --git a/java/com/google/gerrit/server/git/receive/ResultChangeIds.java b/java/com/google/gerrit/server/git/receive/ResultChangeIds.java
index bbf8d95..e326141 100644
--- a/java/com/google/gerrit/server/git/receive/ResultChangeIds.java
+++ b/java/com/google/gerrit/server/git/receive/ResultChangeIds.java
@@ -33,6 +33,7 @@
AUTOCLOSED,
}
+ private boolean isMagicPush;
private final Map<Key, List<Change.Id>> ids;
ResultChangeIds() {
@@ -43,16 +44,24 @@
}
/** Record a change ID update as having completed. Thread-safe. */
- public void add(Key key, Change.Id id) {
- synchronized (this) {
- ids.get(key).add(id);
- }
+ public synchronized void add(Key key, Change.Id id) {
+ ids.get(key).add(id);
}
- /** Returns change IDs of the given type for which the BatchUpdate succeeded. Thread-safe. */
- public List<Change.Id> get(Key key) {
- synchronized (this) {
- return ImmutableList.copyOf(ids.get(key));
- }
+ /** Indicate that the ReceiveCommits call involved a magic branch. */
+ public synchronized void setMagicPush(boolean magic) {
+ isMagicPush = magic;
+ }
+
+ public synchronized boolean isMagicPush() {
+ return isMagicPush;
+ }
+
+ /**
+ * Returns change IDs of the given type for which the BatchUpdate succeeded, or empty list if
+ * there are none. Thread-safe.
+ */
+ public synchronized List<Change.Id> get(Key key) {
+ return ImmutableList.copyOf(ids.get(key));
}
}
diff --git a/java/com/google/gerrit/server/index/change/ChangeField.java b/java/com/google/gerrit/server/index/change/ChangeField.java
index b79a1c2..bae3377 100644
--- a/java/com/google/gerrit/server/index/change/ChangeField.java
+++ b/java/com/google/gerrit/server/index/change/ChangeField.java
@@ -15,6 +15,7 @@
package com.google.gerrit.server.index.change;
import static com.google.common.base.MoreObjects.firstNonNull;
+import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.gerrit.index.FieldDef.exact;
import static com.google.gerrit.index.FieldDef.fullText;
import static com.google.gerrit.index.FieldDef.intRange;
@@ -22,9 +23,7 @@
import static com.google.gerrit.index.FieldDef.prefix;
import static com.google.gerrit.index.FieldDef.storedOnly;
import static com.google.gerrit.index.FieldDef.timestamp;
-import static com.google.gerrit.reviewdb.server.ReviewDbCodecs.APPROVAL_CODEC;
import static com.google.gerrit.reviewdb.server.ReviewDbCodecs.CHANGE_CODEC;
-import static com.google.gerrit.reviewdb.server.ReviewDbCodecs.PATCH_SET_CODEC;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;
@@ -46,6 +45,7 @@
import com.google.gerrit.index.RefState;
import com.google.gerrit.index.SchemaUtil;
import com.google.gerrit.mail.Address;
+import com.google.gerrit.proto.Protos;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.ChangeMessage;
@@ -53,6 +53,9 @@
import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
+import com.google.gerrit.reviewdb.converter.PatchSetApprovalProtoConverter;
+import com.google.gerrit.reviewdb.converter.PatchSetProtoConverter;
+import com.google.gerrit.reviewdb.converter.ProtoConverter;
import com.google.gerrit.server.OutputFormat;
import com.google.gerrit.server.ReviewerByEmailSet;
import com.google.gerrit.server.ReviewerSet;
@@ -68,10 +71,7 @@
import com.google.gerrit.server.query.change.ChangeQueryBuilder;
import com.google.gerrit.server.query.change.ChangeStatusPredicate;
import com.google.gson.Gson;
-import com.google.gwtorm.protobuf.ProtobufCodec;
import com.google.gwtorm.server.OrmException;
-import com.google.protobuf.CodedOutputStream;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.ArrayList;
@@ -474,7 +474,8 @@
/** Serialized approvals for the current patch set, used for pre-populating results. */
public static final FieldDef<ChangeData, Iterable<byte[]>> APPROVAL =
storedOnly("_approval")
- .buildRepeatable(cd -> toProtos(APPROVAL_CODEC, cd.currentApprovals()));
+ .buildRepeatable(
+ cd -> toProtos(PatchSetApprovalProtoConverter.INSTANCE, cd.currentApprovals()));
public static String formatLabel(String label, int value) {
return formatLabel(label, value, null);
@@ -596,7 +597,8 @@
/** Serialized patch set object, used for pre-populating results. */
public static final FieldDef<ChangeData, Iterable<byte[]>> PATCH_SET =
- storedOnly("_patch_set").buildRepeatable(cd -> toProtos(PATCH_SET_CODEC, cd.patchSets()));
+ storedOnly("_patch_set")
+ .buildRepeatable(cd -> toProtos(PatchSetProtoConverter.INSTANCE, cd.patchSets()));
/** Users who have edits on this change. */
public static final FieldDef<ChangeData, Iterable<Integer>> EDITBY =
@@ -856,22 +858,12 @@
return firstNonNull(c.getTopic(), "");
}
- private static <T> List<byte[]> toProtos(ProtobufCodec<T> codec, Collection<T> objs)
- throws OrmException {
- List<byte[]> result = Lists.newArrayListWithCapacity(objs.size());
- ByteArrayOutputStream out = new ByteArrayOutputStream(256);
- try {
- for (T obj : objs) {
- out.reset();
- CodedOutputStream cos = CodedOutputStream.newInstance(out);
- codec.encode(obj, cos);
- cos.flush();
- result.add(out.toByteArray());
- }
- } catch (IOException e) {
- throw new OrmException(e);
- }
- return result;
+ private static <T> List<byte[]> toProtos(ProtoConverter<?, T> converter, Collection<T> objects) {
+ return objects
+ .stream()
+ .map(converter::toProto)
+ .map(Protos::toByteArray)
+ .collect(toImmutableList());
}
private static <T> FieldDef.Getter<ChangeData, T> changeGetter(Function<Change, T> func) {
diff --git a/java/com/google/gerrit/server/notedb/ChangeNotesCache.java b/java/com/google/gerrit/server/notedb/ChangeNotesCache.java
index cc316e5..add5803 100644
--- a/java/com/google/gerrit/server/notedb/ChangeNotesCache.java
+++ b/java/com/google/gerrit/server/notedb/ChangeNotesCache.java
@@ -20,6 +20,7 @@
import com.google.common.collect.Table;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
+import com.google.gerrit.proto.Protos;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
@@ -28,8 +29,7 @@
import com.google.gerrit.server.cache.CacheModule;
import com.google.gerrit.server.cache.proto.Cache.ChangeNotesKeyProto;
import com.google.gerrit.server.cache.serialize.CacheSerializer;
-import com.google.gerrit.server.cache.serialize.ProtoCacheSerializers;
-import com.google.gerrit.server.cache.serialize.ProtoCacheSerializers.ObjectIdConverter;
+import com.google.gerrit.server.cache.serialize.ObjectIdConverter;
import com.google.gerrit.server.notedb.AbstractChangeNotes.Args;
import com.google.gerrit.server.notedb.ChangeNotesCommit.ChangeNotesRevWalk;
import com.google.inject.Inject;
@@ -85,7 +85,7 @@
@Override
public byte[] serialize(Key object) {
- return ProtoCacheSerializers.toByteArray(
+ return Protos.toByteArray(
ChangeNotesKeyProto.newBuilder()
.setProject(object.project().get())
.setChangeId(object.changeId().get())
@@ -95,8 +95,7 @@
@Override
public Key deserialize(byte[] in) {
- ChangeNotesKeyProto proto =
- ProtoCacheSerializers.parseUnchecked(ChangeNotesKeyProto.parser(), in);
+ ChangeNotesKeyProto proto = Protos.parseUnchecked(ChangeNotesKeyProto.parser(), in);
return Key.create(
new Project.NameKey(proto.getProject()),
new Change.Id(proto.getChangeId()),
diff --git a/java/com/google/gerrit/server/notedb/ChangeNotesState.java b/java/com/google/gerrit/server/notedb/ChangeNotesState.java
index ca579ae..7ce7e66 100644
--- a/java/com/google/gerrit/server/notedb/ChangeNotesState.java
+++ b/java/com/google/gerrit/server/notedb/ChangeNotesState.java
@@ -19,10 +19,6 @@
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableListMultimap.toImmutableListMultimap;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
-import static com.google.gerrit.reviewdb.server.ReviewDbCodecs.APPROVAL_CODEC;
-import static com.google.gerrit.reviewdb.server.ReviewDbCodecs.MESSAGE_CODEC;
-import static com.google.gerrit.reviewdb.server.ReviewDbCodecs.PATCH_SET_CODEC;
-import static com.google.gerrit.server.cache.serialize.ProtoCacheSerializers.toByteString;
import static java.util.Objects.requireNonNull;
import com.google.auto.value.AutoValue;
@@ -40,6 +36,7 @@
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.SubmitRecord;
import com.google.gerrit.mail.Address;
+import com.google.gerrit.proto.Protos;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Change;
@@ -49,6 +46,10 @@
import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RevId;
+import com.google.gerrit.reviewdb.converter.ChangeMessageProtoConverter;
+import com.google.gerrit.reviewdb.converter.PatchSetApprovalProtoConverter;
+import com.google.gerrit.reviewdb.converter.PatchSetProtoConverter;
+import com.google.gerrit.reviewdb.converter.ProtoConverter;
import com.google.gerrit.server.OutputFormat;
import com.google.gerrit.server.ReviewerByEmailSet;
import com.google.gerrit.server.ReviewerSet;
@@ -59,11 +60,12 @@
import com.google.gerrit.server.cache.proto.Cache.ChangeNotesStateProto.ReviewerSetEntryProto;
import com.google.gerrit.server.cache.proto.Cache.ChangeNotesStateProto.ReviewerStatusUpdateProto;
import com.google.gerrit.server.cache.serialize.CacheSerializer;
-import com.google.gerrit.server.cache.serialize.ProtoCacheSerializers;
-import com.google.gerrit.server.cache.serialize.ProtoCacheSerializers.ObjectIdConverter;
+import com.google.gerrit.server.cache.serialize.ObjectIdConverter;
import com.google.gerrit.server.index.change.ChangeField.StoredSubmitRecord;
import com.google.gerrit.server.notedb.NoteDbChangeState.PrimaryStorage;
import com.google.gson.Gson;
+import com.google.protobuf.ByteString;
+import com.google.protobuf.MessageLite;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.List;
@@ -455,8 +457,15 @@
object.pastAssignees().forEach(a -> b.addPastAssignee(a.get()));
object.hashtags().forEach(b::addHashtag);
- object.patchSets().forEach(e -> b.addPatchSet(toByteString(e.getValue(), PATCH_SET_CODEC)));
- object.approvals().forEach(e -> b.addApproval(toByteString(e.getValue(), APPROVAL_CODEC)));
+ object
+ .patchSets()
+ .forEach(e -> b.addPatchSet(toByteString(e.getValue(), PatchSetProtoConverter.INSTANCE)));
+ object
+ .approvals()
+ .forEach(
+ e ->
+ b.addApproval(
+ toByteString(e.getValue(), PatchSetApprovalProtoConverter.INSTANCE)));
object.reviewers().asTable().cellSet().forEach(c -> b.addReviewer(toReviewerSetEntry(c)));
object
@@ -480,14 +489,22 @@
object
.submitRecords()
.forEach(r -> b.addSubmitRecord(GSON.toJson(new StoredSubmitRecord(r))));
- object.changeMessages().forEach(m -> b.addChangeMessage(toByteString(m, MESSAGE_CODEC)));
+ object
+ .changeMessages()
+ .forEach(m -> b.addChangeMessage(toByteString(m, ChangeMessageProtoConverter.INSTANCE)));
object.publishedComments().values().forEach(c -> b.addPublishedComment(GSON.toJson(c)));
if (object.readOnlyUntil() != null) {
b.setReadOnlyUntil(object.readOnlyUntil().getTime()).setHasReadOnlyUntil(true);
}
- return ProtoCacheSerializers.toByteArray(b.build());
+ return Protos.toByteArray(b.build());
+ }
+
+ @VisibleForTesting
+ static <T> ByteString toByteString(T object, ProtoConverter<?, T> converter) {
+ MessageLite message = converter.toProto(object);
+ return Protos.toByteString(message);
}
private static ChangeColumnsProto toChangeColumnsProto(ChangeColumns cols) {
@@ -555,8 +572,7 @@
@Override
public ChangeNotesState deserialize(byte[] in) {
- ChangeNotesStateProto proto =
- ProtoCacheSerializers.parseUnchecked(ChangeNotesStateProto.parser(), in);
+ ChangeNotesStateProto proto = Protos.parseUnchecked(ChangeNotesStateProto.parser(), in);
Change.Id changeId = new Change.Id(proto.getChangeId());
ChangeNotesState.Builder b =
@@ -575,14 +591,14 @@
proto
.getPatchSetList()
.stream()
- .map(PATCH_SET_CODEC::decode)
+ .map(bytes -> parseProtoFrom(PatchSetProtoConverter.INSTANCE, bytes))
.map(ps -> Maps.immutableEntry(ps.getId(), ps))
.collect(toImmutableList()))
.approvals(
proto
.getApprovalList()
.stream()
- .map(APPROVAL_CODEC::decode)
+ .map(bytes -> parseProtoFrom(PatchSetApprovalProtoConverter.INSTANCE, bytes))
.map(a -> Maps.immutableEntry(a.getPatchSetId(), a))
.collect(toImmutableList()))
.reviewers(toReviewerSet(proto.getReviewerList()))
@@ -606,7 +622,7 @@
proto
.getChangeMessageList()
.stream()
- .map(MESSAGE_CODEC::decode)
+ .map(bytes -> parseProtoFrom(ChangeMessageProtoConverter.INSTANCE, bytes))
.collect(toImmutableList()))
.publishedComments(
proto
@@ -620,6 +636,12 @@
return b.build();
}
+ private static <P extends MessageLite, T> T parseProtoFrom(
+ ProtoConverter<P, T> converter, ByteString byteString) {
+ P message = Protos.parseUnchecked(converter.getParser(), byteString);
+ return converter.fromProto(message);
+ }
+
private static ChangeColumns toChangeColumns(Change.Id changeId, ChangeColumnsProto proto) {
ChangeColumns.Builder b =
ChangeColumns.builder()
diff --git a/java/com/google/gerrit/server/query/change/ConflictKey.java b/java/com/google/gerrit/server/query/change/ConflictKey.java
index 42f5b13..01fdbfa 100644
--- a/java/com/google/gerrit/server/query/change/ConflictKey.java
+++ b/java/com/google/gerrit/server/query/change/ConflictKey.java
@@ -20,10 +20,10 @@
import com.google.common.base.Enums;
import com.google.common.collect.Ordering;
import com.google.gerrit.extensions.client.SubmitType;
+import com.google.gerrit.proto.Protos;
import com.google.gerrit.server.cache.proto.Cache.ConflictKeyProto;
import com.google.gerrit.server.cache.serialize.CacheSerializer;
-import com.google.gerrit.server.cache.serialize.ProtoCacheSerializers;
-import com.google.gerrit.server.cache.serialize.ProtoCacheSerializers.ObjectIdConverter;
+import com.google.gerrit.server.cache.serialize.ObjectIdConverter;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.ObjectId;
@@ -70,7 +70,7 @@
@Override
public byte[] serialize(ConflictKey object) {
ObjectIdConverter idConverter = ObjectIdConverter.create();
- return ProtoCacheSerializers.toByteArray(
+ return Protos.toByteArray(
ConflictKeyProto.newBuilder()
.setCommit(idConverter.toByteString(object.commit()))
.setOtherCommit(idConverter.toByteString(object.otherCommit()))
@@ -81,7 +81,7 @@
@Override
public ConflictKey deserialize(byte[] in) {
- ConflictKeyProto proto = ProtoCacheSerializers.parseUnchecked(ConflictKeyProto.parser(), in);
+ ConflictKeyProto proto = Protos.parseUnchecked(ConflictKeyProto.parser(), in);
ObjectIdConverter idConverter = ObjectIdConverter.create();
return create(
idConverter.fromByteString(proto.getCommit()),
diff --git a/javatests/com/google/gerrit/proto/BUILD b/javatests/com/google/gerrit/proto/BUILD
index a249638..c7d3aca 100644
--- a/javatests/com/google/gerrit/proto/BUILD
+++ b/javatests/com/google/gerrit/proto/BUILD
@@ -4,15 +4,13 @@
name = "proto_tests",
srcs = glob(["*.java"]),
deps = [
+ "//java/com/google/gerrit/proto",
"//java/com/google/gerrit/testing:gerrit-test-util",
- "//lib/truth:truth-proto-extension",
- "//proto:reviewdb_java_proto",
-
- # TODO(dborowitz): These are already runtime_deps of
- # truth-proto-extension, but either omitting them or adding them as
- # runtime_deps to this target fails with:
- # class file for com.google.common.collect.Multimap not found
"//lib:guava",
+ "//lib:protobuf",
"//lib/truth",
+ "//lib/truth:truth-proto-extension",
+ "//proto:cache_java_proto",
+ "//proto:reviewdb_java_proto",
],
)
diff --git a/javatests/com/google/gerrit/proto/ProtosTest.java b/javatests/com/google/gerrit/proto/ProtosTest.java
new file mode 100644
index 0000000..29e8fe0
--- /dev/null
+++ b/javatests/com/google/gerrit/proto/ProtosTest.java
@@ -0,0 +1,156 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.proto;
+
+import static com.google.common.truth.Truth.assert_;
+import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
+
+import com.google.gerrit.server.cache.proto.Cache.ChangeNotesKeyProto;
+import com.google.gerrit.server.cache.proto.Cache.ChangeNotesStateProto;
+import com.google.gerrit.testing.GerritBaseTests;
+import com.google.protobuf.ByteString;
+import java.util.Arrays;
+import org.junit.Test;
+
+public class ProtosTest extends GerritBaseTests {
+ @Test
+ public void parseUncheckedByteArrayWrongProtoType() {
+ ChangeNotesKeyProto proto =
+ ChangeNotesKeyProto.newBuilder()
+ .setProject("project")
+ .setChangeId(1234)
+ .setId(ByteString.copyFromUtf8("foo"))
+ .build();
+ byte[] bytes = Protos.toByteArray(proto);
+ try {
+ Protos.parseUnchecked(ChangeNotesStateProto.parser(), bytes);
+ assert_().fail("expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+ }
+
+ @Test
+ public void parseUncheckedByteArrayInvalidData() {
+ byte[] bytes = new byte[] {0x00};
+ try {
+ Protos.parseUnchecked(ChangeNotesStateProto.parser(), bytes);
+ assert_().fail("expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+ }
+
+ @Test
+ public void parseUncheckedByteArray() {
+ ChangeNotesKeyProto proto =
+ ChangeNotesKeyProto.newBuilder()
+ .setProject("project")
+ .setChangeId(1234)
+ .setId(ByteString.copyFromUtf8("foo"))
+ .build();
+ byte[] bytes = Protos.toByteArray(proto);
+ assertThat(Protos.parseUnchecked(ChangeNotesKeyProto.parser(), bytes)).isEqualTo(proto);
+ }
+
+ @Test
+ public void parseUncheckedSegmentOfByteArrayWrongProtoType() {
+ ChangeNotesKeyProto proto =
+ ChangeNotesKeyProto.newBuilder()
+ .setProject("project")
+ .setChangeId(1234)
+ .setId(ByteString.copyFromUtf8("foo"))
+ .build();
+ byte[] bytes = Protos.toByteArray(proto);
+ try {
+ Protos.parseUnchecked(ChangeNotesStateProto.parser(), bytes, 0, bytes.length);
+ assert_().fail("expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+ }
+
+ @Test
+ public void parseUncheckedSegmentOfByteArrayInvalidData() {
+ byte[] bytes = new byte[] {0x00};
+ try {
+ Protos.parseUnchecked(ChangeNotesStateProto.parser(), bytes, 0, bytes.length);
+ assert_().fail("expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+ }
+
+ @Test
+ public void parseUncheckedSegmentOfByteArray() {
+ ChangeNotesKeyProto proto =
+ ChangeNotesKeyProto.newBuilder()
+ .setProject("project")
+ .setChangeId(1234)
+ .setId(ByteString.copyFromUtf8("foo"))
+ .build();
+ byte[] protoBytes = Protos.toByteArray(proto);
+ int offset = 3;
+ int length = protoBytes.length;
+ byte[] bytes = new byte[length + 20];
+ Arrays.fill(bytes, (byte) 1);
+ System.arraycopy(protoBytes, 0, bytes, offset, length);
+
+ ChangeNotesKeyProto parsedProto =
+ Protos.parseUnchecked(ChangeNotesKeyProto.parser(), bytes, offset, length);
+
+ assertThat(parsedProto).isEqualTo(proto);
+ }
+
+ @Test
+ public void parseUncheckedByteStringWrongProtoType() {
+ ChangeNotesKeyProto proto =
+ ChangeNotesKeyProto.newBuilder()
+ .setProject("project")
+ .setChangeId(1234)
+ .setId(ByteString.copyFromUtf8("foo"))
+ .build();
+ ByteString byteString = Protos.toByteString(proto);
+ try {
+ Protos.parseUnchecked(ChangeNotesStateProto.parser(), byteString);
+ assert_().fail("expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+ }
+
+ @Test
+ public void parseUncheckedByteStringInvalidData() {
+ ByteString byteString = ByteString.copyFrom(new byte[] {0x00});
+ try {
+ Protos.parseUnchecked(ChangeNotesStateProto.parser(), byteString);
+ assert_().fail("expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+ }
+
+ @Test
+ public void parseUncheckedByteString() {
+ ChangeNotesKeyProto proto =
+ ChangeNotesKeyProto.newBuilder()
+ .setProject("project")
+ .setChangeId(1234)
+ .setId(ByteString.copyFromUtf8("foo"))
+ .build();
+ ByteString byteString = Protos.toByteString(proto);
+ assertThat(Protos.parseUnchecked(ChangeNotesKeyProto.parser(), byteString)).isEqualTo(proto);
+ }
+}
diff --git a/javatests/com/google/gerrit/reviewdb/converter/AccountIdProtoConverterTest.java b/javatests/com/google/gerrit/reviewdb/converter/AccountIdProtoConverterTest.java
new file mode 100644
index 0000000..38d4195
--- /dev/null
+++ b/javatests/com/google/gerrit/reviewdb/converter/AccountIdProtoConverterTest.java
@@ -0,0 +1,67 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
+import static com.google.gerrit.proto.testing.SerializedClassSubject.assertThatSerializedClass;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.gerrit.proto.reviewdb.Reviewdb;
+import com.google.gerrit.proto.testing.SerializedClassSubject;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.protobuf.Parser;
+import org.junit.Test;
+
+public class AccountIdProtoConverterTest {
+ private final AccountIdProtoConverter accountIdProtoConverter = AccountIdProtoConverter.INSTANCE;
+
+ @Test
+ public void allValuesConvertedToProto() {
+ Account.Id accountId = new Account.Id(24);
+
+ Reviewdb.Account_Id proto = accountIdProtoConverter.toProto(accountId);
+
+ Reviewdb.Account_Id expectedProto = Reviewdb.Account_Id.newBuilder().setId(24).build();
+ assertThat(proto).isEqualTo(expectedProto);
+ }
+
+ @Test
+ public void allValuesConvertedToProtoAndBackAgain() {
+ Account.Id accountId = new Account.Id(34832);
+
+ Account.Id convertedAccountId =
+ accountIdProtoConverter.fromProto(accountIdProtoConverter.toProto(accountId));
+
+ assertThat(convertedAccountId).isEqualTo(accountId);
+ }
+
+ @Test
+ public void protoCanBeParsedFromBytes() throws Exception {
+ Reviewdb.Account_Id proto = Reviewdb.Account_Id.newBuilder().setId(24).build();
+ byte[] bytes = proto.toByteArray();
+
+ Parser<Reviewdb.Account_Id> parser = accountIdProtoConverter.getParser();
+ Reviewdb.Account_Id parsedProto = parser.parseFrom(bytes);
+
+ assertThat(parsedProto).isEqualTo(proto);
+ }
+
+ /** See {@link SerializedClassSubject} for background and what to do if this test fails. */
+ @Test
+ public void fieldsExistAsExpected() {
+ assertThatSerializedClass(Account.Id.class).hasFields(ImmutableMap.of("id", int.class));
+ }
+}
diff --git a/javatests/com/google/gerrit/reviewdb/converter/BUILD b/javatests/com/google/gerrit/reviewdb/converter/BUILD
new file mode 100644
index 0000000..7c15910
--- /dev/null
+++ b/javatests/com/google/gerrit/reviewdb/converter/BUILD
@@ -0,0 +1,33 @@
+load("//tools/bzl:junit.bzl", "junit_tests")
+
+COMPATIBLITY_TEST_SRCS = glob(["*CompatibilityTest.java"])
+
+junit_tests(
+ name = "proto_converter_tests",
+ srcs = glob(
+ ["*.java"],
+ exclude = COMPATIBLITY_TEST_SRCS,
+ ),
+ deps = [
+ "//java/com/google/gerrit/proto/testing",
+ "//java/com/google/gerrit/reviewdb:server",
+ "//lib:guava",
+ "//lib:protobuf",
+ "//lib/truth",
+ "//lib/truth:truth-proto-extension",
+ "//proto:reviewdb_java_proto",
+ ],
+)
+
+junit_tests(
+ name = "compatibility_tests",
+ srcs = COMPATIBLITY_TEST_SRCS,
+ deps = [
+ "//java/com/google/gerrit/proto",
+ "//java/com/google/gerrit/reviewdb:server",
+ "//lib:guava",
+ "//lib:gwtorm-client",
+ "//lib:protobuf",
+ "//lib/truth",
+ ],
+)
diff --git a/javatests/com/google/gerrit/reviewdb/converter/ChangeIdProtoConverterTest.java b/javatests/com/google/gerrit/reviewdb/converter/ChangeIdProtoConverterTest.java
new file mode 100644
index 0000000..d5f055b
--- /dev/null
+++ b/javatests/com/google/gerrit/reviewdb/converter/ChangeIdProtoConverterTest.java
@@ -0,0 +1,67 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
+import static com.google.gerrit.proto.testing.SerializedClassSubject.assertThatSerializedClass;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.gerrit.proto.reviewdb.Reviewdb;
+import com.google.gerrit.proto.testing.SerializedClassSubject;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.protobuf.Parser;
+import org.junit.Test;
+
+public class ChangeIdProtoConverterTest {
+ private final ChangeIdProtoConverter changeIdProtoConverter = ChangeIdProtoConverter.INSTANCE;
+
+ @Test
+ public void allValuesConvertedToProto() {
+ Change.Id changeId = new Change.Id(94);
+
+ Reviewdb.Change_Id proto = changeIdProtoConverter.toProto(changeId);
+
+ Reviewdb.Change_Id expectedProto = Reviewdb.Change_Id.newBuilder().setId(94).build();
+ assertThat(proto).isEqualTo(expectedProto);
+ }
+
+ @Test
+ public void allValuesConvertedToProtoAndBackAgain() {
+ Change.Id changeId = new Change.Id(2903482);
+
+ Change.Id convertedChangeId =
+ changeIdProtoConverter.fromProto(changeIdProtoConverter.toProto(changeId));
+
+ assertThat(convertedChangeId).isEqualTo(changeId);
+ }
+
+ @Test
+ public void protoCanBeParsedFromBytes() throws Exception {
+ Reviewdb.Change_Id proto = Reviewdb.Change_Id.newBuilder().setId(94).build();
+ byte[] bytes = proto.toByteArray();
+
+ Parser<Reviewdb.Change_Id> parser = changeIdProtoConverter.getParser();
+ Reviewdb.Change_Id parsedProto = parser.parseFrom(bytes);
+
+ assertThat(parsedProto).isEqualTo(proto);
+ }
+
+ /** See {@link SerializedClassSubject} for background and what to do if this test fails. */
+ @Test
+ public void fieldsExistAsExpected() {
+ assertThatSerializedClass(Change.Id.class).hasFields(ImmutableMap.of("id", int.class));
+ }
+}
diff --git a/javatests/com/google/gerrit/reviewdb/converter/ChangeMessageConverterCompatibilityTest.java b/javatests/com/google/gerrit/reviewdb/converter/ChangeMessageConverterCompatibilityTest.java
new file mode 100644
index 0000000..a194ec6
--- /dev/null
+++ b/javatests/com/google/gerrit/reviewdb/converter/ChangeMessageConverterCompatibilityTest.java
@@ -0,0 +1,195 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import static com.google.common.collect.ImmutableList.toImmutableList;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.gerrit.proto.Protos;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.ChangeMessage;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gwtorm.protobuf.CodecFactory;
+import com.google.gwtorm.protobuf.ProtobufCodec;
+import com.google.gwtorm.server.OrmException;
+import com.google.protobuf.ByteString;
+import com.google.protobuf.CodedOutputStream;
+import com.google.protobuf.MessageLite;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.sql.Timestamp;
+import java.util.Collection;
+import java.util.List;
+import org.junit.Test;
+
+// TODO(aliceks): Delete after proving binary compatibility.
+public class ChangeMessageConverterCompatibilityTest {
+
+ private final ProtobufCodec<ChangeMessage> changeMessageCodec =
+ CodecFactory.encoder(ChangeMessage.class);
+ private final ChangeMessageProtoConverter changeMessageProtoConverter =
+ ChangeMessageProtoConverter.INSTANCE;
+
+ @Test
+ public void changeIndexFieldWithAllValuesIsBinaryCompatible() throws Exception {
+ ChangeMessage changeMessage =
+ new ChangeMessage(
+ new ChangeMessage.Key(new Change.Id(543), "change-message-21"),
+ new Account.Id(63),
+ new Timestamp(9876543),
+ new PatchSet.Id(new Change.Id(34), 13));
+ changeMessage.setMessage("This is a change message.");
+ changeMessage.setTag("An arbitrary tag.");
+ changeMessage.setRealAuthor(new Account.Id(10003));
+ ImmutableList<ChangeMessage> changeMessages = ImmutableList.of(changeMessage);
+
+ byte[] resultOfOldConverter =
+ getOnlyElement(convertToProtos_old(changeMessageCodec, changeMessages));
+ byte[] resultOfNewConverter =
+ getOnlyElement(convertToProtos_new(changeMessageProtoConverter, changeMessages));
+
+ assertThat(resultOfNewConverter).isEqualTo(resultOfOldConverter);
+ }
+
+ @Test
+ public void changeIndexFieldWithMandatoryValuesIsBinaryCompatible() throws Exception {
+ ChangeMessage changeMessage =
+ new ChangeMessage(
+ new ChangeMessage.Key(new Change.Id(543), "change-message-21"), null, null, null);
+ ImmutableList<ChangeMessage> changeMessages = ImmutableList.of(changeMessage);
+
+ byte[] resultOfOldConverter =
+ getOnlyElement(convertToProtos_old(changeMessageCodec, changeMessages));
+ byte[] resultOfNewConverter =
+ getOnlyElement(convertToProtos_new(changeMessageProtoConverter, changeMessages));
+
+ assertThat(resultOfNewConverter).isEqualTo(resultOfOldConverter);
+ }
+
+ @Test
+ public void changeNotesFieldWithAllValuesIsBinaryCompatible() {
+ ChangeMessage changeMessage =
+ new ChangeMessage(
+ new ChangeMessage.Key(new Change.Id(543), "change-message-21"),
+ new Account.Id(63),
+ new Timestamp(9876543),
+ new PatchSet.Id(new Change.Id(34), 13));
+ changeMessage.setMessage("This is a change message.");
+ changeMessage.setTag("An arbitrary tag.");
+ changeMessage.setRealAuthor(new Account.Id(10003));
+
+ ByteString resultOfOldConverter = Protos.toByteString(changeMessage, changeMessageCodec);
+ ByteString resultOfNewConverter = toByteString(changeMessage, changeMessageProtoConverter);
+
+ assertThat(resultOfNewConverter).isEqualTo(resultOfOldConverter);
+ }
+
+ @Test
+ public void changeNotesFieldWithMainValuesIsBinaryCompatible() {
+ ChangeMessage changeMessage =
+ new ChangeMessage(
+ new ChangeMessage.Key(new Change.Id(543), "change-message-21"),
+ new Account.Id(63),
+ new Timestamp(9876543),
+ new PatchSet.Id(new Change.Id(34), 13));
+
+ ByteString resultOfOldConverter = Protos.toByteString(changeMessage, changeMessageCodec);
+ ByteString resultOfNewConverter = toByteString(changeMessage, changeMessageProtoConverter);
+
+ assertThat(resultOfNewConverter).isEqualTo(resultOfOldConverter);
+ }
+
+ @Test
+ public void changeNotesFieldWithoutRealAuthorButAuthorIsBinaryCompatible() {
+ ChangeMessage changeMessage =
+ new ChangeMessage(
+ new ChangeMessage.Key(new Change.Id(543), "change-message-21"),
+ new Account.Id(63),
+ null,
+ null);
+
+ ByteString resultOfOldConverter = Protos.toByteString(changeMessage, changeMessageCodec);
+ ByteString resultOfNewConverter = toByteString(changeMessage, changeMessageProtoConverter);
+
+ assertThat(resultOfNewConverter).isEqualTo(resultOfOldConverter);
+ }
+
+ @Test
+ public void changeNotesFieldWithoutSameRealAuthorAndAuthorIsBinaryCompatible() {
+ ChangeMessage changeMessage =
+ new ChangeMessage(
+ new ChangeMessage.Key(new Change.Id(543), "change-message-21"),
+ new Account.Id(63),
+ null,
+ null);
+ changeMessage.setRealAuthor(new Account.Id(63));
+
+ ByteString resultOfOldConverter = Protos.toByteString(changeMessage, changeMessageCodec);
+ ByteString resultOfNewConverter = toByteString(changeMessage, changeMessageProtoConverter);
+
+ assertThat(resultOfNewConverter).isEqualTo(resultOfOldConverter);
+ }
+
+ @Test
+ public void changeNotesFieldWithMandatoryValuesIsBinaryCompatible() {
+ ChangeMessage changeMessage =
+ new ChangeMessage(
+ new ChangeMessage.Key(new Change.Id(543), "change-message-21"), null, null, null);
+
+ ByteString resultOfOldConverter = Protos.toByteString(changeMessage, changeMessageCodec);
+ ByteString resultOfNewConverter = toByteString(changeMessage, changeMessageProtoConverter);
+
+ assertThat(resultOfNewConverter).isEqualTo(resultOfOldConverter);
+ }
+
+ // Copied from ChangeField.
+ private static <T> List<byte[]> convertToProtos_old(ProtobufCodec<T> codec, Collection<T> objs)
+ throws OrmException {
+ List<byte[]> result = Lists.newArrayListWithCapacity(objs.size());
+ ByteArrayOutputStream out = new ByteArrayOutputStream(256);
+ try {
+ for (T obj : objs) {
+ out.reset();
+ CodedOutputStream cos = CodedOutputStream.newInstance(out);
+ codec.encode(obj, cos);
+ cos.flush();
+ result.add(out.toByteArray());
+ }
+ } catch (IOException e) {
+ throw new OrmException(e);
+ }
+ return result;
+ }
+
+ // Copied from ChangeField.
+ private static <T> List<byte[]> convertToProtos_new(
+ ProtoConverter<?, T> converter, Collection<T> objects) {
+ return objects
+ .stream()
+ .map(converter::toProto)
+ .map(Protos::toByteArray)
+ .collect(toImmutableList());
+ }
+
+ // Copied from ChangeNotesState.Serializer.
+ private static <T> ByteString toByteString(T object, ProtoConverter<?, T> converter) {
+ MessageLite message = converter.toProto(object);
+ return Protos.toByteString(message);
+ }
+}
diff --git a/javatests/com/google/gerrit/reviewdb/converter/ChangeMessageKeyProtoConverterTest.java b/javatests/com/google/gerrit/reviewdb/converter/ChangeMessageKeyProtoConverterTest.java
new file mode 100644
index 0000000..9874737
--- /dev/null
+++ b/javatests/com/google/gerrit/reviewdb/converter/ChangeMessageKeyProtoConverterTest.java
@@ -0,0 +1,83 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
+import static com.google.gerrit.proto.testing.SerializedClassSubject.assertThatSerializedClass;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.gerrit.proto.reviewdb.Reviewdb;
+import com.google.gerrit.proto.testing.SerializedClassSubject;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.ChangeMessage;
+import com.google.protobuf.Parser;
+import java.lang.reflect.Type;
+import org.junit.Test;
+
+public class ChangeMessageKeyProtoConverterTest {
+ private final ChangeMessageKeyProtoConverter messageKeyProtoConverter =
+ ChangeMessageKeyProtoConverter.INSTANCE;
+
+ @Test
+ public void allValuesConvertedToProto() {
+ ChangeMessage.Key messageKey = new ChangeMessage.Key(new Change.Id(704), "aabbcc");
+
+ Reviewdb.ChangeMessage_Key proto = messageKeyProtoConverter.toProto(messageKey);
+
+ Reviewdb.ChangeMessage_Key expectedProto =
+ Reviewdb.ChangeMessage_Key.newBuilder()
+ .setChangeId(Reviewdb.Change_Id.newBuilder().setId(704))
+ .setUuid("aabbcc")
+ .build();
+ assertThat(proto).isEqualTo(expectedProto);
+ }
+
+ @Test
+ public void allValuesConvertedToProtoAndBackAgain() {
+ ChangeMessage.Key messageKey = new ChangeMessage.Key(new Change.Id(704), "aabbcc");
+
+ ChangeMessage.Key convertedMessageKey =
+ messageKeyProtoConverter.fromProto(messageKeyProtoConverter.toProto(messageKey));
+
+ assertThat(convertedMessageKey).isEqualTo(messageKey);
+ }
+
+ @Test
+ public void protoCanBeParsedFromBytes() throws Exception {
+ Reviewdb.ChangeMessage_Key proto =
+ Reviewdb.ChangeMessage_Key.newBuilder()
+ .setChangeId(Reviewdb.Change_Id.newBuilder().setId(704))
+ .setUuid("aabbcc")
+ .build();
+ byte[] bytes = proto.toByteArray();
+
+ Parser<Reviewdb.ChangeMessage_Key> parser = messageKeyProtoConverter.getParser();
+ Reviewdb.ChangeMessage_Key parsedProto = parser.parseFrom(bytes);
+
+ assertThat(parsedProto).isEqualTo(proto);
+ }
+
+ /** See {@link SerializedClassSubject} for background and what to do if this test fails. */
+ @Test
+ public void fieldsExistAsExpected() {
+ assertThatSerializedClass(ChangeMessage.Key.class)
+ .hasFields(
+ ImmutableMap.<String, Type>builder()
+ .put("changeId", Change.Id.class)
+ .put("uuid", String.class)
+ .build());
+ }
+}
diff --git a/javatests/com/google/gerrit/reviewdb/converter/ChangeMessageProtoConverterTest.java b/javatests/com/google/gerrit/reviewdb/converter/ChangeMessageProtoConverterTest.java
new file mode 100644
index 0000000..f478deb
--- /dev/null
+++ b/javatests/com/google/gerrit/reviewdb/converter/ChangeMessageProtoConverterTest.java
@@ -0,0 +1,214 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
+import static com.google.gerrit.proto.testing.SerializedClassSubject.assertThatSerializedClass;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.gerrit.proto.reviewdb.Reviewdb;
+import com.google.gerrit.proto.testing.SerializedClassSubject;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.ChangeMessage;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.protobuf.Parser;
+import java.lang.reflect.Type;
+import java.sql.Timestamp;
+import org.junit.Test;
+
+public class ChangeMessageProtoConverterTest {
+ private final ChangeMessageProtoConverter changeMessageProtoConverter =
+ ChangeMessageProtoConverter.INSTANCE;
+
+ @Test
+ public void allValuesConvertedToProto() {
+ ChangeMessage changeMessage =
+ new ChangeMessage(
+ new ChangeMessage.Key(new Change.Id(543), "change-message-21"),
+ new Account.Id(63),
+ new Timestamp(9876543),
+ new PatchSet.Id(new Change.Id(34), 13));
+ changeMessage.setMessage("This is a change message.");
+ changeMessage.setTag("An arbitrary tag.");
+ changeMessage.setRealAuthor(new Account.Id(10003));
+
+ Reviewdb.ChangeMessage proto = changeMessageProtoConverter.toProto(changeMessage);
+
+ Reviewdb.ChangeMessage expectedProto =
+ Reviewdb.ChangeMessage.newBuilder()
+ .setKey(
+ Reviewdb.ChangeMessage_Key.newBuilder()
+ .setChangeId(Reviewdb.Change_Id.newBuilder().setId(543))
+ .setUuid("change-message-21"))
+ .setAuthorId(Reviewdb.Account_Id.newBuilder().setId(63))
+ .setWrittenOn(9876543)
+ .setMessage("This is a change message.")
+ .setPatchset(
+ Reviewdb.PatchSet_Id.newBuilder()
+ .setChangeId(Reviewdb.Change_Id.newBuilder().setId(34))
+ .setPatchSetId(13))
+ .setTag("An arbitrary tag.")
+ .setRealAuthor(Reviewdb.Account_Id.newBuilder().setId(10003))
+ .build();
+ assertThat(proto).isEqualTo(expectedProto);
+ }
+
+ @Test
+ public void mainValuesConvertedToProto() {
+ ChangeMessage changeMessage =
+ new ChangeMessage(
+ new ChangeMessage.Key(new Change.Id(543), "change-message-21"),
+ new Account.Id(63),
+ new Timestamp(9876543),
+ new PatchSet.Id(new Change.Id(34), 13));
+
+ Reviewdb.ChangeMessage proto = changeMessageProtoConverter.toProto(changeMessage);
+
+ Reviewdb.ChangeMessage expectedProto =
+ Reviewdb.ChangeMessage.newBuilder()
+ .setKey(
+ Reviewdb.ChangeMessage_Key.newBuilder()
+ .setChangeId(Reviewdb.Change_Id.newBuilder().setId(543))
+ .setUuid("change-message-21"))
+ .setAuthorId(Reviewdb.Account_Id.newBuilder().setId(63))
+ .setWrittenOn(9876543)
+ .setPatchset(
+ Reviewdb.PatchSet_Id.newBuilder()
+ .setChangeId(Reviewdb.Change_Id.newBuilder().setId(34))
+ .setPatchSetId(13))
+ .build();
+ assertThat(proto).isEqualTo(expectedProto);
+ }
+
+ // This test documents a special behavior which is necessary to ensure binary compatibility.
+ @Test
+ public void realAuthorIsNotAutomaticallySetToAuthorWhenConvertedToProto() {
+ ChangeMessage changeMessage =
+ new ChangeMessage(
+ new ChangeMessage.Key(new Change.Id(543), "change-message-21"),
+ new Account.Id(63),
+ null,
+ null);
+
+ Reviewdb.ChangeMessage proto = changeMessageProtoConverter.toProto(changeMessage);
+
+ Reviewdb.ChangeMessage expectedProto =
+ Reviewdb.ChangeMessage.newBuilder()
+ .setKey(
+ Reviewdb.ChangeMessage_Key.newBuilder()
+ .setChangeId(Reviewdb.Change_Id.newBuilder().setId(543))
+ .setUuid("change-message-21"))
+ .setAuthorId(Reviewdb.Account_Id.newBuilder().setId(63))
+ .build();
+ assertThat(proto).isEqualTo(expectedProto);
+ }
+
+ @Test
+ public void mandatoryValuesConvertedToProto() {
+ // writtenOn may not be null according to the column definition but it's optional for the
+ // protobuf definition. -> assume as optional and hence test null
+ ChangeMessage changeMessage =
+ new ChangeMessage(
+ new ChangeMessage.Key(new Change.Id(543), "change-message-21"), null, null, null);
+
+ Reviewdb.ChangeMessage proto = changeMessageProtoConverter.toProto(changeMessage);
+
+ Reviewdb.ChangeMessage expectedProto =
+ Reviewdb.ChangeMessage.newBuilder()
+ .setKey(
+ Reviewdb.ChangeMessage_Key.newBuilder()
+ .setChangeId(Reviewdb.Change_Id.newBuilder().setId(543))
+ .setUuid("change-message-21"))
+ .build();
+ assertThat(proto).isEqualTo(expectedProto);
+ }
+
+ @Test
+ public void allValuesConvertedToProtoAndBackAgain() {
+ ChangeMessage changeMessage =
+ new ChangeMessage(
+ new ChangeMessage.Key(new Change.Id(543), "change-message-21"),
+ new Account.Id(63),
+ new Timestamp(9876543),
+ new PatchSet.Id(new Change.Id(34), 13));
+ changeMessage.setMessage("This is a change message.");
+ changeMessage.setTag("An arbitrary tag.");
+ changeMessage.setRealAuthor(new Account.Id(10003));
+
+ ChangeMessage convertedChangeMessage =
+ changeMessageProtoConverter.fromProto(changeMessageProtoConverter.toProto(changeMessage));
+ assertThat(convertedChangeMessage).isEqualTo(changeMessage);
+ }
+
+ @Test
+ public void mainValuesConvertedToProtoAndBackAgain() {
+ ChangeMessage changeMessage =
+ new ChangeMessage(
+ new ChangeMessage.Key(new Change.Id(543), "change-message-21"),
+ new Account.Id(63),
+ new Timestamp(9876543),
+ new PatchSet.Id(new Change.Id(34), 13));
+
+ ChangeMessage convertedChangeMessage =
+ changeMessageProtoConverter.fromProto(changeMessageProtoConverter.toProto(changeMessage));
+ assertThat(convertedChangeMessage).isEqualTo(changeMessage);
+ }
+
+ @Test
+ public void mandatoryValuesConvertedToProtoAndBackAgain() {
+ ChangeMessage changeMessage =
+ new ChangeMessage(
+ new ChangeMessage.Key(new Change.Id(543), "change-message-21"), null, null, null);
+
+ ChangeMessage convertedChangeMessage =
+ changeMessageProtoConverter.fromProto(changeMessageProtoConverter.toProto(changeMessage));
+ assertThat(convertedChangeMessage).isEqualTo(changeMessage);
+ }
+
+ @Test
+ public void protoCanBeParsedFromBytes() throws Exception {
+ Reviewdb.ChangeMessage proto =
+ Reviewdb.ChangeMessage.newBuilder()
+ .setKey(
+ Reviewdb.ChangeMessage_Key.newBuilder()
+ .setChangeId(Reviewdb.Change_Id.newBuilder().setId(543))
+ .setUuid("change-message-21"))
+ .build();
+ byte[] bytes = proto.toByteArray();
+
+ Parser<Reviewdb.ChangeMessage> parser = changeMessageProtoConverter.getParser();
+ Reviewdb.ChangeMessage parsedProto = parser.parseFrom(bytes);
+
+ assertThat(parsedProto).isEqualTo(proto);
+ }
+
+ /** See {@link SerializedClassSubject} for background and what to do if this test fails. */
+ @Test
+ public void fieldsExistAsExpected() {
+ assertThatSerializedClass(ChangeMessage.class)
+ .hasFields(
+ ImmutableMap.<String, Type>builder()
+ .put("key", ChangeMessage.Key.class)
+ .put("author", Account.Id.class)
+ .put("writtenOn", Timestamp.class)
+ .put("message", String.class)
+ .put("patchset", PatchSet.Id.class)
+ .put("tag", String.class)
+ .put("realAuthor", Account.Id.class)
+ .build());
+ }
+}
diff --git a/javatests/com/google/gerrit/reviewdb/converter/LabelIdProtoConverterTest.java b/javatests/com/google/gerrit/reviewdb/converter/LabelIdProtoConverterTest.java
new file mode 100644
index 0000000..a6aebd2
--- /dev/null
+++ b/javatests/com/google/gerrit/reviewdb/converter/LabelIdProtoConverterTest.java
@@ -0,0 +1,67 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
+import static com.google.gerrit.proto.testing.SerializedClassSubject.assertThatSerializedClass;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.gerrit.proto.reviewdb.Reviewdb;
+import com.google.gerrit.proto.testing.SerializedClassSubject;
+import com.google.gerrit.reviewdb.client.LabelId;
+import com.google.protobuf.Parser;
+import org.junit.Test;
+
+public class LabelIdProtoConverterTest {
+ private final LabelIdProtoConverter labelIdProtoConverter = LabelIdProtoConverter.INSTANCE;
+
+ @Test
+ public void allValuesConvertedToProto() {
+ LabelId labelId = new LabelId("Label ID 42");
+
+ Reviewdb.LabelId proto = labelIdProtoConverter.toProto(labelId);
+
+ Reviewdb.LabelId expectedProto = Reviewdb.LabelId.newBuilder().setId("Label ID 42").build();
+ assertThat(proto).isEqualTo(expectedProto);
+ }
+
+ @Test
+ public void allValuesConvertedToProtoAndBackAgain() {
+ LabelId labelId = new LabelId("label-5");
+
+ LabelId convertedLabelId =
+ labelIdProtoConverter.fromProto(labelIdProtoConverter.toProto(labelId));
+
+ assertThat(convertedLabelId).isEqualTo(labelId);
+ }
+
+ @Test
+ public void protoCanBeParsedFromBytes() throws Exception {
+ Reviewdb.LabelId proto = Reviewdb.LabelId.newBuilder().setId("label-23").build();
+ byte[] bytes = proto.toByteArray();
+
+ Parser<Reviewdb.LabelId> parser = labelIdProtoConverter.getParser();
+ Reviewdb.LabelId parsedProto = parser.parseFrom(bytes);
+
+ assertThat(parsedProto).isEqualTo(proto);
+ }
+
+ /** See {@link SerializedClassSubject} for background and what to do if this test fails. */
+ @Test
+ public void fieldsExistAsExpected() {
+ assertThatSerializedClass(LabelId.class).hasFields(ImmutableMap.of("id", String.class));
+ }
+}
diff --git a/javatests/com/google/gerrit/reviewdb/converter/PatchSetApprovalConverterCompatibilityTest.java b/javatests/com/google/gerrit/reviewdb/converter/PatchSetApprovalConverterCompatibilityTest.java
new file mode 100644
index 0000000..9da37da
--- /dev/null
+++ b/javatests/com/google/gerrit/reviewdb/converter/PatchSetApprovalConverterCompatibilityTest.java
@@ -0,0 +1,166 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import static com.google.common.collect.ImmutableList.toImmutableList;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.gerrit.proto.Protos;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.LabelId;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gerrit.reviewdb.client.PatchSetApproval;
+import com.google.gwtorm.protobuf.CodecFactory;
+import com.google.gwtorm.protobuf.ProtobufCodec;
+import com.google.gwtorm.server.OrmException;
+import com.google.protobuf.ByteString;
+import com.google.protobuf.CodedOutputStream;
+import com.google.protobuf.MessageLite;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import org.junit.Test;
+
+// TODO(aliceks): Delete after proving binary compatibility.
+public class PatchSetApprovalConverterCompatibilityTest {
+
+ private final ProtobufCodec<PatchSetApproval> patchSetApprovalCodec =
+ CodecFactory.encoder(PatchSetApproval.class);
+ private final PatchSetApprovalProtoConverter patchSetApprovalProtoConverter =
+ PatchSetApprovalProtoConverter.INSTANCE;
+
+ @Test
+ public void changeIndexFieldWithAllValuesIsBinaryCompatible() throws Exception {
+ PatchSetApproval patchSetApproval =
+ new PatchSetApproval(
+ new PatchSetApproval.Key(
+ new PatchSet.Id(new Change.Id(42), 14),
+ new Account.Id(100013),
+ new LabelId("label-8")),
+ (short) 456,
+ new Date(987654L));
+ patchSetApproval.setTag("tag-21");
+ patchSetApproval.setRealAccountId(new Account.Id(612));
+ patchSetApproval.setPostSubmit(true);
+ ImmutableList<PatchSetApproval> patchSetApprovals = ImmutableList.of(patchSetApproval);
+
+ byte[] resultOfOldConverter =
+ getOnlyElement(convertToProtos_old(patchSetApprovalCodec, patchSetApprovals));
+ byte[] resultOfNewConverter =
+ getOnlyElement(convertToProtos_new(patchSetApprovalProtoConverter, patchSetApprovals));
+
+ assertThat(resultOfNewConverter).isEqualTo(resultOfOldConverter);
+ }
+
+ @Test
+ public void changeIndexFieldWithMandatoryValuesIsBinaryCompatible() throws Exception {
+ PatchSetApproval patchSetApproval =
+ new PatchSetApproval(
+ new PatchSetApproval.Key(
+ new PatchSet.Id(new Change.Id(42), 14),
+ new Account.Id(100013),
+ new LabelId("label-8")),
+ (short) 456,
+ new Date(987654L));
+ ImmutableList<PatchSetApproval> patchSetApprovals = ImmutableList.of(patchSetApproval);
+
+ byte[] resultOfOldConverter =
+ getOnlyElement(convertToProtos_old(patchSetApprovalCodec, patchSetApprovals));
+ byte[] resultOfNewConverter =
+ getOnlyElement(convertToProtos_new(patchSetApprovalProtoConverter, patchSetApprovals));
+
+ assertThat(resultOfNewConverter).isEqualTo(resultOfOldConverter);
+ }
+
+ @Test
+ public void changeNotesFieldWithAllValuesIsBinaryCompatible() {
+ PatchSetApproval patchSetApproval =
+ new PatchSetApproval(
+ new PatchSetApproval.Key(
+ new PatchSet.Id(new Change.Id(42), 14),
+ new Account.Id(100013),
+ new LabelId("label-8")),
+ (short) 456,
+ new Date(987654L));
+ patchSetApproval.setTag("tag-21");
+ patchSetApproval.setRealAccountId(new Account.Id(612));
+ patchSetApproval.setPostSubmit(true);
+
+ ByteString resultOfOldConverter = Protos.toByteString(patchSetApproval, patchSetApprovalCodec);
+ ByteString resultOfNewConverter =
+ toByteString(patchSetApproval, patchSetApprovalProtoConverter);
+
+ assertThat(resultOfNewConverter).isEqualTo(resultOfOldConverter);
+ }
+
+ @Test
+ public void changeNotesFieldWithMandatoryValuesIsBinaryCompatible() {
+ PatchSetApproval patchSetApproval =
+ new PatchSetApproval(
+ new PatchSetApproval.Key(
+ new PatchSet.Id(new Change.Id(42), 14),
+ new Account.Id(100013),
+ new LabelId("label-8")),
+ (short) 456,
+ new Date(987654L));
+
+ ByteString resultOfOldConverter = Protos.toByteString(patchSetApproval, patchSetApprovalCodec);
+ ByteString resultOfNewConverter =
+ toByteString(patchSetApproval, patchSetApprovalProtoConverter);
+
+ assertThat(resultOfNewConverter).isEqualTo(resultOfOldConverter);
+ }
+
+ // Copied from ChangeField.
+ private static <T> List<byte[]> convertToProtos_old(ProtobufCodec<T> codec, Collection<T> objs)
+ throws OrmException {
+ List<byte[]> result = Lists.newArrayListWithCapacity(objs.size());
+ ByteArrayOutputStream out = new ByteArrayOutputStream(256);
+ try {
+ for (T obj : objs) {
+ out.reset();
+ CodedOutputStream cos = CodedOutputStream.newInstance(out);
+ codec.encode(obj, cos);
+ cos.flush();
+ result.add(out.toByteArray());
+ }
+ } catch (IOException e) {
+ throw new OrmException(e);
+ }
+ return result;
+ }
+
+ // Copied from ChangeField.
+ private static <T> List<byte[]> convertToProtos_new(
+ ProtoConverter<?, T> converter, Collection<T> objects) {
+ return objects
+ .stream()
+ .map(converter::toProto)
+ .map(Protos::toByteArray)
+ .collect(toImmutableList());
+ }
+
+ // Copied from ChangeNotesState.Serializer.
+ private static <T> ByteString toByteString(T object, ProtoConverter<?, T> converter) {
+ MessageLite message = converter.toProto(object);
+ return Protos.toByteString(message);
+ }
+}
diff --git a/javatests/com/google/gerrit/reviewdb/converter/PatchSetApprovalKeyProtoConverterTest.java b/javatests/com/google/gerrit/reviewdb/converter/PatchSetApprovalKeyProtoConverterTest.java
new file mode 100644
index 0000000..0ed84fd
--- /dev/null
+++ b/javatests/com/google/gerrit/reviewdb/converter/PatchSetApprovalKeyProtoConverterTest.java
@@ -0,0 +1,98 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
+import static com.google.gerrit.proto.testing.SerializedClassSubject.assertThatSerializedClass;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.gerrit.proto.reviewdb.Reviewdb;
+import com.google.gerrit.proto.testing.SerializedClassSubject;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.LabelId;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gerrit.reviewdb.client.PatchSetApproval;
+import com.google.protobuf.Parser;
+import java.lang.reflect.Type;
+import org.junit.Test;
+
+public class PatchSetApprovalKeyProtoConverterTest {
+ private final PatchSetApprovalKeyProtoConverter protoConverter =
+ PatchSetApprovalKeyProtoConverter.INSTANCE;
+
+ @Test
+ public void allValuesConvertedToProto() {
+ PatchSetApproval.Key key =
+ new PatchSetApproval.Key(
+ new PatchSet.Id(new Change.Id(42), 14), new Account.Id(100013), new LabelId("label-8"));
+
+ Reviewdb.PatchSetApproval_Key proto = protoConverter.toProto(key);
+
+ Reviewdb.PatchSetApproval_Key expectedProto =
+ Reviewdb.PatchSetApproval_Key.newBuilder()
+ .setPatchSetId(
+ Reviewdb.PatchSet_Id.newBuilder()
+ .setChangeId(Reviewdb.Change_Id.newBuilder().setId(42))
+ .setPatchSetId(14))
+ .setAccountId(Reviewdb.Account_Id.newBuilder().setId(100013))
+ .setCategoryId(Reviewdb.LabelId.newBuilder().setId("label-8"))
+ .build();
+ assertThat(proto).isEqualTo(expectedProto);
+ }
+
+ @Test
+ public void allValuesConvertedToProtoAndBackAgain() {
+ PatchSetApproval.Key key =
+ new PatchSetApproval.Key(
+ new PatchSet.Id(new Change.Id(42), 14), new Account.Id(100013), new LabelId("label-8"));
+
+ PatchSetApproval.Key convertedKey = protoConverter.fromProto(protoConverter.toProto(key));
+
+ assertThat(convertedKey).isEqualTo(key);
+ }
+
+ @Test
+ public void protoCanBeParsedFromBytes() throws Exception {
+ Reviewdb.PatchSetApproval_Key proto =
+ Reviewdb.PatchSetApproval_Key.newBuilder()
+ .setPatchSetId(
+ Reviewdb.PatchSet_Id.newBuilder()
+ .setChangeId(Reviewdb.Change_Id.newBuilder().setId(42))
+ .setPatchSetId(14))
+ .setAccountId(Reviewdb.Account_Id.newBuilder().setId(100013))
+ .setCategoryId(Reviewdb.LabelId.newBuilder().setId("label-8"))
+ .build();
+ byte[] bytes = proto.toByteArray();
+
+ Parser<Reviewdb.PatchSetApproval_Key> parser = protoConverter.getParser();
+ Reviewdb.PatchSetApproval_Key parsedProto = parser.parseFrom(bytes);
+
+ assertThat(parsedProto).isEqualTo(proto);
+ }
+
+ /** See {@link SerializedClassSubject} for background and what to do if this test fails. */
+ @Test
+ public void fieldsExistAsExpected() {
+ assertThatSerializedClass(PatchSetApproval.Key.class)
+ .hasFields(
+ ImmutableMap.<String, Type>builder()
+ .put("patchSetId", PatchSet.Id.class)
+ .put("accountId", Account.Id.class)
+ .put("categoryId", LabelId.class)
+ .build());
+ }
+}
diff --git a/javatests/com/google/gerrit/reviewdb/converter/PatchSetApprovalProtoConverterTest.java b/javatests/com/google/gerrit/reviewdb/converter/PatchSetApprovalProtoConverterTest.java
new file mode 100644
index 0000000..831696c
--- /dev/null
+++ b/javatests/com/google/gerrit/reviewdb/converter/PatchSetApprovalProtoConverterTest.java
@@ -0,0 +1,203 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
+import static com.google.gerrit.proto.testing.SerializedClassSubject.assertThatSerializedClass;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.gerrit.proto.reviewdb.Reviewdb;
+import com.google.gerrit.proto.testing.SerializedClassSubject;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.LabelId;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gerrit.reviewdb.client.PatchSetApproval;
+import com.google.protobuf.Parser;
+import java.lang.reflect.Type;
+import java.sql.Timestamp;
+import java.util.Date;
+import org.junit.Test;
+
+public class PatchSetApprovalProtoConverterTest {
+ private final PatchSetApprovalProtoConverter protoConverter =
+ PatchSetApprovalProtoConverter.INSTANCE;
+
+ @Test
+ public void allValuesConvertedToProto() {
+ PatchSetApproval patchSetApproval =
+ new PatchSetApproval(
+ new PatchSetApproval.Key(
+ new PatchSet.Id(new Change.Id(42), 14),
+ new Account.Id(100013),
+ new LabelId("label-8")),
+ (short) 456,
+ new Date(987654L));
+ patchSetApproval.setTag("tag-21");
+ patchSetApproval.setRealAccountId(new Account.Id(612));
+ patchSetApproval.setPostSubmit(true);
+
+ Reviewdb.PatchSetApproval proto = protoConverter.toProto(patchSetApproval);
+
+ Reviewdb.PatchSetApproval expectedProto =
+ Reviewdb.PatchSetApproval.newBuilder()
+ .setKey(
+ Reviewdb.PatchSetApproval_Key.newBuilder()
+ .setPatchSetId(
+ Reviewdb.PatchSet_Id.newBuilder()
+ .setChangeId(Reviewdb.Change_Id.newBuilder().setId(42))
+ .setPatchSetId(14))
+ .setAccountId(Reviewdb.Account_Id.newBuilder().setId(100013))
+ .setCategoryId(Reviewdb.LabelId.newBuilder().setId("label-8")))
+ .setValue(456)
+ .setGranted(987654L)
+ .setTag("tag-21")
+ .setRealAccountId(Reviewdb.Account_Id.newBuilder().setId(612))
+ .setPostSubmit(true)
+ .build();
+ assertThat(proto).isEqualTo(expectedProto);
+ }
+
+ @Test
+ public void mandatoryValuesConvertedToProto() {
+ PatchSetApproval patchSetApproval =
+ new PatchSetApproval(
+ new PatchSetApproval.Key(
+ new PatchSet.Id(new Change.Id(42), 14),
+ new Account.Id(100013),
+ new LabelId("label-8")),
+ (short) 456,
+ new Date(987654L));
+
+ Reviewdb.PatchSetApproval proto = protoConverter.toProto(patchSetApproval);
+
+ Reviewdb.PatchSetApproval expectedProto =
+ Reviewdb.PatchSetApproval.newBuilder()
+ .setKey(
+ Reviewdb.PatchSetApproval_Key.newBuilder()
+ .setPatchSetId(
+ Reviewdb.PatchSet_Id.newBuilder()
+ .setChangeId(Reviewdb.Change_Id.newBuilder().setId(42))
+ .setPatchSetId(14))
+ .setAccountId(Reviewdb.Account_Id.newBuilder().setId(100013))
+ .setCategoryId(Reviewdb.LabelId.newBuilder().setId("label-8")))
+ .setValue(456)
+ .setGranted(987654L)
+ // This value can't be unset when our entity class is given.
+ .setPostSubmit(false)
+ .build();
+ assertThat(proto).isEqualTo(expectedProto);
+ }
+
+ @Test
+ public void allValuesConvertedToProtoAndBackAgain() {
+ PatchSetApproval patchSetApproval =
+ new PatchSetApproval(
+ new PatchSetApproval.Key(
+ new PatchSet.Id(new Change.Id(42), 14),
+ new Account.Id(100013),
+ new LabelId("label-8")),
+ (short) 456,
+ new Date(987654L));
+ patchSetApproval.setTag("tag-21");
+ patchSetApproval.setRealAccountId(new Account.Id(612));
+ patchSetApproval.setPostSubmit(true);
+
+ PatchSetApproval convertedPatchSetApproval =
+ protoConverter.fromProto(protoConverter.toProto(patchSetApproval));
+ assertThat(convertedPatchSetApproval).isEqualTo(patchSetApproval);
+ }
+
+ @Test
+ public void mandatoryValuesConvertedToProtoAndBackAgain() {
+ PatchSetApproval patchSetApproval =
+ new PatchSetApproval(
+ new PatchSetApproval.Key(
+ new PatchSet.Id(new Change.Id(42), 14),
+ new Account.Id(100013),
+ new LabelId("label-8")),
+ (short) 456,
+ new Date(987654L));
+
+ PatchSetApproval convertedPatchSetApproval =
+ protoConverter.fromProto(protoConverter.toProto(patchSetApproval));
+ assertThat(convertedPatchSetApproval).isEqualTo(patchSetApproval);
+ }
+
+ // We need this special test as some values are only optional in the protobuf definition but can
+ // never be unset in our entity object.
+ @Test
+ public void protoWithOnlyRequiredValuesCanBeConvertedBack() {
+ Reviewdb.PatchSetApproval proto =
+ Reviewdb.PatchSetApproval.newBuilder()
+ .setKey(
+ Reviewdb.PatchSetApproval_Key.newBuilder()
+ .setPatchSetId(
+ Reviewdb.PatchSet_Id.newBuilder()
+ .setChangeId(Reviewdb.Change_Id.newBuilder().setId(42))
+ .setPatchSetId(14))
+ .setAccountId(Reviewdb.Account_Id.newBuilder().setId(100013))
+ .setCategoryId(Reviewdb.LabelId.newBuilder().setId("label-8")))
+ .build();
+ PatchSetApproval patchSetApproval = protoConverter.fromProto(proto);
+
+ assertThat(patchSetApproval.getPatchSetId()).isEqualTo(new PatchSet.Id(new Change.Id(42), 14));
+ assertThat(patchSetApproval.getAccountId()).isEqualTo(new Account.Id(100013));
+ assertThat(patchSetApproval.getLabelId()).isEqualTo(new LabelId("label-8"));
+ // Default values for unset protobuf fields which can't be unset in the entity object.
+ assertThat(patchSetApproval.getValue()).isEqualTo(0);
+ assertThat(patchSetApproval.getGranted()).isEqualTo(new Timestamp(0));
+ assertThat(patchSetApproval.isPostSubmit()).isEqualTo(false);
+ }
+
+ @Test
+ public void protoCanBeParsedFromBytes() throws Exception {
+ Reviewdb.PatchSetApproval proto =
+ Reviewdb.PatchSetApproval.newBuilder()
+ .setKey(
+ Reviewdb.PatchSetApproval_Key.newBuilder()
+ .setPatchSetId(
+ Reviewdb.PatchSet_Id.newBuilder()
+ .setChangeId(Reviewdb.Change_Id.newBuilder().setId(42))
+ .setPatchSetId(14))
+ .setAccountId(Reviewdb.Account_Id.newBuilder().setId(100013))
+ .setCategoryId(Reviewdb.LabelId.newBuilder().setId("label-8")))
+ .setValue(456)
+ .setGranted(987654L)
+ .build();
+ byte[] bytes = proto.toByteArray();
+
+ Parser<Reviewdb.PatchSetApproval> parser = protoConverter.getParser();
+ Reviewdb.PatchSetApproval parsedProto = parser.parseFrom(bytes);
+
+ assertThat(parsedProto).isEqualTo(proto);
+ }
+
+ /** See {@link SerializedClassSubject} for background and what to do if this test fails. */
+ @Test
+ public void fieldsExistAsExpected() {
+ assertThatSerializedClass(PatchSetApproval.class)
+ .hasFields(
+ ImmutableMap.<String, Type>builder()
+ .put("key", PatchSetApproval.Key.class)
+ .put("value", short.class)
+ .put("granted", Timestamp.class)
+ .put("tag", String.class)
+ .put("realAccountId", Account.Id.class)
+ .put("postSubmit", boolean.class)
+ .build());
+ }
+}
diff --git a/javatests/com/google/gerrit/reviewdb/converter/PatchSetConverterCompatibilityTest.java b/javatests/com/google/gerrit/reviewdb/converter/PatchSetConverterCompatibilityTest.java
new file mode 100644
index 0000000..8d8960c
--- /dev/null
+++ b/javatests/com/google/gerrit/reviewdb/converter/PatchSetConverterCompatibilityTest.java
@@ -0,0 +1,137 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import static com.google.common.collect.ImmutableList.toImmutableList;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.gerrit.proto.Protos;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gerrit.reviewdb.client.RevId;
+import com.google.gwtorm.protobuf.CodecFactory;
+import com.google.gwtorm.protobuf.ProtobufCodec;
+import com.google.gwtorm.server.OrmException;
+import com.google.protobuf.ByteString;
+import com.google.protobuf.CodedOutputStream;
+import com.google.protobuf.MessageLite;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.sql.Timestamp;
+import java.util.Collection;
+import java.util.List;
+import org.junit.Test;
+
+// TODO(aliceks): Delete after proving binary compatibility.
+public class PatchSetConverterCompatibilityTest {
+
+ private final ProtobufCodec<PatchSet> patchSetCodec = CodecFactory.encoder(PatchSet.class);
+ private final PatchSetProtoConverter patchSetProtoConverter = PatchSetProtoConverter.INSTANCE;
+
+ @Test
+ public void changeIndexFieldWithAllValuesIsBinaryCompatible() throws Exception {
+ PatchSet patchSet = new PatchSet(new PatchSet.Id(new Change.Id(103), 73));
+ patchSet.setRevision(new RevId("aabbccddeeff"));
+ patchSet.setUploader(new Account.Id(452));
+ patchSet.setCreatedOn(new Timestamp(930349320L));
+ patchSet.setGroups(ImmutableList.of("group1, group2"));
+ patchSet.setPushCertificate("my push certificate");
+ patchSet.setDescription("This is a patch set description.");
+ ImmutableList<PatchSet> patchSets = ImmutableList.of(patchSet);
+
+ byte[] resultOfOldConverter = getOnlyElement(convertToProtos_old(patchSetCodec, patchSets));
+ byte[] resultOfNewConverter =
+ getOnlyElement(convertToProtos_new(patchSetProtoConverter, patchSets));
+
+ assertThat(resultOfNewConverter).isEqualTo(resultOfOldConverter);
+ }
+
+ @Test
+ public void changeIndexFieldWithMandatoryValuesIsBinaryCompatible() throws Exception {
+ PatchSet patchSet = new PatchSet(new PatchSet.Id(new Change.Id(103), 73));
+ ImmutableList<PatchSet> patchSets = ImmutableList.of(patchSet);
+
+ byte[] resultOfOldConverter = getOnlyElement(convertToProtos_old(patchSetCodec, patchSets));
+ byte[] resultOfNewConverter =
+ getOnlyElement(convertToProtos_new(patchSetProtoConverter, patchSets));
+
+ assertThat(resultOfNewConverter).isEqualTo(resultOfOldConverter);
+ }
+
+ @Test
+ public void changeNotesFieldWithAllValuesIsBinaryCompatible() {
+ PatchSet patchSet = new PatchSet(new PatchSet.Id(new Change.Id(103), 73));
+ patchSet.setRevision(new RevId("aabbccddeeff"));
+ patchSet.setUploader(new Account.Id(452));
+ patchSet.setCreatedOn(new Timestamp(930349320L));
+ patchSet.setGroups(ImmutableList.of("group1, group2"));
+ patchSet.setPushCertificate("my push certificate");
+ patchSet.setDescription("This is a patch set description.");
+
+ ByteString resultOfOldConverter = Protos.toByteString(patchSet, patchSetCodec);
+ ByteString resultOfNewConverter = toByteString(patchSet, patchSetProtoConverter);
+
+ assertThat(resultOfNewConverter).isEqualTo(resultOfOldConverter);
+ }
+
+ @Test
+ public void changeNotesFieldWithMandatoryValuesIsBinaryCompatible() {
+ PatchSet patchSet = new PatchSet(new PatchSet.Id(new Change.Id(103), 73));
+
+ ByteString resultOfOldConverter = Protos.toByteString(patchSet, patchSetCodec);
+ ByteString resultOfNewConverter = toByteString(patchSet, patchSetProtoConverter);
+
+ assertThat(resultOfNewConverter).isEqualTo(resultOfOldConverter);
+ }
+
+ // Copied from ChangeField.
+ private static <T> List<byte[]> convertToProtos_old(ProtobufCodec<T> codec, Collection<T> objs)
+ throws OrmException {
+ List<byte[]> result = Lists.newArrayListWithCapacity(objs.size());
+ ByteArrayOutputStream out = new ByteArrayOutputStream(256);
+ try {
+ for (T obj : objs) {
+ out.reset();
+ CodedOutputStream cos = CodedOutputStream.newInstance(out);
+ codec.encode(obj, cos);
+ cos.flush();
+ result.add(out.toByteArray());
+ }
+ } catch (IOException e) {
+ throw new OrmException(e);
+ }
+ return result;
+ }
+
+ // Copied from ChangeField.
+ private static <T> List<byte[]> convertToProtos_new(
+ ProtoConverter<?, T> converter, Collection<T> objects) {
+ return objects
+ .stream()
+ .map(converter::toProto)
+ .map(Protos::toByteArray)
+ .collect(toImmutableList());
+ }
+
+ // Copied from ChangeNotesState.Serializer.
+ private static <T> ByteString toByteString(T object, ProtoConverter<?, T> converter) {
+ MessageLite message = converter.toProto(object);
+ return Protos.toByteString(message);
+ }
+}
diff --git a/javatests/com/google/gerrit/reviewdb/converter/PatchSetIdProtoConverterTest.java b/javatests/com/google/gerrit/reviewdb/converter/PatchSetIdProtoConverterTest.java
new file mode 100644
index 0000000..3869ab3
--- /dev/null
+++ b/javatests/com/google/gerrit/reviewdb/converter/PatchSetIdProtoConverterTest.java
@@ -0,0 +1,83 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
+import static com.google.gerrit.proto.testing.SerializedClassSubject.assertThatSerializedClass;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.gerrit.proto.reviewdb.Reviewdb;
+import com.google.gerrit.proto.testing.SerializedClassSubject;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.protobuf.Parser;
+import java.lang.reflect.Type;
+import org.junit.Test;
+
+public class PatchSetIdProtoConverterTest {
+ private final PatchSetIdProtoConverter patchSetIdProtoConverter =
+ PatchSetIdProtoConverter.INSTANCE;
+
+ @Test
+ public void allValuesConvertedToProto() {
+ PatchSet.Id patchSetId = new PatchSet.Id(new Change.Id(103), 73);
+
+ Reviewdb.PatchSet_Id proto = patchSetIdProtoConverter.toProto(patchSetId);
+
+ Reviewdb.PatchSet_Id expectedProto =
+ Reviewdb.PatchSet_Id.newBuilder()
+ .setChangeId(Reviewdb.Change_Id.newBuilder().setId(103))
+ .setPatchSetId(73)
+ .build();
+ assertThat(proto).isEqualTo(expectedProto);
+ }
+
+ @Test
+ public void allValuesConvertedToProtoAndBackAgain() {
+ PatchSet.Id patchSetId = new PatchSet.Id(new Change.Id(20), 13);
+
+ PatchSet.Id convertedPatchSetId =
+ patchSetIdProtoConverter.fromProto(patchSetIdProtoConverter.toProto(patchSetId));
+
+ assertThat(convertedPatchSetId).isEqualTo(patchSetId);
+ }
+
+ @Test
+ public void protoCanBeParsedFromBytes() throws Exception {
+ Reviewdb.PatchSet_Id proto =
+ Reviewdb.PatchSet_Id.newBuilder()
+ .setChangeId(Reviewdb.Change_Id.newBuilder().setId(103))
+ .setPatchSetId(73)
+ .build();
+ byte[] bytes = proto.toByteArray();
+
+ Parser<Reviewdb.PatchSet_Id> parser = patchSetIdProtoConverter.getParser();
+ Reviewdb.PatchSet_Id parsedProto = parser.parseFrom(bytes);
+
+ assertThat(parsedProto).isEqualTo(proto);
+ }
+
+ /** See {@link SerializedClassSubject} for background and what to do if this test fails. */
+ @Test
+ public void fieldsExistAsExpected() {
+ assertThatSerializedClass(PatchSet.Id.class)
+ .hasFields(
+ ImmutableMap.<String, Type>builder()
+ .put("changeId", Change.Id.class)
+ .put("patchSetId", int.class)
+ .build());
+ }
+}
diff --git a/javatests/com/google/gerrit/reviewdb/converter/PatchSetProtoConverterTest.java b/javatests/com/google/gerrit/reviewdb/converter/PatchSetProtoConverterTest.java
new file mode 100644
index 0000000..00ccf82
--- /dev/null
+++ b/javatests/com/google/gerrit/reviewdb/converter/PatchSetProtoConverterTest.java
@@ -0,0 +1,137 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
+import static com.google.gerrit.proto.testing.SerializedClassSubject.assertThatSerializedClass;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.truth.Truth;
+import com.google.gerrit.proto.reviewdb.Reviewdb;
+import com.google.gerrit.proto.testing.SerializedClassSubject;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gerrit.reviewdb.client.RevId;
+import com.google.protobuf.Parser;
+import java.lang.reflect.Type;
+import java.sql.Timestamp;
+import org.junit.Test;
+
+public class PatchSetProtoConverterTest {
+ private final PatchSetProtoConverter patchSetProtoConverter = PatchSetProtoConverter.INSTANCE;
+
+ @Test
+ public void allValuesConvertedToProto() {
+ PatchSet patchSet = new PatchSet(new PatchSet.Id(new Change.Id(103), 73));
+ patchSet.setRevision(new RevId("aabbccddeeff"));
+ patchSet.setUploader(new Account.Id(452));
+ patchSet.setCreatedOn(new Timestamp(930349320L));
+ patchSet.setGroups(ImmutableList.of("group1, group2"));
+ patchSet.setPushCertificate("my push certificate");
+ patchSet.setDescription("This is a patch set description.");
+
+ Reviewdb.PatchSet proto = patchSetProtoConverter.toProto(patchSet);
+
+ Reviewdb.PatchSet expectedProto =
+ Reviewdb.PatchSet.newBuilder()
+ .setId(
+ Reviewdb.PatchSet_Id.newBuilder()
+ .setChangeId(Reviewdb.Change_Id.newBuilder().setId(103))
+ .setPatchSetId(73))
+ .setRevision(Reviewdb.RevId.newBuilder().setId("aabbccddeeff"))
+ .setUploaderAccountId(Reviewdb.Account_Id.newBuilder().setId(452))
+ .setCreatedOn(930349320L)
+ .setGroups("group1, group2")
+ .setPushCertificate("my push certificate")
+ .setDescription("This is a patch set description.")
+ .build();
+ assertThat(proto).isEqualTo(expectedProto);
+ }
+
+ @Test
+ public void mandatoryValuesConvertedToProto() {
+ PatchSet patchSet = new PatchSet(new PatchSet.Id(new Change.Id(103), 73));
+
+ Reviewdb.PatchSet proto = patchSetProtoConverter.toProto(patchSet);
+
+ Reviewdb.PatchSet expectedProto =
+ Reviewdb.PatchSet.newBuilder()
+ .setId(
+ Reviewdb.PatchSet_Id.newBuilder()
+ .setChangeId(Reviewdb.Change_Id.newBuilder().setId(103))
+ .setPatchSetId(73))
+ .build();
+ assertThat(proto).isEqualTo(expectedProto);
+ }
+
+ @Test
+ public void allValuesConvertedToProtoAndBackAgain() {
+ PatchSet patchSet = new PatchSet(new PatchSet.Id(new Change.Id(103), 73));
+ patchSet.setRevision(new RevId("aabbccddeeff"));
+ patchSet.setUploader(new Account.Id(452));
+ patchSet.setCreatedOn(new Timestamp(930349320L));
+ patchSet.setGroups(ImmutableList.of("group1, group2"));
+ patchSet.setPushCertificate("my push certificate");
+ patchSet.setDescription("This is a patch set description.");
+
+ PatchSet convertedPatchSet =
+ patchSetProtoConverter.fromProto(patchSetProtoConverter.toProto(patchSet));
+ Truth.assertThat(convertedPatchSet).isEqualTo(patchSet);
+ }
+
+ @Test
+ public void mandatoryValuesConvertedToProtoAndBackAgain() {
+ PatchSet patchSet = new PatchSet(new PatchSet.Id(new Change.Id(103), 73));
+
+ PatchSet convertedPatchSet =
+ patchSetProtoConverter.fromProto(patchSetProtoConverter.toProto(patchSet));
+ Truth.assertThat(convertedPatchSet).isEqualTo(patchSet);
+ }
+
+ @Test
+ public void protoCanBeParsedFromBytes() throws Exception {
+ Reviewdb.PatchSet proto =
+ Reviewdb.PatchSet.newBuilder()
+ .setId(
+ Reviewdb.PatchSet_Id.newBuilder()
+ .setChangeId(Reviewdb.Change_Id.newBuilder().setId(103))
+ .setPatchSetId(73))
+ .build();
+ byte[] bytes = proto.toByteArray();
+
+ Parser<Reviewdb.PatchSet> parser = patchSetProtoConverter.getParser();
+ Reviewdb.PatchSet parsedProto = parser.parseFrom(bytes);
+
+ assertThat(parsedProto).isEqualTo(proto);
+ }
+
+ /** See {@link SerializedClassSubject} for background and what to do if this test fails. */
+ @Test
+ public void fieldsExistAsExpected() {
+ assertThatSerializedClass(PatchSet.class)
+ .hasFields(
+ ImmutableMap.<String, Type>builder()
+ .put("id", PatchSet.Id.class)
+ .put("revision", RevId.class)
+ .put("uploader", Account.Id.class)
+ .put("createdOn", Timestamp.class)
+ .put("groups", String.class)
+ .put("pushCertificate", String.class)
+ .put("description", String.class)
+ .build());
+ }
+}
diff --git a/javatests/com/google/gerrit/reviewdb/converter/RevIdProtoConverterTest.java b/javatests/com/google/gerrit/reviewdb/converter/RevIdProtoConverterTest.java
new file mode 100644
index 0000000..2aa3a84
--- /dev/null
+++ b/javatests/com/google/gerrit/reviewdb/converter/RevIdProtoConverterTest.java
@@ -0,0 +1,66 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.converter;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
+import static com.google.gerrit.proto.testing.SerializedClassSubject.assertThatSerializedClass;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.gerrit.proto.reviewdb.Reviewdb;
+import com.google.gerrit.proto.testing.SerializedClassSubject;
+import com.google.gerrit.reviewdb.client.RevId;
+import com.google.protobuf.Parser;
+import org.junit.Test;
+
+public class RevIdProtoConverterTest {
+ private final RevIdProtoConverter revIdProtoConverter = RevIdProtoConverter.INSTANCE;
+
+ @Test
+ public void allValuesConvertedToProto() {
+ RevId revId = new RevId("9903402f303249e");
+
+ Reviewdb.RevId proto = revIdProtoConverter.toProto(revId);
+
+ Reviewdb.RevId expectedProto = Reviewdb.RevId.newBuilder().setId("9903402f303249e").build();
+ assertThat(proto).isEqualTo(expectedProto);
+ }
+
+ @Test
+ public void allValuesConvertedToProtoAndBackAgain() {
+ RevId revId = new RevId("ff3934a320bb");
+
+ RevId convertedRevId = revIdProtoConverter.fromProto(revIdProtoConverter.toProto(revId));
+
+ assertThat(convertedRevId).isEqualTo(revId);
+ }
+
+ @Test
+ public void protoCanBeParsedFromBytes() throws Exception {
+ Reviewdb.RevId proto = Reviewdb.RevId.newBuilder().setId("9903402f303249e").build();
+ byte[] bytes = proto.toByteArray();
+
+ Parser<Reviewdb.RevId> parser = revIdProtoConverter.getParser();
+ Reviewdb.RevId parsedProto = parser.parseFrom(bytes);
+
+ assertThat(parsedProto).isEqualTo(proto);
+ }
+
+ /** See {@link SerializedClassSubject} for background and what to do if this test fails. */
+ @Test
+ public void fieldsExistAsExpected() {
+ assertThatSerializedClass(RevId.class).hasFields(ImmutableMap.of("id", String.class));
+ }
+}
diff --git a/javatests/com/google/gerrit/server/BUILD b/javatests/com/google/gerrit/server/BUILD
index 88edc2e..e705ec5 100644
--- a/javatests/com/google/gerrit/server/BUILD
+++ b/javatests/com/google/gerrit/server/BUILD
@@ -44,6 +44,8 @@
"//java/com/google/gerrit/lifecycle",
"//java/com/google/gerrit/mail",
"//java/com/google/gerrit/metrics",
+ "//java/com/google/gerrit/proto",
+ "//java/com/google/gerrit/proto/testing",
"//java/com/google/gerrit/reviewdb:server",
"//java/com/google/gerrit/server",
"//java/com/google/gerrit/server/cache/serialize",
diff --git a/javatests/com/google/gerrit/server/account/externalids/AllExternalIdsTest.java b/javatests/com/google/gerrit/server/account/externalids/AllExternalIdsTest.java
index edf6bdd..d757f71 100644
--- a/javatests/com/google/gerrit/server/account/externalids/AllExternalIdsTest.java
+++ b/javatests/com/google/gerrit/server/account/externalids/AllExternalIdsTest.java
@@ -16,8 +16,8 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
+import static com.google.gerrit.proto.testing.SerializedClassSubject.assertThatSerializedClass;
import static com.google.gerrit.server.cache.testing.CacheSerializerTestUtil.byteString;
-import static com.google.gerrit.server.cache.testing.SerializedClassSubject.assertThatSerializedClass;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSetMultimap;
diff --git a/javatests/com/google/gerrit/server/auth/oauth/OAuthTokenCacheTest.java b/javatests/com/google/gerrit/server/auth/oauth/OAuthTokenCacheTest.java
index 81fd6d7..e4f8ba8 100644
--- a/javatests/com/google/gerrit/server/auth/oauth/OAuthTokenCacheTest.java
+++ b/javatests/com/google/gerrit/server/auth/oauth/OAuthTokenCacheTest.java
@@ -2,10 +2,11 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
-import static com.google.gerrit.server.cache.testing.SerializedClassSubject.assertThatSerializedClass;
+import static com.google.gerrit.proto.testing.SerializedClassSubject.assertThatSerializedClass;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.extensions.auth.oauth.OAuthToken;
+import com.google.gerrit.proto.testing.SerializedClassSubject;
import com.google.gerrit.server.cache.proto.Cache.OAuthTokenProto;
import com.google.gerrit.server.cache.serialize.CacheSerializer;
import java.lang.reflect.Type;
@@ -56,10 +57,7 @@
assertThat(s.deserialize(serializedWithEmptyString)).isEqualTo(tokenWithNull);
}
- /**
- * See {@link com.google.gerrit.server.cache.testing.SerializedClassSubject} for background and
- * what to do if this test fails.
- */
+ /** See {@link SerializedClassSubject} for background and what to do if this test fails. */
@Test
public void oAuthTokenFields() throws Exception {
assertThatSerializedClass(OAuthToken.class)
diff --git a/javatests/com/google/gerrit/server/cache/serialize/ProtoCacheSerializersTest.java b/javatests/com/google/gerrit/server/cache/serialize/ObjectIdConverterTest.java
similarity index 62%
rename from javatests/com/google/gerrit/server/cache/serialize/ProtoCacheSerializersTest.java
rename to javatests/com/google/gerrit/server/cache/serialize/ObjectIdConverterTest.java
index 8a02af2..c5ea2ea 100644
--- a/javatests/com/google/gerrit/server/cache/serialize/ProtoCacheSerializersTest.java
+++ b/javatests/com/google/gerrit/server/cache/serialize/ObjectIdConverterTest.java
@@ -16,18 +16,14 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assert_;
-import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
import static com.google.gerrit.server.cache.testing.CacheSerializerTestUtil.byteString;
-import com.google.gerrit.server.cache.proto.Cache.ChangeNotesKeyProto;
-import com.google.gerrit.server.cache.proto.Cache.ChangeNotesStateProto;
-import com.google.gerrit.server.cache.serialize.ProtoCacheSerializers.ObjectIdConverter;
import com.google.gerrit.testing.GerritBaseTests;
import com.google.protobuf.ByteString;
import org.eclipse.jgit.lib.ObjectId;
import org.junit.Test;
-public class ProtoCacheSerializersTest extends GerritBaseTests {
+public class ObjectIdConverterTest extends GerritBaseTests {
@Test
public void objectIdFromByteString() {
ObjectIdConverter idConverter = ObjectIdConverter.create();
@@ -73,45 +69,4 @@
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb));
}
-
- @Test
- public void parseUncheckedWrongProtoType() {
- ChangeNotesKeyProto proto =
- ChangeNotesKeyProto.newBuilder()
- .setProject("project")
- .setChangeId(1234)
- .setId(ByteString.copyFromUtf8("foo"))
- .build();
- byte[] bytes = ProtoCacheSerializers.toByteArray(proto);
- try {
- ProtoCacheSerializers.parseUnchecked(ChangeNotesStateProto.parser(), bytes);
- assert_().fail("expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // Expected.
- }
- }
-
- @Test
- public void parseUncheckedInvalidData() {
- byte[] bytes = new byte[] {0x00};
- try {
- ProtoCacheSerializers.parseUnchecked(ChangeNotesStateProto.parser(), bytes);
- assert_().fail("expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // Expected.
- }
- }
-
- @Test
- public void parseUnchecked() {
- ChangeNotesKeyProto proto =
- ChangeNotesKeyProto.newBuilder()
- .setProject("project")
- .setChangeId(1234)
- .setId(ByteString.copyFromUtf8("foo"))
- .build();
- byte[] bytes = ProtoCacheSerializers.toByteArray(proto);
- assertThat(ProtoCacheSerializers.parseUnchecked(ChangeNotesKeyProto.parser(), bytes))
- .isEqualTo(proto);
- }
}
diff --git a/javatests/com/google/gerrit/server/change/ChangeKindCacheImplTest.java b/javatests/com/google/gerrit/server/change/ChangeKindCacheImplTest.java
index 335ff12..fffb1da 100644
--- a/javatests/com/google/gerrit/server/change/ChangeKindCacheImplTest.java
+++ b/javatests/com/google/gerrit/server/change/ChangeKindCacheImplTest.java
@@ -16,10 +16,11 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
+import static com.google.gerrit.proto.testing.SerializedClassSubject.assertThatSerializedClass;
import static com.google.gerrit.server.cache.testing.CacheSerializerTestUtil.byteString;
-import static com.google.gerrit.server.cache.testing.SerializedClassSubject.assertThatSerializedClass;
import com.google.common.collect.ImmutableMap;
+import com.google.gerrit.proto.testing.SerializedClassSubject;
import com.google.gerrit.server.cache.proto.Cache.ChangeKindKeyProto;
import com.google.gerrit.server.cache.serialize.CacheSerializer;
import com.google.gerrit.server.change.ChangeKindCacheImpl.Key;
@@ -50,10 +51,7 @@
assertThat(s.deserialize(serialized)).isEqualTo(key);
}
- /**
- * See {@link com.google.gerrit.server.cache.testing.SerializedClassSubject} for background and
- * what to do if this test fails.
- */
+ /** See {@link SerializedClassSubject} for background and what to do if this test fails. */
@Test
public void keyFields() throws Exception {
assertThatSerializedClass(ChangeKindCacheImpl.Key.class)
diff --git a/javatests/com/google/gerrit/server/change/MergeabilityCacheImplTest.java b/javatests/com/google/gerrit/server/change/MergeabilityCacheImplTest.java
index c5d35f6..46ddbc2 100644
--- a/javatests/com/google/gerrit/server/change/MergeabilityCacheImplTest.java
+++ b/javatests/com/google/gerrit/server/change/MergeabilityCacheImplTest.java
@@ -16,11 +16,12 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
+import static com.google.gerrit.proto.testing.SerializedClassSubject.assertThatSerializedClass;
import static com.google.gerrit.server.cache.testing.CacheSerializerTestUtil.byteString;
-import static com.google.gerrit.server.cache.testing.SerializedClassSubject.assertThatSerializedClass;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.extensions.client.SubmitType;
+import com.google.gerrit.proto.testing.SerializedClassSubject;
import com.google.gerrit.server.cache.proto.Cache.MergeabilityKeyProto;
import com.google.gerrit.testing.GerritBaseTests;
import org.eclipse.jgit.lib.ObjectId;
@@ -54,10 +55,7 @@
.isEqualTo(key);
}
- /**
- * See {@link com.google.gerrit.server.cache.testing.SerializedClassSubject} for background and
- * what to do if this test fails.
- */
+ /** See {@link SerializedClassSubject} for background and what to do if this test fails. */
@Test
public void keyFields() throws Exception {
assertThatSerializedClass(MergeabilityCacheImpl.EntryKey.class)
diff --git a/javatests/com/google/gerrit/server/git/TagSetHolderTest.java b/javatests/com/google/gerrit/server/git/TagSetHolderTest.java
index 705139a..87ddc75 100644
--- a/javatests/com/google/gerrit/server/git/TagSetHolderTest.java
+++ b/javatests/com/google/gerrit/server/git/TagSetHolderTest.java
@@ -16,7 +16,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
-import static com.google.gerrit.server.cache.testing.SerializedClassSubject.assertThatSerializedClass;
+import static com.google.gerrit.proto.testing.SerializedClassSubject.assertThatSerializedClass;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.reviewdb.client.Project;
diff --git a/javatests/com/google/gerrit/server/git/TagSetTest.java b/javatests/com/google/gerrit/server/git/TagSetTest.java
index 1314ce6..3ac72be 100644
--- a/javatests/com/google/gerrit/server/git/TagSetTest.java
+++ b/javatests/com/google/gerrit/server/git/TagSetTest.java
@@ -17,8 +17,8 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
+import static com.google.gerrit.proto.testing.SerializedClassSubject.assertThatSerializedClass;
import static com.google.gerrit.server.cache.testing.CacheSerializerTestUtil.byteString;
-import static com.google.gerrit.server.cache.testing.SerializedClassSubject.assertThatSerializedClass;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;
diff --git a/javatests/com/google/gerrit/server/notedb/ChangeNotesCacheTest.java b/javatests/com/google/gerrit/server/notedb/ChangeNotesCacheTest.java
index 7b140b7..b4d9738 100644
--- a/javatests/com/google/gerrit/server/notedb/ChangeNotesCacheTest.java
+++ b/javatests/com/google/gerrit/server/notedb/ChangeNotesCacheTest.java
@@ -16,8 +16,8 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
+import static com.google.gerrit.proto.testing.SerializedClassSubject.assertThatSerializedClass;
import static com.google.gerrit.server.cache.testing.CacheSerializerTestUtil.byteString;
-import static com.google.gerrit.server.cache.testing.SerializedClassSubject.assertThatSerializedClass;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.reviewdb.client.Change;
diff --git a/javatests/com/google/gerrit/server/notedb/ChangeNotesStateTest.java b/javatests/com/google/gerrit/server/notedb/ChangeNotesStateTest.java
index 1bd6fbe..0ea1bea 100644
--- a/javatests/com/google/gerrit/server/notedb/ChangeNotesStateTest.java
+++ b/javatests/com/google/gerrit/server/notedb/ChangeNotesStateTest.java
@@ -16,11 +16,8 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
-import static com.google.gerrit.reviewdb.server.ReviewDbCodecs.APPROVAL_CODEC;
-import static com.google.gerrit.reviewdb.server.ReviewDbCodecs.MESSAGE_CODEC;
-import static com.google.gerrit.reviewdb.server.ReviewDbCodecs.PATCH_SET_CODEC;
-import static com.google.gerrit.server.cache.serialize.ProtoCacheSerializers.toByteString;
-import static com.google.gerrit.server.cache.testing.SerializedClassSubject.assertThatSerializedClass;
+import static com.google.gerrit.proto.testing.SerializedClassSubject.assertThatSerializedClass;
+import static com.google.gerrit.server.notedb.ChangeNotesState.Serializer.toByteString;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
@@ -39,6 +36,9 @@
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.client.RevId;
+import com.google.gerrit.reviewdb.converter.ChangeMessageProtoConverter;
+import com.google.gerrit.reviewdb.converter.PatchSetApprovalProtoConverter;
+import com.google.gerrit.reviewdb.converter.PatchSetProtoConverter;
import com.google.gerrit.server.ReviewerByEmailSet;
import com.google.gerrit.server.ReviewerSet;
import com.google.gerrit.server.ReviewerStatusUpdate;
@@ -47,7 +47,7 @@
import com.google.gerrit.server.cache.proto.Cache.ChangeNotesStateProto.ReviewerByEmailSetEntryProto;
import com.google.gerrit.server.cache.proto.Cache.ChangeNotesStateProto.ReviewerSetEntryProto;
import com.google.gerrit.server.cache.proto.Cache.ChangeNotesStateProto.ReviewerStatusUpdateProto;
-import com.google.gerrit.server.cache.serialize.ProtoCacheSerializers.ObjectIdConverter;
+import com.google.gerrit.server.cache.serialize.ObjectIdConverter;
import com.google.gerrit.server.notedb.ChangeNotesState.ChangeColumns;
import com.google.gerrit.server.notedb.ChangeNotesState.Serializer;
import com.google.gerrit.testing.GerritBaseTests;
@@ -340,14 +340,14 @@
ps1.setUploader(new Account.Id(2000));
ps1.setRevision(new RevId("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
ps1.setCreatedOn(cols.createdOn());
- ByteString ps1Bytes = toByteString(ps1, PATCH_SET_CODEC);
+ ByteString ps1Bytes = toByteString(ps1, PatchSetProtoConverter.INSTANCE);
assertThat(ps1Bytes.size()).isEqualTo(66);
PatchSet ps2 = new PatchSet(new PatchSet.Id(ID, 2));
ps2.setUploader(new Account.Id(3000));
ps2.setRevision(new RevId("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
ps2.setCreatedOn(cols.lastUpdatedOn());
- ByteString ps2Bytes = toByteString(ps2, PATCH_SET_CODEC);
+ ByteString ps2Bytes = toByteString(ps2, PatchSetProtoConverter.INSTANCE);
assertThat(ps2Bytes.size()).isEqualTo(66);
assertThat(ps2Bytes).isNotEqualTo(ps1Bytes);
@@ -372,7 +372,7 @@
new PatchSet.Id(ID, 1), new Account.Id(2001), new LabelId("Code-Review")),
(short) 1,
new Timestamp(1212L));
- ByteString a1Bytes = toByteString(a1, APPROVAL_CODEC);
+ ByteString a1Bytes = toByteString(a1, PatchSetApprovalProtoConverter.INSTANCE);
assertThat(a1Bytes.size()).isEqualTo(43);
PatchSetApproval a2 =
@@ -381,7 +381,7 @@
new PatchSet.Id(ID, 1), new Account.Id(2002), new LabelId("Verified")),
(short) -1,
new Timestamp(3434L));
- ByteString a2Bytes = toByteString(a2, APPROVAL_CODEC);
+ ByteString a2Bytes = toByteString(a2, PatchSetApprovalProtoConverter.INSTANCE);
assertThat(a2Bytes.size()).isEqualTo(49);
assertThat(a2Bytes).isNotEqualTo(a1Bytes);
@@ -639,7 +639,7 @@
new Account.Id(1000),
new Timestamp(1212L),
new PatchSet.Id(ID, 1));
- ByteString m1Bytes = toByteString(m1, MESSAGE_CODEC);
+ ByteString m1Bytes = toByteString(m1, ChangeMessageProtoConverter.INSTANCE);
assertThat(m1Bytes.size()).isEqualTo(35);
ChangeMessage m2 =
@@ -648,7 +648,7 @@
new Account.Id(2000),
new Timestamp(3434L),
new PatchSet.Id(ID, 2));
- ByteString m2Bytes = toByteString(m2, MESSAGE_CODEC);
+ ByteString m2Bytes = toByteString(m2, ChangeMessageProtoConverter.INSTANCE);
assertThat(m2Bytes.size()).isEqualTo(35);
assertThat(m2Bytes).isNotEqualTo(m1Bytes);
diff --git a/javatests/com/google/gerrit/server/query/change/BUILD b/javatests/com/google/gerrit/server/query/change/BUILD
index c27be68..7419405 100644
--- a/javatests/com/google/gerrit/server/query/change/BUILD
+++ b/javatests/com/google/gerrit/server/query/change/BUILD
@@ -61,6 +61,7 @@
visibility = ["//visibility:public"],
deps = [
"//java/com/google/gerrit/extensions:api",
+ "//java/com/google/gerrit/proto/testing",
"//java/com/google/gerrit/reviewdb:server",
"//java/com/google/gerrit/server",
"//java/com/google/gerrit/server/cache/testing",
diff --git a/javatests/com/google/gerrit/server/query/change/ConflictKeyTest.java b/javatests/com/google/gerrit/server/query/change/ConflictKeyTest.java
index 1683b56..e550f8e 100644
--- a/javatests/com/google/gerrit/server/query/change/ConflictKeyTest.java
+++ b/javatests/com/google/gerrit/server/query/change/ConflictKeyTest.java
@@ -18,11 +18,12 @@
import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
import static com.google.gerrit.extensions.client.SubmitType.FAST_FORWARD_ONLY;
import static com.google.gerrit.extensions.client.SubmitType.MERGE_IF_NECESSARY;
+import static com.google.gerrit.proto.testing.SerializedClassSubject.assertThatSerializedClass;
import static com.google.gerrit.server.cache.testing.CacheSerializerTestUtil.byteString;
-import static com.google.gerrit.server.cache.testing.SerializedClassSubject.assertThatSerializedClass;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.extensions.client.SubmitType;
+import com.google.gerrit.proto.testing.SerializedClassSubject;
import com.google.gerrit.server.cache.proto.Cache.ConflictKeyProto;
import com.google.gerrit.testing.GerritBaseTests;
import org.eclipse.jgit.lib.ObjectId;
@@ -82,10 +83,7 @@
assertThat(ConflictKey.Serializer.INSTANCE.deserialize(serialized)).isEqualTo(key);
}
- /**
- * See {@link com.google.gerrit.server.cache.testing.SerializedClassSubject} for background and
- * what to do if this test fails.
- */
+ /** See {@link SerializedClassSubject} for background and what to do if this test fails. */
@Test
public void methods() throws Exception {
assertThatSerializedClass(ConflictKey.class)
diff --git a/plugins/delete-project b/plugins/delete-project
index d8fdd55..5f3fe72 160000
--- a/plugins/delete-project
+++ b/plugins/delete-project
@@ -1 +1 @@
-Subproject commit d8fdd5596181cc06707665051f0e03a49e5c3a97
+Subproject commit 5f3fe725b6f943f9acf63270cf8a432f9e7fd97a
diff --git a/proto/BUILD b/proto/BUILD
index 88445c1..7f02a81 100644
--- a/proto/BUILD
+++ b/proto/BUILD
@@ -11,14 +11,11 @@
proto_library(
name = "reviewdb_proto",
- srcs = [":reviewdb.proto"],
+ srcs = ["reviewdb.proto"],
)
java_proto_library(
name = "reviewdb_java_proto",
- visibility = [
- "//javatests/com/google/gerrit/proto:__pkg__",
- "//tools/eclipse:__pkg__",
- ],
+ visibility = ["//visibility:public"],
deps = [":reviewdb_proto"],
)