Merge "Fix styling issue on gr-fixed-panel"
diff --git a/Documentation/check_licenses_test.sh b/Documentation/check_licenses_test.sh
index a65a827..52e27f2 100755
--- a/Documentation/check_licenses_test.sh
+++ b/Documentation/check_licenses_test.sh
@@ -8,7 +8,7 @@
echo "FAIL: ${f}.txt out of date"
echo "to fix: "
echo ""
- echo " cp bazel-genfiles/Documentation/${f}.gen.txt Documentation/${f}.txt"
+ echo " cp bazel-bin/Documentation/${f}.gen.txt Documentation/${f}.txt"
echo ""
exit 1
fi
diff --git a/Documentation/linux-quickstart.txt b/Documentation/linux-quickstart.txt
index c2dcedb..0d8848e 100644
--- a/Documentation/linux-quickstart.txt
+++ b/Documentation/linux-quickstart.txt
@@ -29,10 +29,10 @@
. Download the desired Gerrit archive.
To view previous archives, see
-link:https://gerrit-releases.storage.googleapis.com/index.html[Gerrit Code Review: Releases]. The steps below install Gerrit 2.15.1:
+link:https://gerrit-releases.storage.googleapis.com/index.html[Gerrit Code Review: Releases]. The steps below install Gerrit 3.0.3:
....
-wget https://www.gerritcodereview.com/download/gerrit-2.15.1.war
+wget https://gerrit-releases.storage.googleapis.com/gerrit-3.0.3.war
....
NOTE: To build and install Gerrit from the source files, see
diff --git a/java/com/google/gerrit/acceptance/ExtensionRegistry.java b/java/com/google/gerrit/acceptance/ExtensionRegistry.java
index 32c0fd1..f9116a1 100644
--- a/java/com/google/gerrit/acceptance/ExtensionRegistry.java
+++ b/java/com/google/gerrit/acceptance/ExtensionRegistry.java
@@ -34,6 +34,7 @@
import com.google.gerrit.server.change.ChangeETagComputation;
import com.google.gerrit.server.git.ChangeMessageModifier;
import com.google.gerrit.server.git.validators.CommitValidationListener;
+import com.google.gerrit.server.git.validators.OnSubmitValidationListener;
import com.google.gerrit.server.git.validators.RefOperationValidationListener;
import com.google.gerrit.server.logging.PerformanceLogger;
import com.google.gerrit.server.rules.SubmitRule;
@@ -67,6 +68,7 @@
private final DynamicSet<GroupBackend> groupBackends;
private final DynamicSet<AccountActivationValidationListener>
accountActivationValidationListeners;
+ private final DynamicSet<OnSubmitValidationListener> onSubmitValidationListeners;
@Inject
ExtensionRegistry(
@@ -90,7 +92,8 @@
DynamicSet<PatchSetWebLink> patchSetWebLinks,
DynamicSet<RevisionCreatedListener> revisionCreatedListeners,
DynamicSet<GroupBackend> groupBackends,
- DynamicSet<AccountActivationValidationListener> accountActivationValidationListeners) {
+ DynamicSet<AccountActivationValidationListener> accountActivationValidationListeners,
+ DynamicSet<OnSubmitValidationListener> onSubmitValidationListeners) {
this.accountIndexedListeners = accountIndexedListeners;
this.changeIndexedListeners = changeIndexedListeners;
this.groupIndexedListeners = groupIndexedListeners;
@@ -112,6 +115,7 @@
this.revisionCreatedListeners = revisionCreatedListeners;
this.groupBackends = groupBackends;
this.accountActivationValidationListeners = accountActivationValidationListeners;
+ this.onSubmitValidationListeners = onSubmitValidationListeners;
}
public Registration newRegistration() {
@@ -211,6 +215,10 @@
return add(accountActivationValidationListeners, accountActivationValidationListener);
}
+ public Registration add(OnSubmitValidationListener onSubmitValidationListener) {
+ return add(onSubmitValidationListeners, onSubmitValidationListener);
+ }
+
private <T> Registration add(DynamicSet<T> dynamicSet, T extension) {
return add(dynamicSet, extension, "gerrit");
}
diff --git a/java/com/google/gerrit/extensions/common/AccountInfo.java b/java/com/google/gerrit/extensions/common/AccountInfo.java
index e949f07..d1bbe88 100644
--- a/java/com/google/gerrit/extensions/common/AccountInfo.java
+++ b/java/com/google/gerrit/extensions/common/AccountInfo.java
@@ -14,6 +14,7 @@
package com.google.gerrit.extensions.common;
+import com.google.common.base.MoreObjects;
import java.util.List;
import java.util.Objects;
@@ -55,6 +56,16 @@
}
@Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("id", _accountId)
+ .add("name", name)
+ .add("email", email)
+ .add("username", username)
+ .toString();
+ }
+
+ @Override
public int hashCode() {
return Objects.hash(
_accountId, name, email, secondaryEmails, username, avatars, _moreAccounts, status);
diff --git a/java/com/google/gerrit/server/account/Emails.java b/java/com/google/gerrit/server/account/Emails.java
index ee2b672..5f7ea4e 100644
--- a/java/com/google/gerrit/server/account/Emails.java
+++ b/java/com/google/gerrit/server/account/Emails.java
@@ -24,6 +24,7 @@
import com.google.common.collect.SetMultimap;
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.UserIdentity;
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.account.externalids.ExternalIds;
import com.google.gerrit.server.query.account.InternalAccountQuery;
@@ -34,8 +35,11 @@
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.IOException;
+import java.sql.Timestamp;
import java.util.Arrays;
import java.util.List;
+import java.util.Set;
+import org.eclipse.jgit.lib.PersonIdent;
/** Class to access accounts by email. */
@Singleton
@@ -117,6 +121,24 @@
return externalIds.byEmail(email).stream().map(ExternalId::accountId).collect(toImmutableSet());
}
+ public UserIdentity toUserIdentity(PersonIdent who) throws IOException {
+ UserIdentity u = new UserIdentity();
+ u.setName(who.getName());
+ u.setEmail(who.getEmailAddress());
+ u.setDate(new Timestamp(who.getWhen().getTime()));
+ u.setTimeZone(who.getTimeZoneOffset());
+
+ // If only one account has access to this email address, select it
+ // as the identity of the user.
+ //
+ Set<Account.Id> a = getAccountFor(u.getEmail());
+ if (a.size() == 1) {
+ u.setAccount(a.iterator().next());
+ }
+
+ return u;
+ }
+
private <T> T executeIndexQuery(Action<T> action) {
try {
return retryHelper.execute(
diff --git a/java/com/google/gerrit/server/change/ChangeJson.java b/java/com/google/gerrit/server/change/ChangeJson.java
index d50e740..b0477cd 100644
--- a/java/com/google/gerrit/server/change/ChangeJson.java
+++ b/java/com/google/gerrit/server/change/ChangeJson.java
@@ -298,7 +298,6 @@
Map<Change.Id, ChangeInfo> cache = Maps.newHashMapWithExpectedSize(in.size());
for (QueryResult<ChangeData> r : in) {
List<ChangeInfo> infos = toChangeInfos(r.entities(), cache);
- infos.forEach(c -> cache.put(Change.id(c._number), c));
if (!infos.isEmpty() && r.more()) {
infos.get(infos.size() - 1)._moreChanges = true;
}
@@ -415,15 +414,29 @@
List<ChangeData> changes, Map<Change.Id, ChangeInfo> cache) {
try (Timer0.Context ignored = metrics.toChangeInfosLatency.start()) {
List<ChangeInfo> changeInfos = new ArrayList<>(changes.size());
- for (ChangeData cd : changes) {
- ChangeInfo i = cache.get(cd.getId());
- if (i != null) {
- changeInfos.add(i);
+ for (int i = 0; i < changes.size(); i++) {
+ // We can only cache and re-use an entity if it's not the last in the list. The last entity
+ // may later get _moreChanges set. If it was cached or re-used, that setting would propagate
+ // to the original entity yielding wrong results.
+ // This problem has two sides where 'last in the list' has to be respected:
+ // (1) Caching
+ // (2) Reusing
+ boolean isCacheable = i != changes.size() - 1;
+ ChangeData cd = changes.get(i);
+ ChangeInfo info = cache.get(cd.getId());
+ if (info != null && isCacheable) {
+ changeInfos.add(info);
continue;
}
+
+ // Compute and cache if possible
try {
ensureLoaded(Collections.singleton(cd));
- changeInfos.add(format(cd, Optional.empty(), false, ChangeInfo::new));
+ info = format(cd, Optional.empty(), false, ChangeInfo::new);
+ changeInfos.add(info);
+ if (isCacheable) {
+ cache.put(Change.id(info._number), info);
+ }
} catch (RuntimeException e) {
logger.atWarning().withCause(e).log(
"Omitting corrupt change %s from results", cd.getId());
diff --git a/java/com/google/gerrit/server/documentation/QueryDocumentationExecutor.java b/java/com/google/gerrit/server/documentation/QueryDocumentationExecutor.java
index 569399b..a15b429 100644
--- a/java/com/google/gerrit/server/documentation/QueryDocumentationExecutor.java
+++ b/java/com/google/gerrit/server/documentation/QueryDocumentationExecutor.java
@@ -81,8 +81,7 @@
}
Query query = parser.parse(q);
try {
- // TODO(fishywang): Currently as we don't have much documentation, we just use MAX_VALUE here
- // and skipped paging. Maybe add paging later.
+ // We don't have much documentation, so we just use MAX_VALUE here and skip paging.
TopDocs results = searcher.search(query, Integer.MAX_VALUE);
ScoreDoc[] hits = results.scoreDocs;
long totalHits = results.totalHits;
diff --git a/java/com/google/gerrit/server/events/EventFactory.java b/java/com/google/gerrit/server/events/EventFactory.java
index 4d5f158..0bf888f 100644
--- a/java/com/google/gerrit/server/events/EventFactory.java
+++ b/java/com/google/gerrit/server/events/EventFactory.java
@@ -68,7 +68,6 @@
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.IOException;
-import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -476,7 +475,7 @@
p.parents.add(parent.name());
}
- UserIdentity author = toUserIdentity(c.getAuthorIdent());
+ UserIdentity author = emails.toUserIdentity(c.getAuthorIdent());
if (author.getAccount() == null) {
p.author = new AccountAttribute();
p.author.email = author.getEmail();
@@ -504,26 +503,6 @@
return p;
}
- // TODO: The same method exists in PatchSetInfoFactory, find a common place
- // for it
- private UserIdentity toUserIdentity(PersonIdent who) throws IOException {
- UserIdentity u = new UserIdentity();
- u.setName(who.getName());
- u.setEmail(who.getEmailAddress());
- u.setDate(new Timestamp(who.getWhen().getTime()));
- u.setTimeZone(who.getTimeZoneOffset());
-
- // If only one account has access to this email address, select it
- // as the identity of the user.
- //
- Set<Account.Id> a = emails.getAccountFor(u.getEmail());
- if (a.size() == 1) {
- u.setAccount(a.iterator().next());
- }
-
- return u;
- }
-
public void addApprovals(
PatchSetAttribute p,
PatchSet.Id id,
diff --git a/java/com/google/gerrit/server/git/TracingHook.java b/java/com/google/gerrit/server/git/TracingHook.java
index 4191373..63d8bc6 100644
--- a/java/com/google/gerrit/server/git/TracingHook.java
+++ b/java/com/google/gerrit/server/git/TracingHook.java
@@ -16,9 +16,6 @@
import static com.google.common.base.Preconditions.checkState;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.LinkedListMultimap;
-import com.google.common.collect.ListMultimap;
import com.google.gerrit.server.logging.TraceContext;
import java.util.List;
import java.util.Optional;
@@ -79,21 +76,20 @@
return Optional.empty();
}
- ListMultimap<String, String> serverOptions = LinkedListMultimap.create();
- for (String option : serverOptionList) {
- int e = option.indexOf('=');
- if (e > 0) {
- serverOptions.put(option.substring(0, e), option.substring(e + 1));
- } else {
- serverOptions.put(option, "");
- }
+ Optional<String> traceOption =
+ serverOptionList.stream().filter(o -> o.startsWith("trace")).findAny();
+ if (!traceOption.isPresent()) {
+ return Optional.empty();
}
- List<String> traceValues = serverOptions.get("trace");
- if (!traceValues.isEmpty()) {
- return Optional.of(Iterables.getLast(traceValues));
+ int e = traceOption.get().indexOf('=');
+ if (e > 0) {
+ // trace option was specified with trace ID: "--trace=<trace-ID>"
+ return Optional.of(traceOption.get().substring(e + 1));
}
- return Optional.empty();
+ // trace option was specified without trace ID: "--trace",
+ // return an empty string so that a trace ID is generated
+ return Optional.of("");
}
}
diff --git a/java/com/google/gerrit/server/logging/Metadata.java b/java/com/google/gerrit/server/logging/Metadata.java
index 4defded..7af204e 100644
--- a/java/com/google/gerrit/server/logging/Metadata.java
+++ b/java/com/google/gerrit/server/logging/Metadata.java
@@ -183,63 +183,66 @@
* @return string representation of this instance that is suitable for logging
*/
LazyArg<String> toStringForLoggingLazy() {
- return LazyArgs.lazy(
- () -> {
- // Append class name.
- String className = getClass().getSimpleName();
- if (className.startsWith("AutoValue_")) {
- className = className.substring(10);
- }
- ToStringHelper stringHelper = MoreObjects.toStringHelper(className);
+ // Don't use a lambda because different compilers generate different method names for lambdas,
+ // e.g. "lambda$myFunction$0" vs. just "lambda$0" in Eclipse. We need to identify the method
+ // by name to skip it and avoid infinite recursion.
+ return LazyArgs.lazy(this::toStringForLoggingImpl);
+ }
- // Append key-value pairs for field which are set.
- Method[] methods = Metadata.class.getDeclaredMethods();
- Arrays.sort(methods, Comparator.comparing(Method::getName));
- for (Method method : methods) {
- if (Modifier.isStatic(method.getModifiers())) {
- // skip static method
- continue;
- }
+ private String toStringForLoggingImpl() {
+ // Append class name.
+ String className = getClass().getSimpleName();
+ if (className.startsWith("AutoValue_")) {
+ className = className.substring(10);
+ }
+ ToStringHelper stringHelper = MoreObjects.toStringHelper(className);
- if (method.getName().matches("(lambda\\$)?toStringForLoggingLazy(\\$0)?")) {
- // skip toStringForLoggingLazy() and the lambda itself
- continue;
- }
+ // Append key-value pairs for field which are set.
+ Method[] methods = Metadata.class.getDeclaredMethods();
+ Arrays.sort(methods, Comparator.comparing(Method::getName));
+ for (Method method : methods) {
+ if (Modifier.isStatic(method.getModifiers())) {
+ // skip static method
+ continue;
+ }
- if (method.getReturnType().equals(Void.TYPE) || method.getParameterCount() > 0) {
- // skip method since it's not a getter
- continue;
- }
+ if (method.getName().equals("toStringForLoggingLazy")
+ || method.getName().equals("toStringForLoggingImpl")) {
+ // Don't call myself in infinite recursion.
+ continue;
+ }
- method.setAccessible(true);
+ if (method.getReturnType().equals(Void.TYPE) || method.getParameterCount() > 0) {
+ // skip method since it's not a getter
+ continue;
+ }
- Object returnValue;
- try {
- returnValue = method.invoke(this);
- } catch (IllegalArgumentException
- | IllegalAccessException
- | InvocationTargetException e) {
- // should never happen
- throw new IllegalStateException(e);
- }
+ method.setAccessible(true);
- if (returnValue instanceof Optional) {
- Optional<?> fieldValueOptional = (Optional<?>) returnValue;
- if (!fieldValueOptional.isPresent()) {
- // drop this key-value pair
- continue;
- }
+ Object returnValue;
+ try {
+ returnValue = method.invoke(this);
+ } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
+ // should never happen
+ throw new IllegalStateException(e);
+ }
- // format as 'key=value' instead of 'key=Optional[value]'
- stringHelper.add(method.getName(), fieldValueOptional.get());
- } else {
- // not an Optional value, keep as is
- stringHelper.add(method.getName(), returnValue);
- }
- }
+ if (returnValue instanceof Optional) {
+ Optional<?> fieldValueOptional = (Optional<?>) returnValue;
+ if (!fieldValueOptional.isPresent()) {
+ // drop this key-value pair
+ continue;
+ }
- return stringHelper.toString();
- });
+ // format as 'key=value' instead of 'key=Optional[value]'
+ stringHelper.add(method.getName(), fieldValueOptional.get());
+ } else {
+ // not an Optional value, keep as is
+ stringHelper.add(method.getName(), returnValue);
+ }
+ }
+
+ return stringHelper.toString();
}
public static Metadata.Builder builder() {
diff --git a/java/com/google/gerrit/server/patch/PatchSetInfoFactory.java b/java/com/google/gerrit/server/patch/PatchSetInfoFactory.java
index c684da5..d3cadb2f 100644
--- a/java/com/google/gerrit/server/patch/PatchSetInfoFactory.java
+++ b/java/com/google/gerrit/server/patch/PatchSetInfoFactory.java
@@ -15,11 +15,9 @@
package com.google.gerrit.server.patch;
import com.google.gerrit.exceptions.StorageException;
-import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetInfo;
import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.client.UserIdentity;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.account.Emails;
import com.google.gerrit.server.git.GitRepositoryManager;
@@ -27,12 +25,9 @@
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.io.IOException;
-import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
-import java.util.Set;
import org.eclipse.jgit.errors.MissingObjectException;
-import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
@@ -56,8 +51,8 @@
PatchSetInfo info = new PatchSetInfo(psi);
info.setSubject(src.getShortMessage());
info.setMessage(src.getFullMessage());
- info.setAuthor(toUserIdentity(src.getAuthorIdent()));
- info.setCommitter(toUserIdentity(src.getCommitterIdent()));
+ info.setAuthor(emails.toUserIdentity(src.getAuthorIdent()));
+ info.setCommitter(emails.toUserIdentity(src.getCommitterIdent()));
info.setCommitId(src);
return info;
}
@@ -85,25 +80,6 @@
}
}
- // TODO: The same method exists in EventFactory, find a common place for it
- private UserIdentity toUserIdentity(PersonIdent who) throws IOException {
- final UserIdentity u = new UserIdentity();
- u.setName(who.getName());
- u.setEmail(who.getEmailAddress());
- u.setDate(new Timestamp(who.getWhen().getTime()));
- u.setTimeZone(who.getTimeZoneOffset());
-
- // If only one account has access to this email address, select it
- // as the identity of the user.
- //
- Set<Account.Id> a = emails.getAccountFor(u.getEmail());
- if (a.size() == 1) {
- u.setAccount(a.iterator().next());
- }
-
- return u;
- }
-
private List<PatchSetInfo.ParentInfo> toParentInfos(RevCommit[] parents, RevWalk walk)
throws IOException, MissingObjectException {
List<PatchSetInfo.ParentInfo> pInfos = new ArrayList<>(parents.length);
diff --git a/javatests/com/google/gerrit/acceptance/api/change/QueryChangeIT.java b/javatests/com/google/gerrit/acceptance/api/change/QueryChangeIT.java
index 76166e1..92f914b 100644
--- a/javatests/com/google/gerrit/acceptance/api/change/QueryChangeIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/change/QueryChangeIT.java
@@ -44,8 +44,8 @@
QueryChanges queryChanges = queryChangesProvider.get();
- queryChanges.addQuery("is:open");
- queryChanges.addQuery("is:wip");
+ queryChanges.addQuery("is:open repo:" + project.get());
+ queryChanges.addQuery("is:wip repo:" + project.get());
List<List<ChangeInfo>> result =
(List<List<ChangeInfo>>) queryChanges.apply(TopLevelResource.INSTANCE).value();
@@ -58,4 +58,48 @@
assertThat(firstResultIds).containsExactly(numericId1, numericId2);
assertThat(result.get(1).get(0)._number).isEqualTo(numericId2);
}
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void moreChangesIndicatorDoesNotWronglyCopyToUnrelatedChanges() throws Exception {
+ String queryWithMoreChanges = "is:wip limit:1 repo:" + project.get();
+ String queryWithNoMoreChanges = "is:open limit:10 repo:" + project.get();
+ createChange().getChangeId();
+ String cId2 = createChange().getChangeId();
+ String cId3 = createChange().getChangeId();
+ gApi.changes().id(cId2).setWorkInProgress();
+ gApi.changes().id(cId3).setWorkInProgress();
+
+ // Run the capped query first
+ QueryChanges queryChanges = queryChangesProvider.get();
+ queryChanges.addQuery(queryWithMoreChanges);
+ queryChanges.addQuery(queryWithNoMoreChanges);
+ List<List<ChangeInfo>> result =
+ (List<List<ChangeInfo>>) queryChanges.apply(TopLevelResource.INSTANCE).value();
+ assertThat(result).hasSize(2);
+ assertThat(result.get(0)).hasSize(1);
+ assertThat(result.get(1)).hasSize(3);
+ // _moreChanges is set on the first response, but not on the second.
+ assertThat(result.get(0).get(0)._moreChanges).isTrue();
+ assertNoChangeHasMoreChangesSet(result.get(1));
+
+ // Run the capped query second
+ QueryChanges queryChanges2 = queryChangesProvider.get();
+ queryChanges2.addQuery(queryWithNoMoreChanges);
+ queryChanges2.addQuery(queryWithMoreChanges);
+ List<List<ChangeInfo>> result2 =
+ (List<List<ChangeInfo>>) queryChanges2.apply(TopLevelResource.INSTANCE).value();
+ assertThat(result2).hasSize(2);
+ assertThat(result2.get(0)).hasSize(3);
+ assertThat(result2.get(1)).hasSize(1);
+ // _moreChanges is set on the second response, but not on the first.
+ assertNoChangeHasMoreChangesSet(result2.get(0));
+ assertThat(result2.get(1).get(0)._moreChanges).isTrue();
+ }
+
+ private static void assertNoChangeHasMoreChangesSet(List<ChangeInfo> results) {
+ for (ChangeInfo info : results) {
+ assertThat(info._moreChanges).isNull();
+ }
+ }
}
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
index c0083d2..154fabf 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
@@ -42,6 +42,8 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.ExtensionRegistry;
+import com.google.gerrit.acceptance.ExtensionRegistry.Registration;
import com.google.gerrit.acceptance.GerritConfig;
import com.google.gerrit.acceptance.GitUtil;
import com.google.gerrit.acceptance.NoHttpd;
@@ -67,8 +69,6 @@
import com.google.gerrit.extensions.common.ChangeInput;
import com.google.gerrit.extensions.common.LabelInfo;
import com.google.gerrit.extensions.events.ChangeIndexedListener;
-import com.google.gerrit.extensions.registration.DynamicSet;
-import com.google.gerrit.extensions.registration.RegistrationHandle;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BinaryResult;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
@@ -118,7 +118,6 @@
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.ReceiveCommand;
import org.eclipse.jgit.transport.RefSpec;
-import org.junit.After;
import org.junit.Test;
@NoHttpd
@@ -131,21 +130,11 @@
}
@Inject private ApprovalsUtil approvalsUtil;
- @Inject private DynamicSet<OnSubmitValidationListener> onSubmitValidationListeners;
- @Inject private DynamicSet<ChangeIndexedListener> changeIndexedListeners;
@Inject private IdentifiedUser.GenericFactory userFactory;
@Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@Inject private Submit submitHandler;
-
- private RegistrationHandle onSubmitValidatorHandle;
-
- @After
- public void removeOnSubmitValidator() {
- if (onSubmitValidatorHandle != null) {
- onSubmitValidatorHandle.remove();
- }
- }
+ @Inject private ExtensionRegistry extensionRegistry;
protected abstract SubmitType getSubmitType();
@@ -821,23 +810,28 @@
@Test
public void submitWithValidation() throws Throwable {
AtomicBoolean called = new AtomicBoolean(false);
- this.addOnSubmitValidationListener(
- args -> {
- called.set(true);
- HashSet<String> refs = Sets.newHashSet(args.getCommands().keySet());
- assertThat(refs).contains("refs/heads/master");
- refs.remove("refs/heads/master");
- if (!refs.isEmpty()) {
- // Some submit strategies need to insert new patchset.
- assertThat(refs).hasSize(1);
- assertThat(refs.iterator().next()).startsWith(RefNames.REFS_CHANGES);
+ OnSubmitValidationListener listener =
+ new OnSubmitValidationListener() {
+ @Override
+ public void preBranchUpdate(Arguments args) throws ValidationException {
+ called.set(true);
+ HashSet<String> refs = Sets.newHashSet(args.getCommands().keySet());
+ assertThat(refs).contains("refs/heads/master");
+ refs.remove("refs/heads/master");
+ if (!refs.isEmpty()) {
+ // Some submit strategies need to insert new patchset.
+ assertThat(refs).hasSize(1);
+ assertThat(refs.iterator().next()).startsWith(RefNames.REFS_CHANGES);
+ }
}
- });
+ };
- PushOneCommit.Result change = createChange();
- approve(change.getChangeId());
- submit(change.getChangeId());
- assertThat(called.get()).isTrue();
+ try (Registration registration = extensionRegistry.newRegistration().add(listener)) {
+ PushOneCommit.Result change = createChange();
+ approve(change.getChangeId());
+ submit(change.getChangeId());
+ assertThat(called.get()).isTrue();
+ }
}
@Test
@@ -872,34 +866,39 @@
// Since there are 2 repos, first submit attempt will fail, the second will
// succeed.
List<String> projectsCalled = new ArrayList<>(4);
- this.addOnSubmitValidationListener(
- args -> {
- String master = "refs/heads/master";
- assertThat(args.getCommands()).containsKey(master);
- ReceiveCommand cmd = args.getCommands().get(master);
- ObjectId newMasterId = cmd.getNewId();
- try (Repository repo = repoManager.openRepository(args.getProject())) {
- assertThat(repo.exactRef(master).getObjectId()).isEqualTo(cmd.getOldId());
- assertThat(args.getRef(master)).hasValue(newMasterId);
- args.getRevWalk().parseBody(args.getRevWalk().parseCommit(newMasterId));
- } catch (IOException e) {
- throw new AssertionError("failed checking new ref value", e);
+ OnSubmitValidationListener listener =
+ new OnSubmitValidationListener() {
+ @Override
+ public void preBranchUpdate(Arguments args) throws ValidationException {
+ String master = "refs/heads/master";
+ assertThat(args.getCommands()).containsKey(master);
+ ReceiveCommand cmd = args.getCommands().get(master);
+ ObjectId newMasterId = cmd.getNewId();
+ try (Repository repo = repoManager.openRepository(args.getProject())) {
+ assertThat(repo.exactRef(master).getObjectId()).isEqualTo(cmd.getOldId());
+ assertThat(args.getRef(master)).hasValue(newMasterId);
+ args.getRevWalk().parseBody(args.getRevWalk().parseCommit(newMasterId));
+ } catch (IOException e) {
+ throw new AssertionError("failed checking new ref value", e);
+ }
+ projectsCalled.add(args.getProject().get());
+ if (projectsCalled.size() == 2) {
+ throw new ValidationException("time to fail");
+ }
}
- projectsCalled.add(args.getProject().get());
- if (projectsCalled.size() == 2) {
- throw new ValidationException("time to fail");
- }
- });
- submitWithConflict(change4.getChangeId(), "time to fail");
- assertThat(projectsCalled).containsExactly(keyA.get(), keyB.get());
- for (PushOneCommit.Result change : changes) {
- change.assertChange(Change.Status.NEW, name(topic), admin);
- }
+ };
+ try (Registration registration = extensionRegistry.newRegistration().add(listener)) {
+ submitWithConflict(change4.getChangeId(), "time to fail");
+ assertThat(projectsCalled).containsExactly(keyA.get(), keyB.get());
+ for (PushOneCommit.Result change : changes) {
+ change.assertChange(Change.Status.NEW, name(topic), admin);
+ }
- submit(change4.getChangeId());
- assertThat(projectsCalled).containsExactly(keyA.get(), keyB.get(), keyA.get(), keyB.get());
- for (PushOneCommit.Result change : changes) {
- change.assertChange(Change.Status.MERGED, name(topic), admin);
+ submit(change4.getChangeId());
+ assertThat(projectsCalled).containsExactly(keyA.get(), keyB.get(), keyA.get(), keyB.get());
+ for (PushOneCommit.Result change : changes) {
+ change.assertChange(Change.Status.MERGED, name(topic), admin);
+ }
}
}
@@ -1228,9 +1227,8 @@
PushOneCommit.Result changeOtherBranch = createChange("refs/for/dev");
ChangeIndexedListener changeIndexedListener = mock(ChangeIndexedListener.class);
- RegistrationHandle registrationHandle =
- changeIndexedListeners.add("gerrit", changeIndexedListener);
- try {
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(changeIndexedListener)) {
// submit a change, this should trigger asynchronous reindexing of the open changes on the
// same branch
approve(change1.getChangeId());
@@ -1257,8 +1255,6 @@
// open changes on other branches don't get reindexed
verify(changeIndexedListener, times(0))
.onChangeScheduledForIndexing(project.get(), changeOtherBranch.getChange().getId().get());
- } finally {
- registrationHandle.remove();
}
}
@@ -1438,11 +1434,6 @@
return getRemoteLog(project, "master");
}
- protected void addOnSubmitValidationListener(OnSubmitValidationListener listener) {
- assertThat(onSubmitValidatorHandle).isNull();
- onSubmitValidatorHandle = onSubmitValidationListeners.add("gerrit", listener);
- }
-
private String getLatestDiff(Repository repo) throws Throwable {
ObjectId oldTreeId = repo.resolve("HEAD~1^{tree}");
ObjectId newTreeId = repo.resolve("HEAD^{tree}");
diff --git a/javatests/com/google/gerrit/acceptance/ssh/AbstractIndexTests.java b/javatests/com/google/gerrit/acceptance/ssh/AbstractIndexTests.java
index a03d7f3..c841559 100644
--- a/javatests/com/google/gerrit/acceptance/ssh/AbstractIndexTests.java
+++ b/javatests/com/google/gerrit/acceptance/ssh/AbstractIndexTests.java
@@ -20,102 +20,91 @@
import com.google.common.base.Joiner;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.ChangeIndexedCounter;
+import com.google.gerrit.acceptance.ExtensionRegistry;
+import com.google.gerrit.acceptance.ExtensionRegistry.Registration;
import com.google.gerrit.acceptance.GerritConfig;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.UseSsh;
import com.google.gerrit.extensions.common.ChangeInfo;
-import com.google.gerrit.extensions.events.ChangeIndexedListener;
-import com.google.gerrit.extensions.registration.DynamicSet;
-import com.google.gerrit.extensions.registration.RegistrationHandle;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.inject.Inject;
import com.google.inject.Injector;
import java.util.List;
-import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
@NoHttpd
@UseSsh
public abstract class AbstractIndexTests extends AbstractDaemonTest {
- @Inject private DynamicSet<ChangeIndexedListener> changeIndexedListeners;
-
- private ChangeIndexedCounter changeIndexedCounter;
- private RegistrationHandle changeIndexedCounterHandle;
+ @Inject private ExtensionRegistry extensionRegistry;
/** @param injector injector */
public void configureIndex(Injector injector) {}
- @Before
- public void addChangeIndexedCounter() {
- changeIndexedCounter = new ChangeIndexedCounter();
- changeIndexedCounterHandle = changeIndexedListeners.add("gerrit", changeIndexedCounter);
- }
-
- @After
- public void removeChangeIndexedCounter() {
- if (changeIndexedCounterHandle != null) {
- changeIndexedCounterHandle.remove();
- }
- }
-
@Test
@GerritConfig(name = "index.autoReindexIfStale", value = "false")
public void indexChange() throws Exception {
- configureIndex(server.getTestInjector());
+ ChangeIndexedCounter changeIndexedCounter = new ChangeIndexedCounter();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(changeIndexedCounter)) {
+ configureIndex(server.getTestInjector());
- PushOneCommit.Result change = createChange("first change", "test1.txt", "test1");
- String changeId = change.getChangeId();
- String changeLegacyId = change.getChange().getId().toString();
- ChangeInfo changeInfo = gApi.changes().id(changeId).get();
+ PushOneCommit.Result change = createChange("first change", "test1.txt", "test1");
+ String changeId = change.getChangeId();
+ String changeLegacyId = change.getChange().getId().toString();
+ ChangeInfo changeInfo = gApi.changes().id(changeId).get();
- disableChangeIndexWrites();
- amendChange(changeId, "second test", "test2.txt", "test2");
+ disableChangeIndexWrites();
+ amendChange(changeId, "second test", "test2.txt", "test2");
- assertChangeQuery("message:second", change.getChange(), false);
- enableChangeIndexWrites();
+ assertChangeQuery("message:second", change.getChange(), false);
+ enableChangeIndexWrites();
- changeIndexedCounter.clear();
- String cmd = Joiner.on(" ").join("gerrit", "index", "changes", changeLegacyId);
- adminSshSession.exec(cmd);
- adminSshSession.assertSuccess();
+ changeIndexedCounter.clear();
+ String cmd = Joiner.on(" ").join("gerrit", "index", "changes", changeLegacyId);
+ adminSshSession.exec(cmd);
+ adminSshSession.assertSuccess();
- changeIndexedCounter.assertReindexOf(changeInfo, 1);
+ changeIndexedCounter.assertReindexOf(changeInfo, 1);
- assertChangeQuery("message:second", change.getChange(), true);
+ assertChangeQuery("message:second", change.getChange(), true);
+ }
}
@Test
@GerritConfig(name = "index.autoReindexIfStale", value = "false")
public void indexProject() throws Exception {
- configureIndex(server.getTestInjector());
+ ChangeIndexedCounter changeIndexedCounter = new ChangeIndexedCounter();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(changeIndexedCounter)) {
+ configureIndex(server.getTestInjector());
- PushOneCommit.Result change = createChange("first change", "test1.txt", "test1");
- String changeId = change.getChangeId();
- ChangeInfo changeInfo = gApi.changes().id(changeId).get();
+ PushOneCommit.Result change = createChange("first change", "test1.txt", "test1");
+ String changeId = change.getChangeId();
+ ChangeInfo changeInfo = gApi.changes().id(changeId).get();
- disableChangeIndexWrites();
- amendChange(changeId, "second test", "test2.txt", "test2");
+ disableChangeIndexWrites();
+ amendChange(changeId, "second test", "test2.txt", "test2");
- assertChangeQuery("message:second", change.getChange(), false);
- enableChangeIndexWrites();
+ assertChangeQuery("message:second", change.getChange(), false);
+ enableChangeIndexWrites();
- changeIndexedCounter.clear();
- String cmd = Joiner.on(" ").join("gerrit", "index", "changes-in-project", project.get());
- adminSshSession.exec(cmd);
- adminSshSession.assertSuccess();
-
- boolean indexing = true;
- while (indexing) {
- String out = adminSshSession.exec("gerrit show-queue --wide");
+ changeIndexedCounter.clear();
+ String cmd = Joiner.on(" ").join("gerrit", "index", "changes-in-project", project.get());
+ adminSshSession.exec(cmd);
adminSshSession.assertSuccess();
- indexing = out.contains("Index all changes of project " + project.get());
+
+ boolean indexing = true;
+ while (indexing) {
+ String out = adminSshSession.exec("gerrit show-queue --wide");
+ adminSshSession.assertSuccess();
+ indexing = out.contains("Index all changes of project " + project.get());
+ }
+
+ changeIndexedCounter.assertReindexOf(changeInfo, 1);
+
+ assertChangeQuery("message:second", change.getChange(), true);
}
-
- changeIndexedCounter.assertReindexOf(changeInfo, 1);
-
- assertChangeQuery("message:second", change.getChange(), true);
}
protected void assertChangeQuery(String q, ChangeData change, boolean assertTrue)
diff --git a/javatests/com/google/gerrit/acceptance/ssh/SshTraceIT.java b/javatests/com/google/gerrit/acceptance/ssh/SshTraceIT.java
index 09e97b2..ae45d90 100644
--- a/javatests/com/google/gerrit/acceptance/ssh/SshTraceIT.java
+++ b/javatests/com/google/gerrit/acceptance/ssh/SshTraceIT.java
@@ -20,9 +20,9 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.ExtensionRegistry;
+import com.google.gerrit.acceptance.ExtensionRegistry.Registration;
import com.google.gerrit.acceptance.UseSsh;
-import com.google.gerrit.extensions.registration.DynamicSet;
-import com.google.gerrit.extensions.registration.RegistrationHandle;
import com.google.gerrit.server.logging.LoggingContext;
import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.PerformanceLogger;
@@ -33,66 +33,58 @@
import com.google.inject.Inject;
import java.util.ArrayList;
import java.util.List;
-import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
@UseSsh
public class SshTraceIT extends AbstractDaemonTest {
- @Inject private DynamicSet<ProjectCreationValidationListener> projectCreationValidationListeners;
- @Inject private DynamicSet<PerformanceLogger> performanceLoggers;
-
- private TraceValidatingProjectCreationValidationListener projectCreationListener;
- private RegistrationHandle projectCreationListenerRegistrationHandle;
- private TestPerformanceLogger testPerformanceLogger;
- private RegistrationHandle performanceLoggerRegistrationHandle;
-
- @Before
- public void setup() {
- projectCreationListener = new TraceValidatingProjectCreationValidationListener();
- projectCreationListenerRegistrationHandle =
- projectCreationValidationListeners.add("gerrit", projectCreationListener);
- testPerformanceLogger = new TestPerformanceLogger();
- performanceLoggerRegistrationHandle = performanceLoggers.add("gerrit", testPerformanceLogger);
- }
-
- @After
- public void cleanup() {
- projectCreationListenerRegistrationHandle.remove();
- performanceLoggerRegistrationHandle.remove();
- }
+ @Inject private ExtensionRegistry extensionRegistry;
@Test
public void sshCallWithoutTrace() throws Exception {
- adminSshSession.exec("gerrit create-project new1");
- adminSshSession.assertSuccess();
- assertThat(projectCreationListener.traceId).isNull();
- assertThat(projectCreationListener.foundTraceId).isFalse();
- assertThat(projectCreationListener.isLoggingForced).isFalse();
+ TraceValidatingProjectCreationValidationListener projectCreationListener =
+ new TraceValidatingProjectCreationValidationListener();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(projectCreationListener)) {
+ adminSshSession.exec("gerrit create-project new1");
+ adminSshSession.assertSuccess();
+ assertThat(projectCreationListener.traceId).isNull();
+ assertThat(projectCreationListener.foundTraceId).isFalse();
+ assertThat(projectCreationListener.isLoggingForced).isFalse();
+ }
}
@Test
public void sshCallWithTrace() throws Exception {
- adminSshSession.exec("gerrit create-project --trace new2");
+ TraceValidatingProjectCreationValidationListener projectCreationListener =
+ new TraceValidatingProjectCreationValidationListener();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(projectCreationListener)) {
+ adminSshSession.exec("gerrit create-project --trace new2");
- // The trace ID is written to stderr.
- adminSshSession.assertFailure(RequestId.Type.TRACE_ID.name());
+ // The trace ID is written to stderr.
+ adminSshSession.assertFailure(RequestId.Type.TRACE_ID.name());
- assertThat(projectCreationListener.traceId).isNotNull();
- assertThat(projectCreationListener.foundTraceId).isTrue();
- assertThat(projectCreationListener.isLoggingForced).isTrue();
+ assertThat(projectCreationListener.traceId).isNotNull();
+ assertThat(projectCreationListener.foundTraceId).isTrue();
+ assertThat(projectCreationListener.isLoggingForced).isTrue();
+ }
}
@Test
public void sshCallWithTraceAndProvidedTraceId() throws Exception {
- adminSshSession.exec("gerrit create-project --trace --trace-id issue/123 new3");
+ TraceValidatingProjectCreationValidationListener projectCreationListener =
+ new TraceValidatingProjectCreationValidationListener();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(projectCreationListener)) {
+ adminSshSession.exec("gerrit create-project --trace --trace-id issue/123 new3");
- // The trace ID is written to stderr.
- adminSshSession.assertFailure(RequestId.Type.TRACE_ID.name());
+ // The trace ID is written to stderr.
+ adminSshSession.assertFailure(RequestId.Type.TRACE_ID.name());
- assertThat(projectCreationListener.traceId).isEqualTo("issue/123");
- assertThat(projectCreationListener.foundTraceId).isTrue();
- assertThat(projectCreationListener.isLoggingForced).isTrue();
+ assertThat(projectCreationListener.traceId).isEqualTo("issue/123");
+ assertThat(projectCreationListener.foundTraceId).isTrue();
+ assertThat(projectCreationListener.isLoggingForced).isTrue();
+ }
}
@Test
@@ -103,9 +95,13 @@
@Test
public void performanceLoggingForSshCall() throws Exception {
- adminSshSession.exec("gerrit create-project new5");
- adminSshSession.assertSuccess();
- assertThat(testPerformanceLogger.logEntries()).isNotEmpty();
+ TestPerformanceLogger testPerformanceLogger = new TestPerformanceLogger();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(testPerformanceLogger)) {
+ adminSshSession.exec("gerrit create-project new5");
+ adminSshSession.assertSuccess();
+ assertThat(testPerformanceLogger.logEntries()).isNotEmpty();
+ }
}
private static class TraceValidatingProjectCreationValidationListener
diff --git a/polygerrit-ui/app/elements/gr-app-p2.js b/polygerrit-ui/app/elements/gr-app-p2.js
index 2163c02..5b6e316 100644
--- a/polygerrit-ui/app/elements/gr-app-p2.js
+++ b/polygerrit-ui/app/elements/gr-app-p2.js
@@ -17,6 +17,9 @@
(function() {
'use strict';
+ // Disable extra font load from paper-styles
+ window.polymerSkipLoadingFontRoboto = true;
+
Polymer({
is: 'gr-app-p2',
});