Format all Java files with google-java-format

Having a standard tool for formatting saves reviewers' valuable time.
google-java-format is Google's standard formatter and is somewhat
inspired by gofmt[1]. This commit formats everything using
google-java-format version 1.2.

The downside of this one-off formatting is breaking blame. This can be
somewhat hacked around with a tool like git-hyper-blame[2], but it's
definitely not optimal until/unless this kind of feature makes its way
to git core.

Not in this change:
* Tool support, e.g. Eclipse. The command must be run manually [3].
* Documentation of best practice, e.g. new 100-column default.

[1] https://talks.golang.org/2015/gofmt-en.slide#3
[2] https://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/git-hyper-blame.html
[3] git ls-files | grep java$ | xargs google-java-format -i

Change-Id: Id5f3c6de95ce0b68b41f0a478b5c99a93675aaa3
Signed-off-by: David Pursehouse <dpursehouse@collab.net>
This commit is contained in:
Dave Borowitz 2016-11-13 09:56:32 -08:00 committed by David Pursehouse
parent 6723b6d0fa
commit 292fa154c1
2443 changed files with 54816 additions and 57825 deletions

View File

@ -16,17 +16,14 @@ package com.googlesource.gerrit.convertkey;
import com.jcraft.jsch.HostKey;
import com.jcraft.jsch.JSchException;
import org.apache.sshd.common.util.Buffer;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.security.KeyPair;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import org.apache.sshd.common.util.Buffer;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
public class ConvertKey {
public static void main(String[] args)
@ -69,5 +66,4 @@ public class ConvertKey {
System.out.println(privout);
}
}
}

View File

@ -30,14 +30,12 @@ import com.google.inject.OutOfScopeException;
import com.google.inject.Provider;
import com.google.inject.Scope;
import com.google.inject.util.Providers;
import java.util.HashMap;
import java.util.Map;
/** Guice scopes for state during an Acceptance Test connection. */
public class AcceptanceTestRequestScope {
private static final Key<RequestCleanup> RC_KEY =
Key.get(RequestCleanup.class);
private static final Key<RequestCleanup> RC_KEY = Key.get(RequestCleanup.class);
private static final Key<RequestScopedReviewDbProvider> DB_KEY =
Key.get(RequestScopedReviewDbProvider.class);
@ -53,16 +51,13 @@ public class AcceptanceTestRequestScope {
volatile long started;
volatile long finished;
private Context(SchemaFactory<ReviewDb> sf, SshSession s,
CurrentUser u, long at) {
private Context(SchemaFactory<ReviewDb> sf, SshSession s, CurrentUser u, long at) {
schemaFactory = sf;
session = s;
user = u;
created = started = finished = at;
map.put(RC_KEY, cleanup);
map.put(DB_KEY, new RequestScopedReviewDbProvider(
schemaFactory,
Providers.of(cleanup)));
map.put(DB_KEY, new RequestScopedReviewDbProvider(schemaFactory, Providers.of(cleanup)));
}
private Context(Context p, SshSession s, CurrentUser c) {
@ -117,7 +112,9 @@ public class AcceptanceTestRequestScope {
private final AcceptanceTestRequestScope atrScope;
@Inject
Propagator(AcceptanceTestRequestScope atrScope, ThreadLocalRequestContext local,
Propagator(
AcceptanceTestRequestScope atrScope,
ThreadLocalRequestContext local,
Provider<RequestScopedReviewDbProvider> dbProviderProvider) {
super(REQUEST, current, local, dbProviderProvider);
this.atrScope = atrScope;
@ -169,12 +166,13 @@ public class AcceptanceTestRequestScope {
public Context disableDb() {
Context old = current.get();
SchemaFactory<ReviewDb> sf = new SchemaFactory<ReviewDb>() {
@Override
public ReviewDb open() {
return new DisabledReviewDb();
}
};
SchemaFactory<ReviewDb> sf =
new SchemaFactory<ReviewDb>() {
@Override
public ReviewDb open() {
return new DisabledReviewDb();
}
};
Context ctx = new Context(sf, old.session, old.user, old.created);
current.set(ctx);
@ -186,30 +184,30 @@ public class AcceptanceTestRequestScope {
// Setting a new context with the same fields is enough to get the ReviewDb
// provider to reopen the database.
Context old = current.get();
return set(
new Context(old.schemaFactory, old.session, old.user, old.created));
return set(new Context(old.schemaFactory, old.session, old.user, old.created));
}
/** Returns exactly one instance per command executed. */
static final Scope REQUEST = new Scope() {
@Override
public <T> Provider<T> scope(final Key<T> key, final Provider<T> creator) {
return new Provider<T>() {
static final Scope REQUEST =
new Scope() {
@Override
public T get() {
return requireContext().get(key, creator);
public <T> Provider<T> scope(final Key<T> key, final Provider<T> creator) {
return new Provider<T>() {
@Override
public T get() {
return requireContext().get(key, creator);
}
@Override
public String toString() {
return String.format("%s[%s]", creator, REQUEST);
}
};
}
@Override
public String toString() {
return String.format("%s[%s]", creator, REQUEST);
return "Acceptance Test Scope.REQUEST";
}
};
}
@Override
public String toString() {
return "Acceptance Test Scope.REQUEST";
}
};
}

View File

@ -34,11 +34,9 @@ import com.google.gerrit.testutil.SshMode;
import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.KeyPair;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Collections;
@ -58,7 +56,8 @@ public class AccountCreator {
private final AccountIndexer indexer;
@Inject
AccountCreator(SchemaFactory<ReviewDb> schema,
AccountCreator(
SchemaFactory<ReviewDb> schema,
VersionedAuthorizedKeys.Accessor authorizedKeys,
GroupCache groupCache,
SshKeyCache sshKeyCache,
@ -75,8 +74,8 @@ public class AccountCreator {
this.indexer = indexer;
}
public synchronized TestAccount create(String username, String email,
String fullName, String... groups) throws Exception {
public synchronized TestAccount create(
String username, String email, String fullName, String... groups) throws Exception {
TestAccount account = accounts.get(username);
if (account != null) {
return account;
@ -85,8 +84,8 @@ public class AccountCreator {
Account.Id id = new Account.Id(db.nextAccountId());
AccountExternalId extUser =
new AccountExternalId(id, new AccountExternalId.Key(
AccountExternalId.SCHEME_USERNAME, username));
new AccountExternalId(
id, new AccountExternalId.Key(AccountExternalId.SCHEME_USERNAME, username));
String httpPass = "http-pass";
extUser.setPassword(httpPass);
db.accountExternalIds().insert(Collections.singleton(extUser));
@ -107,8 +106,7 @@ public class AccountCreator {
AccountGroup.NameKey k = new AccountGroup.NameKey(n);
AccountGroup g = groupCache.get(k);
checkArgument(g != null, "group not found: %s", n);
AccountGroupMember m =
new AccountGroupMember(new AccountGroupMember.Key(id, g.getId()));
AccountGroupMember m = new AccountGroupMember(new AccountGroupMember.Key(id, g.getId()));
db.accountGroupMembers().insert(Collections.singleton(m));
}
}
@ -125,8 +123,7 @@ public class AccountCreator {
indexer.index(id);
account =
new TestAccount(id, username, email, fullName, sshKey, httpPass);
account = new TestAccount(id, username, email, fullName, sshKey, httpPass);
accounts.put(username, account);
return account;
}
@ -141,13 +138,11 @@ public class AccountCreator {
}
public TestAccount admin() throws Exception {
return create("admin", "admin@example.com", "Administrator",
"Administrators");
return create("admin", "admin@example.com", "Administrator", "Administrators");
}
public TestAccount admin2() throws Exception {
return create("admin2", "admin2@example.com", "Administrator2",
"Administrators");
return create("admin2", "admin2@example.com", "Administrator2", "Administrators");
}
public TestAccount user() throws Exception {
@ -159,9 +154,7 @@ public class AccountCreator {
}
public TestAccount get(String username) {
return checkNotNull(
accounts.get(username),
"No TestAccount created for %s", username);
return checkNotNull(accounts.get(username), "No TestAccount created for %s", username);
}
private AccountExternalId.Key getEmailKey(String email) {

View File

@ -23,9 +23,8 @@ import java.util.HashSet;
import java.util.Set;
public class AssertUtil {
public static <T> void assertPrefs(T actual, T expected,
String... fieldsToExclude)
throws IllegalArgumentException, IllegalAccessException {
public static <T> void assertPrefs(T actual, T expected, String... fieldsToExclude)
throws IllegalArgumentException, IllegalAccessException {
Set<String> exludedFields = new HashSet<>(Arrays.asList(fieldsToExclude));
for (Field field : actual.getClass().getDeclaredFields()) {
if (exludedFields.contains(field.getName()) || skipField(field)) {

View File

@ -17,11 +17,9 @@ package com.google.gerrit.acceptance;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import org.eclipse.jgit.lib.Config;
import java.util.ArrayList;
import java.util.Arrays;
import org.eclipse.jgit.lib.Config;
class ConfigAnnotationParser {
private static Splitter splitter = Splitter.on(".").trimResults();
@ -57,13 +55,11 @@ class ConfigAnnotationParser {
if (!Strings.isNullOrEmpty(c.value())) {
cfg.setString(l.get(0), l.get(1), l.get(2), c.value());
} else {
cfg.setStringList(l.get(0), l.get(1), l.get(2),
Arrays.asList(c.value()));
cfg.setStringList(l.get(0), l.get(1), l.get(2), Arrays.asList(c.value()));
}
} else {
throw new IllegalArgumentException(
"GerritConfig.name must be of the format"
+ " section.subsection.name or section.name");
"GerritConfig.name must be of the format" + " section.subsection.name or section.name");
}
}
}

View File

@ -33,7 +33,6 @@ import com.google.gerrit.server.events.RefUpdatedEvent;
import com.google.gerrit.server.events.ReviewerDeletedEvent;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
@ -47,7 +46,8 @@ public class EventRecorder {
private final IdentifiedUser.GenericFactory userFactory;
@Inject
Factory(DynamicSet<UserScopedEventListener> eventListeners,
Factory(
DynamicSet<UserScopedEventListener> eventListeners,
IdentifiedUser.GenericFactory userFactory) {
this.eventListeners = eventListeners;
this.userFactory = userFactory;
@ -58,39 +58,39 @@ public class EventRecorder {
}
}
public EventRecorder(DynamicSet<UserScopedEventListener> eventListeners,
final IdentifiedUser user) {
public EventRecorder(
DynamicSet<UserScopedEventListener> eventListeners, final IdentifiedUser user) {
recordedEvents = LinkedListMultimap.create();
eventListenerRegistration = eventListeners.add(
new UserScopedEventListener() {
@Override
public void onEvent(Event e) {
if (e instanceof ReviewerDeletedEvent) {
recordedEvents.put(
ReviewerDeletedEvent.TYPE, (ReviewerDeletedEvent) e);
} else if (e instanceof RefEvent) {
RefEvent event = (RefEvent) e;
String key = refEventKey(event.getType(),
event.getProjectNameKey().get(),
event.getRefName());
recordedEvents.put(key, event);
}
}
eventListenerRegistration =
eventListeners.add(
new UserScopedEventListener() {
@Override
public void onEvent(Event e) {
if (e instanceof ReviewerDeletedEvent) {
recordedEvents.put(ReviewerDeletedEvent.TYPE, (ReviewerDeletedEvent) e);
} else if (e instanceof RefEvent) {
RefEvent event = (RefEvent) e;
String key =
refEventKey(
event.getType(), event.getProjectNameKey().get(), event.getRefName());
recordedEvents.put(key, event);
}
}
@Override
public CurrentUser getUser() {
return user;
}
});
@Override
public CurrentUser getUser() {
return user;
}
});
}
private static String refEventKey(String type, String project, String ref) {
return String.format("%s-%s-%s", type, project, ref);
}
private ImmutableList<RefUpdatedEvent> getRefUpdatedEvents(String project,
String refName, int expectedSize) {
private ImmutableList<RefUpdatedEvent> getRefUpdatedEvents(
String project, String refName, int expectedSize) {
String key = refEventKey(RefUpdatedEvent.TYPE, project, refName);
if (expectedSize == 0) {
assertThat(recordedEvents).doesNotContainKey(key);
@ -98,16 +98,16 @@ public class EventRecorder {
}
assertThat(recordedEvents).containsKey(key);
ImmutableList<RefUpdatedEvent> events = FluentIterable
.from(recordedEvents.get(key))
.transform(RefUpdatedEvent.class::cast)
.toList();
ImmutableList<RefUpdatedEvent> events =
FluentIterable.from(recordedEvents.get(key))
.transform(RefUpdatedEvent.class::cast)
.toList();
assertThat(events).hasSize(expectedSize);
return events;
}
private ImmutableList<ChangeMergedEvent> getChangeMergedEvents(String project,
String branch, int expectedSize) {
private ImmutableList<ChangeMergedEvent> getChangeMergedEvents(
String project, String branch, int expectedSize) {
String key = refEventKey(ChangeMergedEvent.TYPE, project, branch);
if (expectedSize == 0) {
assertThat(recordedEvents).doesNotContainKey(key);
@ -115,90 +115,80 @@ public class EventRecorder {
}
assertThat(recordedEvents).containsKey(key);
ImmutableList<ChangeMergedEvent> events = FluentIterable
.from(recordedEvents.get(key))
.transform(ChangeMergedEvent.class::cast)
.toList();
ImmutableList<ChangeMergedEvent> events =
FluentIterable.from(recordedEvents.get(key))
.transform(ChangeMergedEvent.class::cast)
.toList();
assertThat(events).hasSize(expectedSize);
return events;
}
private ImmutableList<ReviewerDeletedEvent> getReviewerDeletedEvents(
int expectedSize) {
private ImmutableList<ReviewerDeletedEvent> getReviewerDeletedEvents(int expectedSize) {
String key = ReviewerDeletedEvent.TYPE;
if (expectedSize == 0) {
assertThat(recordedEvents).doesNotContainKey(key);
return ImmutableList.of();
}
assertThat(recordedEvents).containsKey(key);
ImmutableList<ReviewerDeletedEvent> events = FluentIterable
.from(recordedEvents.get(key))
.transform(ReviewerDeletedEvent.class::cast)
.toList();
ImmutableList<ReviewerDeletedEvent> events =
FluentIterable.from(recordedEvents.get(key))
.transform(ReviewerDeletedEvent.class::cast)
.toList();
assertThat(events).hasSize(expectedSize);
return events;
}
public void assertRefUpdatedEvents(String project, String branch,
String... expected) throws Exception {
ImmutableList<RefUpdatedEvent> events = getRefUpdatedEvents(project,
branch, expected.length / 2);
public void assertRefUpdatedEvents(String project, String branch, String... expected)
throws Exception {
ImmutableList<RefUpdatedEvent> events =
getRefUpdatedEvents(project, branch, expected.length / 2);
int i = 0;
for (RefUpdatedEvent event : events) {
RefUpdateAttribute actual = event.refUpdate.get();
String oldRev = expected[i] == null
? ObjectId.zeroId().name()
: expected[i];
String newRev = expected[i+1] == null
? ObjectId.zeroId().name()
: expected[i+1];
String oldRev = expected[i] == null ? ObjectId.zeroId().name() : expected[i];
String newRev = expected[i + 1] == null ? ObjectId.zeroId().name() : expected[i + 1];
assertThat(actual.oldRev).isEqualTo(oldRev);
assertThat(actual.newRev).isEqualTo(newRev);
i += 2;
}
}
public void assertRefUpdatedEvents(String project, String branch,
RevCommit... expected) throws Exception {
ImmutableList<RefUpdatedEvent> events = getRefUpdatedEvents(project,
branch, expected.length / 2);
public void assertRefUpdatedEvents(String project, String branch, RevCommit... expected)
throws Exception {
ImmutableList<RefUpdatedEvent> events =
getRefUpdatedEvents(project, branch, expected.length / 2);
int i = 0;
for (RefUpdatedEvent event : events) {
RefUpdateAttribute actual = event.refUpdate.get();
String oldRev = expected[i] == null
? ObjectId.zeroId().name()
: expected[i].name();
String newRev = expected[i+1] == null
? ObjectId.zeroId().name()
: expected[i+1].name();
String oldRev = expected[i] == null ? ObjectId.zeroId().name() : expected[i].name();
String newRev = expected[i + 1] == null ? ObjectId.zeroId().name() : expected[i + 1].name();
assertThat(actual.oldRev).isEqualTo(oldRev);
assertThat(actual.newRev).isEqualTo(newRev);
i += 2;
}
}
public void assertChangeMergedEvents(String project, String branch,
String... expected) throws Exception {
ImmutableList<ChangeMergedEvent> events = getChangeMergedEvents(project,
branch, expected.length / 2);
public void assertChangeMergedEvents(String project, String branch, String... expected)
throws Exception {
ImmutableList<ChangeMergedEvent> events =
getChangeMergedEvents(project, branch, expected.length / 2);
int i = 0;
for (ChangeMergedEvent event : events) {
String id = event.change.get().id;
assertThat(id).isEqualTo(expected[i]);
assertThat(event.newRev).isEqualTo(expected[i+1]);
assertThat(event.newRev).isEqualTo(expected[i + 1]);
i += 2;
}
}
public void assertReviewerDeletedEvents(String... expected) {
ImmutableList<ReviewerDeletedEvent> events =
getReviewerDeletedEvents(expected.length / 2);
ImmutableList<ReviewerDeletedEvent> events = getReviewerDeletedEvents(expected.length / 2);
int i = 0;
for (ReviewerDeletedEvent event : events) {
String id = event.change.get().id;
assertThat(id).isEqualTo(expected[i]);
String reviewer = event.reviewer.get().email;
assertThat(reviewer).isEqualTo(expected[i+1]);
assertThat(reviewer).isEqualTo(expected[i + 1]);
i += 2;
}
}

View File

@ -19,13 +19,11 @@ import static com.google.common.truth.Truth.assert_;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.inject.Inject;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Repository;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Repository;
public class GcAssert {
@ -40,9 +38,9 @@ public class GcAssert {
throws RepositoryNotFoundException, IOException {
for (Project.NameKey p : projects) {
assert_()
.withFailureMessage("Project " + p.get() + " has no pack files.")
.that(getPackFiles(p))
.isNotEmpty();
.withFailureMessage("Project " + p.get() + " has no pack files.")
.that(getPackFiles(p))
.isNotEmpty();
}
}
@ -50,22 +48,22 @@ public class GcAssert {
throws RepositoryNotFoundException, IOException {
for (Project.NameKey p : projects) {
assert_()
.withFailureMessage("Project " + p.get() + " has pack files.")
.that(getPackFiles(p))
.isEmpty();
.withFailureMessage("Project " + p.get() + " has pack files.")
.that(getPackFiles(p))
.isEmpty();
}
}
private String[] getPackFiles(Project.NameKey p)
throws RepositoryNotFoundException, IOException {
private String[] getPackFiles(Project.NameKey p) throws RepositoryNotFoundException, IOException {
try (Repository repo = repoManager.openRepository(p)) {
File packDir = new File(repo.getDirectory(), "objects/pack");
return packDir.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".pack");
}
});
return packDir.list(
new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".pack");
}
});
}
}
}

View File

@ -26,6 +26,8 @@ import java.lang.annotation.Target;
@Repeatable(GerritConfigs.class)
public @interface GerritConfig {
String name();
String value() default "";
String[] values() default "";
}

View File

@ -37,13 +37,6 @@ import com.google.gerrit.testutil.TempFileUtil;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.RepositoryCache;
import org.eclipse.jgit.util.FS;
import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
@ -57,12 +50,16 @@ import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.RepositoryCache;
import org.eclipse.jgit.util.FS;
public class GerritServer {
@AutoValue
abstract static class Description {
static Description forTestClass(org.junit.runner.Description testDesc,
String configName) {
static Description forTestClass(org.junit.runner.Description testDesc, String configName) {
return new AutoValue_GerritServer_Description(
testDesc,
configName,
@ -72,27 +69,24 @@ public class GerritServer {
has(UseSsh.class, testDesc.getTestClass()),
null, // @GerritConfig is only valid on methods.
null); // @GerritConfigs is only valid on methods.
}
static Description forTestMethod(org.junit.runner.Description testDesc,
String configName) {
static Description forTestMethod(org.junit.runner.Description testDesc, String configName) {
return new AutoValue_GerritServer_Description(
testDesc,
configName,
testDesc.getAnnotation(UseLocalDisk.class) == null,
testDesc.getAnnotation(NoHttpd.class) == null
&& !has(NoHttpd.class, testDesc.getTestClass()),
testDesc.getAnnotation(Sandboxed.class) != null ||
has(Sandboxed.class, testDesc.getTestClass()),
testDesc.getAnnotation(UseSsh.class) != null ||
has(UseSsh.class, testDesc.getTestClass()),
&& !has(NoHttpd.class, testDesc.getTestClass()),
testDesc.getAnnotation(Sandboxed.class) != null
|| has(Sandboxed.class, testDesc.getTestClass()),
testDesc.getAnnotation(UseSsh.class) != null
|| has(UseSsh.class, testDesc.getTestClass()),
testDesc.getAnnotation(GerritConfig.class),
testDesc.getAnnotation(GerritConfigs.class));
}
private static boolean has(
Class<? extends Annotation> annotation, Class<?> clazz) {
private static boolean has(Class<? extends Annotation> annotation, Class<?> clazz) {
for (; clazz != null; clazz = clazz.getSuperclass()) {
if (clazz.getAnnotation(annotation) != null) {
return true;
@ -102,18 +96,27 @@ public class GerritServer {
}
abstract org.junit.runner.Description testDescription();
@Nullable abstract String configName();
@Nullable
abstract String configName();
abstract boolean memory();
abstract boolean httpd();
abstract boolean sandboxed();
abstract boolean useSsh();
@Nullable abstract GerritConfig config();
@Nullable abstract GerritConfigs configs();
@Nullable
abstract GerritConfig config();
@Nullable
abstract GerritConfigs configs();
private Config buildConfig(Config baseConfig) {
if (configs() != null && config() != null) {
throw new IllegalStateException(
"Use either @GerritConfigs or @GerritConfig not both");
throw new IllegalStateException("Use either @GerritConfigs or @GerritConfig not both");
}
if (configs() != null) {
return ConfigAnnotationParser.parse(baseConfig, configs());
@ -126,21 +129,23 @@ public class GerritServer {
}
/** Returns fully started Gerrit server */
static GerritServer start(Description desc, Config baseConfig)
throws Exception {
static GerritServer start(Description desc, Config baseConfig) throws Exception {
Config cfg = desc.buildConfig(baseConfig);
Logger.getLogger("com.google.gerrit").setLevel(Level.DEBUG);
final CyclicBarrier serverStarted = new CyclicBarrier(2);
final Daemon daemon = new Daemon(new Runnable() {
@Override
public void run() {
try {
serverStarted.await();
} catch (InterruptedException | BrokenBarrierException e) {
throw new RuntimeException(e);
}
}
}, Paths.get(baseConfig.getString("gerrit", null, "tempSiteDir")));
final Daemon daemon =
new Daemon(
new Runnable() {
@Override
public void run() {
try {
serverStarted.await();
} catch (InterruptedException | BrokenBarrierException e) {
throw new RuntimeException(e);
}
}
},
Paths.get(baseConfig.getString("gerrit", null, "tempSiteDir")));
daemon.setEmailModuleForTesting(new FakeEmailSender.Module());
daemon.setEnableSshd(SshMode.useSsh());
@ -158,25 +163,28 @@ public class GerritServer {
cfg.setString("gitweb", null, "cgi", "");
daemon.setEnableHttpd(desc.httpd());
daemon.setLuceneModule(LuceneIndexModule.singleVersionAllLatest(0));
daemon.setDatabaseForTesting(ImmutableList.<Module>of(
new InMemoryTestingDatabaseModule(cfg)));
daemon.setDatabaseForTesting(
ImmutableList.<Module>of(new InMemoryTestingDatabaseModule(cfg)));
daemon.start();
} else {
site = initSite(cfg);
daemonService = Executors.newSingleThreadExecutor();
daemonService.submit(new Callable<Void>() {
@Override
public Void call() throws Exception {
int rc = daemon.main(new String[] {
"-d", site.getPath(),
"--headless", "--console-log", "--show-stack-trace",});
if (rc != 0) {
System.err.println("Failed to start Gerrit daemon");
serverStarted.reset();
}
return null;
}
});
daemonService.submit(
new Callable<Void>() {
@Override
public Void call() throws Exception {
int rc =
daemon.main(
new String[] {
"-d", site.getPath(), "--headless", "--console-log", "--show-stack-trace",
});
if (rc != 0) {
System.err.println("Failed to start Gerrit daemon");
serverStarted.reset();
}
return null;
}
});
serverStarted.await();
System.out.println("Gerrit Server Started");
}
@ -188,16 +196,17 @@ public class GerritServer {
private static File initSite(Config base) throws Exception {
File tmp = TempFileUtil.createTempDirectory();
Init init = new Init();
int rc = init.main(new String[] {
"-d", tmp.getPath(), "--batch", "--no-auto-start",
"--skip-plugins",});
int rc =
init.main(
new String[] {
"-d", tmp.getPath(), "--batch", "--no-auto-start", "--skip-plugins",
});
if (rc != 0) {
throw new RuntimeException("Couldn't initialize site");
}
MergeableFileBasedConfig cfg = new MergeableFileBasedConfig(
new File(new File(tmp, "etc"), "gerrit.config"),
FS.DETECTED);
MergeableFileBasedConfig cfg =
new MergeableFileBasedConfig(new File(new File(tmp, "etc"), "gerrit.config"), FS.DETECTED);
cfg.load();
cfg.merge(base);
mergeTestConfig(cfg);
@ -206,8 +215,7 @@ public class GerritServer {
}
private static void mergeTestConfig(Config cfg) {
String forceEphemeralPort = String.format("%s:0",
getLocalHost().getHostName());
String forceEphemeralPort = String.format("%s:0", getLocalHost().getHostName());
String url = "http://" + forceEphemeralPort + "/";
cfg.setString("gerrit", null, "canonicalWebUrl", url);
cfg.setString("httpd", null, "listenUrl", url);
@ -228,22 +236,24 @@ public class GerritServer {
private static Injector createTestInjector(Daemon daemon) throws Exception {
Injector sysInjector = get(daemon, "sysInjector");
Module module = new FactoryModule() {
@Override
protected void configure() {
bind(AccountCreator.class);
factory(PushOneCommit.Factory.class);
install(InProcessProtocol.module());
install(new NoSshModule());
install(new AsyncReceiveCommits.Module());
}
};
Module module =
new FactoryModule() {
@Override
protected void configure() {
bind(AccountCreator.class);
factory(PushOneCommit.Factory.class);
install(InProcessProtocol.module());
install(new NoSshModule());
install(new AsyncReceiveCommits.Module());
}
};
return sysInjector.createChildInjector(module);
}
@SuppressWarnings("unchecked")
private static <T> T get(Object obj, String field) throws SecurityException,
NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
private static <T> T get(Object obj, String field)
throws SecurityException, NoSuchFieldException, IllegalArgumentException,
IllegalAccessException {
Field f = obj.getClass().getDeclaredField(field);
f.setAccessible(true);
return (T) f.get(obj);
@ -262,21 +272,18 @@ public class GerritServer {
private InetSocketAddress sshdAddress;
private InetSocketAddress httpAddress;
private GerritServer(Description desc, Injector testInjector, Daemon daemon,
ExecutorService daemonService) {
private GerritServer(
Description desc, Injector testInjector, Daemon daemon, ExecutorService daemonService) {
this.desc = desc;
this.testInjector = testInjector;
this.daemon = daemon;
this.daemonService = daemonService;
Config cfg = testInjector.getInstance(
Key.get(Config.class, GerritServerConfig.class));
Config cfg = testInjector.getInstance(Key.get(Config.class, GerritServerConfig.class));
url = cfg.getString("gerrit", null, "canonicalWebUrl");
URI uri = URI.create(url);
sshdAddress = SocketUtil.resolve(
cfg.getString("sshd", null, "listenAddress"),
0);
sshdAddress = SocketUtil.resolve(cfg.getString("sshd", null, "listenAddress"), 0);
httpAddress = new InetSocketAddress(uri.getHost(), uri.getPort());
}

View File

@ -21,11 +21,15 @@ import com.google.common.collect.Lists;
import com.google.common.primitives.Ints;
import com.google.gerrit.common.FooterConstants;
import com.google.gerrit.reviewdb.client.Project;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.jgit.api.FetchCommand;
import org.eclipse.jgit.api.PushCommand;
import org.eclipse.jgit.api.TagCommand;
@ -48,13 +52,6 @@ import org.eclipse.jgit.transport.RemoteRefUpdate;
import org.eclipse.jgit.transport.SshSessionFactory;
import org.eclipse.jgit.util.FS;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class GitUtil {
private static final AtomicInteger testRepoCount = new AtomicInteger();
private static final int TEST_REPO_WINDOW_DAYS = 2;
@ -67,66 +64,64 @@ public class GitUtil {
// register a JschConfigSessionFactory that adds the private key as identity
// to the JSch instance of JGit so that SSH communication via JGit can
// succeed
SshSessionFactory.setInstance(new JschConfigSessionFactory() {
@Override
protected void configure(Host hc, Session session) {
try {
final JSch jsch = getJSch(hc, FS.DETECTED);
jsch.addIdentity("KeyPair", a.privateKey(),
a.sshKey.getPublicKeyBlob(), null);
} catch (JSchException e) {
throw new RuntimeException(e);
}
}
});
SshSessionFactory.setInstance(
new JschConfigSessionFactory() {
@Override
protected void configure(Host hc, Session session) {
try {
final JSch jsch = getJSch(hc, FS.DETECTED);
jsch.addIdentity("KeyPair", a.privateKey(), a.sshKey.getPublicKeyBlob(), null);
} catch (JSchException e) {
throw new RuntimeException(e);
}
}
});
}
/**
* Create a new {@link TestRepository} with a distinct commit clock.
* <p>
* It is very easy for tests to create commits with identical subjects and
* trees; if such commits also have identical authors/committers, then the
* computed Change-Id is identical as well. Tests may generally assume that
* Change-Ids are unique, so to ensure this, we provision TestRepository
* instances with non-overlapping commit clock times.
* <p>
* Space test repos 1 day apart, which allows for about 86k ticks per repo
* before overlapping, and about 8k instances per process before hitting
* JGit's year 2038 limit.
*
* <p>It is very easy for tests to create commits with identical subjects and trees; if such
* commits also have identical authors/committers, then the computed Change-Id is identical as
* well. Tests may generally assume that Change-Ids are unique, so to ensure this, we provision
* TestRepository instances with non-overlapping commit clock times.
*
* <p>Space test repos 1 day apart, which allows for about 86k ticks per repo before overlapping,
* and about 8k instances per process before hitting JGit's year 2038 limit.
*
* @param repo repository to wrap.
* @return wrapped test repository with distinct commit time space.
*/
public static <R extends Repository> TestRepository<R> newTestRepository(
R repo) throws IOException {
public static <R extends Repository> TestRepository<R> newTestRepository(R repo)
throws IOException {
TestRepository<R> tr = new TestRepository<>(repo);
tr.tick(Ints.checkedCast(TimeUnit.SECONDS.convert(
testRepoCount.getAndIncrement() * TEST_REPO_WINDOW_DAYS,
TimeUnit.DAYS)));
tr.tick(
Ints.checkedCast(
TimeUnit.SECONDS.convert(
testRepoCount.getAndIncrement() * TEST_REPO_WINDOW_DAYS, TimeUnit.DAYS)));
return tr;
}
public static TestRepository<InMemoryRepository> cloneProject(
Project.NameKey project, String uri) throws Exception {
DfsRepositoryDescription desc =
new DfsRepositoryDescription("clone of " + project.get());
public static TestRepository<InMemoryRepository> cloneProject(Project.NameKey project, String uri)
throws Exception {
DfsRepositoryDescription desc = new DfsRepositoryDescription("clone of " + project.get());
FS fs = FS.detect();
// Avoid leaking user state into our tests.
fs.setUserHome(null);
InMemoryRepository dest = new InMemoryRepository.Builder()
.setRepositoryDescription(desc)
// SshTransport depends on a real FS to read ~/.ssh/config, but
// InMemoryRepository by default uses a null FS.
// TODO(dborowitz): Remove when we no longer depend on SSH.
.setFS(fs)
.build();
InMemoryRepository dest =
new InMemoryRepository.Builder()
.setRepositoryDescription(desc)
// SshTransport depends on a real FS to read ~/.ssh/config, but
// InMemoryRepository by default uses a null FS.
// TODO(dborowitz): Remove when we no longer depend on SSH.
.setFS(fs)
.build();
Config cfg = dest.getConfig();
cfg.setString("remote", "origin", "url", uri);
cfg.setString("remote", "origin", "fetch",
"+refs/heads/*:refs/remotes/origin/*");
cfg.setString("remote", "origin", "fetch", "+refs/heads/*:refs/remotes/origin/*");
TestRepository<InMemoryRepository> testRepo = newTestRepository(dest);
FetchResult result = testRepo.git().fetch().setRemote("origin").call();
String originMaster = "refs/remotes/origin/master";
@ -141,51 +136,47 @@ public class GitUtil {
return cloneProject(project, sshSession.getUrl() + "/" + project.get());
}
public static Ref createAnnotatedTag(TestRepository<?> testRepo, String name,
PersonIdent tagger) throws GitAPIException {
TagCommand cmd = testRepo.git().tag()
.setName(name)
.setAnnotated(true)
.setMessage(name)
.setTagger(tagger);
public static Ref createAnnotatedTag(TestRepository<?> testRepo, String name, PersonIdent tagger)
throws GitAPIException {
TagCommand cmd =
testRepo.git().tag().setName(name).setAnnotated(true).setMessage(name).setTagger(tagger);
return cmd.call();
}
public static Ref updateAnnotatedTag(TestRepository<?> testRepo, String name,
PersonIdent tagger) throws GitAPIException {
public static Ref updateAnnotatedTag(TestRepository<?> testRepo, String name, PersonIdent tagger)
throws GitAPIException {
TagCommand tc = testRepo.git().tag().setName(name);
return tc.setAnnotated(true)
.setMessage(name)
.setTagger(tagger)
.setForceUpdate(true)
.call();
return tc.setAnnotated(true).setMessage(name).setTagger(tagger).setForceUpdate(true).call();
}
public static void fetch(TestRepository<?> testRepo, String spec)
throws GitAPIException {
public static void fetch(TestRepository<?> testRepo, String spec) throws GitAPIException {
FetchCommand fetch = testRepo.git().fetch();
fetch.setRefSpecs(new RefSpec(spec));
fetch.call();
}
public static PushResult pushHead(TestRepository<?> testRepo, String ref)
throws GitAPIException {
public static PushResult pushHead(TestRepository<?> testRepo, String ref) throws GitAPIException {
return pushHead(testRepo, ref, false);
}
public static PushResult pushHead(TestRepository<?> testRepo, String ref,
boolean pushTags) throws GitAPIException {
public static PushResult pushHead(TestRepository<?> testRepo, String ref, boolean pushTags)
throws GitAPIException {
return pushHead(testRepo, ref, pushTags, false);
}
public static PushResult pushHead(TestRepository<?> testRepo, String ref,
boolean pushTags, boolean force) throws GitAPIException {
public static PushResult pushHead(
TestRepository<?> testRepo, String ref, boolean pushTags, boolean force)
throws GitAPIException {
return pushOne(testRepo, "HEAD", ref, pushTags, force, null);
}
public static PushResult pushHead(TestRepository<?> testRepo, String ref,
boolean pushTags, boolean force, List<String> pushOptions)
throws GitAPIException {
public static PushResult pushHead(
TestRepository<?> testRepo,
String ref,
boolean pushTags,
boolean force,
List<String> pushOptions)
throws GitAPIException {
return pushOne(testRepo, "HEAD", ref, pushTags, force, pushOptions);
}
@ -194,9 +185,14 @@ public class GitUtil {
return pushOne(testRepo, "", ref, false, true, null);
}
public static PushResult pushOne(TestRepository<?> testRepo, String source,
String target, boolean pushTags, boolean force, List<String> pushOptions)
throws GitAPIException {
public static PushResult pushOne(
TestRepository<?> testRepo,
String source,
String target,
boolean pushTags,
boolean force,
List<String> pushOptions)
throws GitAPIException {
PushCommand pushCmd = testRepo.git().push();
pushCmd.setForce(force);
pushCmd.setPushOptions(pushOptions);
@ -210,25 +206,23 @@ public class GitUtil {
public static void assertPushOk(PushResult result, String ref) {
RemoteRefUpdate rru = result.getRemoteUpdate(ref);
assertThat(rru.getStatus()).named(rru.toString())
.isEqualTo(RemoteRefUpdate.Status.OK);
assertThat(rru.getStatus()).named(rru.toString()).isEqualTo(RemoteRefUpdate.Status.OK);
}
public static void assertPushRejected(PushResult result, String ref,
String expectedMessage) {
public static void assertPushRejected(PushResult result, String ref, String expectedMessage) {
RemoteRefUpdate rru = result.getRemoteUpdate(ref);
assertThat(rru.getStatus()).named(rru.toString())
assertThat(rru.getStatus())
.named(rru.toString())
.isEqualTo(RemoteRefUpdate.Status.REJECTED_OTHER_REASON);
assertThat(rru.getMessage()).isEqualTo(expectedMessage);
}
public static PushResult pushTag(TestRepository<?> testRepo, String tag)
throws GitAPIException {
public static PushResult pushTag(TestRepository<?> testRepo, String tag) throws GitAPIException {
return pushTag(testRepo, tag, false);
}
public static PushResult pushTag(TestRepository<?> testRepo, String tag,
boolean force) throws GitAPIException {
public static PushResult pushTag(TestRepository<?> testRepo, String tag, boolean force)
throws GitAPIException {
PushCommand pushCmd = testRepo.git().push();
pushCmd.setForce(force);
pushCmd.setRefSpecs(new RefSpec("refs/tags/" + tag + ":refs/tags/" + tag));
@ -236,11 +230,9 @@ public class GitUtil {
return Iterables.getOnlyElement(r);
}
public static Optional<String> getChangeId(TestRepository<?> tr, ObjectId id)
throws IOException {
public static Optional<String> getChangeId(TestRepository<?> tr, ObjectId id) throws IOException {
RevCommit c = tr.getRevWalk().parseCommit(id);
tr.getRevWalk().parseBody(c);
return Lists.reverse(c.getFooterLines(FooterConstants.CHANGE_ID)).stream()
.findFirst();
return Lists.reverse(c.getFooterLines(FooterConstants.CHANGE_ID)).stream().findFirst();
}
}

View File

@ -15,15 +15,13 @@
package com.google.gerrit.acceptance;
import com.google.common.base.Preconditions;
import org.apache.http.Header;
import org.eclipse.jgit.util.IO;
import org.eclipse.jgit.util.RawParseUtils;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.ByteBuffer;
import org.apache.http.Header;
import org.eclipse.jgit.util.IO;
import org.eclipse.jgit.util.RawParseUtils;
public class HttpResponse {
@ -62,23 +60,14 @@ public class HttpResponse {
}
public boolean hasContent() {
Preconditions.checkNotNull(response,
"Response is not initialized.");
Preconditions.checkNotNull(response, "Response is not initialized.");
return response.getEntity() != null;
}
public String getEntityContent() throws IOException {
Preconditions.checkNotNull(response,
"Response is not initialized.");
Preconditions.checkNotNull(response.getEntity(),
"Response.Entity is not initialized.");
ByteBuffer buf = IO.readWholeStream(
response.getEntity().getContent(),
1024);
return RawParseUtils.decode(
buf.array(),
buf.arrayOffset(),
buf.limit())
.trim();
Preconditions.checkNotNull(response, "Response is not initialized.");
Preconditions.checkNotNull(response.getEntity(), "Response.Entity is not initialized.");
ByteBuffer buf = IO.readWholeStream(response.getEntity().getContent(), 1024);
return RawParseUtils.decode(buf.array(), buf.arrayOffset(), buf.limit()).trim();
}
}

View File

@ -16,14 +16,12 @@ package com.google.gerrit.acceptance;
import com.google.common.base.CharMatcher;
import com.google.gerrit.common.Nullable;
import java.io.IOException;
import java.net.URI;
import org.apache.http.HttpHost;
import org.apache.http.client.fluent.Executor;
import org.apache.http.client.fluent.Request;
import java.io.IOException;
import java.net.URI;
public class HttpSession {
protected TestAccount account;
protected final String url;
@ -35,9 +33,8 @@ public class HttpSession {
this.executor = Executor.newInstance();
this.account = account;
if (account != null) {
executor.auth(
new HttpHost(uri.getHost(), uri.getPort()),
account.username, account.httpPassword);
executor.auth(
new HttpHost(uri.getHost(), uri.getPort()), account.username, account.httpPassword);
}
}

View File

@ -48,15 +48,13 @@ import com.google.inject.Provides;
import com.google.inject.ProvisionException;
import com.google.inject.Singleton;
import com.google.inject.TypeLiteral;
import org.apache.sshd.common.keyprovider.KeyPairProvider;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
import org.eclipse.jgit.lib.Config;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.apache.sshd.common.keyprovider.KeyPairProvider;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
import org.eclipse.jgit.lib.Config;
class InMemoryTestingDatabaseModule extends LifecycleModule {
private final Config cfg;
@ -67,19 +65,14 @@ class InMemoryTestingDatabaseModule extends LifecycleModule {
@Override
protected void configure() {
bind(Config.class)
.annotatedWith(GerritServerConfig.class)
.toInstance(cfg);
bind(Config.class).annotatedWith(GerritServerConfig.class).toInstance(cfg);
// TODO(dborowitz): Use jimfs.
Path p = Paths.get(cfg.getString("gerrit", null, "tempSiteDir"));
bind(Path.class)
.annotatedWith(SitePath.class)
.toInstance(p);
bind(Path.class).annotatedWith(SitePath.class).toInstance(p);
makeSiteDirs(p);
bind(GitRepositoryManager.class)
.to(InMemoryRepositoryManager.class);
bind(GitRepositoryManager.class).to(InMemoryRepositoryManager.class);
bind(InMemoryRepositoryManager.class).in(SINGLETON);
bind(MetricMaker.class).to(DisabledMetricMaker.class);
@ -89,17 +82,14 @@ class InMemoryTestingDatabaseModule extends LifecycleModule {
TypeLiteral<SchemaFactory<ReviewDb>> schemaFactory =
new TypeLiteral<SchemaFactory<ReviewDb>>() {};
bind(schemaFactory).to(NotesMigrationSchemaFactory.class);
bind(Key.get(schemaFactory, ReviewDbFactory.class))
.to(InMemoryDatabase.class);
bind(Key.get(schemaFactory, ReviewDbFactory.class)).to(InMemoryDatabase.class);
bind(InMemoryDatabase.class).in(SINGLETON);
bind(ChangeBundleReader.class).to(GwtormChangeBundleReader.class);
listener().to(CreateDatabase.class);
bind(SitePaths.class);
bind(TrackingFooters.class)
.toProvider(TrackingFootersProvider.class)
.in(SINGLETON);
bind(TrackingFooters.class).toProvider(TrackingFootersProvider.class).in(SINGLETON);
install(new SchemaModule());
bind(SchemaVersion.class).to(SchemaVersion.C);

View File

@ -55,7 +55,11 @@ import com.google.inject.Provides;
import com.google.inject.Scope;
import com.google.inject.servlet.RequestScoped;
import com.google.inject.util.Providers;
import java.io.IOException;
import java.net.SocketAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.PostReceiveHook;
import org.eclipse.jgit.transport.PostReceiveHookChain;
@ -68,12 +72,6 @@ import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
import org.eclipse.jgit.transport.resolver.UploadPackFactory;
import java.io.IOException;
import java.net.SocketAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
class InProcessProtocol extends TestProtocol<Context> {
static Module module() {
return new AbstractModule() {
@ -94,36 +92,37 @@ class InProcessProtocol extends TestProtocol<Context> {
};
}
private static final Scope REQUEST = new Scope() {
@Override
public <T> Provider<T> scope(final Key<T> key, final Provider<T> creator) {
return new Provider<T>() {
private static final Scope REQUEST =
new Scope() {
@Override
public T get() {
Context ctx = current.get();
if (ctx == null) {
throw new OutOfScopeException("Not in TestProtocol scope");
}
return ctx.get(key, creator);
public <T> Provider<T> scope(final Key<T> key, final Provider<T> creator) {
return new Provider<T>() {
@Override
public T get() {
Context ctx = current.get();
if (ctx == null) {
throw new OutOfScopeException("Not in TestProtocol scope");
}
return ctx.get(key, creator);
}
@Override
public String toString() {
return String.format("%s[%s]", creator, REQUEST);
}
};
}
@Override
public String toString() {
return String.format("%s[%s]", creator, REQUEST);
return "InProcessProtocol.REQUEST";
}
};
}
@Override
public String toString() {
return "InProcessProtocol.REQUEST";
}
};
private static class Propagator
extends ThreadLocalRequestScopePropagator<Context> {
private static class Propagator extends ThreadLocalRequestScopePropagator<Context> {
@Inject
Propagator(ThreadLocalRequestContext local,
Propagator(
ThreadLocalRequestContext local,
Provider<RequestScopedReviewDbProvider> dbProviderProvider) {
super(REQUEST, current, local, dbProviderProvider);
}
@ -139,22 +138,20 @@ class InProcessProtocol extends TestProtocol<Context> {
// TODO(dborowitz): Merge this with AcceptanceTestRequestScope.
/**
* Multi-purpose session/context object.
* <p>
* Confusingly, Gerrit has two ideas of what a "context" object is:
* one for Guice {@link RequestScoped}, and one for its own simplified
* version of request scoping using {@link ThreadLocalRequestContext}.
* This class provides both, in essence just delegating the {@code
*
* <p>Confusingly, Gerrit has two ideas of what a "context" object is: one for Guice {@link
* RequestScoped}, and one for its own simplified version of request scoping using {@link
* ThreadLocalRequestContext}. This class provides both, in essence just delegating the {@code
* ThreadLocalRequestContext} scoping to the Guice scoping mechanism.
* <p>
* It is also used as the session type for {@code UploadPackFactory} and
* {@code ReceivePackFactory}, since, after all, it encapsulates all the
* information about a single request.
*
* <p>It is also used as the session type for {@code UploadPackFactory} and {@code
* ReceivePackFactory}, since, after all, it encapsulates all the information about a single
* request.
*/
static class Context implements RequestContext {
private static final Key<RequestScopedReviewDbProvider> DB_KEY =
Key.get(RequestScopedReviewDbProvider.class);
private static final Key<RequestCleanup> RC_KEY =
Key.get(RequestCleanup.class);
private static final Key<RequestCleanup> RC_KEY = Key.get(RequestCleanup.class);
private static final Key<CurrentUser> USER_KEY = Key.get(CurrentUser.class);
private final SchemaFactory<ReviewDb> schemaFactory;
@ -164,7 +161,8 @@ class InProcessProtocol extends TestProtocol<Context> {
private final RequestCleanup cleanup;
private final Map<Key<?>, Object> map;
Context(SchemaFactory<ReviewDb> schemaFactory,
Context(
SchemaFactory<ReviewDb> schemaFactory,
IdentifiedUser.GenericFactory userFactory,
Account.Id accountId,
Project.NameKey project) {
@ -174,9 +172,7 @@ class InProcessProtocol extends TestProtocol<Context> {
this.project = project;
map = new HashMap<>();
cleanup = new RequestCleanup();
map.put(DB_KEY,
new RequestScopedReviewDbProvider(
schemaFactory, Providers.of(cleanup)));
map.put(DB_KEY, new RequestScopedReviewDbProvider(schemaFactory, Providers.of(cleanup)));
map.put(RC_KEY, cleanup);
IdentifiedUser user = userFactory.create(accountId);
@ -255,8 +251,7 @@ class InProcessProtocol extends TestProtocol<Context> {
threadContext.setContext(req);
current.set(req);
try {
ProjectControl ctl = projectControlFactory.controlFor(
req.project, userProvider.get());
ProjectControl ctl = projectControlFactory.controlFor(req.project, userProvider.get());
if (!ctl.canRunUploadPack()) {
throw new ServiceNotAuthorizedException();
}
@ -264,12 +259,11 @@ class InProcessProtocol extends TestProtocol<Context> {
UploadPack up = new UploadPack(repo);
up.setPackConfig(transferConfig.getPackConfig());
up.setTimeout(transferConfig.getTimeout());
up.setAdvertiseRefsHook(new VisibleRefFilter(
tagCache, changeNotesFactory, changeCache, repo, ctl,
dbProvider.get(), true));
up.setAdvertiseRefsHook(
new VisibleRefFilter(
tagCache, changeNotesFactory, changeCache, repo, ctl, dbProvider.get(), true));
List<PreUploadHook> hooks = Lists.newArrayList(preUploadHooks);
hooks.add(uploadValidatorsFactory.create(
ctl.getProject(), repo, "localhost-test"));
hooks.add(uploadValidatorsFactory.create(ctl.getProject(), repo, "localhost-test"));
up.setPreUploadHook(PreUploadHookChain.newChain(hooks));
return up;
} catch (NoSuchProjectException | IOException e) {
@ -315,8 +309,7 @@ class InProcessProtocol extends TestProtocol<Context> {
threadContext.setContext(req);
current.set(req);
try {
ProjectControl ctl =
projectControlFactory.controlFor(req.project, userProvider.get());
ProjectControl ctl = projectControlFactory.controlFor(req.project, userProvider.get());
if (!ctl.canRunReceivePack()) {
throw new ServiceNotAuthorizedException();
}
@ -337,8 +330,7 @@ class InProcessProtocol extends TestProtocol<Context> {
initializer.init(ctl.getProject().getNameKey(), rp);
}
rp.setPostReceiveHook(PostReceiveHookChain.newChain(
Lists.newArrayList(postReceiveHooks)));
rp.setPostReceiveHook(PostReceiveHookChain.newChain(Lists.newArrayList(postReceiveHooks)));
return rp;
} catch (NoSuchProjectException | IOException e) {
throw new RuntimeException(e);
@ -347,8 +339,7 @@ class InProcessProtocol extends TestProtocol<Context> {
}
@Inject
InProcessProtocol(Upload uploadPackFactory,
Receive receivePackFactory) {
InProcessProtocol(Upload uploadPackFactory, Receive receivePackFactory) {
super(uploadPackFactory, receivePackFactory);
}
}

View File

@ -18,16 +18,13 @@ import com.google.gerrit.server.PluginUser;
import com.google.gerrit.server.plugins.PluginGuiceEnvironment;
import com.google.gerrit.server.plugins.TestServerPlugin;
import com.google.inject.Inject;
import org.junit.After;
import org.junit.Before;
public class LightweightPluginDaemonTest extends AbstractDaemonTest {
@Inject
private PluginGuiceEnvironment env;
@Inject private PluginGuiceEnvironment env;
@Inject
private PluginUser.Factory pluginUserFactory;
@Inject private PluginUser.Factory pluginUserFactory;
private TestServerPlugin plugin;
@ -35,13 +32,15 @@ public class LightweightPluginDaemonTest extends AbstractDaemonTest {
public void setUp() throws Exception {
TestPlugin testPlugin = getTestPlugin(getClass());
String name = testPlugin.name();
plugin = new TestServerPlugin(name,
canonicalWebUrl.get() + "plugins/" + name,
pluginUserFactory.create(name),
getClass().getClassLoader(),
testPlugin.sysModule(),
testPlugin.httpModule(),
testPlugin.sshModule());
plugin =
new TestServerPlugin(
name,
canonicalWebUrl.get() + "plugins/" + name,
pluginUserFactory.create(name),
getClass().getClassLoader(),
testPlugin.sysModule(),
testPlugin.httpModule(),
testPlugin.sshModule());
plugin.start(env);
env.onStartPlugin(plugin);

View File

@ -15,16 +15,12 @@
package com.google.gerrit.acceptance;
import com.google.common.collect.Lists;
import java.io.File;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.FS;
import java.io.File;
/**
* A file based Config that can merge another Config instance.
*/
/** A file based Config that can merge another Config instance. */
public class MergeableFileBasedConfig extends FileBasedConfig {
public MergeableFileBasedConfig(File cfgLocation, FS fs) {
super(cfgLocation, fs);
@ -33,9 +29,8 @@ public class MergeableFileBasedConfig extends FileBasedConfig {
/**
* Merge another Config into this Config.
*
* In case a configuration parameter exists both in this instance and in the
* merged instance then the value in this instance will simply replaced by
* the value from the merged instance.
* <p>In case a configuration parameter exists both in this instance and in the merged instance
* then the value in this instance will simply replaced by the value from the merged instance.
*
* @param s Config to merge into this instance
*/
@ -46,14 +41,17 @@ public class MergeableFileBasedConfig extends FileBasedConfig {
for (String section : s.getSections()) {
for (String subsection : s.getSubsections(section)) {
for (String name : s.getNames(section, subsection)) {
setStringList(section, subsection, name, Lists.newArrayList(s
.getStringList(section, subsection, name)));
setStringList(
section,
subsection,
name,
Lists.newArrayList(s.getStringList(section, subsection, name)));
}
}
for (String name : s.getNames(section, true)) {
setStringList(section, null, name,
Lists.newArrayList(s.getStringList(section, null, name)));
setStringList(
section, null, name, Lists.newArrayList(s.getStringList(section, null, name)));
}
}
}

View File

@ -23,5 +23,4 @@ import java.lang.annotation.Target;
@Target({TYPE, METHOD})
@Retention(RUNTIME)
public @interface NoHttpd {
}
public @interface NoHttpd {}

View File

@ -20,12 +20,6 @@ import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
import com.google.gerrit.launcher.GerritLauncher;
import com.google.gerrit.server.config.SitePaths;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.FS;
import org.junit.runner.Description;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ProcessBuilder.Redirect;
@ -37,10 +31,12 @@ import java.nio.file.StandardCopyOption;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.FS;
import org.junit.runner.Description;
/**
* @deprecated use {@link LightweightPluginDaemonTest} instead.
*/
/** @deprecated use {@link LightweightPluginDaemonTest} instead. */
@Deprecated
public abstract class PluginDaemonTest extends AbstractDaemonTest {
@ -73,8 +69,7 @@ public abstract class PluginDaemonTest extends AbstractDaemonTest {
super.beforeTest(description);
}
protected void beforeTestServerStarts() throws Exception {
}
protected void beforeTestServerStarts() throws Exception {}
protected void setPluginConfigString(String name, String value)
throws IOException, ConfigInvalidException {
@ -85,10 +80,8 @@ public abstract class PluginDaemonTest extends AbstractDaemonTest {
cfg.save();
}
private FileBasedConfig getGerritConfigFile(SitePaths sitePath)
throws IOException {
FileBasedConfig cfg =
new FileBasedConfig(sitePath.gerrit_config.toFile(), FS.DETECTED);
private FileBasedConfig getGerritConfigFile(SitePaths sitePath) throws IOException {
FileBasedConfig cfg = new FileBasedConfig(sitePath.gerrit_config.toFile(), FS.DETECTED);
if (!cfg.getFile().exists()) {
Path etc_path = Files.createDirectories(sitePath.etc_dir);
Files.createFile(etc_path.resolve("gerrit.config"));
@ -97,8 +90,7 @@ public abstract class PluginDaemonTest extends AbstractDaemonTest {
}
private void locatePaths() throws IOException {
URL pluginClassesUrl =
getClass().getProtectionDomain().getCodeSource().getLocation();
URL pluginClassesUrl = getClass().getProtectionDomain().getCodeSource().getLocation();
basePath = Paths.get(pluginClassesUrl.getPath()).getParent();
int idx = 0;
@ -141,17 +133,15 @@ public abstract class PluginDaemonTest extends AbstractDaemonTest {
return false;
}
String pathCharStringOrNone = "[a-zA-Z0-9._-]*?";
Pattern pattern = Pattern.compile(pathCharStringOrNone + "gerrit" +
pathCharStringOrNone);
Pattern pattern = Pattern.compile(pathCharStringOrNone + "gerrit" + pathCharStringOrNone);
Path partialPath = basePath;
for (int i = basePath.getNameCount(); i > 0; i--) {
int count = partialPath.getNameCount();
if (count > 1) {
String gerritDirCandidate =
partialPath.subpath(count - 2, count - 1).toString();
String gerritDirCandidate = partialPath.subpath(count - 2, count - 1).toString();
if (pattern.matcher(gerritDirCandidate).matches()) {
if (partialPath.endsWith(gerritDirCandidate + "/" + BUCKOUT) ||
partialPath.endsWith(gerritDirCandidate + "/" + ECLIPSE)) {
if (partialPath.endsWith(gerritDirCandidate + "/" + BUCKOUT)
|| partialPath.endsWith(gerritDirCandidate + "/" + ECLIPSE)) {
return false;
}
}
@ -171,14 +161,11 @@ public abstract class PluginDaemonTest extends AbstractDaemonTest {
buildfile = pluginSource.resolve("BUILD");
}
if (!Files.exists(buildfile)) {
throw new IllegalStateException("Cannot find build file in: "
+ pluginSource);
throw new IllegalStateException("Cannot find build file in: " + pluginSource);
}
byte[] bytes = Files.readAllBytes(buildfile);
String buckContent =
new String(bytes, UTF_8).replaceAll("\\s+", "");
Matcher matcher =
Pattern.compile("gerrit_plugin\\(name='(.*?)'").matcher(buckContent);
String buckContent = new String(bytes, UTF_8).replaceAll("\\s+", "");
Matcher matcher = Pattern.compile("gerrit_plugin\\(name='(.*?)'").matcher(buckContent);
if (matcher.find()) {
pluginName = matcher.group(1);
}
@ -196,13 +183,11 @@ public abstract class PluginDaemonTest extends AbstractDaemonTest {
String build;
if (bazel) {
dir = GerritLauncher.resolveInSourceRoot(".");
Properties properties = loadBuildProperties(
dir.resolve(".primary_build_tool"));
build = MoreObjects.firstNonNull(
properties.getProperty(BAZELLC), BAZELLC);
Properties properties = loadBuildProperties(dir.resolve(".primary_build_tool"));
build = MoreObjects.firstNonNull(properties.getProperty(BAZELLC), BAZELLC);
} else {
Properties properties = loadBuildProperties(
gen.resolve(Paths.get("tools/buck/buck.properties")));
Properties properties =
loadBuildProperties(gen.resolve(Paths.get("tools/buck/buck.properties")));
build = MoreObjects.firstNonNull(properties.getProperty(BUCKLC), BUCKLC);
}
String target;
@ -213,7 +198,8 @@ public abstract class PluginDaemonTest extends AbstractDaemonTest {
}
ProcessBuilder processBuilder =
new ProcessBuilder(build, "build", target).directory(dir.toFile())
new ProcessBuilder(build, "build", target)
.directory(dir.toFile())
.redirectErrorStream(true);
Path forceJar = pluginSource.resolve("src/main/java/ForceJarIfMissing.java");
if (!bazel) {

View File

@ -35,7 +35,8 @@ import com.google.gwtorm.server.OrmException;
import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
import java.util.List;
import java.util.Map;
import org.eclipse.jgit.api.TagCommand;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.PersonIdent;
@ -44,37 +45,32 @@ import org.eclipse.jgit.transport.PushResult;
import org.eclipse.jgit.transport.RemoteRefUpdate;
import org.eclipse.jgit.transport.RemoteRefUpdate.Status;
import java.util.List;
import java.util.Map;
public class PushOneCommit {
public static final String SUBJECT = "test commit";
public static final String FILE_NAME = "a.txt";
public static final String FILE_CONTENT = "some content";
public static final String PATCH_FILE_ONLY =
"diff --git a/a.txt b/a.txt\n" +
"new file mode 100644\n" +
"index 0000000..f0eec86\n" +
"--- /dev/null\n" +
"+++ b/a.txt\n" +
"@@ -0,0 +1 @@\n" +
"+some content\n" +
"\\ No newline at end of file\n";
"diff --git a/a.txt b/a.txt\n"
+ "new file mode 100644\n"
+ "index 0000000..f0eec86\n"
+ "--- /dev/null\n"
+ "+++ b/a.txt\n"
+ "@@ -0,0 +1 @@\n"
+ "+some content\n"
+ "\\ No newline at end of file\n";
public static final String PATCH =
"From %s Mon Sep 17 00:00:00 2001\n" +
"From: Administrator <admin@example.com>\n" +
"Date: %s\n" +
"Subject: [PATCH] test commit\n" +
"\n" +
"Change-Id: %s\n" +
"---\n" +
"\n" + PATCH_FILE_ONLY;
"From %s Mon Sep 17 00:00:00 2001\n"
+ "From: Administrator <admin@example.com>\n"
+ "Date: %s\n"
+ "Subject: [PATCH] test commit\n"
+ "\n"
+ "Change-Id: %s\n"
+ "---\n"
+ "\n"
+ PATCH_FILE_ONLY;
public interface Factory {
PushOneCommit create(
ReviewDb db,
PersonIdent i,
TestRepository<?> testRepo);
PushOneCommit create(ReviewDb db, PersonIdent i, TestRepository<?> testRepo);
PushOneCommit create(
ReviewDb db,
@ -142,30 +138,52 @@ public class PushOneCommit {
private final TestRepository<?>.CommitBuilder commitBuilder;
@AssistedInject
PushOneCommit(ChangeNotes.Factory notesFactory,
PushOneCommit(
ChangeNotes.Factory notesFactory,
ApprovalsUtil approvalsUtil,
Provider<InternalChangeQuery> queryProvider,
@Assisted ReviewDb db,
@Assisted PersonIdent i,
@Assisted TestRepository<?> testRepo) throws Exception {
this(notesFactory, approvalsUtil, queryProvider,
db, i, testRepo, SUBJECT, FILE_NAME, FILE_CONTENT);
@Assisted TestRepository<?> testRepo)
throws Exception {
this(
notesFactory,
approvalsUtil,
queryProvider,
db,
i,
testRepo,
SUBJECT,
FILE_NAME,
FILE_CONTENT);
}
@AssistedInject
PushOneCommit(ChangeNotes.Factory notesFactory,
PushOneCommit(
ChangeNotes.Factory notesFactory,
ApprovalsUtil approvalsUtil,
Provider<InternalChangeQuery> queryProvider,
@Assisted ReviewDb db,
@Assisted PersonIdent i,
@Assisted TestRepository<?> testRepo,
@Assisted("changeId") String changeId) throws Exception {
this(notesFactory, approvalsUtil, queryProvider,
db, i, testRepo, SUBJECT, FILE_NAME, FILE_CONTENT, changeId);
@Assisted("changeId") String changeId)
throws Exception {
this(
notesFactory,
approvalsUtil,
queryProvider,
db,
i,
testRepo,
SUBJECT,
FILE_NAME,
FILE_CONTENT,
changeId);
}
@AssistedInject
PushOneCommit(ChangeNotes.Factory notesFactory,
PushOneCommit(
ChangeNotes.Factory notesFactory,
ApprovalsUtil approvalsUtil,
Provider<InternalChangeQuery> queryProvider,
@Assisted ReviewDb db,
@ -173,26 +191,38 @@ public class PushOneCommit {
@Assisted TestRepository<?> testRepo,
@Assisted("subject") String subject,
@Assisted("fileName") String fileName,
@Assisted("content") String content) throws Exception {
this(notesFactory, approvalsUtil, queryProvider,
db, i, testRepo, subject, fileName, content, null);
@Assisted("content") String content)
throws Exception {
this(
notesFactory,
approvalsUtil,
queryProvider,
db,
i,
testRepo,
subject,
fileName,
content,
null);
}
@AssistedInject
PushOneCommit(ChangeNotes.Factory notesFactory,
PushOneCommit(
ChangeNotes.Factory notesFactory,
ApprovalsUtil approvalsUtil,
Provider<InternalChangeQuery> queryProvider,
@Assisted ReviewDb db,
@Assisted PersonIdent i,
@Assisted TestRepository<?> testRepo,
@Assisted String subject,
@Assisted Map<String, String> files) throws Exception {
this(notesFactory, approvalsUtil, queryProvider, db, i, testRepo,
subject, files, null);
@Assisted Map<String, String> files)
throws Exception {
this(notesFactory, approvalsUtil, queryProvider, db, i, testRepo, subject, files, null);
}
@AssistedInject
PushOneCommit(ChangeNotes.Factory notesFactory,
PushOneCommit(
ChangeNotes.Factory notesFactory,
ApprovalsUtil approvalsUtil,
Provider<InternalChangeQuery> queryProvider,
@Assisted ReviewDb db,
@ -201,12 +231,22 @@ public class PushOneCommit {
@Assisted("subject") String subject,
@Assisted("fileName") String fileName,
@Assisted("content") String content,
@Nullable @Assisted("changeId") String changeId) throws Exception {
this(notesFactory, approvalsUtil, queryProvider, db, i, testRepo,
subject, ImmutableMap.of(fileName, content), changeId);
@Nullable @Assisted("changeId") String changeId)
throws Exception {
this(
notesFactory,
approvalsUtil,
queryProvider,
db,
i,
testRepo,
subject,
ImmutableMap.of(fileName, content),
changeId);
}
private PushOneCommit(ChangeNotes.Factory notesFactory,
private PushOneCommit(
ChangeNotes.Factory notesFactory,
ApprovalsUtil approvalsUtil,
Provider<InternalChangeQuery> queryProvider,
ReviewDb db,
@ -214,7 +254,8 @@ public class PushOneCommit {
TestRepository<?> testRepo,
String subject,
Map<String, String> files,
String changeId) throws Exception {
String changeId)
throws Exception {
this.db = db;
this.testRepo = testRepo;
this.notesFactory = notesFactory;
@ -224,14 +265,11 @@ public class PushOneCommit {
this.files = files;
this.changeId = changeId;
if (changeId != null) {
commitBuilder = testRepo.amendRef("HEAD")
.insertChangeId(changeId.substring(1));
commitBuilder = testRepo.amendRef("HEAD").insertChangeId(changeId.substring(1));
} else {
commitBuilder = testRepo.branch("HEAD").commit().insertChangeId();
}
commitBuilder.message(subject)
.author(i)
.committer(new PersonIdent(i, testRepo.getDate()));
commitBuilder.message(subject).author(i).committer(new PersonIdent(i, testRepo.getDate()));
}
public void setParents(List<RevCommit> parents) throws Exception {
@ -268,17 +306,17 @@ public class PushOneCommit {
if (tag != null) {
TagCommand tagCommand = testRepo.git().tag().setName(tag.name);
if (tag instanceof AnnotatedTag) {
AnnotatedTag annotatedTag = (AnnotatedTag)tag;
tagCommand.setAnnotated(true)
.setMessage(annotatedTag.message)
.setTagger(annotatedTag.tagger);
AnnotatedTag annotatedTag = (AnnotatedTag) tag;
tagCommand
.setAnnotated(true)
.setMessage(annotatedTag.message)
.setTagger(annotatedTag.tagger);
} else {
tagCommand.setAnnotated(false);
}
tagCommand.call();
}
return new Result(ref,
pushHead(testRepo, ref, tag != null, force, pushOptions), c, subject);
return new Result(ref, pushHead(testRepo, ref, tag != null, force, pushOptions), c, subject);
}
public void setTag(final Tag tag) {
@ -307,8 +345,7 @@ public class PushOneCommit {
private final RevCommit commit;
private final String resSubj;
private Result(String ref, PushResult resSubj, RevCommit commit,
String subject) {
private Result(String ref, PushResult resSubj, RevCommit commit, String subject) {
this.ref = ref;
this.result = resSubj;
this.commit = commit;
@ -316,8 +353,7 @@ public class PushOneCommit {
}
public ChangeData getChange() throws OrmException {
return Iterables.getOnlyElement(
queryProvider.get().byKeyPrefix(changeId));
return Iterables.getOnlyElement(queryProvider.get().byKeyPrefix(changeId));
}
public PatchSet getPatchSet() throws OrmException {
@ -340,8 +376,8 @@ public class PushOneCommit {
assertEquals(pushOptions, getPushOptions());
}
public void assertChange(Change.Status expectedStatus,
String expectedTopic, TestAccount... expectedReviewers)
public void assertChange(
Change.Status expectedStatus, String expectedTopic, TestAccount... expectedReviewers)
throws OrmException {
Change c = getChange().change();
assertThat(c.getSubject()).isEqualTo(resSubj);
@ -350,13 +386,11 @@ public class PushOneCommit {
assertReviewers(c, expectedReviewers);
}
private void assertReviewers(Change c, TestAccount... expectedReviewers)
throws OrmException {
Iterable<Account.Id> actualIds = approvalsUtil
.getReviewers(db, notesFactory.createChecked(db, c))
.all();
assertThat(actualIds).containsExactlyElementsIn(
Sets.newHashSet(TestAccount.ids(expectedReviewers)));
private void assertReviewers(Change c, TestAccount... expectedReviewers) throws OrmException {
Iterable<Account.Id> actualIds =
approvalsUtil.getReviewers(db, notesFactory.createChecked(db, c)).all();
assertThat(actualIds)
.containsExactlyElementsIn(Sets.newHashSet(TestAccount.ids(expectedReviewers)));
}
public void assertOkStatus() {
@ -370,22 +404,19 @@ public class PushOneCommit {
public void assertErrorStatus() {
RemoteRefUpdate refUpdate = result.getRemoteUpdate(ref);
assertThat(refUpdate.getStatus())
.named(message(refUpdate))
.isEqualTo(Status.REJECTED_OTHER_REASON);
.named(message(refUpdate))
.isEqualTo(Status.REJECTED_OTHER_REASON);
}
private void assertStatus(Status expectedStatus, String expectedMessage) {
RemoteRefUpdate refUpdate = result.getRemoteUpdate(ref);
assertThat(refUpdate.getStatus())
.named(message(refUpdate))
.isEqualTo(expectedStatus);
assertThat(refUpdate.getStatus()).named(message(refUpdate)).isEqualTo(expectedStatus);
assertThat(refUpdate.getMessage()).isEqualTo(expectedMessage);
}
public void assertMessage(String expectedMessage) {
RemoteRefUpdate refUpdate = result.getRemoteUpdate(ref);
assertThat(message(refUpdate).toLowerCase())
.contains(expectedMessage.toLowerCase());
assertThat(message(refUpdate).toLowerCase()).contains(expectedMessage.toLowerCase());
}
public String getMessage() {

View File

@ -22,7 +22,6 @@ import com.google.gerrit.server.query.DataSource;
import com.google.gerrit.server.query.Predicate;
import com.google.gerrit.server.query.QueryParseException;
import com.google.gerrit.server.query.change.ChangeData;
import java.io.IOException;
public class ReadOnlyChangeIndex implements ChangeIndex {
@ -62,8 +61,8 @@ public class ReadOnlyChangeIndex implements ChangeIndex {
}
@Override
public DataSource<ChangeData> getSource(Predicate<ChangeData> p,
QueryOptions opts) throws QueryParseException {
public DataSource<ChangeData> getSource(Predicate<ChangeData> p, QueryOptions opts)
throws QueryParseException {
return index.getSource(p, opts);
}

View File

@ -18,11 +18,10 @@ import static com.google.common.truth.Truth.assert_;
import static com.google.gerrit.httpd.restapi.RestApiServlet.JSON_MAGIC;
import static java.nio.charset.StandardCharsets.UTF_8;
import org.apache.http.HttpStatus;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import org.apache.http.HttpStatus;
public class RestResponse extends HttpResponse {
@ -33,8 +32,7 @@ public class RestResponse extends HttpResponse {
@Override
public Reader getReader() throws IllegalStateException, IOException {
if (reader == null && response.getEntity() != null) {
reader = new InputStreamReader(
response.getEntity().getContent(), UTF_8);
reader = new InputStreamReader(response.getEntity().getContent(), UTF_8);
reader.skip(JSON_MAGIC.length);
}
return reader;

View File

@ -21,7 +21,7 @@ import com.google.common.net.HttpHeaders;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.restapi.RawInput;
import com.google.gerrit.server.OutputFormat;
import java.io.IOException;
import org.apache.http.Header;
import org.apache.http.HttpStatus;
import org.apache.http.client.fluent.Request;
@ -30,21 +30,17 @@ import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import java.io.IOException;
public class RestSession extends HttpSession {
public RestSession(GerritServer server, @Nullable TestAccount account) {
super(server, account);
}
public RestResponse getOK(String endPoint)
throws Exception {
public RestResponse getOK(String endPoint) throws Exception {
return get(endPoint, HttpStatus.SC_OK);
}
public RestResponse get(String endPoint, int expectedStatus)
throws Exception {
public RestResponse get(String endPoint, int expectedStatus) throws Exception {
RestResponse r = get(endPoint);
r.assertStatus(expectedStatus);
return r;
@ -55,12 +51,10 @@ public class RestSession extends HttpSession {
}
public RestResponse getJsonAccept(String endPoint) throws IOException {
return getWithHeader(endPoint,
new BasicHeader(HttpHeaders.ACCEPT, "application/json"));
return getWithHeader(endPoint, new BasicHeader(HttpHeaders.ACCEPT, "application/json"));
}
public RestResponse getWithHeader(String endPoint, Header header)
throws IOException {
public RestResponse getWithHeader(String endPoint, Header header) throws IOException {
Request get = Request.Get(getUrl(endPoint));
if (header != null) {
get.addHeader(header);
@ -80,22 +74,19 @@ public class RestSession extends HttpSession {
return putWithHeader(endPoint, null, content);
}
public RestResponse putWithHeader(String endPoint, Header header)
throws IOException {
public RestResponse putWithHeader(String endPoint, Header header) throws IOException {
return putWithHeader(endPoint, header, null);
}
public RestResponse putWithHeader(String endPoint, Header header,
Object content) throws IOException {
public RestResponse putWithHeader(String endPoint, Header header, Object content)
throws IOException {
Request put = Request.Put(getUrl(endPoint));
if (header != null) {
put.addHeader(header);
}
if (content != null) {
put.addHeader(new BasicHeader("Content-Type", "application/json"));
put.body(new StringEntity(
OutputFormat.JSON_COMPACT.newGson().toJson(content),
UTF_8));
put.body(new StringEntity(OutputFormat.JSON_COMPACT.newGson().toJson(content), UTF_8));
}
return execute(put);
}
@ -104,10 +95,9 @@ public class RestSession extends HttpSession {
Preconditions.checkNotNull(stream);
Request put = Request.Put(getUrl(endPoint));
put.addHeader(new BasicHeader("Content-Type", stream.getContentType()));
put.body(new BufferedHttpEntity(
new InputStreamEntity(
stream.getInputStream(),
stream.getContentLength())));
put.body(
new BufferedHttpEntity(
new InputStreamEntity(stream.getInputStream(), stream.getContentLength())));
return execute(put);
}
@ -115,13 +105,11 @@ public class RestSession extends HttpSession {
return post(endPoint, null);
}
public RestResponse postOK(String endPoint, Object content)
throws Exception {
public RestResponse postOK(String endPoint, Object content) throws Exception {
return post(endPoint, content, HttpStatus.SC_OK);
}
public RestResponse post(String endPoint, Object content, int expectedStatus)
throws Exception {
public RestResponse post(String endPoint, Object content, int expectedStatus) throws Exception {
RestResponse r = post(endPoint, content);
r.assertStatus(expectedStatus);
return r;
@ -131,17 +119,15 @@ public class RestSession extends HttpSession {
return postWithHeader(endPoint, content, null);
}
public RestResponse postWithHeader(String endPoint, Object content,
Header header) throws IOException {
public RestResponse postWithHeader(String endPoint, Object content, Header header)
throws IOException {
Request post = Request.Post(getUrl(endPoint));
if (header != null) {
post.addHeader(header);
}
if (content != null) {
post.addHeader(new BasicHeader("Content-Type", "application/json"));
post.body(new StringEntity(
OutputFormat.JSON_COMPACT.newGson().toJson(content),
UTF_8));
post.body(new StringEntity(OutputFormat.JSON_COMPACT.newGson().toJson(content), UTF_8));
}
return execute(post);
}

View File

@ -23,5 +23,4 @@ import java.lang.annotation.Target;
@Target({TYPE, METHOD})
@Retention(RUNTIME)
public @interface Sandboxed {
}
public @interface Sandboxed {}

View File

@ -20,7 +20,6 @@ import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
@ -42,8 +41,7 @@ public class SshSession {
}
@SuppressWarnings("resource")
public String exec(String command, InputStream opt) throws JSchException,
IOException {
public String exec(String command, InputStream opt) throws JSchException, IOException {
ChannelExec channel = (ChannelExec) getSession().openChannel("exec");
try {
channel.setCommand(command);
@ -62,8 +60,7 @@ public class SshSession {
}
}
public InputStream exec2(String command, InputStream opt) throws JSchException,
IOException {
public InputStream exec2(String command, InputStream opt) throws JSchException, IOException {
ChannelExec channel = (ChannelExec) getSession().openChannel("exec");
channel.setCommand(command);
channel.setInputStream(opt);
@ -94,12 +91,9 @@ public class SshSession {
private Session getSession() throws JSchException {
if (session == null) {
JSch jsch = new JSch();
jsch.addIdentity("KeyPair",
account.privateKey(), account.sshKey.getPublicKeyBlob(), null);
session = jsch.getSession(
account.username,
addr.getAddress().getHostAddress(),
addr.getPort());
jsch.addIdentity("KeyPair", account.privateKey(), account.sshKey.getPublicKeyBlob(), null);
session =
jsch.getSession(account.username, addr.getAddress().getHostAddress(), addr.getPort());
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
}

View File

@ -18,14 +18,11 @@ import static java.util.stream.Collectors.toList;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.server.mail.Address;
import com.jcraft.jsch.KeyPair;
import org.eclipse.jgit.lib.PersonIdent;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
import java.util.List;
import org.eclipse.jgit.lib.PersonIdent;
public class TestAccount {
public static List<Account.Id> ids(List<TestAccount> accounts) {
@ -53,8 +50,13 @@ public class TestAccount {
public final String httpPassword;
public String status;
TestAccount(Account.Id id, String username, String email, String fullName,
KeyPair sshKey, String httpPassword) {
TestAccount(
Account.Id id,
String username,
String email,
String fullName,
KeyPair sshKey,
String httpPassword) {
this.id = id;
this.username = username;
this.email = email;
@ -75,7 +77,8 @@ public class TestAccount {
}
public String getHttpUrl(GerritServer server) {
return String.format("http://%s:%s@%s:%d",
return String.format(
"http://%s:%s@%s:%d",
username,
httpPassword,
server.getHttpAddress().getAddress().getHostAddress(),

View File

@ -26,6 +26,8 @@ public @interface TestPlugin {
String name();
String sysModule() default "";
String httpModule() default "";
String sshModule() default "";
}

View File

@ -19,7 +19,6 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
import com.google.gerrit.extensions.client.InheritableBoolean;
import com.google.gerrit.extensions.client.SubmitType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@ -29,18 +28,22 @@ public @interface TestProjectInput {
// Fields from ProjectInput for creating the project.
String parent() default "";
boolean createEmptyCommit() default true;
String description() default "";
// These may be null in a ProjectInput, but annotations do not allow null
// default values. Thus these defaults should match ProjectConfig.
SubmitType submitType() default SubmitType.MERGE_IF_NECESSARY;
InheritableBoolean useContributorAgreements()
default InheritableBoolean.INHERIT;
InheritableBoolean useSignedOffBy() default InheritableBoolean.INHERIT;
InheritableBoolean useContentMerge() default InheritableBoolean.INHERIT;
InheritableBoolean requireChangeId() default InheritableBoolean.INHERIT;
InheritableBoolean useContributorAgreements() default InheritableBoolean.INHERIT;
InheritableBoolean useSignedOffBy() default InheritableBoolean.INHERIT;
InheritableBoolean useContentMerge() default InheritableBoolean.INHERIT;
InheritableBoolean requireChangeId() default InheritableBoolean.INHERIT;
// Fields specific to acceptance test behavior.

View File

@ -22,5 +22,4 @@ import java.lang.annotation.Target;
@Target({METHOD})
@Retention(RUNTIME)
public @interface UseLocalDisk {
}
public @interface UseLocalDisk {}

View File

@ -23,5 +23,4 @@ import java.lang.annotation.Target;
@Target({TYPE, METHOD})
@Retention(RUNTIME)
public @interface UseSsh {
}
public @interface UseSsh {}

View File

@ -18,15 +18,12 @@ import static com.google.common.truth.Truth.assertThat;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.inject.Inject;
import org.eclipse.jgit.lib.Config;
import org.junit.Test;
public class UseGerritConfigAnnotationTest extends AbstractDaemonTest {
@Inject
@GerritServerConfig
Config serverConfig;
@Inject @GerritServerConfig Config serverConfig;
@Test
@GerritConfig(name = "x.y", value = "z")

View File

@ -71,7 +71,15 @@ import com.google.gerrit.testutil.ConfigSuite;
import com.google.gerrit.testutil.FakeEmailSender.Message;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
@ -88,16 +96,6 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class AccountIT extends AbstractDaemonTest {
@ConfigSuite.Default
public static Config enableSignedPushConfig() {
@ -106,11 +104,9 @@ public class AccountIT extends AbstractDaemonTest {
return cfg;
}
@Inject
private Provider<PublicKeyStore> publicKeyStoreProvider;
@Inject private Provider<PublicKeyStore> publicKeyStoreProvider;
@Inject
private AllUsersName allUsers;
@Inject private AllUsersName allUsers;
private List<AccountExternalId> savedExternalIds;
@ -147,8 +143,7 @@ public class AccountIT extends AbstractDaemonTest {
}
}
private Collection<AccountExternalId> getExternalIds(TestAccount account)
throws Exception {
private Collection<AccountExternalId> getExternalIds(TestAccount account) throws Exception {
return accountCache.get(account.getId()).getExternalIds();
}
@ -159,18 +154,17 @@ public class AccountIT extends AbstractDaemonTest {
if (repo.getRefDatabase().exactRef(ref) != null) {
RefUpdate ru = repo.updateRef(ref);
ru.setForceUpdate(true);
assert_().withFailureMessage("Failed to delete " + ref)
.that(ru.delete()).isEqualTo(RefUpdate.Result.FORCED);
assert_()
.withFailureMessage("Failed to delete " + ref)
.that(ru.delete())
.isEqualTo(RefUpdate.Result.FORCED);
}
}
}
@Test
public void get() throws Exception {
AccountInfo info = gApi
.accounts()
.id("admin")
.get();
AccountInfo info = gApi.accounts().id("admin").get();
assertThat(info.name).isEqualTo("Administrator");
assertThat(info.email).isEqualTo("admin@example.com");
assertThat(info.username).isEqualTo("admin");
@ -178,29 +172,17 @@ public class AccountIT extends AbstractDaemonTest {
@Test
public void getByIntId() throws Exception {
AccountInfo info = gApi
.accounts()
.id("admin")
.get();
AccountInfo infoByIntId = gApi
.accounts()
.id(info._accountId)
.get();
AccountInfo info = gApi.accounts().id("admin").get();
AccountInfo infoByIntId = gApi.accounts().id(info._accountId).get();
assertThat(info.name).isEqualTo(infoByIntId.name);
}
@Test
public void self() throws Exception {
AccountInfo info = gApi
.accounts()
.self()
.get();
AccountInfo info = gApi.accounts().self().get();
assertUser(info, admin);
info = gApi
.accounts()
.id("self")
.get();
info = gApi.accounts().id("self").get();
assertUser(info, admin);
}
@ -238,16 +220,12 @@ public class AccountIT extends AbstractDaemonTest {
public void starUnstarChange() throws Exception {
PushOneCommit.Result r = createChange();
String triplet = project.get() + "~master~" + r.getChangeId();
gApi.accounts()
.self()
.starChange(triplet);
gApi.accounts().self().starChange(triplet);
ChangeInfo change = info(triplet);
assertThat(change.starred).isTrue();
assertThat(change.stars).contains(DEFAULT_LABEL);
gApi.accounts()
.self()
.unstarChange(triplet);
gApi.accounts().self().unstarChange(triplet);
change = info(triplet);
assertThat(change.starred).isNull();
assertThat(change.stars).isNull();
@ -260,31 +238,31 @@ public class AccountIT extends AbstractDaemonTest {
assertThat(gApi.accounts().self().getStars(triplet)).isEmpty();
assertThat(gApi.accounts().self().getStarredChanges()).isEmpty();
gApi.accounts().self().setStars(triplet,
new StarsInput(ImmutableSet.of(DEFAULT_LABEL, "red", "blue")));
gApi.accounts()
.self()
.setStars(triplet, new StarsInput(ImmutableSet.of(DEFAULT_LABEL, "red", "blue")));
ChangeInfo change = info(triplet);
assertThat(change.starred).isTrue();
assertThat(change.stars)
.containsExactly("blue", "red", DEFAULT_LABEL).inOrder();
assertThat(change.stars).containsExactly("blue", "red", DEFAULT_LABEL).inOrder();
assertThat(gApi.accounts().self().getStars(triplet))
.containsExactly("blue", "red", DEFAULT_LABEL).inOrder();
List<ChangeInfo> starredChanges =
gApi.accounts().self().getStarredChanges();
.containsExactly("blue", "red", DEFAULT_LABEL)
.inOrder();
List<ChangeInfo> starredChanges = gApi.accounts().self().getStarredChanges();
assertThat(starredChanges).hasSize(1);
ChangeInfo starredChange = starredChanges.get(0);
assertThat(starredChange._number).isEqualTo(r.getChange().getId().get());
assertThat(starredChange.starred).isTrue();
assertThat(starredChange.stars)
.containsExactly("blue", "red", DEFAULT_LABEL).inOrder();
assertThat(starredChange.stars).containsExactly("blue", "red", DEFAULT_LABEL).inOrder();
gApi.accounts().self().setStars(triplet,
new StarsInput(ImmutableSet.of("yellow"),
ImmutableSet.of(DEFAULT_LABEL, "blue")));
gApi.accounts()
.self()
.setStars(
triplet,
new StarsInput(ImmutableSet.of("yellow"), ImmutableSet.of(DEFAULT_LABEL, "blue")));
change = info(triplet);
assertThat(change.starred).isNull();
assertThat(change.stars).containsExactly("red", "yellow").inOrder();
assertThat(gApi.accounts().self().getStars(triplet)).containsExactly(
"red", "yellow").inOrder();
assertThat(gApi.accounts().self().getStars(triplet)).containsExactly("red", "yellow").inOrder();
starredChanges = gApi.accounts().self().getStarredChanges();
assertThat(starredChanges).hasSize(1);
starredChange = starredChanges.get(0);
@ -303,11 +281,13 @@ public class AccountIT extends AbstractDaemonTest {
PushOneCommit.Result r = createChange();
String triplet = project.get() + "~master~" + r.getChangeId();
exception.expect(BadRequestException.class);
exception.expectMessage(
"invalid labels: another invalid label, invalid label");
gApi.accounts().self().setStars(triplet,
new StarsInput(ImmutableSet.of(DEFAULT_LABEL, "invalid label", "blue",
"another invalid label")));
exception.expectMessage("invalid labels: another invalid label, invalid label");
gApi.accounts()
.self()
.setStars(
triplet,
new StarsInput(
ImmutableSet.of(DEFAULT_LABEL, "invalid label", "blue", "another invalid label")));
}
@Test
@ -315,11 +295,16 @@ public class AccountIT extends AbstractDaemonTest {
PushOneCommit.Result r = createChange();
String triplet = project.get() + "~master~" + r.getChangeId();
exception.expect(BadRequestException.class);
exception.expectMessage("The labels " + DEFAULT_LABEL
+ " and " + IGNORE_LABEL + " are mutually exclusive."
+ " Only one of them can be set.");
gApi.accounts().self().setStars(triplet,
new StarsInput(ImmutableSet.of(DEFAULT_LABEL, "blue", IGNORE_LABEL)));
exception.expectMessage(
"The labels "
+ DEFAULT_LABEL
+ " and "
+ IGNORE_LABEL
+ " are mutually exclusive."
+ " Only one of them can be set.");
gApi.accounts()
.self()
.setStars(triplet, new StarsInput(ImmutableSet.of(DEFAULT_LABEL, "blue", IGNORE_LABEL)));
}
@Test
@ -328,26 +313,19 @@ public class AccountIT extends AbstractDaemonTest {
AddReviewerInput in = new AddReviewerInput();
in.reviewer = user.email;
gApi.changes()
.id(r.getChangeId())
.addReviewer(in);
gApi.changes().id(r.getChangeId()).addReviewer(in);
TestAccount user2 = accounts.user2();
in = new AddReviewerInput();
in.reviewer = user2.email;
gApi.changes()
.id(r.getChangeId())
.addReviewer(in);
gApi.changes().id(r.getChangeId()).addReviewer(in);
setApiUser(user);
gApi.accounts().self().setStars(r.getChangeId(),
new StarsInput(ImmutableSet.of(IGNORE_LABEL)));
gApi.accounts().self().setStars(r.getChangeId(), new StarsInput(ImmutableSet.of(IGNORE_LABEL)));
sender.clear();
setApiUser(admin);
gApi.changes()
.id(r.getChangeId())
.abandon();
gApi.changes().id(r.getChangeId()).abandon();
List<Message> messages = sender.getMessages();
assertThat(messages).hasSize(1);
assertThat(messages.get(0).rcpt()).containsExactly(user2.emailAddress);
@ -358,17 +336,14 @@ public class AccountIT extends AbstractDaemonTest {
PushOneCommit.Result r = createChange();
setApiUser(user);
gApi.accounts().self().setStars(r.getChangeId(),
new StarsInput(ImmutableSet.of(IGNORE_LABEL)));
gApi.accounts().self().setStars(r.getChangeId(), new StarsInput(ImmutableSet.of(IGNORE_LABEL)));
sender.clear();
setApiUser(admin);
AddReviewerInput in = new AddReviewerInput();
in.reviewer = user.email;
gApi.changes()
.id(r.getChangeId())
.addReviewer(in);
gApi.changes().id(r.getChangeId()).addReviewer(in);
List<Message> messages = sender.getMessages();
assertThat(messages).hasSize(1);
Message message = messages.get(0);
@ -379,28 +354,26 @@ public class AccountIT extends AbstractDaemonTest {
@Test
public void suggestAccounts() throws Exception {
String adminUsername = "admin";
List<AccountInfo> result = gApi.accounts()
.suggestAccounts().withQuery(adminUsername).get();
List<AccountInfo> result = gApi.accounts().suggestAccounts().withQuery(adminUsername).get();
assertThat(result).hasSize(1);
assertThat(result.get(0).username).isEqualTo(adminUsername);
List<AccountInfo> resultShortcutApi = gApi.accounts()
.suggestAccounts(adminUsername).get();
List<AccountInfo> resultShortcutApi = gApi.accounts().suggestAccounts(adminUsername).get();
assertThat(resultShortcutApi).hasSize(result.size());
List<AccountInfo> emptyResult = gApi.accounts()
.suggestAccounts("unknown").get();
List<AccountInfo> emptyResult = gApi.accounts().suggestAccounts("unknown").get();
assertThat(emptyResult).isEmpty();
}
@Test
public void addEmail() throws Exception {
List<String> emails = ImmutableList.of(
"new.email@example.com",
"new.email@example.systems",
List<String> emails =
ImmutableList.of(
"new.email@example.com",
"new.email@example.systems",
// Not in the list of TLDs but added to override in OutgoingEmailValidator
"new.email@example.local");
// Not in the list of TLDs but added to override in OutgoingEmailValidator
"new.email@example.local");
for (String email : emails) {
EmailInput input = new EmailInput();
input.email = email;
@ -411,8 +384,7 @@ public class AccountIT extends AbstractDaemonTest {
@Test
public void putStatus() throws Exception {
List<String> statuses = ImmutableList.of(
"OOO", "Busy");
List<String> statuses = ImmutableList.of("OOO", "Busy");
AccountInfo info;
for (String status : statuses) {
gApi.accounts().self().setStatus(status);
@ -424,21 +396,21 @@ public class AccountIT extends AbstractDaemonTest {
@Test
public void addInvalidEmail() throws Exception {
List<String> emails = ImmutableList.of(
// Missing domain part
"new.email",
List<String> emails =
ImmutableList.of(
// Missing domain part
"new.email",
// Missing domain part
"new.email@",
// Missing domain part
"new.email@",
// Missing user part
"@example.com",
// Missing user part
"@example.com",
// Non-supported TLD (see tlds-alpha-by-domain.txt)
"new.email@example.blog"
);
// Non-supported TLD (see tlds-alpha-by-domain.txt)
"new.email@example.blog");
for (String email : emails) {
EmailInput input = new EmailInput();
EmailInput input = new EmailInput();
input.email = email;
input.noConfirmation = true;
try {
@ -456,18 +428,15 @@ public class AccountIT extends AbstractDaemonTest {
// is created
setApiUser(user);
GeneralPreferencesInfo input = new GeneralPreferencesInfo();
input.changesPerPage =
GeneralPreferencesInfo.defaults().changesPerPage + 10;
input.changesPerPage = GeneralPreferencesInfo.defaults().changesPerPage + 10;
gApi.accounts().self().setPreferences(input);
TestRepository<InMemoryRepository> allUsersRepo =
cloneProject(allUsers, user);
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers, user);
String userRefName = RefNames.refsUsers(user.id);
// remove default READ permissions
ProjectConfig cfg = projectCache.checkedGet(allUsers).getConfig();
cfg.getAccessSection(
RefNames.REFS_USERS + "${" + RefPattern.USERID_SHARDED + "}", true)
cfg.getAccessSection(RefNames.REFS_USERS + "${" + RefPattern.USERID_SHARDED + "}", true)
.remove(new Permission(Permission.READ));
saveProjectConfig(allUsers, cfg);
@ -477,15 +446,17 @@ public class AccountIT extends AbstractDaemonTest {
// fetching user branch without READ permission fails
try {
fetch(allUsersRepo, userRefName + ":userRef");
Assert.fail(
"user branch is visible although no READ permission is granted");
Assert.fail("user branch is visible although no READ permission is granted");
} catch (TransportException e) {
// expected because no READ granted on user branch
}
// allow each user to read its own user branch
grant(Permission.READ, allUsers,
RefNames.REFS_USERS + "${" + RefPattern.USERID_SHARDED + "}", false,
grant(
Permission.READ,
allUsers,
RefNames.REFS_USERS + "${" + RefPattern.USERID_SHARDED + "}",
false,
REGISTERED_USERS);
// fetch user branch using refs/users/YY/XXXXXXX
@ -495,16 +466,14 @@ public class AccountIT extends AbstractDaemonTest {
// fetch user branch using refs/users/self
fetch(allUsersRepo, RefNames.REFS_USERS_SELF + ":userSelfRef");
Ref userSelfRef =
allUsersRepo.getRepository().getRefDatabase().exactRef("userSelfRef");
Ref userSelfRef = allUsersRepo.getRepository().getRefDatabase().exactRef("userSelfRef");
assertThat(userSelfRef).isNotNull();
assertThat(userSelfRef.getObjectId()).isEqualTo(userRef.getObjectId());
// fetching user branch of another user fails
String otherUserRefName = RefNames.refsUsers(admin.id);
exception.expect(TransportException.class);
exception.expectMessage(
"Remote does not have " + otherUserRefName + " available for fetch.");
exception.expectMessage("Remote does not have " + otherUserRefName + " available for fetch.");
fetch(allUsersRepo, otherUserRefName + ":otherUserRef");
}
@ -513,8 +482,7 @@ public class AccountIT extends AbstractDaemonTest {
// change something in the user preferences to ensure that the user branch
// is created
GeneralPreferencesInfo input = new GeneralPreferencesInfo();
input.changesPerPage =
GeneralPreferencesInfo.defaults().changesPerPage + 10;
input.changesPerPage = GeneralPreferencesInfo.defaults().changesPerPage + 10;
gApi.accounts().self().setPreferences(input);
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
@ -532,8 +500,7 @@ public class AccountIT extends AbstractDaemonTest {
// change something in the user preferences to ensure that the user branch
// is created
GeneralPreferencesInfo input = new GeneralPreferencesInfo();
input.changesPerPage =
GeneralPreferencesInfo.defaults().changesPerPage + 10;
input.changesPerPage = GeneralPreferencesInfo.defaults().changesPerPage + 10;
gApi.accounts().self().setPreferences(input);
String userRefName = RefNames.refsUsers(admin.id);
@ -560,8 +527,7 @@ public class AccountIT extends AbstractDaemonTest {
// change something in the user preferences to ensure that the user branch
// is created
GeneralPreferencesInfo input = new GeneralPreferencesInfo();
input.changesPerPage =
GeneralPreferencesInfo.defaults().changesPerPage + 10;
input.changesPerPage = GeneralPreferencesInfo.defaults().changesPerPage + 10;
gApi.accounts().self().setPreferences(input);
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
@ -569,24 +535,37 @@ public class AccountIT extends AbstractDaemonTest {
allUsersRepo.reset("userRef");
Config wc = new Config();
wc.setString(WatchConfig.PROJECT, project.get(), WatchConfig.KEY_NOTIFY,
WatchConfig.NotifyValue
.create(null, EnumSet.of(NotifyType.ALL_COMMENTS)).toString());
PushOneCommit push = pushFactory.create(db, admin.getIdent(), allUsersRepo,
"Add project watch", WatchConfig.WATCH_CONFIG, wc.toText());
wc.setString(
WatchConfig.PROJECT,
project.get(),
WatchConfig.KEY_NOTIFY,
WatchConfig.NotifyValue.create(null, EnumSet.of(NotifyType.ALL_COMMENTS)).toString());
PushOneCommit push =
pushFactory.create(
db,
admin.getIdent(),
allUsersRepo,
"Add project watch",
WatchConfig.WATCH_CONFIG,
wc.toText());
push.to(RefNames.REFS_USERS_SELF).assertOkStatus();
String invalidNotifyValue = "]invalid[";
wc.setString(WatchConfig.PROJECT, project.get(), WatchConfig.KEY_NOTIFY,
invalidNotifyValue);
push = pushFactory.create(db, admin.getIdent(), allUsersRepo,
"Add invalid project watch", WatchConfig.WATCH_CONFIG, wc.toText());
wc.setString(WatchConfig.PROJECT, project.get(), WatchConfig.KEY_NOTIFY, invalidNotifyValue);
push =
pushFactory.create(
db,
admin.getIdent(),
allUsersRepo,
"Add invalid project watch",
WatchConfig.WATCH_CONFIG,
wc.toText());
PushOneCommit.Result r = push.to(RefNames.REFS_USERS_SELF);
r.assertErrorStatus("invalid watch configuration");
r.assertMessage(String.format(
"%s: Invalid project watch of account %d for project %s: %s",
WatchConfig.WATCH_CONFIG, admin.getId().get(), project.get(),
invalidNotifyValue));
r.assertMessage(
String.format(
"%s: Invalid project watch of account %d for project %s: %s",
WatchConfig.WATCH_CONFIG, admin.getId().get(), project.get(), invalidNotifyValue));
}
@Test
@ -625,8 +604,8 @@ public class AccountIT extends AbstractDaemonTest {
public void addOtherUsersGpgKey_Conflict() throws Exception {
// Both users have a matching external ID for this key.
addExternalIdEmail(admin, "test5@example.com");
AccountExternalId extId = new AccountExternalId(
user.getId(), new AccountExternalId.Key("foo:myId"));
AccountExternalId extId =
new AccountExternalId(user.getId(), new AccountExternalId.Key("foo:myId"));
db.accountExternalIds().insert(Collections.singleton(extId));
accountCache.evict(user.getId());
@ -645,11 +624,10 @@ public class AccountIT extends AbstractDaemonTest {
List<TestKey> keys = allValidKeys();
List<String> toAdd = new ArrayList<>(keys.size());
for (TestKey key : keys) {
addExternalIdEmail(admin,
PushCertificateIdent.parse(key.getFirstUserId()).getEmailAddress());
addExternalIdEmail(admin, PushCertificateIdent.parse(key.getFirstUserId()).getEmailAddress());
toAdd.add(key.getPublicKeyArmored());
}
gApi.accounts().self().putGpgKeys(toAdd, ImmutableList.<String> of());
gApi.accounts().self().putGpgKeys(toAdd, ImmutableList.<String>of());
assertKeys(keys);
}
@ -672,37 +650,40 @@ public class AccountIT extends AbstractDaemonTest {
@Test
public void addAndRemoveGpgKeys() throws Exception {
for (TestKey key : allValidKeys()) {
addExternalIdEmail(admin,
PushCertificateIdent.parse(key.getFirstUserId()).getEmailAddress());
addExternalIdEmail(admin, PushCertificateIdent.parse(key.getFirstUserId()).getEmailAddress());
}
TestKey key1 = validKeyWithoutExpiration();
TestKey key2 = validKeyWithExpiration();
TestKey key5 = validKeyWithSecondUserId();
Map<String, GpgKeyInfo> infos = gApi.accounts().self().putGpgKeys(
ImmutableList.of(
key1.getPublicKeyArmored(),
key2.getPublicKeyArmored()),
ImmutableList.of(key5.getKeyIdString()));
assertThat(infos.keySet())
.containsExactly(key1.getKeyIdString(), key2.getKeyIdString());
Map<String, GpgKeyInfo> infos =
gApi.accounts()
.self()
.putGpgKeys(
ImmutableList.of(key1.getPublicKeyArmored(), key2.getPublicKeyArmored()),
ImmutableList.of(key5.getKeyIdString()));
assertThat(infos.keySet()).containsExactly(key1.getKeyIdString(), key2.getKeyIdString());
assertKeys(key1, key2);
infos = gApi.accounts().self().putGpgKeys(
ImmutableList.of(key5.getPublicKeyArmored()),
ImmutableList.of(key1.getKeyIdString()));
assertThat(infos.keySet())
.containsExactly(key1.getKeyIdString(), key5.getKeyIdString());
infos =
gApi.accounts()
.self()
.putGpgKeys(
ImmutableList.of(key5.getPublicKeyArmored()),
ImmutableList.of(key1.getKeyIdString()));
assertThat(infos.keySet()).containsExactly(key1.getKeyIdString(), key5.getKeyIdString());
assertKeyMapContains(key5, infos);
assertThat(infos.get(key1.getKeyIdString()).key).isNull();
assertKeys(key2, key5);
exception.expect(BadRequestException.class);
exception.expectMessage("Cannot both add and delete key: "
+ keyToString(key2.getPublicKey()));
infos = gApi.accounts().self().putGpgKeys(
ImmutableList.of(key2.getPublicKeyArmored()),
ImmutableList.of(key2.getKeyIdString()));
exception.expectMessage("Cannot both add and delete key: " + keyToString(key2.getPublicKey()));
infos =
gApi.accounts()
.self()
.putGpgKeys(
ImmutableList.of(key2.getPublicKeyArmored()),
ImmutableList.of(key2.getKeyIdString()));
}
@Test
@ -718,8 +699,7 @@ public class AccountIT extends AbstractDaemonTest {
assertThat(key.sshPublicKey).isEqualTo(inital);
// Add a new key
String newKey = AccountCreator.publicKey(
AccountCreator.genSshKey(), admin.email);
String newKey = AccountCreator.publicKey(AccountCreator.genSshKey(), admin.email);
gApi.accounts().self().addSshKey(newKey);
info = gApi.accounts().self().listSshKeys();
assertThat(info).hasSize(2);
@ -732,8 +712,7 @@ public class AccountIT extends AbstractDaemonTest {
assertSequenceNumbers(info);
// Add another new key
String newKey2 = AccountCreator.publicKey(
AccountCreator.genSshKey(), admin.email);
String newKey2 = AccountCreator.publicKey(AccountCreator.genSshKey(), admin.email);
gApi.accounts().self().addSshKey(newKey2);
info = gApi.accounts().self().listSshKeys();
assertThat(info).hasSize(3);
@ -792,8 +771,7 @@ public class AccountIT extends AbstractDaemonTest {
assertThat(ImmutableList.copyOf(it)).hasSize(size);
}
private static void assertKeyMapContains(TestKey expected,
Map<String, GpgKeyInfo> actualMap) {
private static void assertKeyMapContains(TestKey expected, Map<String, GpgKeyInfo> actualMap) {
GpgKeyInfo actual = actualMap.get(expected.getKeyIdString());
assertThat(actual).isNotNull();
assertThat(actual.id).isNull();
@ -814,22 +792,23 @@ public class AccountIT extends AbstractDaemonTest {
.containsExactlyElementsIn(expected.transform(TestKey::getKeyIdString));
for (TestKey key : expected) {
assertKeyEquals(key, gApi.accounts().self().gpgKey(
key.getKeyIdString()).get());
assertKeyEquals(key, gApi.accounts().self().gpgKey(
Fingerprint.toString(key.getPublicKey().getFingerprint())).get());
assertKeyEquals(key, gApi.accounts().self().gpgKey(key.getKeyIdString()).get());
assertKeyEquals(
key,
gApi.accounts()
.self()
.gpgKey(Fingerprint.toString(key.getPublicKey().getFingerprint()))
.get());
assertKeyMapContains(key, keyMap);
}
// Check raw external IDs.
Account.Id currAccountId = atrScope.get().getUser().getAccountId();
Iterable<String> expectedFps = expected.transform(
k -> BaseEncoding.base16().encode(k.getPublicKey().getFingerprint()));
Iterable<String> actualFps = GpgKeys.getGpgExtIds(db, currAccountId)
.transform(AccountExternalId::getSchemeRest);
assertThat(actualFps)
.named("external IDs in database")
.containsExactlyElementsIn(expectedFps);
Iterable<String> expectedFps =
expected.transform(k -> BaseEncoding.base16().encode(k.getPublicKey().getFingerprint()));
Iterable<String> actualFps =
GpgKeys.getGpgExtIds(db, currAccountId).transform(AccountExternalId::getSchemeRest);
assertThat(actualFps).named("external IDs in database").containsExactlyElementsIn(expectedFps);
// Check raw stored keys.
for (TestKey key : expected) {
@ -840,23 +819,21 @@ public class AccountIT extends AbstractDaemonTest {
private static void assertKeyEquals(TestKey expected, GpgKeyInfo actual) {
String id = expected.getKeyIdString();
assertThat(actual.id).named(id).isEqualTo(id);
assertThat(actual.fingerprint).named(id).isEqualTo(
Fingerprint.toString(expected.getPublicKey().getFingerprint()));
assertThat(actual.fingerprint)
.named(id)
.isEqualTo(Fingerprint.toString(expected.getPublicKey().getFingerprint()));
@SuppressWarnings("unchecked")
List<String> userIds =
ImmutableList.copyOf(expected.getPublicKey().getUserIDs());
List<String> userIds = ImmutableList.copyOf(expected.getPublicKey().getUserIDs());
assertThat(actual.userIds).named(id).containsExactlyElementsIn(userIds);
assertThat(actual.key).named(id)
.startsWith("-----BEGIN PGP PUBLIC KEY BLOCK-----\n");
assertThat(actual.key).named(id).startsWith("-----BEGIN PGP PUBLIC KEY BLOCK-----\n");
assertThat(actual.status).isEqualTo(GpgKeyInfo.Status.TRUSTED);
assertThat(actual.problems).isEmpty();
}
private void addExternalIdEmail(TestAccount account, String email)
throws Exception {
private void addExternalIdEmail(TestAccount account, String email) throws Exception {
checkNotNull(email);
AccountExternalId extId = new AccountExternalId(
account.getId(), new AccountExternalId.Key(name("test"), email));
AccountExternalId extId =
new AccountExternalId(account.getId(), new AccountExternalId.Key(name("test"), email));
extId.setEmailAddress(email);
db.accountExternalIds().insert(Collections.singleton(extId));
// Clear saved AccountState and AccountExternalIds.
@ -865,13 +842,10 @@ public class AccountIT extends AbstractDaemonTest {
}
private Map<String, GpgKeyInfo> addGpgKey(String armored) throws Exception {
return gApi.accounts().self().putGpgKeys(
ImmutableList.of(armored),
ImmutableList.<String> of());
return gApi.accounts().self().putGpgKeys(ImmutableList.of(armored), ImmutableList.<String>of());
}
private void assertUser(AccountInfo info, TestAccount account)
throws Exception {
private void assertUser(AccountInfo info, TestAccount account) throws Exception {
assertThat(info.name).isEqualTo(account.fullName);
assertThat(info.email).isEqualTo(account.email);
assertThat(info.username).isEqualTo(account.username);

View File

@ -37,15 +37,13 @@ import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.testutil.ConfigSuite;
import com.google.gerrit.testutil.TestTimeUtil;
import java.util.List;
import org.eclipse.jgit.lib.Config;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.List;
public class AgreementsIT extends AbstractDaemonTest {
private ContributorAgreement caAutoVerify;
private ContributorAgreement caNoAutoVerify;
@ -173,8 +171,12 @@ public class AgreementsIT extends AbstractDaemonTest {
// Create a new branch
setApiUser(admin);
BranchInfo dest = gApi.projects().name(project.get())
.branch("cherry-pick-to").create(new BranchInput()).get();
BranchInfo dest =
gApi.projects()
.name(project.get())
.branch("cherry-pick-to")
.create(new BranchInput())
.get();
// Create a change succeeds when agreement is not required
setUseContributorAgreements(InheritableBoolean.FALSE);
@ -209,8 +211,7 @@ public class AgreementsIT extends AbstractDaemonTest {
gApi.changes().create(newChangeInput());
fail("Expected AuthException");
} catch (AuthException e) {
assertThat(e.getMessage()).contains(
"A Contributor Agreement must be completed");
assertThat(e.getMessage()).contains("A Contributor Agreement must be completed");
}
// Sign the agreement
@ -228,8 +229,7 @@ public class AgreementsIT extends AbstractDaemonTest {
assertThat(info.description).isEqualTo(ca.getDescription());
assertThat(info.url).isEqualTo(ca.getAgreementUrl());
if (ca.getAutoVerify() != null) {
assertThat(info.autoVerifyGroup.name)
.isEqualTo(ca.getAutoVerify().getName());
assertThat(info.autoVerifyGroup.name).isEqualTo(ca.getAutoVerify().getName());
} else {
assertThat(info.autoVerifyGroup).isNull();
}

View File

@ -28,7 +28,6 @@ import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.account.VersionedAccountPreferences;
import com.google.gerrit.server.config.AllUsersName;
import com.google.inject.Inject;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
@ -37,37 +36,39 @@ import org.junit.Test;
@NoHttpd
public class DiffPreferencesIT extends AbstractDaemonTest {
@Inject
private AllUsersName allUsers;
@Inject private AllUsersName allUsers;
@After
public void cleanUp() throws Exception {
gApi.accounts().id(admin.getId().toString())
.setDiffPreferences(DiffPreferencesInfo.defaults());
gApi.accounts().id(admin.getId().toString()).setDiffPreferences(DiffPreferencesInfo.defaults());
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
try {
fetch(allUsersRepo, RefNames.REFS_USERS_DEFAULT + ":defaults");
} catch (TransportException e) {
if (e.getMessage().equals("Remote does not have "
+ RefNames.REFS_USERS_DEFAULT + " available for fetch.")) {
if (e.getMessage()
.equals(
"Remote does not have " + RefNames.REFS_USERS_DEFAULT + " available for fetch.")) {
return;
}
throw e;
}
allUsersRepo.reset("defaults");
PushOneCommit push = pushFactory.create(db, admin.getIdent(), allUsersRepo,
"Delete default preferences", VersionedAccountPreferences.PREFERENCES,
"");
PushOneCommit push =
pushFactory.create(
db,
admin.getIdent(),
allUsersRepo,
"Delete default preferences",
VersionedAccountPreferences.PREFERENCES,
"");
push.rm(RefNames.REFS_USERS_DEFAULT).assertOkStatus();
}
@Test
public void getDiffPreferences() throws Exception {
DiffPreferencesInfo d = DiffPreferencesInfo.defaults();
DiffPreferencesInfo o = gApi.accounts()
.id(admin.getId().toString())
.getDiffPreferences();
DiffPreferencesInfo o = gApi.accounts().id(admin.getId().toString()).getDiffPreferences();
assertPrefs(o, d);
}
@ -102,17 +103,13 @@ public class DiffPreferencesIT extends AbstractDaemonTest {
i.matchBrackets ^= true;
i.lineWrapping ^= true;
DiffPreferencesInfo o = gApi.accounts()
.id(admin.getId().toString())
.setDiffPreferences(i);
DiffPreferencesInfo o = gApi.accounts().id(admin.getId().toString()).setDiffPreferences(i);
assertPrefs(o, i);
// Partially fill input record
i = new DiffPreferencesInfo();
i.tabSize = 42;
DiffPreferencesInfo a = gApi.accounts()
.id(admin.getId().toString())
.setDiffPreferences(i);
DiffPreferencesInfo a = gApi.accounts().id(admin.getId().toString()).setDiffPreferences(i);
assertPrefs(a, o, "tabSize");
assertThat(a.tabSize).isEqualTo(42);
}
@ -129,9 +126,7 @@ public class DiffPreferencesIT extends AbstractDaemonTest {
update.fontSize = newFontSize;
gApi.config().server().setDefaultDiffPreferences(update);
DiffPreferencesInfo o = gApi.accounts()
.id(admin.getId().toString())
.getDiffPreferences();
DiffPreferencesInfo o = gApi.accounts().id(admin.getId().toString()).getDiffPreferences();
// assert configured defaults
assertThat(o.lineLength).isEqualTo(newLineLength);

View File

@ -21,16 +21,13 @@ import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.extensions.client.EditPreferencesInfo;
import com.google.gerrit.extensions.client.KeyMapType;
import com.google.gerrit.extensions.client.Theme;
import org.junit.Test;
@NoHttpd
public class EditPreferencesIT extends AbstractDaemonTest {
@Test
public void getSetEditPreferences() throws Exception {
EditPreferencesInfo out = gApi.accounts()
.id(admin.getId().toString())
.getEditPreferences();
EditPreferencesInfo out = gApi.accounts().id(admin.getId().toString()).getEditPreferences();
assertThat(out.lineLength).isEqualTo(100);
assertThat(out.indentUnit).isEqualTo(2);
@ -65,9 +62,7 @@ public class EditPreferencesIT extends AbstractDaemonTest {
out.theme = Theme.TWILIGHT;
out.keyMapType = KeyMapType.EMACS;
EditPreferencesInfo info = gApi.accounts()
.id(admin.getId().toString())
.setEditPreferences(out);
EditPreferencesInfo info = gApi.accounts().id(admin.getId().toString()).setEditPreferences(out);
assertEditPreferences(info, out);
@ -75,16 +70,14 @@ public class EditPreferencesIT extends AbstractDaemonTest {
EditPreferencesInfo in = new EditPreferencesInfo();
in.tabSize = 42;
info = gApi.accounts()
.id(admin.getId().toString())
.setEditPreferences(in);
info = gApi.accounts().id(admin.getId().toString()).setEditPreferences(in);
out.tabSize = in.tabSize;
assertEditPreferences(info, out);
}
private void assertEditPreferences(EditPreferencesInfo out,
EditPreferencesInfo in) throws Exception {
private void assertEditPreferences(EditPreferencesInfo out, EditPreferencesInfo in)
throws Exception {
assertThat(out.lineLength).isEqualTo(in.lineLength);
assertThat(out.indentUnit).isEqualTo(in.indentUnit);
assertThat(out.tabSize).isEqualTo(in.tabSize);

View File

@ -32,20 +32,17 @@ import com.google.gerrit.extensions.client.MenuItem;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.config.AllUsersName;
import com.google.inject.Inject;
import java.util.ArrayList;
import java.util.HashMap;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashMap;
@NoHttpd
public class GeneralPreferencesIT extends AbstractDaemonTest {
@Inject
private AllUsersName allUsers;
@Inject private AllUsersName allUsers;
private TestAccount user42;
@ -57,8 +54,7 @@ public class GeneralPreferencesIT extends AbstractDaemonTest {
@After
public void cleanUp() throws Exception {
gApi.accounts().id(user42.getId().toString())
.setPreferences(GeneralPreferencesInfo.defaults());
gApi.accounts().id(user42.getId().toString()).setPreferences(GeneralPreferencesInfo.defaults());
try (Repository git = repoManager.openRepository(allUsers)) {
if (git.exactRef(RefNames.REFS_USERS_DEFAULT) != null) {
@ -72,9 +68,7 @@ public class GeneralPreferencesIT extends AbstractDaemonTest {
@Test
public void getAndSetPreferences() throws Exception {
GeneralPreferencesInfo o = gApi.accounts()
.id(user42.id.toString())
.getPreferences();
GeneralPreferencesInfo o = gApi.accounts().id(user42.id.toString()).getPreferences();
assertPrefs(o, GeneralPreferencesInfo.defaults(), "my", "changeTable");
assertThat(o.my).hasSize(7);
assertThat(o.changeTable).isEmpty();
@ -106,9 +100,7 @@ public class GeneralPreferencesIT extends AbstractDaemonTest {
i.urlAliases = new HashMap<>();
i.urlAliases.put("foo", "bar");
o = gApi.accounts()
.id(user42.getId().toString())
.setPreferences(i);
o = gApi.accounts().id(user42.getId().toString()).setPreferences(i);
assertPrefs(o, i, "my");
assertThat(o.my).hasSize(1);
assertThat(o.changeTable).hasSize(1);
@ -122,9 +114,7 @@ public class GeneralPreferencesIT extends AbstractDaemonTest {
update.changesPerPage = newChangesPerPage;
gApi.config().server().setDefaultPreferences(update);
GeneralPreferencesInfo o = gApi.accounts()
.id(user42.getId().toString())
.getPreferences();
GeneralPreferencesInfo o = gApi.accounts().id(user42.getId().toString()).getPreferences();
// assert configured defaults
assertThat(o.changesPerPage).isEqualTo(newChangesPerPage);

View File

@ -30,16 +30,14 @@ import com.google.gerrit.extensions.common.CommitInfo;
import com.google.gerrit.extensions.common.DiffInfo;
import com.google.gerrit.extensions.restapi.BinaryResult;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import java.io.ByteArrayOutputStream;
import java.util.List;
import java.util.Set;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Before;
import org.junit.Test;
import java.io.ByteArrayOutputStream;
import java.util.List;
import java.util.Set;
@NoHttpd
public class MergeListIT extends AbstractDaemonTest {
@ -54,35 +52,60 @@ public class MergeListIT extends AbstractDaemonTest {
public void setup() throws Exception {
ObjectId initial = repo().exactRef(HEAD).getLeaf().getObjectId();
PushOneCommit.Result gp1 = pushFactory
.create(db, admin.getIdent(), testRepo, "grand parent 1",
ImmutableMap.of("foo", "foo-1.1", "bar", "bar-1.1"))
.to("refs/for/master");
PushOneCommit.Result gp1 =
pushFactory
.create(
db,
admin.getIdent(),
testRepo,
"grand parent 1",
ImmutableMap.of("foo", "foo-1.1", "bar", "bar-1.1"))
.to("refs/for/master");
grandParent1 = gp1.getCommit();
PushOneCommit.Result p1 = pushFactory
.create(db, admin.getIdent(), testRepo, "parent 1",
ImmutableMap.of("foo", "foo-1.2", "bar", "bar-1.2"))
.to("refs/for/master");
PushOneCommit.Result p1 =
pushFactory
.create(
db,
admin.getIdent(),
testRepo,
"parent 1",
ImmutableMap.of("foo", "foo-1.2", "bar", "bar-1.2"))
.to("refs/for/master");
parent1 = p1.getCommit();
// reset HEAD in order to create a sibling of the first change
testRepo.reset(initial);
PushOneCommit.Result gp2 = pushFactory
.create(db, admin.getIdent(), testRepo, "grand parent 2",
ImmutableMap.of("foo", "foo-2.1", "bar", "bar-2.1"))
.to("refs/for/master");
PushOneCommit.Result gp2 =
pushFactory
.create(
db,
admin.getIdent(),
testRepo,
"grand parent 2",
ImmutableMap.of("foo", "foo-2.1", "bar", "bar-2.1"))
.to("refs/for/master");
grandParent2 = gp2.getCommit();
PushOneCommit.Result p2 = pushFactory
.create(db, admin.getIdent(), testRepo, "parent 2",
ImmutableMap.of("foo", "foo-2.2", "bar", "bar-2.2"))
.to("refs/for/master");
PushOneCommit.Result p2 =
pushFactory
.create(
db,
admin.getIdent(),
testRepo,
"parent 2",
ImmutableMap.of("foo", "foo-2.2", "bar", "bar-2.2"))
.to("refs/for/master");
parent2 = p2.getCommit();
PushOneCommit m = pushFactory.create(db, admin.getIdent(), testRepo,
"merge", ImmutableMap.of("foo", "foo-1", "bar", "bar-2"));
PushOneCommit m =
pushFactory.create(
db,
admin.getIdent(),
testRepo,
"merge",
ImmutableMap.of("foo", "foo-1", "bar", "bar-2"));
m.setParents(ImmutableList.of(p1.getCommit(), p2.getCommit()));
PushOneCommit.Result result = m.to("refs/for/master");
result.assertOkStatus();
@ -97,8 +120,7 @@ public class MergeListIT extends AbstractDaemonTest {
assertThat(mergeList.get(0).commit).isEqualTo(parent2.name());
assertThat(mergeList.get(1).commit).isEqualTo(grandParent2.name());
mergeList = current(changeId).getMergeList()
.withUninterestingParent(2).get();
mergeList = current(changeId).getMergeList().withUninterestingParent(2).get();
assertThat(mergeList).hasSize(2);
assertThat(mergeList.get(0).commit).isEqualTo(parent1.name());
assertThat(mergeList.get(1).commit).isEqualTo(grandParent1.name());
@ -110,8 +132,7 @@ public class MergeListIT extends AbstractDaemonTest {
ByteArrayOutputStream os = new ByteArrayOutputStream();
bin.writeTo(os);
String content = new String(os.toByteArray(), UTF_8);
assertThat(content).isEqualTo(
getMergeListContent(parent2, grandParent2));
assertThat(content).isEqualTo(getMergeListContent(parent2, grandParent2));
}
@Test
@ -120,59 +141,44 @@ public class MergeListIT extends AbstractDaemonTest {
assertThat(getFiles(changeId, 1)).contains(MERGE_LIST);
assertThat(getFiles(changeId, 2)).contains(MERGE_LIST);
assertThat(getFiles(createChange().getChangeId()))
.doesNotContain(MERGE_LIST);
assertThat(getFiles(createChange().getChangeId())).doesNotContain(MERGE_LIST);
}
@Test
public void getDiffForMergeList() throws Exception {
DiffInfo diff = getMergeListDiff(changeId);
assertDiffForNewFile(diff, merge, MERGE_LIST,
getMergeListContent(parent2, grandParent2));
assertDiffForNewFile(diff, merge, MERGE_LIST, getMergeListContent(parent2, grandParent2));
diff = getMergeListDiff(changeId, 1);
assertDiffForNewFile(diff, merge, MERGE_LIST,
getMergeListContent(parent2, grandParent2));
assertDiffForNewFile(diff, merge, MERGE_LIST, getMergeListContent(parent2, grandParent2));
diff = getMergeListDiff(changeId, 2);
assertDiffForNewFile(diff, merge, MERGE_LIST,
getMergeListContent(parent1, grandParent1));
assertDiffForNewFile(diff, merge, MERGE_LIST, getMergeListContent(parent1, grandParent1));
}
@Test
public void editMergeList() throws Exception {
gApi.changes()
.id(changeId)
.edit()
.create();
gApi.changes().id(changeId).edit().create();
exception.expect(ResourceConflictException.class);
exception.expectMessage("Invalid path: " + MERGE_LIST);
gApi.changes()
.id(changeId)
.edit()
.modifyFile(MERGE_LIST, RawInputUtil.create("new content"));
gApi.changes().id(changeId).edit().modifyFile(MERGE_LIST, RawInputUtil.create("new content"));
}
@Test
public void deleteMergeList() throws Exception {
gApi.changes()
.id(changeId)
.edit()
.create();
gApi.changes().id(changeId).edit().create();
exception.expect(ResourceConflictException.class);
exception.expectMessage("no changes were made");
gApi.changes()
.id(changeId)
.edit()
.deleteFile(MERGE_LIST);
gApi.changes().id(changeId).edit().deleteFile(MERGE_LIST);
}
private String getMergeListContent(RevCommit... commits) {
StringBuilder mergeList = new StringBuilder("Merge List:\n\n");
for (RevCommit c : commits) {
mergeList.append("* ")
mergeList
.append("* ")
.append(c.abbreviate(8).name())
.append(" ")
.append(c.getShortMessage())
@ -193,14 +199,11 @@ public class MergeListIT extends AbstractDaemonTest {
return current(changeId).file(MERGE_LIST).diff();
}
private DiffInfo getMergeListDiff(String changeId, int parent)
throws Exception {
private DiffInfo getMergeListDiff(String changeId, int parent) throws Exception {
return current(changeId).file(MERGE_LIST).diff(parent);
}
private RevisionApi current(String changeId) throws Exception {
return gApi.changes()
.id(changeId)
.current();
return gApi.changes().id(changeId).current();
}
}

View File

@ -46,7 +46,9 @@ import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.project.Util;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
@ -54,10 +56,6 @@ import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Before;
import org.junit.Test;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
@NoHttpd
public class StickyApprovalsIT extends AbstractDaemonTest {
@Before
@ -67,7 +65,9 @@ public class StickyApprovalsIT extends AbstractDaemonTest {
// Overwrite "Code-Review" label that is inherited from All-Projects.
// This way changes to the "Code Review" label don't affect other tests.
LabelType codeReview =
category("Code-Review", value(2, "Looks good to me, approved"),
category(
"Code-Review",
value(2, "Looks good to me, approved"),
value(1, "Looks good to me, but someone else must approve"),
value(0, "No score"),
value(-1, "I would prefer that you didn't submit this"),
@ -75,25 +75,23 @@ public class StickyApprovalsIT extends AbstractDaemonTest {
codeReview.setCopyAllScoresIfNoChange(false);
cfg.getLabelSections().put(codeReview.getName(), codeReview);
LabelType verified = category("Verified", value(1, "Passes"),
value(0, "No score"), value(-1, "Failed"));
LabelType verified =
category("Verified", value(1, "Passes"), value(0, "No score"), value(-1, "Failed"));
verified.setCopyAllScoresIfNoChange(false);
cfg.getLabelSections().put(verified.getName(), verified);
AccountGroup.UUID registeredUsers =
systemGroupBackend.getGroup(REGISTERED_USERS).getUUID();
AccountGroup.UUID registeredUsers = systemGroupBackend.getGroup(REGISTERED_USERS).getUUID();
String heads = RefNames.REFS_HEADS + "*";
Util.allow(cfg, Permission.forLabel(Util.codeReview().getName()), -2, 2,
registeredUsers, heads);
Util.allow(cfg, Permission.forLabel(Util.verified().getName()), -1, 1,
registeredUsers, heads);
Util.allow(
cfg, Permission.forLabel(Util.codeReview().getName()), -2, 2, registeredUsers, heads);
Util.allow(cfg, Permission.forLabel(Util.verified().getName()), -1, 1, registeredUsers, heads);
saveProjectConfig(project, cfg);
}
@Test
public void notSticky() throws Exception {
assertNotSticky(EnumSet.of(REWORK, TRIVIAL_REBASE, NO_CODE_CHANGE,
MERGE_FIRST_PARENT_UPDATE, NO_CHANGE));
assertNotSticky(
EnumSet.of(REWORK, TRIVIAL_REBASE, NO_CODE_CHANGE, MERGE_FIRST_PARENT_UPDATE, NO_CHANGE));
}
@Test
@ -102,8 +100,8 @@ public class StickyApprovalsIT extends AbstractDaemonTest {
cfg.getLabelSections().get("Code-Review").setCopyMinScore(true);
saveProjectConfig(project, cfg);
for (ChangeKind changeKind : EnumSet.of(REWORK, TRIVIAL_REBASE,
NO_CODE_CHANGE, MERGE_FIRST_PARENT_UPDATE, NO_CHANGE)) {
for (ChangeKind changeKind :
EnumSet.of(REWORK, TRIVIAL_REBASE, NO_CODE_CHANGE, MERGE_FIRST_PARENT_UPDATE, NO_CHANGE)) {
testRepo.reset(getRemoteHead());
String changeId = createChange(changeKind);
@ -123,8 +121,8 @@ public class StickyApprovalsIT extends AbstractDaemonTest {
cfg.getLabelSections().get("Code-Review").setCopyMaxScore(true);
saveProjectConfig(project, cfg);
for (ChangeKind changeKind : EnumSet.of(REWORK, TRIVIAL_REBASE,
NO_CODE_CHANGE, MERGE_FIRST_PARENT_UPDATE, NO_CHANGE)) {
for (ChangeKind changeKind :
EnumSet.of(REWORK, TRIVIAL_REBASE, NO_CODE_CHANGE, MERGE_FIRST_PARENT_UPDATE, NO_CHANGE)) {
testRepo.reset(getRemoteHead());
String changeId = createChange(changeKind);
@ -141,8 +139,7 @@ public class StickyApprovalsIT extends AbstractDaemonTest {
@Test
public void stickyOnTrivialRebase() throws Exception {
ProjectConfig cfg = projectCache.checkedGet(project).getConfig();
cfg.getLabelSections().get("Code-Review")
.setCopyAllScoresOnTrivialRebase(true);
cfg.getLabelSections().get("Code-Review").setCopyAllScoresOnTrivialRebase(true);
saveProjectConfig(project, cfg);
String changeId = createChange(TRIVIAL_REBASE);
@ -159,8 +156,7 @@ public class StickyApprovalsIT extends AbstractDaemonTest {
assertVotes(c, admin, 2, 0, TRIVIAL_REBASE);
assertVotes(c, user, -2, 0, TRIVIAL_REBASE);
assertNotSticky(
EnumSet.of(REWORK, NO_CODE_CHANGE, MERGE_FIRST_PARENT_UPDATE));
assertNotSticky(EnumSet.of(REWORK, NO_CODE_CHANGE, MERGE_FIRST_PARENT_UPDATE));
// check that votes are sticky when trivial rebase is done by cherry-pick
testRepo.reset(getRemoteHead());
@ -188,8 +184,7 @@ public class StickyApprovalsIT extends AbstractDaemonTest {
@Test
public void stickyOnNoCodeChange() throws Exception {
ProjectConfig cfg = projectCache.checkedGet(project).getConfig();
cfg.getLabelSections().get("Verified")
.setCopyAllScoresIfNoCodeChange(true);
cfg.getLabelSections().get("Verified").setCopyAllScoresIfNoCodeChange(true);
saveProjectConfig(project, cfg);
String changeId = createChange(NO_CODE_CHANGE);
@ -206,15 +201,13 @@ public class StickyApprovalsIT extends AbstractDaemonTest {
assertVotes(c, admin, 0, 1, NO_CODE_CHANGE);
assertVotes(c, user, 0, -1, NO_CODE_CHANGE);
assertNotSticky(
EnumSet.of(REWORK, TRIVIAL_REBASE, MERGE_FIRST_PARENT_UPDATE));
assertNotSticky(EnumSet.of(REWORK, TRIVIAL_REBASE, MERGE_FIRST_PARENT_UPDATE));
}
@Test
public void stickyOnMergeFirstParentUpdate() throws Exception {
ProjectConfig cfg = projectCache.checkedGet(project).getConfig();
cfg.getLabelSections().get("Code-Review")
.setCopyAllScoresOnMergeFirstParentUpdate(true);
cfg.getLabelSections().get("Code-Review").setCopyAllScoresOnMergeFirstParentUpdate(true);
saveProjectConfig(project, cfg);
String changeId = createChange(MERGE_FIRST_PARENT_UPDATE);
@ -237,13 +230,12 @@ public class StickyApprovalsIT extends AbstractDaemonTest {
@Test
public void removedVotesNotSticky() throws Exception {
ProjectConfig cfg = projectCache.checkedGet(project).getConfig();
cfg.getLabelSections().get("Code-Review")
.setCopyAllScoresOnTrivialRebase(true);
cfg.getLabelSections().get("Code-Review").setCopyAllScoresOnTrivialRebase(true);
cfg.getLabelSections().get("Verified").setCopyAllScoresIfNoCodeChange(true);
saveProjectConfig(project, cfg);
for (ChangeKind changeKind : EnumSet.of(REWORK, TRIVIAL_REBASE,
NO_CODE_CHANGE, MERGE_FIRST_PARENT_UPDATE, NO_CHANGE)) {
for (ChangeKind changeKind :
EnumSet.of(REWORK, TRIVIAL_REBASE, NO_CODE_CHANGE, MERGE_FIRST_PARENT_UPDATE, NO_CHANGE)) {
testRepo.reset(getRemoteHead());
String changeId = createChange(changeKind);
@ -267,10 +259,8 @@ public class StickyApprovalsIT extends AbstractDaemonTest {
@Test
public void stickyAcrossMultiplePatchSets() throws Exception {
ProjectConfig cfg = projectCache.checkedGet(project).getConfig();
cfg.getLabelSections().get("Code-Review")
.setCopyMaxScore(true);
cfg.getLabelSections().get("Verified")
.setCopyAllScoresIfNoCodeChange(true);
cfg.getLabelSections().get("Code-Review").setCopyMaxScore(true);
cfg.getLabelSections().get("Verified").setCopyAllScoresIfNoCodeChange(true);
saveProjectConfig(project, cfg);
String changeId = createChange(REWORK);
@ -290,10 +280,8 @@ public class StickyApprovalsIT extends AbstractDaemonTest {
@Test
public void copyMinMaxAcrossMultiplePatchSets() throws Exception {
ProjectConfig cfg = projectCache.checkedGet(project).getConfig();
cfg.getLabelSections().get("Code-Review")
.setCopyMaxScore(true);
cfg.getLabelSections().get("Code-Review")
.setCopyMinScore(true);
cfg.getLabelSections().get("Code-Review").setCopyMaxScore(true);
cfg.getLabelSections().get("Code-Review").setCopyMinScore(true);
saveProjectConfig(project, cfg);
// Vote max score on PS1
@ -332,8 +320,7 @@ public class StickyApprovalsIT extends AbstractDaemonTest {
public void deleteStickyVote() throws Exception {
String label = "Code-Review";
ProjectConfig cfg = projectCache.checkedGet(project).getConfig();
cfg.getLabelSections().get(label)
.setCopyMaxScore(true);
cfg.getLabelSections().get(label).setCopyMaxScore(true);
saveProjectConfig(project, cfg);
// Vote max score on PS1
@ -349,10 +336,13 @@ public class StickyApprovalsIT extends AbstractDaemonTest {
}
private ChangeInfo detailedChange(String changeId) throws Exception {
return gApi.changes().id(changeId)
.get(EnumSet.of(ListChangesOption.DETAILED_LABELS,
ListChangesOption.CURRENT_REVISION,
ListChangesOption.CURRENT_COMMIT));
return gApi.changes()
.id(changeId)
.get(
EnumSet.of(
ListChangesOption.DETAILED_LABELS,
ListChangesOption.CURRENT_REVISION,
ListChangesOption.CURRENT_COMMIT));
}
private void assertNotSticky(Set<ChangeKind> changeKinds) throws Exception {
@ -384,8 +374,7 @@ public class StickyApprovalsIT extends AbstractDaemonTest {
}
}
private void updateChange(String changeId, ChangeKind changeKind)
throws Exception {
private void updateChange(String changeId, ChangeKind changeKind) throws Exception {
switch (changeKind) {
case NO_CODE_CHANGE:
noCodeChange(changeId);
@ -410,7 +399,8 @@ public class StickyApprovalsIT extends AbstractDaemonTest {
private void noCodeChange(String changeId) throws Exception {
TestRepository<?>.CommitBuilder commitBuilder =
testRepo.amendRef("HEAD").insertChangeId(changeId.substring(1));
commitBuilder.message("New subject " + System.nanoTime())
commitBuilder
.message("New subject " + System.nanoTime())
.author(admin.getIdent())
.committer(new PersonIdent(admin.getIdent(), testRepo.getDate()));
commitBuilder.create();
@ -420,12 +410,12 @@ public class StickyApprovalsIT extends AbstractDaemonTest {
private void noChange(String changeId) throws Exception {
ChangeInfo change = gApi.changes().id(changeId).get();
String commitMessage =
change.revisions.get(change.currentRevision).commit.message;
String commitMessage = change.revisions.get(change.currentRevision).commit.message;
TestRepository<?>.CommitBuilder commitBuilder =
testRepo.amendRef("HEAD").insertChangeId(changeId.substring(1));
commitBuilder.message(commitMessage)
commitBuilder
.message(commitMessage)
.author(admin.getIdent())
.committer(new PersonIdent(admin.getIdent(), testRepo.getDate()));
commitBuilder.create();
@ -434,9 +424,15 @@ public class StickyApprovalsIT extends AbstractDaemonTest {
}
private void rework(String changeId) throws Exception {
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo,
PushOneCommit.SUBJECT, PushOneCommit.FILE_NAME,
"new content " + System.nanoTime(), changeId);
PushOneCommit push =
pushFactory.create(
db,
admin.getIdent(),
testRepo,
PushOneCommit.SUBJECT,
PushOneCommit.FILE_NAME,
"new content " + System.nanoTime(),
changeId);
push.to("refs/for/master").assertOkStatus();
assertThat(getChangeKind(changeId)).isEqualTo(REWORK);
}
@ -445,41 +441,36 @@ public class StickyApprovalsIT extends AbstractDaemonTest {
setApiUser(admin);
testRepo.reset(getRemoteHead());
PushOneCommit push =
pushFactory.create(db, admin.getIdent(), testRepo, "Other Change",
"a" + System.nanoTime() + ".txt", PushOneCommit.FILE_CONTENT);
pushFactory.create(
db,
admin.getIdent(),
testRepo,
"Other Change",
"a" + System.nanoTime() + ".txt",
PushOneCommit.FILE_CONTENT);
PushOneCommit.Result r = push.to("refs/for/master");
r.assertOkStatus();
RevisionApi revision = gApi.changes()
.id(r.getChangeId())
.current();
ReviewInput in = new ReviewInput()
.label("Code-Review", 2)
.label("Verified", 1);
RevisionApi revision = gApi.changes().id(r.getChangeId()).current();
ReviewInput in = new ReviewInput().label("Code-Review", 2).label("Verified", 1);
revision.review(in);
revision.submit();
gApi.changes()
.id(changeId)
.current()
.rebase();
gApi.changes().id(changeId).current().rebase();
assertThat(getChangeKind(changeId)).isEqualTo(TRIVIAL_REBASE);
}
private String createChangeForMergeCommit() throws Exception {
ObjectId initial = repo().exactRef(HEAD).getLeaf().getObjectId();
PushOneCommit.Result parent1 =
createChange("parent 1", "p1.txt", "content 1");
PushOneCommit.Result parent1 = createChange("parent 1", "p1.txt", "content 1");
testRepo.reset(initial);
PushOneCommit.Result parent2 =
createChange("parent 2", "p2.txt", "content 2");
PushOneCommit.Result parent2 = createChange("parent 2", "p2.txt", "content 2");
testRepo.reset(parent1.getCommit());
PushOneCommit merge = pushFactory.create(db, admin.getIdent(), testRepo);
merge.setParents(
ImmutableList.of(parent1.getCommit(), parent2.getCommit()));
merge.setParents(ImmutableList.of(parent1.getCommit(), parent2.getCommit()));
PushOneCommit.Result result = merge.to("refs/for/master");
result.assertOkStatus();
return result.getChangeId();
@ -490,17 +481,13 @@ public class StickyApprovalsIT extends AbstractDaemonTest {
List<CommitInfo> parents = c.revisions.get(c.currentRevision).commit.parents;
String parent1 = parents.get(0).commit;
String parent2 = parents.get(1).commit;
RevCommit commitParent2 =
testRepo.getRevWalk().parseCommit(ObjectId.fromString(parent2));
RevCommit commitParent2 = testRepo.getRevWalk().parseCommit(ObjectId.fromString(parent2));
testRepo.reset(parent1);
PushOneCommit.Result newParent1 =
createChange("new parent 1", "p1-1.txt", "content 1-1");
PushOneCommit.Result newParent1 = createChange("new parent 1", "p1-1.txt", "content 1-1");
PushOneCommit merge =
pushFactory.create(db, admin.getIdent(), testRepo, changeId);
merge.setParents(
ImmutableList.of(newParent1.getCommit(), commitParent2));
PushOneCommit merge = pushFactory.create(db, admin.getIdent(), testRepo, changeId);
merge.setParents(ImmutableList.of(newParent1.getCommit(), commitParent2));
PushOneCommit.Result result = merge.to("refs/for/master");
result.assertOkStatus();
@ -520,75 +507,66 @@ public class StickyApprovalsIT extends AbstractDaemonTest {
}
testRepo.reset(getRemoteHead());
PushOneCommit.Result r = pushFactory
.create(db, admin.getIdent(), testRepo, PushOneCommit.SUBJECT,
"other.txt", "new content " + System.nanoTime())
.to("refs/for/master");
PushOneCommit.Result r =
pushFactory
.create(
db,
admin.getIdent(),
testRepo,
PushOneCommit.SUBJECT,
"other.txt",
"new content " + System.nanoTime())
.to("refs/for/master");
r.assertOkStatus();
vote(admin, r.getChangeId(), 2, 1);
merge(r);
String subject = TRIVIAL_REBASE.equals(changeKind)
? PushOneCommit.SUBJECT
: "Reworked change " + System.nanoTime();
String subject =
TRIVIAL_REBASE.equals(changeKind)
? PushOneCommit.SUBJECT
: "Reworked change " + System.nanoTime();
CherryPickInput in = new CherryPickInput();
in.destination = "master";
in.message =
String.format("%s\n\nChange-Id: %s", subject, changeId);
ChangeInfo c = gApi.changes()
.id(changeId)
.revision("current")
.cherryPick(in)
.get();
in.message = String.format("%s\n\nChange-Id: %s", subject, changeId);
ChangeInfo c = gApi.changes().id(changeId).revision("current").cherryPick(in).get();
return c.changeId;
}
private ChangeKind getChangeKind(String changeId) throws Exception {
ChangeInfo c = gApi.changes().id(changeId)
.get(EnumSet.of(ListChangesOption.CURRENT_REVISION));
ChangeInfo c = gApi.changes().id(changeId).get(EnumSet.of(ListChangesOption.CURRENT_REVISION));
return c.revisions.get(c.currentRevision).kind;
}
private void vote(TestAccount user, String changeId, String label, int vote)
throws Exception {
private void vote(TestAccount user, String changeId, String label, int vote) throws Exception {
setApiUser(user);
gApi.changes()
.id(changeId)
.current()
.review(new ReviewInput().label(label, vote));
gApi.changes().id(changeId).current().review(new ReviewInput().label(label, vote));
}
private void vote(TestAccount user, String changeId, int codeReviewVote,
int verifiedVote) throws Exception {
private void vote(TestAccount user, String changeId, int codeReviewVote, int verifiedVote)
throws Exception {
setApiUser(user);
ReviewInput in = new ReviewInput()
.label("Code-Review", codeReviewVote)
.label("Verified", verifiedVote);
ReviewInput in =
new ReviewInput().label("Code-Review", codeReviewVote).label("Verified", verifiedVote);
gApi.changes().id(changeId).current().review(in);
}
private void deleteVote(TestAccount user, String changeId, String label)
throws Exception {
private void deleteVote(TestAccount user, String changeId, String label) throws Exception {
setApiUser(user);
gApi.changes()
.id(changeId)
.reviewer(user.getId().toString())
.deleteVote(label);
gApi.changes().id(changeId).reviewer(user.getId().toString()).deleteVote(label);
}
private void assertVotes(ChangeInfo c, TestAccount user, int codeReviewVote,
int verifiedVote) {
private void assertVotes(ChangeInfo c, TestAccount user, int codeReviewVote, int verifiedVote) {
assertVotes(c, user, codeReviewVote, verifiedVote, null);
}
private void assertVotes(ChangeInfo c, TestAccount user, int codeReviewVote,
int verifiedVote, ChangeKind changeKind) {
private void assertVotes(
ChangeInfo c, TestAccount user, int codeReviewVote, int verifiedVote, ChangeKind changeKind) {
assertVotes(c, user, "Code-Review", codeReviewVote, changeKind);
assertVotes(c, user, "Verified", verifiedVote, changeKind);
}
private void assertVotes(ChangeInfo c, TestAccount user, String label,
int expectedVote, ChangeKind changeKind) {
private void assertVotes(
ChangeInfo c, TestAccount user, String label, int expectedVote, ChangeKind changeKind) {
Integer vote = 0;
if (c.labels.get(label) != null && c.labels.get(label).all != null) {
for (ApprovalInfo approval : c.labels.get(label).all) {
@ -603,8 +581,6 @@ public class StickyApprovalsIT extends AbstractDaemonTest {
if (changeKind != null) {
name += "; changeKind = " + changeKind.name();
}
assertThat(vote)
.named(name)
.isEqualTo(expectedVote);
assertThat(vote).named(name).isEqualTo(expectedVote);
}
}

View File

@ -38,7 +38,9 @@ import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.VersionedMetaData;
import com.google.gerrit.testutil.ConfigSuite;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.CommitBuilder;
@ -49,10 +51,6 @@ import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@NoHttpd
public class SubmitTypeRuleIT extends AbstractDaemonTest {
@ConfigSuite.Default
@ -76,8 +74,7 @@ public class SubmitTypeRuleIT extends AbstractDaemonTest {
}
@Override
protected boolean onSave(CommitBuilder commit)
throws IOException, ConfigInvalidException {
protected boolean onSave(CommitBuilder commit) throws IOException, ConfigInvalidException {
TestSubmitRuleInput in = new TestSubmitRuleInput();
in.rule = rule;
try {
@ -97,8 +94,7 @@ public class SubmitTypeRuleIT extends AbstractDaemonTest {
@Before
public void setUp() throws Exception {
fileCounter = new AtomicInteger();
gApi.projects().name(project.get()).branch("test")
.create(new BranchInput());
gApi.projects().name(project.get()).branch("test").create(new BranchInput());
testChangeId = createChange("test", "test change").getChange().getId();
}
@ -113,36 +109,40 @@ public class SubmitTypeRuleIT extends AbstractDaemonTest {
private static final String SUBMIT_TYPE_FROM_SUBJECT =
"submit_type(fast_forward_only) :-"
+ "gerrit:commit_message(M),"
+ "regex_matches('.*FAST_FORWARD_ONLY.*', M),"
+ "!.\n"
+ "submit_type(merge_if_necessary) :-"
+ "gerrit:commit_message(M),"
+ "regex_matches('.*MERGE_IF_NECESSARY.*', M),"
+ "!.\n"
+ "submit_type(rebase_if_necessary) :-"
+ "gerrit:commit_message(M),"
+ "regex_matches('.*REBASE_IF_NECESSARY.*', M),"
+ "!.\n"
+ "submit_type(rebase_always) :-"
+ "gerrit:commit_message(M),"
+ "regex_matches('.*REBASE_ALWAYS.*', M),"
+ "!.\n"
+ "submit_type(merge_always) :-"
+ "gerrit:commit_message(M),"
+ "regex_matches('.*MERGE_ALWAYS.*', M),"
+ "!.\n"
+ "submit_type(cherry_pick) :-"
+ "gerrit:commit_message(M),"
+ "regex_matches('.*CHERRY_PICK.*', M),"
+ "!.\n"
+ "submit_type(T) :- gerrit:project_default_submit_type(T).";
+ "gerrit:commit_message(M),"
+ "regex_matches('.*FAST_FORWARD_ONLY.*', M),"
+ "!.\n"
+ "submit_type(merge_if_necessary) :-"
+ "gerrit:commit_message(M),"
+ "regex_matches('.*MERGE_IF_NECESSARY.*', M),"
+ "!.\n"
+ "submit_type(rebase_if_necessary) :-"
+ "gerrit:commit_message(M),"
+ "regex_matches('.*REBASE_IF_NECESSARY.*', M),"
+ "!.\n"
+ "submit_type(rebase_always) :-"
+ "gerrit:commit_message(M),"
+ "regex_matches('.*REBASE_ALWAYS.*', M),"
+ "!.\n"
+ "submit_type(merge_always) :-"
+ "gerrit:commit_message(M),"
+ "regex_matches('.*MERGE_ALWAYS.*', M),"
+ "!.\n"
+ "submit_type(cherry_pick) :-"
+ "gerrit:commit_message(M),"
+ "regex_matches('.*CHERRY_PICK.*', M),"
+ "!.\n"
+ "submit_type(T) :- gerrit:project_default_submit_type(T).";
private PushOneCommit.Result createChange(String dest, String subject)
throws Exception {
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo,
subject, "file" + fileCounter.incrementAndGet(),
PushOneCommit.FILE_CONTENT);
private PushOneCommit.Result createChange(String dest, String subject) throws Exception {
PushOneCommit push =
pushFactory.create(
db,
admin.getIdent(),
testRepo,
subject,
"file" + fileCounter.incrementAndGet(),
PushOneCommit.FILE_CONTENT);
PushOneCommit.Result r = push.to("refs/for/" + dest);
r.assertOkStatus();
return r;
@ -197,8 +197,7 @@ public class SubmitTypeRuleIT extends AbstractDaemonTest {
List<RevCommit> log = log("master", 1);
assertThat(log.get(0).getShortMessage()).isEqualTo("CHERRY_PICK 1");
assertThat(log.get(0).name()).isNotEqualTo(r.getCommit().name());
assertThat(log.get(0).getFullMessage())
.contains("Change-Id: " + r.getChangeId());
assertThat(log.get(0).getFullMessage()).contains("Change-Id: " + r.getChangeId());
assertThat(log.get(0).getFullMessage()).contains("Reviewed-on: ");
}
@ -226,8 +225,7 @@ public class SubmitTypeRuleIT extends AbstractDaemonTest {
List<RevCommit> branchLog = log("branch", 1);
assertThat(branchLog.get(0).getParents()).hasLength(2);
assertThat(branchLog.get(0).getParent(1).name())
.isEqualTo(r2.getCommit().name());
assertThat(branchLog.get(0).getParent(1).name()).isEqualTo(r2.getCommit().name());
}
@Test
@ -244,11 +242,16 @@ public class SubmitTypeRuleIT extends AbstractDaemonTest {
gApi.changes().id(r2.getChangeId()).current().submit();
fail("Expected ResourceConflictException");
} catch (ResourceConflictException e) {
assertThat(e).hasMessage(
"Failed to submit 2 changes due to the following problems:\n"
+ "Change " + r1.getChange().getId() + ": Change has submit type "
+ "CHERRY_PICK, but previously chose submit type MERGE_IF_NECESSARY "
+ "from change " + r2.getChange().getId() + " in the same batch");
assertThat(e)
.hasMessage(
"Failed to submit 2 changes due to the following problems:\n"
+ "Change "
+ r1.getChange().getId()
+ ": Change has submit type "
+ "CHERRY_PICK, but previously chose submit type MERGE_IF_NECESSARY "
+ "from change "
+ r2.getChange().getId()
+ " in the same batch");
}
}
@ -261,9 +264,7 @@ public class SubmitTypeRuleIT extends AbstractDaemonTest {
}
}
private void assertSubmitType(SubmitType expected, String id)
throws Exception {
assertThat(gApi.changes().id(id).current().submitType())
.isEqualTo(expected);
private void assertSubmitType(SubmitType expected, String id) throws Exception {
assertThat(gApi.changes().id(id).current().submitType()).isEqualTo(expected);
}
}

View File

@ -20,7 +20,6 @@ import static com.google.gerrit.acceptance.AssertUtil.assertPrefs;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.extensions.client.DiffPreferencesInfo;
import org.junit.Test;
@NoHttpd
@ -28,8 +27,7 @@ public class DiffPreferencesIT extends AbstractDaemonTest {
@Test
public void getDiffPreferences() throws Exception {
DiffPreferencesInfo result =
gApi.config().server().getDefaultDiffPreferences();
DiffPreferencesInfo result = gApi.config().server().getDefaultDiffPreferences();
assertPrefs(result, DiffPreferencesInfo.defaults());
}
@ -38,8 +36,7 @@ public class DiffPreferencesIT extends AbstractDaemonTest {
int newLineLength = DiffPreferencesInfo.defaults().lineLength + 10;
DiffPreferencesInfo update = new DiffPreferencesInfo();
update.lineLength = newLineLength;
DiffPreferencesInfo result =
gApi.config().server().setDefaultDiffPreferences(update);
DiffPreferencesInfo result = gApi.config().server().setDefaultDiffPreferences(update);
assertThat(result.lineLength).named("lineLength").isEqualTo(newLineLength);
result = gApi.config().server().getDefaultDiffPreferences();

View File

@ -23,7 +23,6 @@ import com.google.gerrit.extensions.client.GeneralPreferencesInfo;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.config.AllUsersName;
import com.google.inject.Inject;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.junit.After;
@ -31,8 +30,7 @@ import org.junit.Test;
@NoHttpd
public class GeneralPreferencesIT extends AbstractDaemonTest {
@Inject
private AllUsersName allUsers;
@Inject private AllUsersName allUsers;
@After
public void cleanUp() throws Exception {
@ -48,8 +46,7 @@ public class GeneralPreferencesIT extends AbstractDaemonTest {
@Test
public void getGeneralPreferences() throws Exception {
GeneralPreferencesInfo result =
gApi.config().server().getDefaultPreferences();
GeneralPreferencesInfo result = gApi.config().server().getDefaultPreferences();
assertPrefs(result, GeneralPreferencesInfo.defaults(), "my");
}
@ -58,8 +55,7 @@ public class GeneralPreferencesIT extends AbstractDaemonTest {
boolean newSignedOffBy = !GeneralPreferencesInfo.defaults().signedOffBy;
GeneralPreferencesInfo update = new GeneralPreferencesInfo();
update.signedOffBy = newSignedOffBy;
GeneralPreferencesInfo result =
gApi.config().server().setDefaultPreferences(update);
GeneralPreferencesInfo result = gApi.config().server().setDefaultPreferences(update);
assertThat(result.signedOffBy).named("signedOffBy").isEqualTo(newSignedOffBy);
result = gApi.config().server().getDefaultPreferences();

View File

@ -19,14 +19,12 @@ import static com.google.common.truth.Truth.assertThat;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.common.Version;
import org.junit.Test;
@NoHttpd
public class ServerIT extends AbstractDaemonTest {
@Test
public void getVersion() throws Exception {
assertThat(gApi.config().server().getVersion())
.isEqualTo(Version.getVersion());
assertThat(gApi.config().server().getVersion()).isEqualTo(Version.getVersion());
}
}

View File

@ -20,18 +20,15 @@ import static com.google.common.truth.Truth.assert_;
import com.google.gerrit.extensions.common.GroupInfo;
import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.reviewdb.client.AccountGroup;
import java.util.Set;
public class GroupAssert {
public static void assertGroups(Iterable<String> expected, Set<String> actual) {
for (String g : expected) {
assert_().withFailureMessage("missing group " + g)
.that(actual.remove(g)).isTrue();
assert_().withFailureMessage("missing group " + g).that(actual.remove(g)).isTrue();
}
assert_().withFailureMessage("unexpected groups: " + actual)
.that(actual).isEmpty();
assert_().withFailureMessage("unexpected groups: " + actual).that(actual).isEmpty();
}
public static void assertGroupInfo(AccountGroup group, GroupInfo info) {

View File

@ -43,15 +43,13 @@ import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.group.SystemGroupBackend;
import org.junit.Test;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.junit.Test;
@NoHttpd
public class GroupsIT extends AbstractDaemonTest {
@ -141,8 +139,7 @@ public class GroupsIT extends AbstractDaemonTest {
}
@Test
public void createDuplicateInternalGroupCaseSensitiveName_Conflict()
throws Exception {
public void createDuplicateInternalGroupCaseSensitiveName_Conflict() throws Exception {
String dupGroupName = name("dupGroup");
gApi.groups().create(dupGroupName);
exception.expect(ResourceConflictException.class);
@ -151,8 +148,7 @@ public class GroupsIT extends AbstractDaemonTest {
}
@Test
public void createDuplicateInternalGroupCaseInsensitiveName()
throws Exception {
public void createDuplicateInternalGroupCaseInsensitiveName() throws Exception {
String dupGroupName = name("dupGroupA");
String dupGroupNameLowerCase = name("dupGroupA").toLowerCase();
gApi.groups().create(dupGroupName);
@ -162,8 +158,7 @@ public class GroupsIT extends AbstractDaemonTest {
}
@Test
public void createDuplicateSystemGroupCaseSensitiveName_Conflict()
throws Exception {
public void createDuplicateSystemGroupCaseSensitiveName_Conflict() throws Exception {
String newGroupName = "Registered Users";
exception.expect(ResourceConflictException.class);
exception.expectMessage("group 'Registered Users' already exists");
@ -171,8 +166,7 @@ public class GroupsIT extends AbstractDaemonTest {
}
@Test
public void createDuplicateSystemGroupCaseInsensitiveName_Conflict()
throws Exception {
public void createDuplicateSystemGroupCaseInsensitiveName_Conflict() throws Exception {
String newGroupName = "registered users";
exception.expect(ResourceConflictException.class);
exception.expectMessage("group 'Registered Users' already exists");
@ -181,8 +175,7 @@ public class GroupsIT extends AbstractDaemonTest {
@Test
@GerritConfig(name = "groups.global:Anonymous-Users.name", value = "All Users")
public void createGroupWithConfiguredNameOfSystemGroup_Conflict()
throws Exception {
public void createGroupWithConfiguredNameOfSystemGroup_Conflict() throws Exception {
exception.expect(ResourceConflictException.class);
exception.expectMessage("group 'All Users' already exists");
gApi.groups().create("all users");
@ -190,8 +183,7 @@ public class GroupsIT extends AbstractDaemonTest {
@Test
@GerritConfig(name = "groups.global:Anonymous-Users.name", value = "All Users")
public void createGroupWithDefaultNameOfSystemGroup_Conflict()
throws Exception {
public void createGroupWithDefaultNameOfSystemGroup_Conflict() throws Exception {
exception.expect(ResourceConflictException.class);
exception.expectMessage("group name 'Anonymous Users' is reserved");
gApi.groups().create("anonymous users");
@ -225,42 +217,34 @@ public class GroupsIT extends AbstractDaemonTest {
testGetGroup(adminGroup.getId().get(), adminGroup);
}
private void testGetGroup(Object id, AccountGroup expectedGroup)
throws Exception {
private void testGetGroup(Object id, AccountGroup expectedGroup) throws Exception {
GroupInfo group = gApi.groups().id(id.toString()).get();
assertGroupInfo(expectedGroup, group);
}
@Test
@GerritConfig(name = "groups.global:Anonymous-Users.name",
value = "All Users")
@GerritConfig(name = "groups.global:Anonymous-Users.name", value = "All Users")
public void getSystemGroupByConfiguredName() throws Exception {
GroupReference anonymousUsersGroup =
systemGroupBackend.getGroup(ANONYMOUS_USERS);
GroupReference anonymousUsersGroup = systemGroupBackend.getGroup(ANONYMOUS_USERS);
assertThat(anonymousUsersGroup.getName()).isEqualTo("All Users");
GroupInfo group =
gApi.groups().id(anonymousUsersGroup.getUUID().get()).get();
GroupInfo group = gApi.groups().id(anonymousUsersGroup.getUUID().get()).get();
assertThat(group.name).isEqualTo(anonymousUsersGroup.getName());
group = gApi.groups().id(anonymousUsersGroup.getName()).get();
assertThat(group.id)
.isEqualTo(Url.encode((anonymousUsersGroup.getUUID().get())));
assertThat(group.id).isEqualTo(Url.encode((anonymousUsersGroup.getUUID().get())));
}
@Test
public void getSystemGroupByDefaultName() throws Exception {
GroupReference anonymousUsersGroup =
systemGroupBackend.getGroup(ANONYMOUS_USERS);
GroupReference anonymousUsersGroup = systemGroupBackend.getGroup(ANONYMOUS_USERS);
GroupInfo group = gApi.groups().id("Anonymous Users").get();
assertThat(group.name).isEqualTo(anonymousUsersGroup.getName());
assertThat(group.id)
.isEqualTo(Url.encode((anonymousUsersGroup.getUUID().get())));
assertThat(group.id).isEqualTo(Url.encode((anonymousUsersGroup.getUUID().get())));
}
@Test
@GerritConfig(name = "groups.global:Anonymous-Users.name",
value = "All Users")
@GerritConfig(name = "groups.global:Anonymous-Users.name", value = "All Users")
public void getSystemGroupByDefaultName_NotFound() throws Exception {
exception.expect(ResourceNotFoundException.class);
gApi.groups().id("Anonymous-Users").get();
@ -345,18 +329,15 @@ public class GroupsIT extends AbstractDaemonTest {
String registeredUUID = SystemGroupBackend.REGISTERED_USERS.get();
// get owner
assertThat(Url.decode(gApi.groups().id(name).owner().id))
.isEqualTo(info.id);
assertThat(Url.decode(gApi.groups().id(name).owner().id)).isEqualTo(info.id);
// set owner by name
gApi.groups().id(name).owner("Registered Users");
assertThat(Url.decode(gApi.groups().id(name).owner().id))
.isEqualTo(registeredUUID);
assertThat(Url.decode(gApi.groups().id(name).owner().id)).isEqualTo(registeredUUID);
// set owner by UUID
gApi.groups().id(name).owner(adminUUID);
assertThat(Url.decode(gApi.groups().id(name).owner().id))
.isEqualTo(adminUUID);
assertThat(Url.decode(gApi.groups().id(name).owner().id)).isEqualTo(adminUUID);
// set non existing owner
exception.expect(UnprocessableEntityException.class);
@ -447,19 +428,17 @@ public class GroupsIT extends AbstractDaemonTest {
@Test
public void defaultGroupsCreated() throws Exception {
Iterable<String> names = gApi.groups().list().getAsMap().keySet();
assertThat(names).containsAllOf("Administrators", "Non-Interactive Users")
.inOrder();
assertThat(names).containsAllOf("Administrators", "Non-Interactive Users").inOrder();
}
@Test
public void listAllGroups() throws Exception {
List<String> expectedGroups = groupCache.all().stream()
.map(a -> a.getName())
.sorted()
.collect(toList());
List<String> expectedGroups =
groupCache.all().stream().map(a -> a.getName()).sorted().collect(toList());
assertThat(expectedGroups.size()).isAtLeast(2);
assertThat(gApi.groups().list().getAsMap().keySet())
.containsExactlyElementsIn(expectedGroups).inOrder();
.containsExactlyElementsIn(expectedGroups)
.inOrder();
}
@Test
@ -473,8 +452,7 @@ public class GroupsIT extends AbstractDaemonTest {
gApi.groups().create(in);
setApiUser(user);
assertThat(gApi.groups().list().getAsMap())
.doesNotContainKey(newGroupName);
assertThat(gApi.groups().list().getAsMap()).doesNotContainKey(newGroupName);
setApiUser(admin);
gApi.groups().id(newGroupName).addMembers(user.username);
@ -493,8 +471,7 @@ public class GroupsIT extends AbstractDaemonTest {
@Test
public void allGroupInfoFieldsSetCorrectly() throws Exception {
AccountGroup adminGroup = getFromCache("Administrators");
Map<String, GroupInfo> groups =
gApi.groups().list().addGroup(adminGroup.getName()).getAsMap();
Map<String, GroupInfo> groups = gApi.groups().list().addGroup(adminGroup.getName()).getAsMap();
assertThat(groups).hasSize(1);
assertThat(groups).containsKey("Administrators");
assertGroupInfo(adminGroup, Iterables.getOnlyElement(groups.values()));
@ -544,8 +521,8 @@ public class GroupsIT extends AbstractDaemonTest {
TestAccount groupOwner = accounts.user2();
GroupInput in = new GroupInput();
in.name = name("group");
in.members = Collections.singleton(groupOwner).stream()
.map(u -> u.id.toString()).collect(toList());
in.members =
Collections.singleton(groupOwner).stream().map(u -> u.id.toString()).collect(toList());
in.visibleToAll = true;
GroupInfo group = gApi.groups().create(in).get();
@ -564,53 +541,53 @@ public class GroupsIT extends AbstractDaemonTest {
gApi.groups().id(group.id).index();
}
private void assertAuditEvent(GroupAuditEventInfo info, Type expectedType,
Account.Id expectedUser, Account.Id expectedMember) {
private void assertAuditEvent(
GroupAuditEventInfo info,
Type expectedType,
Account.Id expectedUser,
Account.Id expectedMember) {
assertThat(info.user._accountId).isEqualTo(expectedUser.get());
assertThat(info.type).isEqualTo(expectedType);
assertThat(info).isInstanceOf(UserMemberAuditEventInfo.class);
assertThat(((UserMemberAuditEventInfo) info).member._accountId).isEqualTo(
expectedMember.get());
assertThat(((UserMemberAuditEventInfo) info).member._accountId).isEqualTo(expectedMember.get());
}
private void assertAuditEvent(GroupAuditEventInfo info, Type expectedType,
Account.Id expectedUser, String expectedMemberGroupName) {
private void assertAuditEvent(
GroupAuditEventInfo info,
Type expectedType,
Account.Id expectedUser,
String expectedMemberGroupName) {
assertThat(info.user._accountId).isEqualTo(expectedUser.get());
assertThat(info.type).isEqualTo(expectedType);
assertThat(info).isInstanceOf(GroupMemberAuditEventInfo.class);
assertThat(((GroupMemberAuditEventInfo) info).member.name).isEqualTo(
expectedMemberGroupName);
assertThat(((GroupMemberAuditEventInfo) info).member.name).isEqualTo(expectedMemberGroupName);
}
private void assertMembers(String group, TestAccount... expectedMembers)
throws Exception {
private void assertMembers(String group, TestAccount... expectedMembers) throws Exception {
assertMembers(
gApi.groups().id(group).members(),
TestAccount.names(expectedMembers).stream().toArray(String[]::new));
assertAccountInfos(
Arrays.asList(expectedMembers),
gApi.groups().id(group).members());
assertAccountInfos(Arrays.asList(expectedMembers), gApi.groups().id(group).members());
}
private void assertMembers(Iterable<AccountInfo> members,
String... expectedNames) {
private void assertMembers(Iterable<AccountInfo> members, String... expectedNames) {
assertThat(Iterables.transform(members, i -> i.name))
.containsExactlyElementsIn(Arrays.asList(expectedNames)).inOrder();
.containsExactlyElementsIn(Arrays.asList(expectedNames))
.inOrder();
}
private void assertNoMembers(String group) throws Exception {
assertThat(gApi.groups().id(group).members()).isEmpty();
}
private void assertIncludes(String group, String... expectedNames)
throws Exception {
private void assertIncludes(String group, String... expectedNames) throws Exception {
assertIncludes(gApi.groups().id(group).includedGroups(), expectedNames);
}
private static void assertIncludes(
Iterable<GroupInfo> includes, String... expectedNames) {
private static void assertIncludes(Iterable<GroupInfo> includes, String... expectedNames) {
assertThat(Iterables.transform(includes, i -> i.name))
.containsExactlyElementsIn(Arrays.asList(expectedNames)).inOrder();
.containsExactlyElementsIn(Arrays.asList(expectedNames))
.inOrder();
}
private void assertNoIncludes(String group) throws Exception {

View File

@ -29,45 +29,32 @@ import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.reviewdb.client.RefNames;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Test;
@NoHttpd
public class ProjectIT extends AbstractDaemonTest {
public class ProjectIT extends AbstractDaemonTest {
@Test
public void createProject() throws Exception {
String name = name("foo");
assertThat(name).isEqualTo(
gApi.projects()
.create(name)
.get()
.name);
assertThat(name).isEqualTo(gApi.projects().create(name).get().name);
RevCommit head = getRemoteHead(name, RefNames.REFS_CONFIG);
eventRecorder.assertRefUpdatedEvents(name, RefNames.REFS_CONFIG,
null, head);
eventRecorder.assertRefUpdatedEvents(name, RefNames.REFS_CONFIG, null, head);
eventRecorder.assertRefUpdatedEvents(name, "refs/heads/master",
new String[]{});
eventRecorder.assertRefUpdatedEvents(name, "refs/heads/master", new String[] {});
}
@Test
public void createProjectWithGitSuffix() throws Exception {
String name = name("foo");
assertThat(name).isEqualTo(
gApi.projects()
.create(name + ".git")
.get()
.name);
assertThat(name).isEqualTo(gApi.projects().create(name + ".git").get().name);
RevCommit head = getRemoteHead(name, RefNames.REFS_CONFIG);
eventRecorder.assertRefUpdatedEvents(name, RefNames.REFS_CONFIG,
null, head);
eventRecorder.assertRefUpdatedEvents(name, RefNames.REFS_CONFIG, null, head);
eventRecorder.assertRefUpdatedEvents(name, "refs/heads/master",
new String[]{});
eventRecorder.assertRefUpdatedEvents(name, "refs/heads/master", new String[] {});
}
@Test
@ -76,19 +63,13 @@ public class ProjectIT extends AbstractDaemonTest {
ProjectInput input = new ProjectInput();
input.name = name;
input.createEmptyCommit = true;
assertThat(name).isEqualTo(
gApi.projects()
.create(input)
.get()
.name);
assertThat(name).isEqualTo(gApi.projects().create(input).get().name);
RevCommit head = getRemoteHead(name, RefNames.REFS_CONFIG);
eventRecorder.assertRefUpdatedEvents(name, RefNames.REFS_CONFIG,
null, head);
eventRecorder.assertRefUpdatedEvents(name, RefNames.REFS_CONFIG, null, head);
head = getRemoteHead(name, "refs/heads/master");
eventRecorder.assertRefUpdatedEvents(name, "refs/heads/master",
null, head);
eventRecorder.assertRefUpdatedEvents(name, "refs/heads/master", null, head);
}
@Test
@ -97,9 +78,7 @@ public class ProjectIT extends AbstractDaemonTest {
in.name = name("foo");
exception.expect(BadRequestException.class);
exception.expectMessage("name must match input.name");
gApi.projects()
.name("bar")
.create(in);
gApi.projects().name("bar").create(in);
}
@Test
@ -107,51 +86,37 @@ public class ProjectIT extends AbstractDaemonTest {
ProjectInput in = new ProjectInput();
exception.expect(BadRequestException.class);
exception.expectMessage("input.name is required");
gApi.projects()
.create(in);
gApi.projects().create(in);
}
@Test
public void createProjectDuplicate() throws Exception {
ProjectInput in = new ProjectInput();
in.name = name("baz");
gApi.projects()
.create(in);
gApi.projects().create(in);
exception.expect(ResourceConflictException.class);
exception.expectMessage("Project already exists");
gApi.projects()
.create(in);
gApi.projects().create(in);
}
@Test
public void createBranch() throws Exception {
allow(Permission.READ, ANONYMOUS_USERS, "refs/*");
gApi.projects()
.name(project.get())
.branch("foo")
.create(new BranchInput());
gApi.projects().name(project.get()).branch("foo").create(new BranchInput());
}
@Test
public void description() throws Exception {
RevCommit initialHead = getRemoteHead(project, RefNames.REFS_CONFIG);
assertThat(gApi.projects()
.name(project.get())
.description())
.isEmpty();
assertThat(gApi.projects().name(project.get()).description()).isEmpty();
DescriptionInput in = new DescriptionInput();
in.description = "new project description";
gApi.projects()
.name(project.get())
.description(in);
assertThat(gApi.projects()
.name(project.get())
.description())
.isEqualTo(in.description);
gApi.projects().name(project.get()).description(in);
assertThat(gApi.projects().name(project.get()).description()).isEqualTo(in.description);
RevCommit updatedHead = getRemoteHead(project, RefNames.REFS_CONFIG);
eventRecorder.assertRefUpdatedEvents(project.get(), RefNames.REFS_CONFIG,
initialHead, updatedHead);
eventRecorder.assertRefUpdatedEvents(
project.get(), RefNames.REFS_CONFIG, initialHead, updatedHead);
}
@Test
@ -168,7 +133,7 @@ public class ProjectIT extends AbstractDaemonTest {
assertThat(info.submitType).isEqualTo(SubmitType.CHERRY_PICK);
RevCommit updatedHead = getRemoteHead(project, RefNames.REFS_CONFIG);
eventRecorder.assertRefUpdatedEvents(project.get(), RefNames.REFS_CONFIG,
initialHead, updatedHead);
eventRecorder.assertRefUpdatedEvents(
project.get(), RefNames.REFS_CONFIG, initialHead, updatedHead);
}
}

View File

@ -31,15 +31,13 @@ import com.google.gerrit.extensions.common.RobotCommentInfo;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
import com.google.gerrit.extensions.restapi.RestApiException;
import org.junit.Before;
import org.junit.Test;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
public class RobotCommentsIT extends AbstractDaemonTest {
private String changeId;
@ -58,14 +56,11 @@ public class RobotCommentsIT extends AbstractDaemonTest {
}
@Test
public void retrievingRobotCommentsBeforeAddingAnyDoesNotRaiseAnException()
throws Exception {
public void retrievingRobotCommentsBeforeAddingAnyDoesNotRaiseAnException() throws Exception {
assume().that(notesMigration.enabled()).isTrue();
Map<String, List<RobotCommentInfo>> robotComments = gApi.changes()
.id(changeId)
.current()
.robotComments();
Map<String, List<RobotCommentInfo>> robotComments =
gApi.changes().id(changeId).current().robotComments();
assertThat(robotComments).isNotNull();
assertThat(robotComments).isEmpty();
@ -78,10 +73,7 @@ public class RobotCommentsIT extends AbstractDaemonTest {
RobotCommentInput in = createRobotCommentInput();
addRobotComment(changeId, in);
Map<String, List<RobotCommentInfo>> out = gApi.changes()
.id(changeId)
.current()
.robotComments();
Map<String, List<RobotCommentInfo>> out = gApi.changes().id(changeId).current().robotComments();
assertThat(out).hasSize(1);
RobotCommentInfo comment = Iterables.getOnlyElement(out.get(in.path));
@ -95,14 +87,12 @@ public class RobotCommentsIT extends AbstractDaemonTest {
RobotCommentInput in = createRobotCommentInput();
addRobotComment(changeId, in);
pushFactory.create(db, admin.getIdent(), testRepo, changeId)
.to("refs/for/master");
pushFactory.create(db, admin.getIdent(), testRepo, changeId).to("refs/for/master");
RobotCommentInput in2 = createRobotCommentInput();
addRobotComment(changeId, in2);
Map<String, List<RobotCommentInfo>> out =
gApi.changes().id(changeId).robotComments();
Map<String, List<RobotCommentInfo>> out = gApi.changes().id(changeId).robotComments();
assertThat(out).hasSize(1);
assertThat(out.get(in.path)).hasSize(2);
@ -120,14 +110,11 @@ public class RobotCommentsIT extends AbstractDaemonTest {
RobotCommentInput robotCommentInput = createRobotCommentInput();
addRobotComment(changeId, robotCommentInput);
List<RobotCommentInfo> robotCommentInfos = gApi.changes()
.id(changeId)
.current()
.robotCommentsAsList();
List<RobotCommentInfo> robotCommentInfos =
gApi.changes().id(changeId).current().robotCommentsAsList();
assertThat(robotCommentInfos).hasSize(1);
RobotCommentInfo robotCommentInfo =
Iterables.getOnlyElement(robotCommentInfos);
RobotCommentInfo robotCommentInfo = Iterables.getOnlyElement(robotCommentInfos);
assertRobotComment(robotCommentInfo, robotCommentInput);
}
@ -139,14 +126,10 @@ public class RobotCommentsIT extends AbstractDaemonTest {
addRobotComment(changeId, robotCommentInput);
List<RobotCommentInfo> robotCommentInfos = getRobotComments();
RobotCommentInfo robotCommentInfo =
Iterables.getOnlyElement(robotCommentInfos);
RobotCommentInfo robotCommentInfo = Iterables.getOnlyElement(robotCommentInfos);
RobotCommentInfo specificRobotCommentInfo = gApi.changes()
.id(changeId)
.current()
.robotComment(robotCommentInfo.id)
.get();
RobotCommentInfo specificRobotCommentInfo =
gApi.changes().id(changeId).current().robotComment(robotCommentInfo.id).get();
assertRobotComment(specificRobotCommentInfo, robotCommentInput);
}
@ -157,10 +140,7 @@ public class RobotCommentsIT extends AbstractDaemonTest {
RobotCommentInput in = createRobotCommentInputWithMandatoryFields();
addRobotComment(changeId, in);
Map<String, List<RobotCommentInfo>> out = gApi.changes()
.id(changeId)
.current()
.robotComments();
Map<String, List<RobotCommentInfo>> out = gApi.changes().id(changeId).current().robotComments();
assertThat(out).hasSize(1);
RobotCommentInfo comment = Iterables.getOnlyElement(out.get(in.path));
assertRobotComment(comment, in, false);
@ -173,22 +153,22 @@ public class RobotCommentsIT extends AbstractDaemonTest {
addRobotComment(changeId, withFixRobotCommentInput);
List<RobotCommentInfo> robotCommentInfos = getRobotComments();
assertThatList(robotCommentInfos).onlyElement()
.onlyFixSuggestion().isNotNull();
assertThatList(robotCommentInfos).onlyElement().onlyFixSuggestion().isNotNull();
}
@Test
public void fixIdIsGeneratedForFixSuggestion()
throws Exception {
public void fixIdIsGeneratedForFixSuggestion() throws Exception {
assume().that(notesMigration.enabled()).isTrue();
addRobotComment(changeId, withFixRobotCommentInput);
List<RobotCommentInfo> robotCommentInfos = getRobotComments();
assertThatList(robotCommentInfos).onlyElement()
.onlyFixSuggestion().fixId().isNotEmpty();
assertThatList(robotCommentInfos).onlyElement()
.onlyFixSuggestion().fixId().isNotEqualTo(fixSuggestionInfo.fixId);
assertThatList(robotCommentInfos).onlyElement().onlyFixSuggestion().fixId().isNotEmpty();
assertThatList(robotCommentInfos)
.onlyElement()
.onlyFixSuggestion()
.fixId()
.isNotEqualTo(fixSuggestionInfo.fixId);
}
@Test
@ -198,8 +178,11 @@ public class RobotCommentsIT extends AbstractDaemonTest {
addRobotComment(changeId, withFixRobotCommentInput);
List<RobotCommentInfo> robotCommentInfos = getRobotComments();
assertThatList(robotCommentInfos).onlyElement().onlyFixSuggestion()
.description().isEqualTo(fixSuggestionInfo.description);
assertThatList(robotCommentInfos)
.onlyElement()
.onlyFixSuggestion()
.description()
.isEqualTo(fixSuggestionInfo.description);
}
@Test
@ -209,9 +192,10 @@ public class RobotCommentsIT extends AbstractDaemonTest {
fixSuggestionInfo.description = null;
exception.expect(BadRequestException.class);
exception.expectMessage(String.format("A description is required for the "
+ "suggested fix of the robot comment on %s",
withFixRobotCommentInput.path));
exception.expectMessage(
String.format(
"A description is required for the " + "suggested fix of the robot comment on %s",
withFixRobotCommentInput.path));
addRobotComment(changeId, withFixRobotCommentInput);
}
@ -222,8 +206,11 @@ public class RobotCommentsIT extends AbstractDaemonTest {
addRobotComment(changeId, withFixRobotCommentInput);
List<RobotCommentInfo> robotCommentInfos = getRobotComments();
assertThatList(robotCommentInfos).onlyElement().onlyFixSuggestion()
.onlyReplacement().isNotNull();
assertThatList(robotCommentInfos)
.onlyElement()
.onlyFixSuggestion()
.onlyReplacement()
.isNotNull();
}
@Test
@ -233,9 +220,11 @@ public class RobotCommentsIT extends AbstractDaemonTest {
fixSuggestionInfo.replacements = Collections.emptyList();
exception.expect(BadRequestException.class);
exception.expectMessage(String.format("At least one replacement is required"
+ " for the suggested fix of the robot comment on %s",
withFixRobotCommentInput.path));
exception.expectMessage(
String.format(
"At least one replacement is required"
+ " for the suggested fix of the robot comment on %s",
withFixRobotCommentInput.path));
addRobotComment(changeId, withFixRobotCommentInput);
}
@ -247,8 +236,12 @@ public class RobotCommentsIT extends AbstractDaemonTest {
List<RobotCommentInfo> robotCommentInfos = getRobotComments();
assertThatList(robotCommentInfos).onlyElement().onlyFixSuggestion()
.onlyReplacement().path().isEqualTo(fixReplacementInfo.path);
assertThatList(robotCommentInfos)
.onlyElement()
.onlyFixSuggestion()
.onlyReplacement()
.path()
.isEqualTo(fixReplacementInfo.path);
}
@Test
@ -258,9 +251,10 @@ public class RobotCommentsIT extends AbstractDaemonTest {
fixReplacementInfo.path = null;
exception.expect(BadRequestException.class);
exception.expectMessage(String.format("A file path must be given for the "
+ "replacement of the robot comment on %s",
withFixRobotCommentInput.path));
exception.expectMessage(
String.format(
"A file path must be given for the " + "replacement of the robot comment on %s",
withFixRobotCommentInput.path));
addRobotComment(changeId, withFixRobotCommentInput);
}
@ -271,9 +265,11 @@ public class RobotCommentsIT extends AbstractDaemonTest {
fixReplacementInfo.path = "anotherFile.txt";
exception.expect(BadRequestException.class);
exception.expectMessage(String.format("Replacements may only be specified "
+ "for the file %s on which the robot comment was added",
withFixRobotCommentInput.path));
exception.expectMessage(
String.format(
"Replacements may only be specified "
+ "for the file %s on which the robot comment was added",
withFixRobotCommentInput.path));
addRobotComment(changeId, withFixRobotCommentInput);
}
@ -285,8 +281,12 @@ public class RobotCommentsIT extends AbstractDaemonTest {
List<RobotCommentInfo> robotCommentInfos = getRobotComments();
assertThatList(robotCommentInfos).onlyElement().onlyFixSuggestion()
.onlyReplacement().range().isEqualTo(fixReplacementInfo.range);
assertThatList(robotCommentInfos)
.onlyElement()
.onlyFixSuggestion()
.onlyReplacement()
.range()
.isEqualTo(fixReplacementInfo.range);
}
@Test
@ -296,9 +296,10 @@ public class RobotCommentsIT extends AbstractDaemonTest {
fixReplacementInfo.range = null;
exception.expect(BadRequestException.class);
exception.expectMessage(String.format("A range must be given for the "
+ "replacement of the robot comment on %s",
withFixRobotCommentInput.path));
exception.expectMessage(
String.format(
"A range must be given for the " + "replacement of the robot comment on %s",
withFixRobotCommentInput.path));
addRobotComment(changeId, withFixRobotCommentInput);
}
@ -309,37 +310,41 @@ public class RobotCommentsIT extends AbstractDaemonTest {
fixReplacementInfo.range = createRange(13, 9, 5, 10);
exception.expect(BadRequestException.class);
exception.expectMessage(String.format("Range (13:9 - 5:10) is not "
+ "valid for the replacement of the robot comment on %s",
withFixRobotCommentInput.path));
exception.expectMessage(
String.format(
"Range (13:9 - 5:10) is not " + "valid for the replacement of the robot comment on %s",
withFixRobotCommentInput.path));
addRobotComment(changeId, withFixRobotCommentInput);
}
@Test
public void replacementStringOfFixReplacementIsAcceptedAsIs()
throws Exception {
public void replacementStringOfFixReplacementIsAcceptedAsIs() throws Exception {
assume().that(notesMigration.enabled()).isTrue();
addRobotComment(changeId, withFixRobotCommentInput);
List<RobotCommentInfo> robotCommentInfos = getRobotComments();
assertThatList(robotCommentInfos).onlyElement()
.onlyFixSuggestion().onlyReplacement()
.replacement().isEqualTo(fixReplacementInfo.replacement);
assertThatList(robotCommentInfos)
.onlyElement()
.onlyFixSuggestion()
.onlyReplacement()
.replacement()
.isEqualTo(fixReplacementInfo.replacement);
}
@Test
public void replacementStringOfFixReplacementIsMandatory()
throws Exception {
public void replacementStringOfFixReplacementIsMandatory() throws Exception {
assume().that(notesMigration.enabled()).isTrue();
fixReplacementInfo.replacement = null;
exception.expect(BadRequestException.class);
exception.expectMessage(String.format("A content for replacement must be "
+ "indicated for the replacement of the robot comment on %s",
withFixRobotCommentInput.path));
exception.expectMessage(
String.format(
"A content for replacement must be "
+ "indicated for the replacement of the robot comment on %s",
withFixRobotCommentInput.path));
addRobotComment(changeId, withFixRobotCommentInput);
}
@ -356,10 +361,7 @@ public class RobotCommentsIT extends AbstractDaemonTest {
exception.expect(MethodNotAllowedException.class);
exception.expectMessage("robot comments not supported");
gApi.changes()
.id(changeId)
.current()
.review(reviewInput);
gApi.changes().id(changeId).current().review(reviewInput);
}
private RobotCommentInput createRobotCommentInputWithMandatoryFields() {
@ -372,8 +374,7 @@ public class RobotCommentsIT extends AbstractDaemonTest {
return in;
}
private RobotCommentInput createRobotCommentInput(
FixSuggestionInfo... fixSuggestionInfos) {
private RobotCommentInput createRobotCommentInput(FixSuggestionInfo... fixSuggestionInfos) {
RobotCommentInput in = createRobotCommentInputWithMandatoryFields();
in.url = "http://www.happy-robot.com";
in.properties = new HashMap<>();
@ -383,8 +384,7 @@ public class RobotCommentsIT extends AbstractDaemonTest {
return in;
}
private FixSuggestionInfo createFixSuggestionInfo(
FixReplacementInfo... fixReplacementInfos) {
private FixSuggestionInfo createFixSuggestionInfo(FixReplacementInfo... fixReplacementInfos) {
FixSuggestionInfo newFixSuggestionInfo = new FixSuggestionInfo();
newFixSuggestionInfo.fixId = "An ID which must be overwritten.";
newFixSuggestionInfo.description = "A description for a suggested fix.";
@ -400,8 +400,8 @@ public class RobotCommentsIT extends AbstractDaemonTest {
return newFixReplacementInfo;
}
private Comment.Range createRange(int startLine, int startCharacter,
int endLine, int endCharacter) {
private Comment.Range createRange(
int startLine, int startCharacter, int endLine, int endCharacter) {
Comment.Range range = new Comment.Range();
range.startLine = startLine;
range.startCharacter = startCharacter;
@ -410,32 +410,26 @@ public class RobotCommentsIT extends AbstractDaemonTest {
return range;
}
private void addRobotComment(String targetChangeId,
RobotCommentInput robotCommentInput) throws Exception {
private void addRobotComment(String targetChangeId, RobotCommentInput robotCommentInput)
throws Exception {
ReviewInput reviewInput = new ReviewInput();
reviewInput.robotComments = Collections.singletonMap(robotCommentInput.path,
Collections.singletonList(robotCommentInput));
reviewInput.robotComments =
Collections.singletonMap(
robotCommentInput.path, Collections.singletonList(robotCommentInput));
reviewInput.message = "robot comment test";
gApi.changes()
.id(targetChangeId)
.current()
.review(reviewInput);
gApi.changes().id(targetChangeId).current().review(reviewInput);
}
private List<RobotCommentInfo> getRobotComments() throws RestApiException {
return gApi.changes()
.id(changeId)
.current()
.robotCommentsAsList();
return gApi.changes().id(changeId).current().robotCommentsAsList();
}
private void assertRobotComment(RobotCommentInfo c,
RobotCommentInput expected) {
private void assertRobotComment(RobotCommentInfo c, RobotCommentInput expected) {
assertRobotComment(c, expected, true);
}
private void assertRobotComment(RobotCommentInfo c,
RobotCommentInput expected, boolean expectPath) {
private void assertRobotComment(
RobotCommentInfo c, RobotCommentInput expected, boolean expectPath) {
assertThat(c.robotId).isEqualTo(expected.robotId);
assertThat(c.robotRunId).isEqualTo(expected.robotRunId);
assertThat(c.url).isEqualTo(expected.url);

View File

@ -59,7 +59,12 @@ import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.ObjectId;
@ -73,13 +78,6 @@ import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
public class ChangeEditIT extends AbstractDaemonTest {
private static final String FILE_NAME = "foo";
@ -90,8 +88,7 @@ public class ChangeEditIT extends AbstractDaemonTest {
private static final String CONTENT_NEW2_STR = "quxÄÜÖßµ";
private static final byte[] CONTENT_NEW2 = CONTENT_NEW2_STR.getBytes(UTF_8);
@Inject
private SchemaFactory<ReviewDb> reviewDbProvider;
@Inject private SchemaFactory<ReviewDb> reviewDbProvider;
private String changeId;
private String changeId2;
@ -136,10 +133,7 @@ public class ChangeEditIT extends AbstractDaemonTest {
@Test
public void deleteEditOfCurrentPatchSet() throws Exception {
createArbitraryEditFor(changeId);
gApi.changes()
.id(changeId)
.edit()
.delete();
gApi.changes().id(changeId).edit().delete();
assertThat(getEdit(changeId)).isAbsent();
}
@ -148,10 +142,7 @@ public class ChangeEditIT extends AbstractDaemonTest {
createArbitraryEditFor(changeId2);
amendChange(admin.getIdent(), changeId2);
gApi.changes()
.id(changeId2)
.edit()
.delete();
gApi.changes().id(changeId2).edit().delete();
assertThat(getEdit(changeId2)).isAbsent();
}
@ -161,14 +152,13 @@ public class ChangeEditIT extends AbstractDaemonTest {
PublishChangeEditInput publishInput = new PublishChangeEditInput();
publishInput.notify = NotifyHandling.NONE;
gApi.changes()
.id(changeId)
.edit()
.publish(publishInput);
gApi.changes().id(changeId).edit().publish(publishInput);
assertThat(getEdit(changeId)).isAbsent();
assertChangeMessages(changeId,
ImmutableList.of("Uploaded patch set 1.",
assertChangeMessages(
changeId,
ImmutableList.of(
"Uploaded patch set 1.",
"Uploaded patch set 2.",
"Patch Set 3: Published edit on patch set 2."));
}
@ -181,10 +171,11 @@ public class ChangeEditIT extends AbstractDaemonTest {
adminRestSession.post(urlPublish(changeId)).assertNoContent();
assertThat(getEdit(changeId)).isAbsent();
PatchSet newCurrentPatchSet = getCurrentPatchSet(changeId);
assertThat(newCurrentPatchSet.getId())
.isNotEqualTo(oldCurrentPatchSet.getId());
assertChangeMessages(changeId,
ImmutableList.of("Uploaded patch set 1.",
assertThat(newCurrentPatchSet.getId()).isNotEqualTo(oldCurrentPatchSet.getId());
assertChangeMessages(
changeId,
ImmutableList.of(
"Uploaded patch set 1.",
"Uploaded patch set 2.",
"Patch Set 3: Published edit on patch set 2."));
}
@ -208,17 +199,12 @@ public class ChangeEditIT extends AbstractDaemonTest {
public void publishEditWithDefaultNotify() throws Exception {
AddReviewerInput in = new AddReviewerInput();
in.reviewer = user.email;
gApi.changes()
.id(changeId)
.addReviewer(in);
gApi.changes().id(changeId).addReviewer(in);
createArbitraryEditFor(changeId);
sender.clear();
gApi.changes()
.id(changeId)
.edit()
.publish();
gApi.changes().id(changeId).edit().publish();
assertThat(sender.getMessages()).isNotEmpty();
}
@ -242,69 +228,56 @@ public class ChangeEditIT extends AbstractDaemonTest {
public void rebaseEdit() throws Exception {
PatchSet previousPatchSet = getCurrentPatchSet(changeId2);
createEmptyEditFor(changeId2);
gApi.changes()
.id(changeId2)
.edit()
.modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
gApi.changes().id(changeId2).edit().modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
amendChange(admin.getIdent(), changeId2);
PatchSet currentPatchSet = getCurrentPatchSet(changeId2);
Optional<EditInfo> originalEdit = getEdit(changeId2);
assertThat(originalEdit).value().baseRevision()
.isEqualTo(previousPatchSet.getRevision().get());
assertThat(originalEdit).value().baseRevision().isEqualTo(previousPatchSet.getRevision().get());
Timestamp beforeRebase = originalEdit.get().commit.committer.date;
gApi.changes()
.id(changeId2)
.edit()
.rebase();
gApi.changes().id(changeId2).edit().rebase();
ensureSameBytes(getFileContentOfEdit(changeId2, FILE_NAME), CONTENT_NEW);
ensureSameBytes(getFileContentOfEdit(changeId2, FILE_NAME2), CONTENT_NEW2);
Optional<EditInfo> rebasedEdit = getEdit(changeId2);
assertThat(rebasedEdit).value().baseRevision()
.isEqualTo(currentPatchSet.getRevision().get());
assertThat(rebasedEdit).value().commit().committer().creationDate()
.isNotEqualTo(beforeRebase);
assertThat(rebasedEdit).value().baseRevision().isEqualTo(currentPatchSet.getRevision().get());
assertThat(rebasedEdit).value().commit().committer().creationDate().isNotEqualTo(beforeRebase);
}
@Test
public void rebaseEditRest() throws Exception {
PatchSet previousPatchSet = getCurrentPatchSet(changeId2);
createEmptyEditFor(changeId2);
gApi.changes()
.id(changeId2)
.edit()
.modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
gApi.changes().id(changeId2).edit().modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
amendChange(admin.getIdent(), changeId2);
PatchSet currentPatchSet = getCurrentPatchSet(changeId2);
Optional<EditInfo> originalEdit = getEdit(changeId2);
assertThat(originalEdit).value().baseRevision()
.isEqualTo(previousPatchSet.getRevision().get());
assertThat(originalEdit).value().baseRevision().isEqualTo(previousPatchSet.getRevision().get());
Timestamp beforeRebase = originalEdit.get().commit.committer.date;
adminRestSession.post(urlRebase(changeId2)).assertNoContent();
ensureSameBytes(getFileContentOfEdit(changeId2, FILE_NAME), CONTENT_NEW);
ensureSameBytes(getFileContentOfEdit(changeId2, FILE_NAME2), CONTENT_NEW2);
Optional<EditInfo> rebasedEdit = getEdit(changeId2);
assertThat(rebasedEdit).value().baseRevision()
.isEqualTo(currentPatchSet.getRevision().get());
assertThat(rebasedEdit).value().commit().committer().creationDate()
.isNotEqualTo(beforeRebase);
assertThat(rebasedEdit).value().baseRevision().isEqualTo(currentPatchSet.getRevision().get());
assertThat(rebasedEdit).value().commit().committer().creationDate().isNotEqualTo(beforeRebase);
}
@Test
public void rebaseEditWithConflictsRest_Conflict() throws Exception {
PatchSet currentPatchSet = getCurrentPatchSet(changeId2);
createEmptyEditFor(changeId2);
gApi.changes()
.id(changeId2)
.edit()
.modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
gApi.changes().id(changeId2).edit().modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
Optional<EditInfo> edit = getEdit(changeId2);
assertThat(edit).value().baseRevision()
.isEqualTo(currentPatchSet.getRevision().get());
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo,
PushOneCommit.SUBJECT, FILE_NAME, new String(CONTENT_NEW2, UTF_8),
changeId2);
assertThat(edit).value().baseRevision().isEqualTo(currentPatchSet.getRevision().get());
PushOneCommit push =
pushFactory.create(
db,
admin.getIdent(),
testRepo,
PushOneCommit.SUBJECT,
FILE_NAME,
new String(CONTENT_NEW2, UTF_8),
changeId2);
push.to("refs/for/master").assertOkStatus();
adminRestSession.post(urlRebase(changeId2)).assertConflict();
}
@ -312,10 +285,7 @@ public class ChangeEditIT extends AbstractDaemonTest {
@Test
public void updateExistingFile() throws Exception {
createEmptyEditFor(changeId);
gApi.changes()
.id(changeId)
.edit()
.modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
gApi.changes().id(changeId).edit().modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
assertThat(getEdit(changeId)).isPresent();
ensureSameBytes(getFileContentOfEdit(changeId, FILE_NAME), CONTENT_NEW);
ensureSameBytes(getFileContentOfEdit(changeId, FILE_NAME), CONTENT_NEW);
@ -332,85 +302,55 @@ public class ChangeEditIT extends AbstractDaemonTest {
Optional<EditInfo> edit = getEdit(changeId);
assertThat(edit).value().commit().parents().isEmpty();
String msg = String.format("New commit message\n\nChange-Id: %s\n",
changeId);
gApi.changes()
.id(changeId)
.edit()
.modifyCommitMessage(msg);
String commitMessage = gApi.changes()
.id(changeId)
.edit()
.getCommitMessage();
String msg = String.format("New commit message\n\nChange-Id: %s\n", changeId);
gApi.changes().id(changeId).edit().modifyCommitMessage(msg);
String commitMessage = gApi.changes().id(changeId).edit().getCommitMessage();
assertThat(commitMessage).isEqualTo(msg);
}
@Test
public void updateMessageNoChange() throws Exception {
createEmptyEditFor(changeId);
String commitMessage = gApi.changes()
.id(changeId)
.edit()
.getCommitMessage();
String commitMessage = gApi.changes().id(changeId).edit().getCommitMessage();
exception.expect(ResourceConflictException.class);
exception.expectMessage(
"New commit message cannot be same as existing commit message");
gApi.changes()
.id(changeId)
.edit()
.modifyCommitMessage(commitMessage);
exception.expectMessage("New commit message cannot be same as existing commit message");
gApi.changes().id(changeId).edit().modifyCommitMessage(commitMessage);
}
@Test
public void updateMessageOnlyAddTrailingNewLines() throws Exception {
createEmptyEditFor(changeId);
String commitMessage = gApi.changes()
.id(changeId)
.edit()
.getCommitMessage();
String commitMessage = gApi.changes().id(changeId).edit().getCommitMessage();
exception.expect(ResourceConflictException.class);
exception.expectMessage(
"New commit message cannot be same as existing commit message");
gApi.changes()
.id(changeId)
.edit()
.modifyCommitMessage(commitMessage + "\n\n");
exception.expectMessage("New commit message cannot be same as existing commit message");
gApi.changes().id(changeId).edit().modifyCommitMessage(commitMessage + "\n\n");
}
@Test
public void updateMessage() throws Exception {
createEmptyEditFor(changeId);
String msg = String.format("New commit message\n\nChange-Id: %s\n",
changeId);
gApi.changes()
.id(changeId)
.edit()
.modifyCommitMessage(msg);
String commitMessage = gApi.changes()
.id(changeId)
.edit()
.getCommitMessage();
String msg = String.format("New commit message\n\nChange-Id: %s\n", changeId);
gApi.changes().id(changeId).edit().modifyCommitMessage(msg);
String commitMessage = gApi.changes().id(changeId).edit().getCommitMessage();
assertThat(commitMessage).isEqualTo(msg);
PublishChangeEditInput publishInput = new PublishChangeEditInput();
publishInput.notify = NotifyHandling.NONE;
gApi.changes()
.id(changeId)
.edit()
.publish(publishInput);
gApi.changes().id(changeId).edit().publish(publishInput);
assertThat(getEdit(changeId)).isAbsent();
ChangeInfo info = get(changeId, ListChangesOption.CURRENT_COMMIT,
ListChangesOption.CURRENT_REVISION);
assertThat(info.revisions.get(info.currentRevision).commit.message)
.isEqualTo(msg);
ChangeInfo info =
get(changeId, ListChangesOption.CURRENT_COMMIT, ListChangesOption.CURRENT_REVISION);
assertThat(info.revisions.get(info.currentRevision).commit.message).isEqualTo(msg);
assertThat(info.revisions.get(info.currentRevision).description)
.isEqualTo("Edit commit message");
assertChangeMessages(changeId,
ImmutableList.of("Uploaded patch set 1.",
assertChangeMessages(
changeId,
ImmutableList.of(
"Uploaded patch set 1.",
"Uploaded patch set 2.",
"Patch Set 3: Commit message was updated."));
}
@ -419,44 +359,34 @@ public class ChangeEditIT extends AbstractDaemonTest {
public void updateMessageRest() throws Exception {
adminRestSession.get(urlEditMessage(changeId, false)).assertNotFound();
EditMessage.Input in = new EditMessage.Input();
in.message = String.format("New commit message\n\n" +
CONTENT_NEW2_STR + "\n\nChange-Id: %s\n",
changeId);
in.message =
String.format(
"New commit message\n\n" + CONTENT_NEW2_STR + "\n\nChange-Id: %s\n", changeId);
adminRestSession.put(urlEditMessage(changeId, false), in).assertNoContent();
RestResponse r = adminRestSession.getJsonAccept(urlEditMessage(changeId,
false));
RestResponse r = adminRestSession.getJsonAccept(urlEditMessage(changeId, false));
r.assertOK();
assertThat(readContentFromJson(r)).isEqualTo(in.message);
String commitMessage = gApi.changes()
.id(changeId)
.edit()
.getCommitMessage();
String commitMessage = gApi.changes().id(changeId).edit().getCommitMessage();
assertThat(commitMessage).isEqualTo(in.message);
in.message = String.format("New commit message2\n\nChange-Id: %s\n",
changeId);
in.message = String.format("New commit message2\n\nChange-Id: %s\n", changeId);
adminRestSession.put(urlEditMessage(changeId, false), in).assertNoContent();
String updatedCommitMessage = gApi.changes()
.id(changeId)
.edit()
.getCommitMessage();
String updatedCommitMessage = gApi.changes().id(changeId).edit().getCommitMessage();
assertThat(updatedCommitMessage).isEqualTo(in.message);
r = adminRestSession.getJsonAccept(urlEditMessage(changeId, true));
try (Repository repo = repoManager.openRepository(project);
RevWalk rw = new RevWalk(repo)) {
RevCommit commit = rw.parseCommit(
ObjectId.fromString(ps.getRevision().get()));
RevCommit commit = rw.parseCommit(ObjectId.fromString(ps.getRevision().get()));
assertThat(readContentFromJson(r)).isEqualTo(commit.getFullMessage());
}
PublishChangeEditInput publishInput = new PublishChangeEditInput();
publishInput.notify = NotifyHandling.NONE;
gApi.changes()
.id(changeId)
.edit()
.publish(publishInput);
assertChangeMessages(changeId,
ImmutableList.of("Uploaded patch set 1.",
gApi.changes().id(changeId).edit().publish(publishInput);
assertChangeMessages(
changeId,
ImmutableList.of(
"Uploaded patch set 1.",
"Uploaded patch set 2.",
"Patch Set 3: Commit message was updated."));
}
@ -471,10 +401,7 @@ public class ChangeEditIT extends AbstractDaemonTest {
assertThat(editInfo).commit().parents().hasSize(1);
assertThat(editInfo).baseRevision().isEqualTo(changeInfo.currentRevision);
gApi.changes()
.id(changeId)
.edit()
.delete();
gApi.changes().id(changeId).edit().delete();
adminRestSession.get(urlEdit(changeId)).assertNoContent();
}
@ -482,34 +409,24 @@ public class ChangeEditIT extends AbstractDaemonTest {
@Test
public void retrieveFilesInEdit() throws Exception {
createEmptyEditFor(changeId);
gApi.changes()
.id(changeId)
.edit()
.modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
gApi.changes().id(changeId).edit().modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
EditInfo info = getEditInfo(changeId, true);
assertThat(info.files).isNotNull();
assertThat(info.files.keySet()).containsExactly(Patch.COMMIT_MSG,
FILE_NAME, FILE_NAME2);
assertThat(info.files.keySet()).containsExactly(Patch.COMMIT_MSG, FILE_NAME, FILE_NAME2);
}
@Test
public void deleteExistingFile() throws Exception {
createEmptyEditFor(changeId);
gApi.changes()
.id(changeId)
.edit()
.deleteFile(FILE_NAME);
gApi.changes().id(changeId).edit().deleteFile(FILE_NAME);
assertThat(getFileContentOfEdit(changeId, FILE_NAME)).isAbsent();
}
@Test
public void renameExistingFile() throws Exception {
createEmptyEditFor(changeId);
gApi.changes()
.id(changeId)
.edit()
.renameFile(FILE_NAME, FILE_NAME3);
gApi.changes().id(changeId).edit().renameFile(FILE_NAME, FILE_NAME3);
ensureSameBytes(getFileContentOfEdit(changeId, FILE_NAME3), CONTENT_OLD);
assertThat(getFileContentOfEdit(changeId, FILE_NAME)).isAbsent();
}
@ -535,30 +452,18 @@ public class ChangeEditIT extends AbstractDaemonTest {
@Test
public void restoreDeletedFileInPatchSet() throws Exception {
createEmptyEditFor(changeId2);
gApi.changes()
.id(changeId2)
.edit()
.restoreFile(FILE_NAME);
gApi.changes().id(changeId2).edit().restoreFile(FILE_NAME);
ensureSameBytes(getFileContentOfEdit(changeId2, FILE_NAME), CONTENT_OLD);
}
@Test
public void revertChanges() throws Exception {
createEmptyEditFor(changeId2);
gApi.changes()
.id(changeId2)
.edit()
.restoreFile(FILE_NAME);
gApi.changes().id(changeId2).edit().restoreFile(FILE_NAME);
ensureSameBytes(getFileContentOfEdit(changeId2, FILE_NAME), CONTENT_OLD);
gApi.changes()
.id(changeId2)
.edit()
.modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
gApi.changes().id(changeId2).edit().modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
ensureSameBytes(getFileContentOfEdit(changeId2, FILE_NAME), CONTENT_NEW);
gApi.changes()
.id(changeId2)
.edit()
.restoreFile(FILE_NAME);
gApi.changes().id(changeId2).edit().restoreFile(FILE_NAME);
ensureSameBytes(getFileContentOfEdit(changeId2, FILE_NAME), CONTENT_OLD);
}
@ -584,15 +489,9 @@ public class ChangeEditIT extends AbstractDaemonTest {
@Test
public void amendExistingFile() throws Exception {
createEmptyEditFor(changeId);
gApi.changes()
.id(changeId)
.edit()
.modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
gApi.changes().id(changeId).edit().modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
ensureSameBytes(getFileContentOfEdit(changeId, FILE_NAME), CONTENT_NEW);
gApi.changes()
.id(changeId)
.edit()
.modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW2));
gApi.changes().id(changeId).edit().modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW2));
ensureSameBytes(getFileContentOfEdit(changeId, FILE_NAME), CONTENT_NEW2);
}
@ -600,12 +499,10 @@ public class ChangeEditIT extends AbstractDaemonTest {
public void createAndChangeEditInOneRequestRest() throws Exception {
Put.Input in = new Put.Input();
in.content = RawInputUtil.create(CONTENT_NEW);
adminRestSession.putRaw(urlEditFile(changeId, FILE_NAME), in.content)
.assertNoContent();
adminRestSession.putRaw(urlEditFile(changeId, FILE_NAME), in.content).assertNoContent();
ensureSameBytes(getFileContentOfEdit(changeId, FILE_NAME), CONTENT_NEW);
in.content = RawInputUtil.create(CONTENT_NEW2);
adminRestSession.putRaw(urlEditFile(changeId, FILE_NAME), in.content)
.assertNoContent();
adminRestSession.putRaw(urlEditFile(changeId, FILE_NAME), in.content).assertNoContent();
ensureSameBytes(getFileContentOfEdit(changeId, FILE_NAME), CONTENT_NEW2);
}
@ -614,8 +511,7 @@ public class ChangeEditIT extends AbstractDaemonTest {
createEmptyEditFor(changeId);
Put.Input in = new Put.Input();
in.content = RawInputUtil.create(CONTENT_NEW);
adminRestSession.putRaw(urlEditFile(changeId, FILE_NAME), in.content)
.assertNoContent();
adminRestSession.putRaw(urlEditFile(changeId, FILE_NAME), in.content).assertNoContent();
ensureSameBytes(getFileContentOfEdit(changeId, FILE_NAME), CONTENT_NEW);
}
@ -623,8 +519,7 @@ public class ChangeEditIT extends AbstractDaemonTest {
public void emptyPutRequest() throws Exception {
createEmptyEditFor(changeId);
adminRestSession.put(urlEditFile(changeId, FILE_NAME)).assertNoContent();
ensureSameBytes(getFileContentOfEdit(changeId, FILE_NAME),
"".getBytes(UTF_8));
ensureSameBytes(getFileContentOfEdit(changeId, FILE_NAME), "".getBytes(UTF_8));
}
@Test
@ -637,22 +532,15 @@ public class ChangeEditIT extends AbstractDaemonTest {
public void getFileContentRest() throws Exception {
Put.Input in = new Put.Input();
in.content = RawInputUtil.create(CONTENT_NEW);
adminRestSession.putRaw(urlEditFile(changeId, FILE_NAME), in.content)
.assertNoContent();
gApi.changes()
.id(changeId)
.edit()
.modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW2));
RestResponse r = adminRestSession.getJsonAccept(urlEditFile(changeId,
FILE_NAME));
adminRestSession.putRaw(urlEditFile(changeId, FILE_NAME), in.content).assertNoContent();
gApi.changes().id(changeId).edit().modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW2));
RestResponse r = adminRestSession.getJsonAccept(urlEditFile(changeId, FILE_NAME));
r.assertOK();
assertThat(readContentFromJson(r)).isEqualTo(
new String(CONTENT_NEW2, UTF_8));
assertThat(readContentFromJson(r)).isEqualTo(new String(CONTENT_NEW2, UTF_8));
r = adminRestSession.getJsonAccept(urlEditFile(changeId, FILE_NAME, true));
r.assertOK();
assertThat(readContentFromJson(r)).isEqualTo(
new String(CONTENT_OLD, UTF_8));
assertThat(readContentFromJson(r)).isEqualTo(new String(CONTENT_OLD, UTF_8));
}
@Test
@ -666,25 +554,16 @@ public class ChangeEditIT extends AbstractDaemonTest {
@Test
public void addNewFile() throws Exception {
createEmptyEditFor(changeId);
gApi.changes()
.id(changeId)
.edit()
.modifyFile(FILE_NAME3, RawInputUtil.create(CONTENT_NEW));
gApi.changes().id(changeId).edit().modifyFile(FILE_NAME3, RawInputUtil.create(CONTENT_NEW));
ensureSameBytes(getFileContentOfEdit(changeId, FILE_NAME3), CONTENT_NEW);
}
@Test
public void addNewFileAndAmend() throws Exception {
createEmptyEditFor(changeId);
gApi.changes()
.id(changeId)
.edit()
.modifyFile(FILE_NAME3, RawInputUtil.create(CONTENT_NEW));
gApi.changes().id(changeId).edit().modifyFile(FILE_NAME3, RawInputUtil.create(CONTENT_NEW));
ensureSameBytes(getFileContentOfEdit(changeId, FILE_NAME3), CONTENT_NEW);
gApi.changes()
.id(changeId)
.edit()
.modifyFile(FILE_NAME3, RawInputUtil.create(CONTENT_NEW2));
gApi.changes().id(changeId).edit().modifyFile(FILE_NAME3, RawInputUtil.create(CONTENT_NEW2));
ensureSameBytes(getFileContentOfEdit(changeId, FILE_NAME3), CONTENT_NEW2);
}
@ -693,10 +572,7 @@ public class ChangeEditIT extends AbstractDaemonTest {
createEmptyEditFor(changeId);
exception.expect(ResourceConflictException.class);
exception.expectMessage("no changes were made");
gApi.changes()
.id(changeId)
.edit()
.modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_OLD));
gApi.changes().id(changeId).edit().modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_OLD));
}
@Test
@ -710,24 +586,15 @@ public class ChangeEditIT extends AbstractDaemonTest {
ReviewInput r = new ReviewInput();
r.labels = ImmutableMap.of(cr, (short) 1);
gApi.changes()
.id(changeId)
.current()
.review(r);
gApi.changes().id(changeId).current().review(r);
createEmptyEditFor(changeId);
String newSubj = "New commit message";
String newMsg = newSubj + "\n\nChange-Id: " + changeId + "\n";
gApi.changes()
.id(changeId)
.edit()
.modifyCommitMessage(newMsg);
gApi.changes().id(changeId).edit().modifyCommitMessage(newMsg);
PublishChangeEditInput publishInput = new PublishChangeEditInput();
publishInput.notify = NotifyHandling.NONE;
gApi.changes()
.id(changeId)
.edit()
.publish(publishInput);
gApi.changes().id(changeId).edit().publish(publishInput);
ChangeInfo info = get(changeId);
assertThat(info.subject).isEqualTo(newSubj);
@ -742,28 +609,16 @@ public class ChangeEditIT extends AbstractDaemonTest {
assertThat(queryEdits()).hasSize(1);
createEmptyEditFor(changeId2);
gApi.changes()
.id(changeId2)
.edit()
.modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
gApi.changes().id(changeId2).edit().modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
assertThat(queryEdits()).hasSize(2);
gApi.changes()
.id(changeId)
.edit()
.modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
gApi.changes()
.id(changeId)
.edit()
.delete();
gApi.changes().id(changeId).edit().modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
gApi.changes().id(changeId).edit().delete();
assertThat(queryEdits()).hasSize(1);
PublishChangeEditInput publishInput = new PublishChangeEditInput();
publishInput.notify = NotifyHandling.NONE;
gApi.changes()
.id(changeId2)
.edit()
.publish(publishInput);
gApi.changes().id(changeId2).edit().publish(publishInput);
assertThat(queryEdits()).isEmpty();
setApiUser(user);
@ -777,18 +632,13 @@ public class ChangeEditIT extends AbstractDaemonTest {
@Test
public void files() throws Exception {
createEmptyEditFor(changeId);
gApi.changes()
.id(changeId)
.edit()
.modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
gApi.changes().id(changeId).edit().modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
Optional<EditInfo> edit = getEdit(changeId);
assertThat(edit).isPresent();
String editCommitId = edit.get().commit.commit;
RestResponse r = adminRestSession.getJsonAccept(urlRevisionFiles(changeId,
editCommitId));
Map<String, FileInfo> files = readContentFromJson(
r, new TypeToken<Map<String, FileInfo>>() {});
RestResponse r = adminRestSession.getJsonAccept(urlRevisionFiles(changeId, editCommitId));
Map<String, FileInfo> files = readContentFromJson(r, new TypeToken<Map<String, FileInfo>>() {});
assertThat(files).containsKey(FILE_NAME);
r = adminRestSession.getJsonAccept(urlRevisionFiles(changeId));
@ -799,16 +649,12 @@ public class ChangeEditIT extends AbstractDaemonTest {
@Test
public void diff() throws Exception {
createEmptyEditFor(changeId);
gApi.changes()
.id(changeId)
.edit()
.modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
gApi.changes().id(changeId).edit().modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
Optional<EditInfo> edit = getEdit(changeId);
assertThat(edit).isPresent();
String editCommitId = edit.get().commit.commit;
RestResponse r = adminRestSession.getJsonAccept(urlDiff(changeId,
editCommitId, FILE_NAME));
RestResponse r = adminRestSession.getJsonAccept(urlDiff(changeId, editCommitId, FILE_NAME));
DiffInfo diff = readContentFromJson(r, DiffInfo.class);
assertThat(diff.diffHeader.get(0)).contains(FILE_NAME);
@ -822,15 +668,13 @@ public class ChangeEditIT extends AbstractDaemonTest {
// Create new project with clean permissions
Project.NameKey p = createProject("addPatchSetEdit");
// Clone repository as user
TestRepository<InMemoryRepository> userTestRepo =
cloneProject(p, user);
TestRepository<InMemoryRepository> userTestRepo = cloneProject(p, user);
// Block default permission
block(Permission.ADD_PATCH_SET, REGISTERED_USERS, "refs/for/*", p);
// Create change as user
PushOneCommit push = pushFactory.create(
db, user.getIdent(), userTestRepo);
PushOneCommit push = pushFactory.create(db, user.getIdent(), userTestRepo);
PushOneCommit.Result r1 = push.to("refs/for/master");
r1.assertOkStatus();
@ -845,25 +689,16 @@ public class ChangeEditIT extends AbstractDaemonTest {
}
private void createEmptyEditFor(String changeId) throws Exception {
gApi.changes()
.id(changeId)
.edit()
.create();
gApi.changes().id(changeId).edit().create();
}
private void arbitrarilyModifyEditOf(String changeId) throws Exception {
gApi.changes()
.id(changeId)
.edit()
.modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
gApi.changes().id(changeId).edit().modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
}
private Optional<BinaryResult> getFileContentOfEdit(String changeId,
String filePath) throws Exception {
return gApi.changes()
.id(changeId)
.edit()
.getFile(filePath);
private Optional<BinaryResult> getFileContentOfEdit(String changeId, String filePath)
throws Exception {
return gApi.changes().id(changeId).edit().getFile(filePath);
}
private List<ChangeInfo> queryEdits() throws Exception {
@ -872,46 +707,46 @@ public class ChangeEditIT extends AbstractDaemonTest {
private String newChange(PersonIdent ident) throws Exception {
PushOneCommit push =
pushFactory.create(db, ident, testRepo, PushOneCommit.SUBJECT, FILE_NAME,
new String(CONTENT_OLD, UTF_8));
pushFactory.create(
db, ident, testRepo, PushOneCommit.SUBJECT, FILE_NAME, new String(CONTENT_OLD, UTF_8));
return push.to("refs/for/master").getChangeId();
}
private String amendChange(PersonIdent ident, String changeId)
throws Exception {
PushOneCommit push = pushFactory.create(db, ident, testRepo,
PushOneCommit.SUBJECT, FILE_NAME2, new String(CONTENT_NEW2, UTF_8),
changeId);
private String amendChange(PersonIdent ident, String changeId) throws Exception {
PushOneCommit push =
pushFactory.create(
db,
ident,
testRepo,
PushOneCommit.SUBJECT,
FILE_NAME2,
new String(CONTENT_NEW2, UTF_8),
changeId);
return push.to("refs/for/master").getChangeId();
}
private String newChange2(PersonIdent ident) throws Exception {
PushOneCommit push = pushFactory.create(db, ident, testRepo,
PushOneCommit.SUBJECT, FILE_NAME, new String(CONTENT_OLD, UTF_8));
PushOneCommit push =
pushFactory.create(
db, ident, testRepo, PushOneCommit.SUBJECT, FILE_NAME, new String(CONTENT_OLD, UTF_8));
return push.rm("refs/for/master").getChangeId();
}
private PatchSet getCurrentPatchSet(String changeId) throws Exception {
return getOnlyElement(queryProvider.get().byKeyPrefix(changeId))
.currentPatchSet();
return getOnlyElement(queryProvider.get().byKeyPrefix(changeId)).currentPatchSet();
}
private void ensureSameBytes(Optional<BinaryResult> fileContent,
byte[] expectedFileBytes) throws IOException {
private void ensureSameBytes(Optional<BinaryResult> fileContent, byte[] expectedFileBytes)
throws IOException {
assertThat(fileContent).value().bytes().isEqualTo(expectedFileBytes);
}
private String urlEdit(String changeId) {
return "/changes/"
+ changeId
+ "/edit";
return "/changes/" + changeId + "/edit";
}
private String urlEditMessage(String changeId, boolean base) {
return "/changes/"
+ changeId
+ "/edit:message"
+ (base ? "?base" : "");
return "/changes/" + changeId + "/edit:message" + (base ? "?base" : "");
}
private String urlEditFile(String changeId, String fileName) {
@ -919,41 +754,27 @@ public class ChangeEditIT extends AbstractDaemonTest {
}
private String urlEditFile(String changeId, String fileName, boolean base) {
return urlEdit(changeId)
+ "/"
+ fileName
+ (base ? "?base" : "");
return urlEdit(changeId) + "/" + fileName + (base ? "?base" : "");
}
private String urlGetFiles(String changeId) {
return urlEdit(changeId)
+ "?list";
return urlEdit(changeId) + "?list";
}
private String urlRevisionFiles(String changeId, String revisionId) {
return "/changes/"
+ changeId
+ "/revisions/"
+ revisionId
+ "/files";
return "/changes/" + changeId + "/revisions/" + revisionId + "/files";
}
private String urlRevisionFiles(String changeId) {
return "/changes/"
+ changeId
+ "/revisions/0/files";
return "/changes/" + changeId + "/revisions/0/files";
}
private String urlPublish(String changeId) {
return "/changes/"
+ changeId
+ "/edit:publish";
return "/changes/" + changeId + "/edit:publish";
}
private String urlRebase(String changeId) {
return "/changes/"
+ changeId
+ "/edit:rebase";
return "/changes/" + changeId + "/edit:rebase";
}
private String urlDiff(String changeId, String fileName) {
@ -974,23 +795,19 @@ public class ChangeEditIT extends AbstractDaemonTest {
+ "/diff?context=ALL&intraline";
}
private EditInfo getEditInfo(String changeId, boolean files)
throws Exception {
RestResponse r = adminRestSession.get(files ? urlGetFiles(changeId)
: urlEdit(changeId));
private EditInfo getEditInfo(String changeId, boolean files) throws Exception {
RestResponse r = adminRestSession.get(files ? urlGetFiles(changeId) : urlEdit(changeId));
return readContentFromJson(r, EditInfo.class);
}
private <T> T readContentFromJson(RestResponse r, Class<T> clazz)
throws Exception {
private <T> T readContentFromJson(RestResponse r, Class<T> clazz) throws Exception {
r.assertOK();
JsonReader jsonReader = new JsonReader(r.getReader());
jsonReader.setLenient(true);
return newGson().fromJson(jsonReader, clazz);
}
private <T> T readContentFromJson(RestResponse r, TypeToken<T> typeToken)
throws Exception {
private <T> T readContentFromJson(RestResponse r, TypeToken<T> typeToken) throws Exception {
r.assertOK();
JsonReader jsonReader = new JsonReader(r.getReader());
jsonReader.setLenient(true);
@ -1001,17 +818,13 @@ public class ChangeEditIT extends AbstractDaemonTest {
return readContentFromJson(r, String.class);
}
private void assertChangeMessages(String changeId,
List<String> expectedMessages)
private void assertChangeMessages(String changeId, List<String> expectedMessages)
throws Exception {
ChangeInfo ci = get(changeId);
assertThat(ci.messages).isNotNull();
assertThat(ci.messages).hasSize(expectedMessages.size());
List<String> actualMessages = ci.messages.stream()
.map(message -> message.message)
.collect(Collectors.toList());
assertThat(actualMessages)
.containsExactlyElementsIn(expectedMessages)
.inOrder();
List<String> actualMessages =
ci.messages.stream().map(message -> message.message).collect(Collectors.toList());
assertThat(actualMessages).containsExactlyElementsIn(expectedMessages).inOrder();
}
}

View File

@ -25,7 +25,7 @@ import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
@ -39,8 +39,6 @@ import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.RemoteRefUpdate;
import org.eclipse.jgit.transport.RemoteRefUpdate.Status;
import java.util.concurrent.atomic.AtomicInteger;
public abstract class AbstractSubmoduleSubscription extends AbstractDaemonTest {
protected SubmitType getSubmitType() {
@ -82,39 +80,39 @@ public abstract class AbstractSubmoduleSubscription extends AbstractDaemonTest {
return cfg;
}
protected TestRepository<?> createProjectWithPush(String name,
@Nullable Project.NameKey parent, boolean createEmptyCommit,
SubmitType submitType) throws Exception {
protected TestRepository<?> createProjectWithPush(
String name,
@Nullable Project.NameKey parent,
boolean createEmptyCommit,
SubmitType submitType)
throws Exception {
Project.NameKey project = createProject(name, parent, createEmptyCommit, submitType);
grant(Permission.PUSH, project, "refs/heads/*");
grant(Permission.SUBMIT, project, "refs/for/refs/heads/*");
return cloneProject(project);
}
protected TestRepository<?> createProjectWithPush(String name,
@Nullable Project.NameKey parent) throws Exception {
protected TestRepository<?> createProjectWithPush(String name, @Nullable Project.NameKey parent)
throws Exception {
return createProjectWithPush(name, parent, true, getSubmitType());
}
protected TestRepository<?> createProjectWithPush(String name,
boolean createEmptyCommit) throws Exception {
protected TestRepository<?> createProjectWithPush(String name, boolean createEmptyCommit)
throws Exception {
return createProjectWithPush(name, null, createEmptyCommit, getSubmitType());
}
protected TestRepository<?> createProjectWithPush(String name)
throws Exception {
protected TestRepository<?> createProjectWithPush(String name) throws Exception {
return createProjectWithPush(name, null, true, getSubmitType());
}
private static AtomicInteger contentCounter = new AtomicInteger(0);
protected ObjectId pushChangeTo(TestRepository<?> repo, String ref,
String file, String content, String message, String topic)
protected ObjectId pushChangeTo(
TestRepository<?> repo, String ref, String file, String content, String message, String topic)
throws Exception {
ObjectId ret = repo.branch("HEAD").commit().insertChangeId()
.message(message)
.add(file, content)
.create();
ObjectId ret =
repo.branch("HEAD").commit().insertChangeId().message(message).add(file, content).create();
String pushedRef = ref;
if (!topic.isEmpty()) {
@ -122,8 +120,8 @@ public abstract class AbstractSubmoduleSubscription extends AbstractDaemonTest {
}
String refspec = "HEAD:" + pushedRef;
Iterable<PushResult> res = repo.git().push()
.setRemote("origin").setRefSpecs(new RefSpec(refspec)).call();
Iterable<PushResult> res =
repo.git().push().setRemote("origin").setRefSpecs(new RefSpec(refspec)).call();
RemoteRefUpdate u = Iterables.getOnlyElement(res).getRemoteUpdate(pushedRef);
assertThat(u).isNotNull();
@ -133,19 +131,18 @@ public abstract class AbstractSubmoduleSubscription extends AbstractDaemonTest {
return ret;
}
protected ObjectId pushChangeTo(TestRepository<?> repo, String ref,
String message, String topic) throws Exception {
return pushChangeTo(repo, ref, "a.txt",
"a contents: " + contentCounter.incrementAndGet(), message, topic);
protected ObjectId pushChangeTo(TestRepository<?> repo, String ref, String message, String topic)
throws Exception {
return pushChangeTo(
repo, ref, "a.txt", "a contents: " + contentCounter.incrementAndGet(), message, topic);
}
protected ObjectId pushChangeTo(TestRepository<?> repo, String branch)
throws Exception {
protected ObjectId pushChangeTo(TestRepository<?> repo, String branch) throws Exception {
return pushChangeTo(repo, "refs/heads/" + branch, "some change", "");
}
protected void allowSubmoduleSubscription(String submodule,
String subBranch, String superproject, String superBranch, boolean match)
protected void allowSubmoduleSubscription(
String submodule, String subBranch, String superproject, String superBranch, boolean match)
throws Exception {
Project.NameKey sub = new Project.NameKey(name(submodule));
Project.NameKey superName = new Project.NameKey(name(superproject));
@ -177,31 +174,37 @@ public abstract class AbstractSubmoduleSubscription extends AbstractDaemonTest {
}
}
protected void allowMatchingSubmoduleSubscription(String submodule,
String subBranch, String superproject, String superBranch)
protected void allowMatchingSubmoduleSubscription(
String submodule, String subBranch, String superproject, String superBranch)
throws Exception {
allowSubmoduleSubscription(submodule, subBranch, superproject,
superBranch, true);
allowSubmoduleSubscription(submodule, subBranch, superproject, superBranch, true);
}
protected void createSubmoduleSubscription(TestRepository<?> repo, String branch,
String subscribeToRepo, String subscribeToBranch) throws Exception {
protected void createSubmoduleSubscription(
TestRepository<?> repo, String branch, String subscribeToRepo, String subscribeToBranch)
throws Exception {
Config config = new Config();
prepareSubmoduleConfigEntry(config, subscribeToRepo, subscribeToBranch);
pushSubmoduleConfig(repo, branch, config);
}
protected void createRelativeSubmoduleSubscription(TestRepository<?> repo,
String branch, String subscribeToRepoPrefix, String subscribeToRepo,
String subscribeToBranch) throws Exception {
protected void createRelativeSubmoduleSubscription(
TestRepository<?> repo,
String branch,
String subscribeToRepoPrefix,
String subscribeToRepo,
String subscribeToBranch)
throws Exception {
Config config = new Config();
prepareRelativeSubmoduleConfigEntry(config, subscribeToRepoPrefix,
subscribeToRepo, subscribeToBranch);
prepareRelativeSubmoduleConfigEntry(
config, subscribeToRepoPrefix, subscribeToRepo, subscribeToBranch);
pushSubmoduleConfig(repo, branch, config);
}
protected void prepareRelativeSubmoduleConfigEntry(Config config,
String subscribeToRepoPrefix, String subscribeToRepo,
protected void prepareRelativeSubmoduleConfigEntry(
Config config,
String subscribeToRepoPrefix,
String subscribeToRepo,
String subscribeToBranch) {
subscribeToRepo = name(subscribeToRepo);
String url = subscribeToRepoPrefix + subscribeToRepo;
@ -212,23 +215,22 @@ public abstract class AbstractSubmoduleSubscription extends AbstractDaemonTest {
}
}
protected void prepareSubmoduleConfigEntry(Config config,
String subscribeToRepo, String subscribeToBranch) {
protected void prepareSubmoduleConfigEntry(
Config config, String subscribeToRepo, String subscribeToBranch) {
// The submodule subscription module checks for gerrit.canonicalWebUrl to
// detect if it's configured for automatic updates. It doesn't matter if
// it serves from that URL.
prepareSubmoduleConfigEntry(config, subscribeToRepo, subscribeToRepo, subscribeToBranch);
}
protected void prepareSubmoduleConfigEntry(Config config,
String subscribeToRepo, String subscribeToRepoPath, String subscribeToBranch) {
protected void prepareSubmoduleConfigEntry(
Config config, String subscribeToRepo, String subscribeToRepoPath, String subscribeToBranch) {
subscribeToRepo = name(subscribeToRepo);
subscribeToRepoPath = name(subscribeToRepoPath);
// The submodule subscription module checks for gerrit.canonicalWebUrl to
// detect if it's configured for automatic updates. It doesn't matter if
// it serves from that URL.
String url = cfg.getString("gerrit", null, "canonicalWebUrl") + "/"
+ subscribeToRepo;
String url = cfg.getString("gerrit", null, "canonicalWebUrl") + "/" + subscribeToRepo;
config.setString("submodule", subscribeToRepoPath, "path", subscribeToRepoPath);
config.setString("submodule", subscribeToRepoPath, "url", url);
if (subscribeToBranch != null) {
@ -236,28 +238,48 @@ public abstract class AbstractSubmoduleSubscription extends AbstractDaemonTest {
}
}
protected void pushSubmoduleConfig(TestRepository<?> repo,
String branch, Config config) throws Exception {
protected void pushSubmoduleConfig(TestRepository<?> repo, String branch, Config config)
throws Exception {
repo.branch("HEAD").commit().insertChangeId()
.message("subject: adding new subscription")
.add(".gitmodules", config.toText().toString())
.create();
repo.branch("HEAD")
.commit()
.insertChangeId()
.message("subject: adding new subscription")
.add(".gitmodules", config.toText().toString())
.create();
repo.git().push().setRemote("origin").setRefSpecs(
new RefSpec("HEAD:refs/heads/" + branch)).call();
repo.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/heads/" + branch))
.call();
}
protected void expectToHaveSubmoduleState(TestRepository<?> repo,
String branch, String submodule, TestRepository<?> subRepo,
String subBranch) throws Exception {
protected void expectToHaveSubmoduleState(
TestRepository<?> repo,
String branch,
String submodule,
TestRepository<?> subRepo,
String subBranch)
throws Exception {
submodule = name(submodule);
ObjectId commitId = repo.git().fetch().setRemote("origin").call()
.getAdvertisedRef("refs/heads/" + branch).getObjectId();
ObjectId commitId =
repo.git()
.fetch()
.setRemote("origin")
.call()
.getAdvertisedRef("refs/heads/" + branch)
.getObjectId();
ObjectId subHead = subRepo.git().fetch().setRemote("origin").call()
.getAdvertisedRef("refs/heads/" + subBranch).getObjectId();
ObjectId subHead =
subRepo
.git()
.fetch()
.setRemote("origin")
.call()
.getAdvertisedRef("refs/heads/" + subBranch)
.getObjectId();
RevWalk rw = repo.getRevWalk();
RevCommit c = rw.parseCommit(commitId);
@ -269,12 +291,18 @@ public abstract class AbstractSubmoduleSubscription extends AbstractDaemonTest {
assertThat(actualId).isEqualTo(subHead);
}
protected void expectToHaveSubmoduleState(TestRepository<?> repo,
String branch, String submodule, ObjectId expectedId) throws Exception {
protected void expectToHaveSubmoduleState(
TestRepository<?> repo, String branch, String submodule, ObjectId expectedId)
throws Exception {
submodule = name(submodule);
ObjectId commitId = repo.git().fetch().setRemote("origin").call()
.getAdvertisedRef("refs/heads/" + branch).getObjectId();
ObjectId commitId =
repo.git()
.fetch()
.setRemote("origin")
.call()
.getAdvertisedRef("refs/heads/" + branch)
.getObjectId();
RevWalk rw = repo.getRevWalk();
RevCommit c = rw.parseCommit(commitId);
@ -286,46 +314,66 @@ public abstract class AbstractSubmoduleSubscription extends AbstractDaemonTest {
assertThat(actualId).isEqualTo(expectedId);
}
protected void deleteAllSubscriptions(TestRepository<?> repo, String branch)
throws Exception {
protected void deleteAllSubscriptions(TestRepository<?> repo, String branch) throws Exception {
repo.git().fetch().setRemote("origin").call();
repo.reset("refs/remotes/origin/" + branch);
ObjectId expectedId = repo.branch("HEAD").commit().insertChangeId()
.message("delete contents in .gitmodules")
.add(".gitmodules", "") // Just remove the contents of the file!
.create();
repo.git().push().setRemote("origin").setRefSpecs(
new RefSpec("HEAD:refs/heads/" + branch)).call();
ObjectId expectedId =
repo.branch("HEAD")
.commit()
.insertChangeId()
.message("delete contents in .gitmodules")
.add(".gitmodules", "") // Just remove the contents of the file!
.create();
repo.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/heads/" + branch))
.call();
ObjectId actualId = repo.git().fetch().setRemote("origin").call()
.getAdvertisedRef("refs/heads/master").getObjectId();
ObjectId actualId =
repo.git()
.fetch()
.setRemote("origin")
.call()
.getAdvertisedRef("refs/heads/master")
.getObjectId();
assertThat(actualId).isEqualTo(expectedId);
}
protected void deleteGitModulesFile(TestRepository<?> repo, String branch)
throws Exception {
protected void deleteGitModulesFile(TestRepository<?> repo, String branch) throws Exception {
repo.git().fetch().setRemote("origin").call();
repo.reset("refs/remotes/origin/" + branch);
ObjectId expectedId = repo.branch("HEAD").commit().insertChangeId()
.message("delete .gitmodules")
.rm(".gitmodules")
.create();
repo.git().push().setRemote("origin").setRefSpecs(
new RefSpec("HEAD:refs/heads/" + branch)).call();
ObjectId expectedId =
repo.branch("HEAD")
.commit()
.insertChangeId()
.message("delete .gitmodules")
.rm(".gitmodules")
.create();
repo.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/heads/" + branch))
.call();
ObjectId actualId = repo.git().fetch().setRemote("origin").call()
.getAdvertisedRef("refs/heads/master").getObjectId();
ObjectId actualId =
repo.git()
.fetch()
.setRemote("origin")
.call()
.getAdvertisedRef("refs/heads/master")
.getObjectId();
assertThat(actualId).isEqualTo(expectedId);
}
protected boolean hasSubmodule(TestRepository<?> repo, String branch,
String submodule) throws Exception {
protected boolean hasSubmodule(TestRepository<?> repo, String branch, String submodule)
throws Exception {
submodule = name(submodule);
Ref branchTip = repo.git().fetch().setRemote("origin").call()
.getAdvertisedRef("refs/heads/" + branch);
Ref branchTip =
repo.git().fetch().setRemote("origin").call().getAdvertisedRef("refs/heads/" + branch);
if (branchTip == null) {
return false;
}
@ -345,11 +393,16 @@ public abstract class AbstractSubmoduleSubscription extends AbstractDaemonTest {
}
}
protected void expectToHaveCommitMessage(TestRepository<?> repo,
String branch, String expectedMessage) throws Exception {
protected void expectToHaveCommitMessage(
TestRepository<?> repo, String branch, String expectedMessage) throws Exception {
ObjectId commitId = repo.git().fetch().setRemote("origin").call()
.getAdvertisedRef("refs/heads/" + branch).getObjectId();
ObjectId commitId =
repo.git()
.fetch()
.setRemote("origin")
.call()
.getAdvertisedRef("refs/heads/" + branch)
.getObjectId();
RevWalk rw = repo.getRevWalk();
RevCommit c = rw.parseCommit(commitId);

View File

@ -20,7 +20,6 @@ import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.common.data.Permission;
import org.junit.Before;
import org.junit.Test;

View File

@ -20,7 +20,6 @@ import static org.eclipse.jgit.lib.Constants.HEAD;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.common.data.Permission;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.RefUpdate;
import org.junit.Test;

View File

@ -21,8 +21,8 @@ import org.junit.Before;
public class HttpPushForReviewIT extends AbstractPushForReview {
@Before
public void selectHttpUrl() throws Exception {
CredentialsProvider.setDefault(new UsernamePasswordCredentialsProvider(
admin.username, admin.httpPassword));
CredentialsProvider.setDefault(
new UsernamePasswordCredentialsProvider(admin.username, admin.httpPassword));
selectProtocol(Protocol.HTTP);
}
}

View File

@ -21,7 +21,6 @@ import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.extensions.client.InheritableBoolean;
import com.google.gerrit.server.git.ProjectConfig;
import org.eclipse.jgit.lib.ObjectId;
import org.junit.Test;
@ -61,8 +60,7 @@ public class ImplicitMergeCheckIT extends AbstractDaemonTest {
PushOneCommit.Result m = push("refs/heads/master", "1", "f", "1");
PushOneCommit.Result c = push("refs/for/stable", "2", "f", "2");
assertThat(c.getMessage().toLowerCase()).doesNotContain(
implicitMergeOf(m.getCommit()));
assertThat(c.getMessage().toLowerCase()).doesNotContain(implicitMergeOf(m.getCommit()));
}
@Test
@ -75,8 +73,7 @@ public class ImplicitMergeCheckIT extends AbstractDaemonTest {
PushOneCommit.Result m = push("refs/heads/master", "1", "f", "1");
PushOneCommit.Result c = push("refs/for/master", "2", "f", "2");
assertThat(c.getMessage().toLowerCase()).doesNotContain(
implicitMergeOf(m.getCommit()));
assertThat(c.getMessage().toLowerCase()).doesNotContain(implicitMergeOf(m.getCommit()));
}
private static String implicitMergeOf(ObjectId commit) {
@ -89,10 +86,10 @@ public class ImplicitMergeCheckIT extends AbstractDaemonTest {
saveProjectConfig(project, cfg);
}
private PushOneCommit.Result push(String ref, String subject,
String fileName, String content) throws Exception {
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo,
subject, fileName, content);
private PushOneCommit.Result push(String ref, String subject, String fileName, String content)
throws Exception {
PushOneCommit push =
pushFactory.create(db, admin.getIdent(), testRepo, subject, fileName, content);
return push.to(ref);
}
}

View File

@ -50,7 +50,10 @@ import com.google.gerrit.testutil.DisabledReviewDb;
import com.google.gerrit.testutil.TestChanges;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
@ -60,32 +63,19 @@ import org.eclipse.jgit.lib.Repository;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@NoHttpd
public class RefAdvertisementIT extends AbstractDaemonTest {
@Inject
private ProjectControl.GenericFactory projectControlFactory;
@Inject private ProjectControl.GenericFactory projectControlFactory;
@Inject
@Nullable
private SearchingChangeCacheImpl changeCache;
@Inject @Nullable private SearchingChangeCacheImpl changeCache;
@Inject
private TagCache tagCache;
@Inject private TagCache tagCache;
@Inject
private Provider<CurrentUser> userProvider;
@Inject private Provider<CurrentUser> userProvider;
@Inject
private ChangeNoteUtil noteUtil;
@Inject private ChangeNoteUtil noteUtil;
@Inject
@AnonymousCowardName
private String anonymousCowardName;
@Inject @AnonymousCowardName private String anonymousCowardName;
private AccountGroup.UUID admins;
@ -100,8 +90,7 @@ public class RefAdvertisementIT extends AbstractDaemonTest {
@Before
public void setUp() throws Exception {
admins = groupCache.get(new AccountGroup.NameKey("Administrators"))
.getGroupUUID();
admins = groupCache.get(new AccountGroup.NameKey("Administrators")).getGroupUUID();
setUpPermissions();
setUpChanges();
}
@ -123,33 +112,28 @@ public class RefAdvertisementIT extends AbstractDaemonTest {
}
private void setUpChanges() throws Exception {
gApi.projects()
.name(project.get())
.branch("branch")
.create(new BranchInput());
gApi.projects().name(project.get()).branch("branch").create(new BranchInput());
// First 2 changes are merged, which means the tags pointing to them are
// visible.
allow(Permission.SUBMIT, admins, "refs/for/refs/heads/*");
PushOneCommit.Result mr = pushFactory.create(db, admin.getIdent(), testRepo)
.to("refs/for/master%submit");
PushOneCommit.Result mr =
pushFactory.create(db, admin.getIdent(), testRepo).to("refs/for/master%submit");
mr.assertOkStatus();
c1 = mr.getChange();
r1 = changeRefPrefix(c1.getId());
PushOneCommit.Result br = pushFactory.create(db, admin.getIdent(), testRepo)
.to("refs/for/branch%submit");
PushOneCommit.Result br =
pushFactory.create(db, admin.getIdent(), testRepo).to("refs/for/branch%submit");
br.assertOkStatus();
c2 = br.getChange();
r2 = changeRefPrefix(c2.getId());
// Second 2 changes are unmerged.
mr = pushFactory.create(db, admin.getIdent(), testRepo)
.to("refs/for/master");
mr = pushFactory.create(db, admin.getIdent(), testRepo).to("refs/for/master");
mr.assertOkStatus();
c3 = mr.getChange();
r3 = changeRefPrefix(c3.getId());
br = pushFactory.create(db, admin.getIdent(), testRepo)
.to("refs/for/branch");
br = pushFactory.create(db, admin.getIdent(), testRepo).to("refs/for/branch");
br.assertOkStatus();
c4 = br.getChange();
r4 = changeRefPrefix(c4.getId());
@ -260,17 +244,11 @@ public class RefAdvertisementIT extends AbstractDaemonTest {
// Admin's edit is not visible.
setApiUser(admin);
gApi.changes()
.id(changeId)
.edit()
.create();
gApi.changes().id(changeId).edit().create();
// User's edit is visible.
setApiUser(user);
gApi.changes()
.id(changeId)
.edit()
.create();
gApi.changes().id(changeId).edit().create();
assertUploadPackRefs(
"HEAD",
@ -292,10 +270,7 @@ public class RefAdvertisementIT extends AbstractDaemonTest {
String changeId = c1.change().getKey().get();
setApiUser(admin);
gApi.changes()
.id(changeId)
.edit()
.create();
gApi.changes().id(changeId).edit().create();
setApiUser(user);
assertUploadPackRefs(
@ -324,8 +299,8 @@ public class RefAdvertisementIT extends AbstractDaemonTest {
public void uploadPackDraftRefs() throws Exception {
allow(Permission.READ, REGISTERED_USERS, "refs/heads/*");
PushOneCommit.Result br = pushFactory.create(db, admin.getIdent(), testRepo)
.to("refs/drafts/master");
PushOneCommit.Result br =
pushFactory.create(db, admin.getIdent(), testRepo).to("refs/drafts/master");
br.assertOkStatus();
Change.Id c5 = br.getChange().getId();
String r5 = changeRefPrefix(c5);
@ -376,8 +351,7 @@ public class RefAdvertisementIT extends AbstractDaemonTest {
try (Repository repo = repoManager.openRepository(project)) {
assertRefs(
repo,
new VisibleRefFilter(tagCache, notesFactory, null, repo,
projectControl(), db, true),
new VisibleRefFilter(tagCache, notesFactory, null, repo, projectControl(), db, true),
// Can't use stored values from the index so DB must be enabled.
false,
"HEAD",
@ -403,16 +377,12 @@ public class RefAdvertisementIT extends AbstractDaemonTest {
setApiUser(user);
assertRefs(repo, newFilter(db, repo, allProjects), true);
allowGlobalCapabilities(
REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
try {
setApiUser(user);
assertRefs(
repo, newFilter(db, repo, allProjects), true,
"refs/sequences/changes");
assertRefs(repo, newFilter(db, repo, allProjects), true, "refs/sequences/changes");
} finally {
removeGlobalCapabilities(
REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
removeGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
}
}
}
@ -420,14 +390,15 @@ public class RefAdvertisementIT extends AbstractDaemonTest {
@Test
public void receivePackListsOpenChangesAsAdditionalHaves() throws Exception {
ReceiveCommitsAdvertiseRefsHook.Result r = getReceivePackRefs();
assertThat(r.allRefs().keySet()).containsExactly(
// meta refs are excluded even when NoteDb is enabled.
"HEAD",
"refs/heads/branch",
"refs/heads/master",
"refs/meta/config",
"refs/tags/branch-tag",
"refs/tags/master-tag");
assertThat(r.allRefs().keySet())
.containsExactly(
// meta refs are excluded even when NoteDb is enabled.
"HEAD",
"refs/heads/branch",
"refs/heads/master",
"refs/meta/config",
"refs/tags/branch-tag",
"refs/tags/master-tag");
assertThat(r.additionalHaves()).containsExactly(obj(c3, 1), obj(c4, 1));
}
@ -437,8 +408,7 @@ public class RefAdvertisementIT extends AbstractDaemonTest {
deny(Permission.READ, REGISTERED_USERS, "refs/heads/branch");
setApiUser(user);
assertThat(getReceivePackRefs().additionalHaves())
.containsExactly(obj(c3, 1));
assertThat(getReceivePackRefs().additionalHaves()).containsExactly(obj(c3, 1));
}
@Test
@ -447,8 +417,7 @@ public class RefAdvertisementIT extends AbstractDaemonTest {
PushOneCommit.Result r = amendChange(c3.change().getKey().get());
r.assertOkStatus();
c3 = r.getChange();
assertThat(getReceivePackRefs().additionalHaves())
.containsExactly(obj(c3, 2), obj(c4, 1));
assertThat(getReceivePackRefs().additionalHaves()).containsExactly(obj(c3, 2), obj(c4, 1));
}
@Test
@ -469,52 +438,66 @@ public class RefAdvertisementIT extends AbstractDaemonTest {
if (notesMigration.commitChangeWrites()) {
PersonIdent committer = serverIdent.get();
PersonIdent author = noteUtil.newIdent(
accountCache.get(admin.getId()).getAccount(),
committer.getWhen(),
committer,
anonymousCowardName);
PersonIdent author =
noteUtil.newIdent(
accountCache.get(admin.getId()).getAccount(),
committer.getWhen(),
committer,
anonymousCowardName);
tr.branch(RefNames.changeMetaRef(c3.getId()))
.commit()
.author(author)
.committer(committer)
.message(
"Update patch set " + psId.get() + "\n"
"Update patch set "
+ psId.get()
+ "\n"
+ "Patch-set: " + psId.get() + "\n"
+ "Commit: " + rev + "\n"
+ "Subject: " + subject + "\n")
+ "\n"
+ "Patch-set: "
+ psId.get()
+ "\n"
+ "Commit: "
+ rev
+ "\n"
+ "Subject: "
+ subject
+ "\n")
.create();
}
indexer.index(db, c.getProject(), c.getId());
}
assertThat(getReceivePackRefs().additionalHaves())
.containsExactly(obj(c4, 1));
assertThat(getReceivePackRefs().additionalHaves()).containsExactly(obj(c4, 1));
}
/**
* Assert that refs seen by a non-admin user match expected.
*
* @param expectedWithMeta expected refs, in order. If NoteDb is disabled by
* the configuration, any NoteDb refs (i.e. ending in "/meta") are removed
* from the expected list before comparing to the actual results.
* @param expectedWithMeta expected refs, in order. If NoteDb is disabled by the configuration,
* any NoteDb refs (i.e. ending in "/meta") are removed from the expected list before
* comparing to the actual results.
* @throws Exception
*/
private void assertUploadPackRefs(String... expectedWithMeta)
throws Exception {
private void assertUploadPackRefs(String... expectedWithMeta) throws Exception {
try (Repository repo = repoManager.openRepository(project)) {
assertRefs(
repo,
new VisibleRefFilter(tagCache, notesFactory, changeCache, repo,
projectControl(), new DisabledReviewDb(), true),
new VisibleRefFilter(
tagCache,
notesFactory,
changeCache,
repo,
projectControl(),
new DisabledReviewDb(),
true),
true,
expectedWithMeta);
}
}
private void assertRefs(Repository repo, VisibleRefFilter filter,
boolean disableDb, String... expectedWithMeta) throws Exception {
private void assertRefs(
Repository repo, VisibleRefFilter filter, boolean disableDb, String... expectedWithMeta)
throws Exception {
List<String> expected = new ArrayList<>(expectedWithMeta.length);
for (String r : expectedWithMeta) {
if (notesMigration.writeChanges() || !r.endsWith(RefNames.META_SUFFIX)) {
@ -528,8 +511,7 @@ public class RefAdvertisementIT extends AbstractDaemonTest {
}
try {
Map<String, Ref> all = repo.getAllRefs();
assertThat(filter.filter(all, false).keySet())
.containsExactlyElementsIn(expected);
assertThat(filter.filter(all, false).keySet()).containsExactlyElementsIn(expected);
} finally {
if (disableDb) {
enableDb(ctx);
@ -537,8 +519,7 @@ public class RefAdvertisementIT extends AbstractDaemonTest {
}
}
private ReceiveCommitsAdvertiseRefsHook.Result getReceivePackRefs()
throws Exception {
private ReceiveCommitsAdvertiseRefsHook.Result getReceivePackRefs() throws Exception {
ReceiveCommitsAdvertiseRefsHook hook =
new ReceiveCommitsAdvertiseRefsHook(queryProvider, project);
try (Repository repo = repoManager.openRepository(project)) {
@ -550,19 +531,22 @@ public class RefAdvertisementIT extends AbstractDaemonTest {
return projectControlFactory.controlFor(project, userProvider.get());
}
private VisibleRefFilter newFilter(ReviewDb db, Repository repo,
Project.NameKey project) throws Exception {
private VisibleRefFilter newFilter(ReviewDb db, Repository repo, Project.NameKey project)
throws Exception {
return new VisibleRefFilter(
tagCache, notesFactory, null, repo,
tagCache,
notesFactory,
null,
repo,
projectControlFactory.controlFor(project, userProvider.get()),
db, true);
db,
true);
}
private static ObjectId obj(ChangeData cd, int psNum) throws Exception {
PatchSet.Id psId = new PatchSet.Id(cd.getId(), psNum);
PatchSet ps = cd.patchSet(psId);
assertWithMessage("%s not found in %s", psId, cd.patchSets()).that(ps)
.isNotNull();
assertWithMessage("%s not found in %s", psId, cd.patchSets()).that(ps).isNotNull();
return ObjectId.fromString(ps.getRevision().get());
}
}

View File

@ -16,7 +16,6 @@ package com.google.gerrit.acceptance.git;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.UseSsh;
import org.junit.Before;
@NoHttpd

View File

@ -33,7 +33,6 @@ import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.inject.Inject;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
@ -46,8 +45,7 @@ import org.junit.Test;
@NoHttpd
public class SubmitOnPushIT extends AbstractDaemonTest {
@Inject
private ApprovalsUtil approvalsUtil;
@Inject private ApprovalsUtil approvalsUtil;
@Test
public void submitOnPush() throws Exception {
@ -116,8 +114,8 @@ public class SubmitOnPushIT extends AbstractDaemonTest {
push("refs/for/master%submit", "other change", "a.txt", "other content");
r.assertErrorStatus();
r.assertChange(Change.Status.NEW, null);
r.assertMessage("Change " + r.getChange().getId()
+ ": change could not be merged due to a path conflict.");
r.assertMessage(
"Change " + r.getChange().getId() + ": change could not be merged due to a path conflict.");
}
@Test
@ -141,12 +139,13 @@ public class SubmitOnPushIT extends AbstractDaemonTest {
push("refs/for/master", PushOneCommit.SUBJECT, "a.txt", "some content");
grant(Permission.SUBMIT, project, "refs/for/refs/heads/master");
r = push("refs/for/master%submit", PushOneCommit.SUBJECT, "a.txt",
"other content", r.getChangeId());
r =
push(
"refs/for/master%submit",
PushOneCommit.SUBJECT, "a.txt", "other content", r.getChangeId());
r.assertOkStatus();
r.assertChange(Change.Status.MERGED, null, admin);
ChangeData cd = Iterables.getOnlyElement(
queryProvider.get().byKeyPrefix(r.getChangeId()));
ChangeData cd = Iterables.getOnlyElement(queryProvider.get().byKeyPrefix(r.getChangeId()));
assertThat(cd.patchSets()).hasSize(2);
assertSubmitApproval(r.getPatchSetId());
assertCommit(project, "refs/heads/master");
@ -163,8 +162,10 @@ public class SubmitOnPushIT extends AbstractDaemonTest {
PushOneCommit.Result r =
push("refs/for/master", PushOneCommit.SUBJECT, "a.txt", "some content");
r = push("refs/for/master%submit", PushOneCommit.SUBJECT, "a.txt",
"other content", r.getChangeId());
r =
push(
"refs/for/master%submit",
PushOneCommit.SUBJECT, "a.txt", "other content", r.getChangeId());
r.assertErrorStatus("submit not allowed");
}
@ -188,13 +189,11 @@ public class SubmitOnPushIT extends AbstractDaemonTest {
push("refs/for/master", PushOneCommit.SUBJECT, "a.txt", "some content");
r.assertOkStatus();
git().push()
.setRefSpecs(new RefSpec(r.getCommit().name() + ":refs/heads/master"))
.call();
git().push().setRefSpecs(new RefSpec(r.getCommit().name() + ":refs/heads/master")).call();
assertCommit(project, "refs/heads/master");
ChangeData cd = Iterables.getOnlyElement(
queryProvider.get().byKey(new Change.Key(r.getChangeId())));
ChangeData cd =
Iterables.getOnlyElement(queryProvider.get().byKey(new Change.Key(r.getChangeId())));
RevCommit c = r.getCommit();
PatchSet.Id psId = cd.currentPatchSet().getId();
assertThat(psId.get()).isEqualTo(1);
@ -215,8 +214,14 @@ public class SubmitOnPushIT extends AbstractDaemonTest {
assertThat(psId1.get()).isEqualTo(1);
PushOneCommit push =
pushFactory.create(db, admin.getIdent(), testRepo, PushOneCommit.SUBJECT,
"b.txt", "anotherContent", r.getChangeId());
pushFactory.create(
db,
admin.getIdent(),
testRepo,
PushOneCommit.SUBJECT,
"b.txt",
"anotherContent",
r.getChangeId());
r = push.to("refs/heads/master");
r.assertOkStatus();
@ -251,8 +256,7 @@ public class SubmitOnPushIT extends AbstractDaemonTest {
assertThat(psId2.get()).isEqualTo(2);
testRepo.reset(c1);
assertPushOk(
pushHead(testRepo, "refs/heads/master", false), "refs/heads/master");
assertPushOk(pushHead(testRepo, "refs/heads/master", false), "refs/heads/master");
cd = changeDataFactory.create(db, project, psId1.getParentKey());
Change c = cd.change();
@ -282,40 +286,35 @@ public class SubmitOnPushIT extends AbstractDaemonTest {
// Amend both changes.
testRepo.reset(initialHead);
RevCommit c1_2 = testRepo.branch("HEAD").commit()
.message(c1_1.getShortMessage() + "v2")
.insertChangeId(r1.getChangeId().substring(1))
.create();
RevCommit c1_2 =
testRepo
.branch("HEAD")
.commit()
.message(c1_1.getShortMessage() + "v2")
.insertChangeId(r1.getChangeId().substring(1))
.create();
RevCommit c2_2 = testRepo.cherryPick(c2_1);
// Push directly to branch.
assertPushOk(
pushHead(testRepo, "refs/heads/master", false), "refs/heads/master");
assertPushOk(pushHead(testRepo, "refs/heads/master", false), "refs/heads/master");
ChangeData cd2 = r2.getChange();
assertThat(cd2.change().getStatus()).isEqualTo(Change.Status.MERGED);
PatchSet.Id psId2_2 = cd2.change().currentPatchSetId();
assertThat(psId2_2.get()).isEqualTo(2);
assertThat(cd2.patchSet(psId2_1).getRevision().get())
.isEqualTo(c2_1.name());
assertThat(cd2.patchSet(psId2_2).getRevision().get())
.isEqualTo(c2_2.name());
assertThat(cd2.patchSet(psId2_1).getRevision().get()).isEqualTo(c2_1.name());
assertThat(cd2.patchSet(psId2_2).getRevision().get()).isEqualTo(c2_2.name());
ChangeData cd1 = r1.getChange();
assertThat(cd1.change().getStatus()).isEqualTo(Change.Status.MERGED);
PatchSet.Id psId1_2 = cd1.change().currentPatchSetId();
assertThat(psId1_2.get()).isEqualTo(2);
assertThat(cd1.patchSet(psId1_1).getRevision().get())
.isEqualTo(c1_1.name());
assertThat(cd1.patchSet(psId1_2).getRevision().get())
.isEqualTo(c1_2.name());
assertThat(cd1.patchSet(psId1_1).getRevision().get()).isEqualTo(c1_1.name());
assertThat(cd1.patchSet(psId1_2).getRevision().get()).isEqualTo(c1_2.name());
}
private PatchSetApproval getSubmitter(PatchSet.Id patchSetId)
throws Exception {
ChangeNotes notes =
notesFactory.createChecked(db, project, patchSetId.getParentKey())
.load();
private PatchSetApproval getSubmitter(PatchSet.Id patchSetId) throws Exception {
ChangeNotes notes = notesFactory.createChecked(db, project, patchSetId.getParentKey()).load();
return approvalsUtil.getSubmitter(db, notes, patchSetId);
}
@ -326,15 +325,13 @@ public class SubmitOnPushIT extends AbstractDaemonTest {
assertThat(a.getAccountId()).isEqualTo(admin.id);
}
private void assertCommit(Project.NameKey project, String branch)
throws Exception {
private void assertCommit(Project.NameKey project, String branch) throws Exception {
try (Repository r = repoManager.openRepository(project);
RevWalk rw = new RevWalk(r)) {
RevCommit c = rw.parseCommit(r.exactRef(branch).getObjectId());
assertThat(c.getShortMessage()).isEqualTo(PushOneCommit.SUBJECT);
assertThat(c.getAuthorIdent().getEmailAddress()).isEqualTo(admin.email);
assertThat(c.getCommitterIdent().getEmailAddress()).isEqualTo(
admin.email);
assertThat(c.getCommitterIdent().getEmailAddress()).isEqualTo(admin.email);
}
}
@ -345,25 +342,24 @@ public class SubmitOnPushIT extends AbstractDaemonTest {
assertThat(c.getParentCount()).isEqualTo(2);
assertThat(c.getShortMessage()).isEqualTo("Merge \"" + subject + "\"");
assertThat(c.getAuthorIdent().getEmailAddress()).isEqualTo(admin.email);
assertThat(c.getCommitterIdent().getEmailAddress()).isEqualTo(
serverIdent.get().getEmailAddress());
assertThat(c.getCommitterIdent().getEmailAddress())
.isEqualTo(serverIdent.get().getEmailAddress());
}
}
private void assertTag(Project.NameKey project, String branch,
PushOneCommit.Tag tag) throws Exception {
private void assertTag(Project.NameKey project, String branch, PushOneCommit.Tag tag)
throws Exception {
try (Repository repo = repoManager.openRepository(project)) {
Ref tagRef = repo.findRef(tag.name);
assertThat(tagRef).isNotNull();
ObjectId taggedCommit = null;
if (tag instanceof PushOneCommit.AnnotatedTag) {
PushOneCommit.AnnotatedTag annotatedTag = (PushOneCommit.AnnotatedTag)tag;
PushOneCommit.AnnotatedTag annotatedTag = (PushOneCommit.AnnotatedTag) tag;
try (RevWalk rw = new RevWalk(repo)) {
RevObject object = rw.parseAny(tagRef.getObjectId());
assertThat(object).isInstanceOf(RevTag.class);
RevTag tagObject = (RevTag) object;
assertThat(tagObject.getFullMessage())
.isEqualTo(annotatedTag.message);
assertThat(tagObject.getFullMessage()).isEqualTo(annotatedTag.message);
assertThat(tagObject.getTaggerIdent()).isEqualTo(annotatedTag.tagger);
taggedCommit = tagObject.getObject();
}
@ -376,17 +372,18 @@ public class SubmitOnPushIT extends AbstractDaemonTest {
}
}
private PushOneCommit.Result push(String ref, String subject,
String fileName, String content) throws Exception {
private PushOneCommit.Result push(String ref, String subject, String fileName, String content)
throws Exception {
PushOneCommit push =
pushFactory.create(db, admin.getIdent(), testRepo, subject, fileName, content);
return push.to(ref);
}
private PushOneCommit.Result push(String ref, String subject,
String fileName, String content, String changeId) throws Exception {
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo, subject,
fileName, content, changeId);
private PushOneCommit.Result push(
String ref, String subject, String fileName, String content, String changeId)
throws Exception {
PushOneCommit push =
pushFactory.create(db, admin.getIdent(), testRepo, subject, fileName, content, changeId);
return push.to(ref);
}
}

View File

@ -22,12 +22,10 @@ import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.SubmoduleSubscription;
import com.google.gerrit.server.util.SubmoduleSectionParser;
import java.util.Set;
import org.eclipse.jgit.lib.Config;
import org.junit.Test;
import java.util.Set;
public class SubmoduleSectionParserIT extends AbstractDaemonTest {
private static final String THIS_SERVER = "http://localhost/";
@ -35,20 +33,23 @@ public class SubmoduleSectionParserIT extends AbstractDaemonTest {
public void followMasterBranch() throws Exception {
Project.NameKey p = createProject("a");
Config cfg = new Config();
cfg.fromText(""
+ "[submodule \"a\"]\n"
+ "path = localpath-to-a\n"
+ "url = ssh://localhost/" + p.get() + "\n"
+ "branch = master\n");
Branch.NameKey targetBranch = new Branch.NameKey(
new Project.NameKey("project"), "master");
cfg.fromText(
""
+ "[submodule \"a\"]\n"
+ "path = localpath-to-a\n"
+ "url = ssh://localhost/"
+ p.get()
+ "\n"
+ "branch = master\n");
Branch.NameKey targetBranch = new Branch.NameKey(new Project.NameKey("project"), "master");
Set<SubmoduleSubscription> res = new SubmoduleSectionParser(
cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> res =
new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> expected = Sets.newHashSet(
new SubmoduleSubscription(targetBranch, new Branch.NameKey(
p, "master"), "localpath-to-a"));
Set<SubmoduleSubscription> expected =
Sets.newHashSet(
new SubmoduleSubscription(
targetBranch, new Branch.NameKey(p, "master"), "localpath-to-a"));
assertThat(res).containsExactlyElementsIn(expected);
}
@ -57,33 +58,34 @@ public class SubmoduleSectionParserIT extends AbstractDaemonTest {
public void followMatchingBranch() throws Exception {
Project.NameKey p = createProject("a");
Config cfg = new Config();
cfg.fromText(""
+ "[submodule \"a\"]\n"
+ "path = a\n"
+ "url = ssh://localhost/" + p.get() + "\n"
+ "branch = .\n");
cfg.fromText(
""
+ "[submodule \"a\"]\n"
+ "path = a\n"
+ "url = ssh://localhost/"
+ p.get()
+ "\n"
+ "branch = .\n");
Branch.NameKey targetBranch1 = new Branch.NameKey(
new Project.NameKey("project"), "master");
Branch.NameKey targetBranch1 = new Branch.NameKey(new Project.NameKey("project"), "master");
Set<SubmoduleSubscription> res1 = new SubmoduleSectionParser(
cfg, THIS_SERVER, targetBranch1).parseAllSections();
Set<SubmoduleSubscription> res1 =
new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch1).parseAllSections();
Set<SubmoduleSubscription> expected1 = Sets.newHashSet(
new SubmoduleSubscription(targetBranch1, new Branch.NameKey(
p, "master"), "a"));
Set<SubmoduleSubscription> expected1 =
Sets.newHashSet(
new SubmoduleSubscription(targetBranch1, new Branch.NameKey(p, "master"), "a"));
assertThat(res1).containsExactlyElementsIn(expected1);
Branch.NameKey targetBranch2 = new Branch.NameKey(
new Project.NameKey("project"), "somebranch");
Branch.NameKey targetBranch2 = new Branch.NameKey(new Project.NameKey("project"), "somebranch");
Set<SubmoduleSubscription> res2 = new SubmoduleSectionParser(
cfg, THIS_SERVER, targetBranch2).parseAllSections();
Set<SubmoduleSubscription> res2 =
new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch2).parseAllSections();
Set<SubmoduleSubscription> expected2 = Sets.newHashSet(
new SubmoduleSubscription(targetBranch2, new Branch.NameKey(
p, "somebranch"), "a"));
Set<SubmoduleSubscription> expected2 =
Sets.newHashSet(
new SubmoduleSubscription(targetBranch2, new Branch.NameKey(p, "somebranch"), "a"));
assertThat(res2).containsExactlyElementsIn(expected2);
}
@ -92,21 +94,23 @@ public class SubmoduleSectionParserIT extends AbstractDaemonTest {
public void followAnotherBranch() throws Exception {
Project.NameKey p = createProject("a");
Config cfg = new Config();
cfg.fromText(""
+ "[submodule \"a\"]\n"
+ "path = a\n"
+ "url = ssh://localhost/" + p.get() + "\n"
+ "branch = anotherbranch\n");
cfg.fromText(
""
+ "[submodule \"a\"]\n"
+ "path = a\n"
+ "url = ssh://localhost/"
+ p.get()
+ "\n"
+ "branch = anotherbranch\n");
Branch.NameKey targetBranch = new Branch.NameKey(
new Project.NameKey("project"), "master");
Branch.NameKey targetBranch = new Branch.NameKey(new Project.NameKey("project"), "master");
Set<SubmoduleSubscription> res = new SubmoduleSectionParser(
cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> res =
new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> expected = Sets.newHashSet(
new SubmoduleSubscription(targetBranch, new Branch.NameKey(
p, "anotherbranch"), "a"));
Set<SubmoduleSubscription> expected =
Sets.newHashSet(
new SubmoduleSubscription(targetBranch, new Branch.NameKey(p, "anotherbranch"), "a"));
assertThat(res).containsExactlyElementsIn(expected);
}
@ -115,21 +119,23 @@ public class SubmoduleSectionParserIT extends AbstractDaemonTest {
public void withAnotherURI() throws Exception {
Project.NameKey p = createProject("a");
Config cfg = new Config();
cfg.fromText(""
+ "[submodule \"a\"]\n"
+ "path = a\n"
+ "url = http://localhost:80/" + p.get() + "\n"
+ "branch = master\n");
cfg.fromText(
""
+ "[submodule \"a\"]\n"
+ "path = a\n"
+ "url = http://localhost:80/"
+ p.get()
+ "\n"
+ "branch = master\n");
Branch.NameKey targetBranch = new Branch.NameKey(
new Project.NameKey("project"), "master");
Branch.NameKey targetBranch = new Branch.NameKey(new Project.NameKey("project"), "master");
Set<SubmoduleSubscription> res =new SubmoduleSectionParser(
cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> res =
new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> expected = Sets.newHashSet(
new SubmoduleSubscription(targetBranch, new Branch.NameKey(
p, "master"), "a"));
Set<SubmoduleSubscription> expected =
Sets.newHashSet(
new SubmoduleSubscription(targetBranch, new Branch.NameKey(p, "master"), "a"));
assertThat(res).containsExactlyElementsIn(expected);
}
@ -138,21 +144,23 @@ public class SubmoduleSectionParserIT extends AbstractDaemonTest {
public void withSlashesInProjectName() throws Exception {
Project.NameKey p = createProject("project/with/slashes/a");
Config cfg = new Config();
cfg.fromText(""
+ "[submodule \"project/with/slashes/a\"]\n"
+ "path = a\n"
+ "url = http://localhost:80/" + p.get() + "\n"
+ "branch = master\n");
cfg.fromText(
""
+ "[submodule \"project/with/slashes/a\"]\n"
+ "path = a\n"
+ "url = http://localhost:80/"
+ p.get()
+ "\n"
+ "branch = master\n");
Branch.NameKey targetBranch = new Branch.NameKey(
new Project.NameKey("project"), "master");
Branch.NameKey targetBranch = new Branch.NameKey(new Project.NameKey("project"), "master");
Set<SubmoduleSubscription> res = new SubmoduleSectionParser(
cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> res =
new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> expected = Sets.newHashSet(
new SubmoduleSubscription(targetBranch, new Branch.NameKey(
p, "master"), "a"));
Set<SubmoduleSubscription> expected =
Sets.newHashSet(
new SubmoduleSubscription(targetBranch, new Branch.NameKey(p, "master"), "a"));
assertThat(res).containsExactlyElementsIn(expected);
}
@ -161,21 +169,23 @@ public class SubmoduleSectionParserIT extends AbstractDaemonTest {
public void withSlashesInPath() throws Exception {
Project.NameKey p = createProject("a");
Config cfg = new Config();
cfg.fromText(""
+ "[submodule \"a\"]\n"
+ "path = a/b/c/d/e\n"
+ "url = http://localhost:80/" + p.get() + "\n"
+ "branch = master\n");
cfg.fromText(
""
+ "[submodule \"a\"]\n"
+ "path = a/b/c/d/e\n"
+ "url = http://localhost:80/"
+ p.get()
+ "\n"
+ "branch = master\n");
Branch.NameKey targetBranch = new Branch.NameKey(
new Project.NameKey("project"), "master");
Branch.NameKey targetBranch = new Branch.NameKey(new Project.NameKey("project"), "master");
Set<SubmoduleSubscription> res = new SubmoduleSectionParser(
cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> res =
new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> expected = Sets.newHashSet(
new SubmoduleSubscription(targetBranch, new Branch.NameKey(
p, "master"), "a/b/c/d/e"));
Set<SubmoduleSubscription> expected =
Sets.newHashSet(
new SubmoduleSubscription(targetBranch, new Branch.NameKey(p, "master"), "a/b/c/d/e"));
assertThat(res).containsExactlyElementsIn(expected);
}
@ -185,27 +195,30 @@ public class SubmoduleSectionParserIT extends AbstractDaemonTest {
Project.NameKey p1 = createProject("a");
Project.NameKey p2 = createProject("b");
Config cfg = new Config();
cfg.fromText(""
+ "[submodule \"a\"]\n"
+ " path = a\n"
+ " url = ssh://localhost/" + p1.get() + "\n"
+ " branch = .\n"
+ "[submodule \"b\"]\n"
+ " path = b\n"
+ " url = http://localhost:80/" + p2.get() + "\n"
+ " branch = master\n");
cfg.fromText(
""
+ "[submodule \"a\"]\n"
+ " path = a\n"
+ " url = ssh://localhost/"
+ p1.get()
+ "\n"
+ " branch = .\n"
+ "[submodule \"b\"]\n"
+ " path = b\n"
+ " url = http://localhost:80/"
+ p2.get()
+ "\n"
+ " branch = master\n");
Branch.NameKey targetBranch = new Branch.NameKey(
new Project.NameKey("project"), "master");
Branch.NameKey targetBranch = new Branch.NameKey(new Project.NameKey("project"), "master");
Set<SubmoduleSubscription> res = new SubmoduleSectionParser(
cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> res =
new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> expected = Sets.newHashSet(
new SubmoduleSubscription(targetBranch, new Branch.NameKey(
p1, "master"), "a"),
new SubmoduleSubscription(targetBranch, new Branch.NameKey(
p2, "master"), "b"));
Set<SubmoduleSubscription> expected =
Sets.newHashSet(
new SubmoduleSubscription(targetBranch, new Branch.NameKey(p1, "master"), "a"),
new SubmoduleSubscription(targetBranch, new Branch.NameKey(p2, "master"), "b"));
assertThat(res).containsExactlyElementsIn(expected);
}
@ -215,27 +228,30 @@ public class SubmoduleSectionParserIT extends AbstractDaemonTest {
Project.NameKey p1 = createProject("a/b");
Project.NameKey p2 = createProject("b");
Config cfg = new Config();
cfg.fromText("\n"
+ "[submodule \"a/b\"]\n"
+ "path = a/b\n"
+ "url = ssh://localhost/" + p1.get() + "\n"
+ "branch = .\n"
+ "[submodule \"b\"]\n"
+ "path = b\n"
+ "url = http://localhost/" + p2.get() + "\n"
+ "branch = .\n");
cfg.fromText(
"\n"
+ "[submodule \"a/b\"]\n"
+ "path = a/b\n"
+ "url = ssh://localhost/"
+ p1.get()
+ "\n"
+ "branch = .\n"
+ "[submodule \"b\"]\n"
+ "path = b\n"
+ "url = http://localhost/"
+ p2.get()
+ "\n"
+ "branch = .\n");
Branch.NameKey targetBranch = new Branch.NameKey(
new Project.NameKey("project"), "master");
Branch.NameKey targetBranch = new Branch.NameKey(new Project.NameKey("project"), "master");
Set<SubmoduleSubscription> res = new SubmoduleSectionParser(
cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> res =
new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> expected = Sets.newHashSet(
new SubmoduleSubscription(targetBranch, new Branch.NameKey(
p2, "master"), "b"),
new SubmoduleSubscription(targetBranch, new Branch.NameKey(
p1, "master"), "a/b"));
Set<SubmoduleSubscription> expected =
Sets.newHashSet(
new SubmoduleSubscription(targetBranch, new Branch.NameKey(p2, "master"), "b"),
new SubmoduleSubscription(targetBranch, new Branch.NameKey(p1, "master"), "a/b"));
assertThat(res).containsExactlyElementsIn(expected);
}
@ -247,39 +263,46 @@ public class SubmoduleSectionParserIT extends AbstractDaemonTest {
Project.NameKey p3 = createProject("d");
Project.NameKey p4 = createProject("e");
Config cfg = new Config();
cfg.fromText("\n"
+ "[submodule \"a\"]\n"
+ " path = a\n"
+ " url = ssh://localhost/" + p1.get() + "\n"
+ " branch = .\n"
+ "[submodule \"b\"]\n"
cfg.fromText(
"\n"
+ "[submodule \"a\"]\n"
+ " path = a\n"
+ " url = ssh://localhost/"
+ p1.get()
+ "\n"
+ " branch = .\n"
+ "[submodule \"b\"]\n"
// path missing
+ " url = http://localhost:80/" + p2.get() + "\n"
+ " branch = master\n"
+ "[submodule \"c\"]\n"
+ " path = c\n"
+ " url = http://localhost:80/"
+ p2.get()
+ "\n"
+ " branch = master\n"
+ "[submodule \"c\"]\n"
+ " path = c\n"
// url missing
+ " branch = .\n"
+ "[submodule \"d\"]\n"
+ " path = d-parent/the-d-folder\n"
+ " url = ssh://localhost/" + p3.get() + "\n"
+ " branch = .\n"
+ "[submodule \"d\"]\n"
+ " path = d-parent/the-d-folder\n"
+ " url = ssh://localhost/"
+ p3.get()
+ "\n"
// branch missing
+ "[submodule \"e\"]\n"
+ " path = e\n"
+ " url = ssh://localhost/" + p4.get() + "\n"
+ " branch = refs/heads/master\n");
+ "[submodule \"e\"]\n"
+ " path = e\n"
+ " url = ssh://localhost/"
+ p4.get()
+ "\n"
+ " branch = refs/heads/master\n");
Branch.NameKey targetBranch = new Branch.NameKey(
new Project.NameKey("project"), "master");
Branch.NameKey targetBranch = new Branch.NameKey(new Project.NameKey("project"), "master");
Set<SubmoduleSubscription> res = new SubmoduleSectionParser(
cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> res =
new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> expected = Sets.newHashSet(
new SubmoduleSubscription(targetBranch, new Branch.NameKey(
p1, "master"), "a"),
new SubmoduleSubscription(targetBranch, new Branch.NameKey(
p4, "master"), "e"));
Set<SubmoduleSubscription> expected =
Sets.newHashSet(
new SubmoduleSubscription(targetBranch, new Branch.NameKey(p1, "master"), "a"),
new SubmoduleSubscription(targetBranch, new Branch.NameKey(p4, "master"), "e"));
assertThat(res).containsExactlyElementsIn(expected);
}
@ -287,18 +310,18 @@ public class SubmoduleSectionParserIT extends AbstractDaemonTest {
@Test
public void withSectionOfNonexistingProject() throws Exception {
Config cfg = new Config();
cfg.fromText("\n"
+ "[submodule \"a\"]\n"
+ "path = a\n"
+ "url = ssh://non-localhost/a\n"
// Project "a" doesn't exist
+ "branch = .\\n");
cfg.fromText(
"\n"
+ "[submodule \"a\"]\n"
+ "path = a\n"
+ "url = ssh://non-localhost/a\n"
// Project "a" doesn't exist
+ "branch = .\\n");
Branch.NameKey targetBranch = new Branch.NameKey(
new Project.NameKey("project"), "master");
Branch.NameKey targetBranch = new Branch.NameKey(new Project.NameKey("project"), "master");
Set<SubmoduleSubscription> res = new SubmoduleSectionParser(
cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> res =
new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
assertThat(res).isEmpty();
}
@ -307,17 +330,19 @@ public class SubmoduleSectionParserIT extends AbstractDaemonTest {
public void withSectionToOtherServer() throws Exception {
Project.NameKey p1 = createProject("a");
Config cfg = new Config();
cfg.fromText(""
+ "[submodule \"a\"]"
+ "path = a"
+ "url = ssh://non-localhost/" + p1.get() + "\n"
+ "branch = .");
cfg.fromText(
""
+ "[submodule \"a\"]"
+ "path = a"
+ "url = ssh://non-localhost/"
+ p1.get()
+ "\n"
+ "branch = .");
Branch.NameKey targetBranch = new Branch.NameKey(
new Project.NameKey("project"), "master");
Branch.NameKey targetBranch = new Branch.NameKey(new Project.NameKey("project"), "master");
Set<SubmoduleSubscription> res = new SubmoduleSectionParser(
cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> res =
new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
assertThat(res).isEmpty();
}
@ -326,21 +351,23 @@ public class SubmoduleSectionParserIT extends AbstractDaemonTest {
public void withRelativeURI() throws Exception {
Project.NameKey p1 = createProject("a");
Config cfg = new Config();
cfg.fromText(""
+ "[submodule \"a\"]\n"
+ "path = a\n"
+ "url = ../" + p1.get() + "\n"
+ "branch = master\n");
cfg.fromText(
""
+ "[submodule \"a\"]\n"
+ "path = a\n"
+ "url = ../"
+ p1.get()
+ "\n"
+ "branch = master\n");
Branch.NameKey targetBranch = new Branch.NameKey(
new Project.NameKey("project"), "master");
Branch.NameKey targetBranch = new Branch.NameKey(new Project.NameKey("project"), "master");
Set<SubmoduleSubscription> res = new SubmoduleSectionParser(
cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> res =
new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> expected = Sets.newHashSet(
new SubmoduleSubscription(targetBranch, new Branch.NameKey(
p1, "master"), "a"));
Set<SubmoduleSubscription> expected =
Sets.newHashSet(
new SubmoduleSubscription(targetBranch, new Branch.NameKey(p1, "master"), "a"));
assertThat(res).containsExactlyElementsIn(expected);
}
@ -349,21 +376,24 @@ public class SubmoduleSectionParserIT extends AbstractDaemonTest {
public void withDeepRelativeURI() throws Exception {
Project.NameKey p1 = createProject("a");
Config cfg = new Config();
cfg.fromText(""
+ "[submodule \"a\"]\n"
+ "path = a\n"
+ "url = ../../" + p1.get() + "\n"
+ "branch = master\n");
cfg.fromText(
""
+ "[submodule \"a\"]\n"
+ "path = a\n"
+ "url = ../../"
+ p1.get()
+ "\n"
+ "branch = master\n");
Branch.NameKey targetBranch = new Branch.NameKey(
new Project.NameKey("nested/project"), "master");
Branch.NameKey targetBranch =
new Branch.NameKey(new Project.NameKey("nested/project"), "master");
Set<SubmoduleSubscription> res = new SubmoduleSectionParser(
cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> res =
new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> expected = Sets.newHashSet(
new SubmoduleSubscription(targetBranch, new Branch.NameKey(
p1, "master"), "a"));
Set<SubmoduleSubscription> expected =
Sets.newHashSet(
new SubmoduleSubscription(targetBranch, new Branch.NameKey(p1, "master"), "a"));
assertThat(res).containsExactlyElementsIn(expected);
}
@ -372,21 +402,24 @@ public class SubmoduleSectionParserIT extends AbstractDaemonTest {
public void withOverlyDeepRelativeURI() throws Exception {
Project.NameKey p1 = createProject("nested/a");
Config cfg = new Config();
cfg.fromText(""
+ "[submodule \"a\"]\n"
+ "path = a\n"
+ "url = ../../" + p1.get() + "\n"
+ "branch = master\n");
cfg.fromText(
""
+ "[submodule \"a\"]\n"
+ "path = a\n"
+ "url = ../../"
+ p1.get()
+ "\n"
+ "branch = master\n");
Branch.NameKey targetBranch = new Branch.NameKey(
new Project.NameKey("nested/project"), "master");
Branch.NameKey targetBranch =
new Branch.NameKey(new Project.NameKey("nested/project"), "master");
Set<SubmoduleSubscription> res = new SubmoduleSectionParser(
cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> res =
new SubmoduleSectionParser(cfg, THIS_SERVER, targetBranch).parseAllSections();
Set<SubmoduleSubscription> expected = Sets.newHashSet(
new SubmoduleSubscription(targetBranch, new Branch.NameKey(
p1, "master"), "a"));
Set<SubmoduleSubscription> expected =
Sets.newHashSet(
new SubmoduleSubscription(targetBranch, new Branch.NameKey(p1, "master"), "a"));
assertThat(res).containsExactlyElementsIn(expected);
}

View File

@ -21,7 +21,6 @@ import com.google.gerrit.acceptance.GerritConfig;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.testutil.ConfigSuite;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
@ -44,14 +43,12 @@ public class SubmoduleSubscriptionsIT extends AbstractSubmoduleSubscription {
public void testSubscriptionWithoutGlobalServerSetting() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/master", "super-project", "refs/heads/master");
createSubmoduleSubscription(superRepo, "master",
"subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
pushChangeTo(subRepo, "master");
assertThat(hasSubmodule(superRepo, "master",
"subscribed-to-project")).isFalse();
assertThat(hasSubmodule(superRepo, "master", "subscribed-to-project")).isFalse();
}
@Test
@ -59,45 +56,37 @@ public class SubmoduleSubscriptionsIT extends AbstractSubmoduleSubscription {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
createSubmoduleSubscription(superRepo, "master",
"subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
pushChangeTo(subRepo, "master");
assertThat(hasSubmodule(superRepo, "master",
"subscribed-to-project")).isFalse();
assertThat(hasSubmodule(superRepo, "master", "subscribed-to-project")).isFalse();
}
@Test
public void subscriptionToEmptyRepo() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/master", "super-project", "refs/heads/master");
createSubmoduleSubscription(superRepo, "master",
"subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
pushChangeTo(subRepo, "master");
ObjectId subHEAD = pushChangeTo(subRepo, "master");
assertThat(hasSubmodule(superRepo, "master",
"subscribed-to-project")).isTrue();
expectToHaveSubmoduleState(superRepo, "master",
"subscribed-to-project", subHEAD);
assertThat(hasSubmodule(superRepo, "master", "subscribed-to-project")).isTrue();
expectToHaveSubmoduleState(superRepo, "master", "subscribed-to-project", subHEAD);
}
@Test
public void subscriptionToExistingRepo() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/master", "super-project", "refs/heads/master");
pushChangeTo(subRepo, "master");
createSubmoduleSubscription(superRepo, "master",
"subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
ObjectId subHEAD = pushChangeTo(subRepo, "master");
assertThat(hasSubmodule(superRepo, "master",
"subscribed-to-project")).isTrue();
expectToHaveSubmoduleState(superRepo, "master",
"subscribed-to-project", subHEAD);
assertThat(hasSubmodule(superRepo, "master", "subscribed-to-project")).isTrue();
expectToHaveSubmoduleState(superRepo, "master", "subscribed-to-project", subHEAD);
}
@Test
@ -105,30 +94,26 @@ public class SubmoduleSubscriptionsIT extends AbstractSubmoduleSubscription {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
// master is allowed to be subscribed to master branch only:
allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", null);
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/master", "super-project", null);
// create 'branch':
pushChangeTo(superRepo, "branch");
pushChangeTo(subRepo, "master");
createSubmoduleSubscription(superRepo, "master",
"subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "branch",
"subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "branch", "subscribed-to-project", "master");
ObjectId subHEAD = pushChangeTo(subRepo, "master");
expectToHaveSubmoduleState(superRepo, "master",
"subscribed-to-project", subHEAD);
assertThat(hasSubmodule(superRepo, "branch",
"subscribed-to-project")).isFalse();
expectToHaveSubmoduleState(superRepo, "master", "subscribed-to-project", subHEAD);
assertThat(hasSubmodule(superRepo, "branch", "subscribed-to-project")).isFalse();
}
@Test
public void subscriptionWildcardACLForMissingProject() throws Exception {
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/*",
"not-existing-super-project", "refs/heads/*");
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/*", "not-existing-super-project", "refs/heads/*");
pushChangeTo(subRepo, "master");
}
@ -136,8 +121,8 @@ public class SubmoduleSubscriptionsIT extends AbstractSubmoduleSubscription {
public void subscriptionWildcardACLForMissingBranch() throws Exception {
createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/*",
"super-project", "refs/heads/*");
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/*", "super-project", "refs/heads/*");
pushChangeTo(subRepo, "foo");
}
@ -145,8 +130,8 @@ public class SubmoduleSubscriptionsIT extends AbstractSubmoduleSubscription {
public void subscriptionWildcardACLForMissingGitmodules() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/*",
"super-project", "refs/heads/*");
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/*", "super-project", "refs/heads/*");
pushChangeTo(superRepo, "master");
pushChangeTo(subRepo, "master");
}
@ -156,36 +141,29 @@ public class SubmoduleSubscriptionsIT extends AbstractSubmoduleSubscription {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
// any branch is allowed to be subscribed to the same superprojects branch:
allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/*",
"super-project", "refs/heads/*");
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/*", "super-project", "refs/heads/*");
// create 'branch' in both repos:
pushChangeTo(superRepo, "branch");
pushChangeTo(subRepo, "branch");
pushChangeTo(subRepo, "master");
createSubmoduleSubscription(superRepo, "master",
"subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "branch",
"subscribed-to-project", "branch");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "branch", "subscribed-to-project", "branch");
ObjectId subHEAD1 = pushChangeTo(subRepo, "master");
ObjectId subHEAD2 = pushChangeTo(subRepo, "branch");
expectToHaveSubmoduleState(superRepo, "master",
"subscribed-to-project", subHEAD1);
expectToHaveSubmoduleState(superRepo, "branch",
"subscribed-to-project", subHEAD2);
expectToHaveSubmoduleState(superRepo, "master", "subscribed-to-project", subHEAD1);
expectToHaveSubmoduleState(superRepo, "branch", "subscribed-to-project", subHEAD2);
// Now test that cross subscriptions do not work:
createSubmoduleSubscription(superRepo, "master",
"subscribed-to-project", "branch");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "branch");
ObjectId subHEAD3 = pushChangeTo(subRepo, "branch");
expectToHaveSubmoduleState(superRepo, "master",
"subscribed-to-project", subHEAD1);
expectToHaveSubmoduleState(superRepo, "branch",
"subscribed-to-project", subHEAD3);
expectToHaveSubmoduleState(superRepo, "master", "subscribed-to-project", subHEAD1);
expectToHaveSubmoduleState(superRepo, "branch", "subscribed-to-project", subHEAD3);
}
@Test
@ -194,15 +172,13 @@ public class SubmoduleSubscriptionsIT extends AbstractSubmoduleSubscription {
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
// Any branch is allowed to be subscribed to any superproject branch:
allowSubmoduleSubscription("subscribed-to-project", "refs/heads/*",
"super-project", null, false);
allowSubmoduleSubscription(
"subscribed-to-project", "refs/heads/*", "super-project", null, false);
pushChangeTo(superRepo, "branch");
pushChangeTo(subRepo, "another-branch");
createSubmoduleSubscription(superRepo, "branch",
"subscribed-to-project", "another-branch");
createSubmoduleSubscription(superRepo, "branch", "subscribed-to-project", "another-branch");
ObjectId subHEAD = pushChangeTo(subRepo, "another-branch");
expectToHaveSubmoduleState(superRepo, "branch",
"subscribed-to-project", subHEAD);
expectToHaveSubmoduleState(superRepo, "branch", "subscribed-to-project", subHEAD);
}
@Test
@ -211,22 +187,18 @@ public class SubmoduleSubscriptionsIT extends AbstractSubmoduleSubscription {
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
// Any branch is allowed to be subscribed to any superproject branch:
allowSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/*", false);
allowSubmoduleSubscription(
"subscribed-to-project", "refs/heads/master", "super-project", "refs/heads/*", false);
pushChangeTo(superRepo, "branch");
createSubmoduleSubscription(superRepo, "branch",
"subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "branch", "subscribed-to-project", "master");
ObjectId subHEAD = pushChangeTo(subRepo, "master");
expectToHaveSubmoduleState(superRepo, "branch",
"subscribed-to-project", subHEAD);
expectToHaveSubmoduleState(superRepo, "branch", "subscribed-to-project", subHEAD);
createSubmoduleSubscription(superRepo, "branch",
"subscribed-to-project", "branch");
createSubmoduleSubscription(superRepo, "branch", "subscribed-to-project", "branch");
pushChangeTo(subRepo, "branch");
// no change expected, as only master is subscribed:
expectToHaveSubmoduleState(superRepo, "branch",
"subscribed-to-project", subHEAD);
expectToHaveSubmoduleState(superRepo, "branch", "subscribed-to-project", subHEAD);
}
@Test
@ -234,26 +206,21 @@ public class SubmoduleSubscriptionsIT extends AbstractSubmoduleSubscription {
public void testSubmoduleShortCommitMessage() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/master", "super-project", "refs/heads/master");
pushChangeTo(subRepo, "master");
createSubmoduleSubscription(superRepo, "master",
"subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
// The first update doesn't include any commit messages
ObjectId subRepoId = pushChangeTo(subRepo, "master");
expectToHaveSubmoduleState(superRepo, "master",
"subscribed-to-project", subRepoId);
expectToHaveCommitMessage(superRepo, "master",
"Update git submodules\n\n");
expectToHaveSubmoduleState(superRepo, "master", "subscribed-to-project", subRepoId);
expectToHaveCommitMessage(superRepo, "master", "Update git submodules\n\n");
// Any following update also has a short message
subRepoId = pushChangeTo(subRepo, "master");
expectToHaveSubmoduleState(superRepo, "master",
"subscribed-to-project", subRepoId);
expectToHaveCommitMessage(superRepo, "master",
"Update git submodules\n\n");
expectToHaveSubmoduleState(superRepo, "master", "subscribed-to-project", subRepoId);
expectToHaveCommitMessage(superRepo, "master", "Update git submodules\n\n");
}
@Test
@ -261,149 +228,153 @@ public class SubmoduleSubscriptionsIT extends AbstractSubmoduleSubscription {
public void testSubmoduleSubjectCommitMessage() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/master", "super-project", "refs/heads/master");
pushChangeTo(subRepo, "master");
createSubmoduleSubscription(superRepo, "master",
"subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
ObjectId subHEAD = pushChangeTo(subRepo, "master");
// The first update doesn't include the rev log
RevWalk rw = subRepo.getRevWalk();
expectToHaveCommitMessage(superRepo, "master",
"Update git submodules\n\n" +
"* Update " + name("subscribed-to-project") + " from branch 'master'");
expectToHaveCommitMessage(
superRepo,
"master",
"Update git submodules\n\n"
+ "* Update "
+ name("subscribed-to-project")
+ " from branch 'master'");
// The next commit should generate only its commit message,
// omitting previous commit logs
subHEAD = pushChangeTo(subRepo, "master");
RevCommit subCommitMsg = rw.parseCommit(subHEAD);
expectToHaveCommitMessage(superRepo, "master",
"Update git submodules\n\n" +
"* Update " + name("subscribed-to-project") + " from branch 'master'"
+ "\n - " + subCommitMsg.getShortMessage());
expectToHaveCommitMessage(
superRepo,
"master",
"Update git submodules\n\n"
+ "* Update "
+ name("subscribed-to-project")
+ " from branch 'master'"
+ "\n - "
+ subCommitMsg.getShortMessage());
}
@Test
public void submoduleCommitMessage() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/master", "super-project", "refs/heads/master");
pushChangeTo(subRepo, "master");
createSubmoduleSubscription(superRepo, "master",
"subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
ObjectId subHEAD = pushChangeTo(subRepo, "master");
// The first update doesn't include the rev log
RevWalk rw = subRepo.getRevWalk();
expectToHaveCommitMessage(superRepo, "master",
"Update git submodules\n\n" +
"* Update " + name("subscribed-to-project") + " from branch 'master'");
expectToHaveCommitMessage(
superRepo,
"master",
"Update git submodules\n\n"
+ "* Update "
+ name("subscribed-to-project")
+ " from branch 'master'");
// The next commit should generate only its commit message,
// omitting previous commit logs
subHEAD = pushChangeTo(subRepo, "master");
RevCommit subCommitMsg = rw.parseCommit(subHEAD);
expectToHaveCommitMessage(superRepo, "master",
"Update git submodules\n\n" +
"* Update " + name("subscribed-to-project") + " from branch 'master'"
+ "\n - " + subCommitMsg.getFullMessage().replace("\n", "\n "));
expectToHaveCommitMessage(
superRepo,
"master",
"Update git submodules\n\n"
+ "* Update "
+ name("subscribed-to-project")
+ " from branch 'master'"
+ "\n - "
+ subCommitMsg.getFullMessage().replace("\n", "\n "));
}
@Test
public void subscriptionUnsubscribe() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/master", "super-project", "refs/heads/master");
pushChangeTo(subRepo, "master");
createSubmoduleSubscription(superRepo, "master",
"subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
pushChangeTo(subRepo, "master");
ObjectId subHEADbeforeUnsubscribing = pushChangeTo(subRepo, "master");
deleteAllSubscriptions(superRepo, "master");
expectToHaveSubmoduleState(superRepo, "master",
"subscribed-to-project", subHEADbeforeUnsubscribing);
expectToHaveSubmoduleState(
superRepo, "master", "subscribed-to-project", subHEADbeforeUnsubscribing);
pushChangeTo(superRepo, "refs/heads/master",
"commit after unsubscribe", "");
pushChangeTo(subRepo, "refs/heads/master",
"commit after unsubscribe", "");
expectToHaveSubmoduleState(superRepo, "master",
"subscribed-to-project", subHEADbeforeUnsubscribing);
pushChangeTo(superRepo, "refs/heads/master", "commit after unsubscribe", "");
pushChangeTo(subRepo, "refs/heads/master", "commit after unsubscribe", "");
expectToHaveSubmoduleState(
superRepo, "master", "subscribed-to-project", subHEADbeforeUnsubscribing);
}
@Test
public void subscriptionUnsubscribeByDeletingGitModules()
throws Exception {
public void subscriptionUnsubscribeByDeletingGitModules() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/master", "super-project", "refs/heads/master");
pushChangeTo(subRepo, "master");
createSubmoduleSubscription(superRepo, "master",
"subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
pushChangeTo(subRepo, "master");
ObjectId subHEADbeforeUnsubscribing = pushChangeTo(subRepo, "master");
deleteGitModulesFile(superRepo, "master");
expectToHaveSubmoduleState(superRepo, "master",
"subscribed-to-project", subHEADbeforeUnsubscribing);
expectToHaveSubmoduleState(
superRepo, "master", "subscribed-to-project", subHEADbeforeUnsubscribing);
pushChangeTo(superRepo, "refs/heads/master",
"commit after unsubscribe", "");
pushChangeTo(subRepo, "refs/heads/master",
"commit after unsubscribe", "");
expectToHaveSubmoduleState(superRepo, "master",
"subscribed-to-project", subHEADbeforeUnsubscribing);
pushChangeTo(superRepo, "refs/heads/master", "commit after unsubscribe", "");
pushChangeTo(subRepo, "refs/heads/master", "commit after unsubscribe", "");
expectToHaveSubmoduleState(
superRepo, "master", "subscribed-to-project", subHEADbeforeUnsubscribing);
}
@Test
public void subscriptionToDifferentBranches() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/foo",
"super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/foo", "super-project", "refs/heads/master");
createSubmoduleSubscription(superRepo, "master",
"subscribed-to-project", "foo");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "foo");
ObjectId subFoo = pushChangeTo(subRepo, "foo");
pushChangeTo(subRepo, "master");
expectToHaveSubmoduleState(superRepo, "master",
"subscribed-to-project", subFoo);
expectToHaveSubmoduleState(superRepo, "master", "subscribed-to-project", subFoo);
}
@Test
public void branchCircularSubscription() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription("super-project", "refs/heads/master",
"subscribed-to-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/master", "super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"super-project", "refs/heads/master", "subscribed-to-project", "refs/heads/master");
pushChangeTo(subRepo, "master");
pushChangeTo(superRepo, "master");
createSubmoduleSubscription(superRepo, "master",
"subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
createSubmoduleSubscription(subRepo, "master", "super-project", "master");
pushChangeTo(subRepo, "master");
pushChangeTo(superRepo, "master");
assertThat(hasSubmodule(subRepo, "master",
"super-project")).isFalse();
assertThat(hasSubmodule(superRepo, "master",
"subscribed-to-project")).isFalse();
assertThat(hasSubmodule(subRepo, "master", "super-project")).isFalse();
assertThat(hasSubmodule(superRepo, "master", "subscribed-to-project")).isFalse();
}
@Test
@ -411,31 +382,26 @@ public class SubmoduleSubscriptionsIT extends AbstractSubmoduleSubscription {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription("super-project", "refs/heads/dev",
"subscribed-to-project", "refs/heads/dev");
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/master", "super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"super-project", "refs/heads/dev", "subscribed-to-project", "refs/heads/dev");
pushChangeTo(subRepo, "master");
pushChangeTo(superRepo, "master");
pushChangeTo(subRepo, "dev");
pushChangeTo(superRepo, "dev");
createSubmoduleSubscription(superRepo, "master",
"subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
createSubmoduleSubscription(subRepo, "dev", "super-project", "dev");
ObjectId subMasterHead = pushChangeTo(subRepo, "master");
ObjectId superDevHead = pushChangeTo(superRepo, "dev");
assertThat(hasSubmodule(superRepo, "master",
"subscribed-to-project")).isTrue();
assertThat(hasSubmodule(subRepo, "dev",
"super-project")).isTrue();
expectToHaveSubmoduleState(superRepo, "master",
"subscribed-to-project", subMasterHead);
expectToHaveSubmoduleState(subRepo, "dev",
"super-project", superDevHead);
assertThat(hasSubmodule(superRepo, "master", "subscribed-to-project")).isTrue();
assertThat(hasSubmodule(subRepo, "dev", "super-project")).isTrue();
expectToHaveSubmoduleState(superRepo, "master", "subscribed-to-project", subMasterHead);
expectToHaveSubmoduleState(subRepo, "dev", "super-project", superDevHead);
}
@Test
@ -444,103 +410,93 @@ public class SubmoduleSubscriptionsIT extends AbstractSubmoduleSubscription {
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
pushChangeTo(subRepo, "master");
createSubmoduleSubscription(superRepo, "master",
"subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
pushChangeTo(subRepo, "master");
assertThat(hasSubmodule(superRepo, "master",
"subscribed-to-project")).isFalse();
assertThat(hasSubmodule(superRepo, "master", "subscribed-to-project")).isFalse();
}
@Test
public void subscriptionFailOnWrongProjectACL() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"wrong-super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/master", "wrong-super-project", "refs/heads/master");
pushChangeTo(subRepo, "master");
createSubmoduleSubscription(superRepo, "master",
"subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
pushChangeTo(subRepo, "master");
assertThat(hasSubmodule(superRepo, "master",
"subscribed-to-project")).isFalse();
assertThat(hasSubmodule(superRepo, "master", "subscribed-to-project")).isFalse();
}
@Test
public void subscriptionFailOnWrongBranchACL() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/wrong-branch");
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/master", "super-project", "refs/heads/wrong-branch");
pushChangeTo(subRepo, "master");
createSubmoduleSubscription(superRepo, "master",
"subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
pushChangeTo(subRepo, "master");
assertThat(hasSubmodule(superRepo, "master",
"subscribed-to-project")).isFalse();
assertThat(hasSubmodule(superRepo, "master", "subscribed-to-project")).isFalse();
}
@Test
public void subscriptionInheritACL() throws Exception {
createProjectWithPush("config-repo");
createProjectWithPush("config-repo2",
new Project.NameKey(name("config-repo")));
createProjectWithPush("config-repo2", new Project.NameKey(name("config-repo")));
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project",
new Project.NameKey(name("config-repo2")));
allowMatchingSubmoduleSubscription("config-repo", "refs/heads/*",
"super-project", "refs/heads/*");
TestRepository<?> subRepo =
createProjectWithPush("subscribed-to-project", new Project.NameKey(name("config-repo2")));
allowMatchingSubmoduleSubscription(
"config-repo", "refs/heads/*", "super-project", "refs/heads/*");
pushChangeTo(subRepo, "master");
createSubmoduleSubscription(superRepo, "master",
"subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
ObjectId subHEAD = pushChangeTo(subRepo, "master");
expectToHaveSubmoduleState(superRepo, "master",
"subscribed-to-project", subHEAD);
expectToHaveSubmoduleState(superRepo, "master", "subscribed-to-project", subHEAD);
}
@Test
public void allowedButNotSubscribed() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/master", "super-project", "refs/heads/master");
pushChangeTo(subRepo, "master");
subRepo.branch("HEAD").commit().insertChangeId()
subRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("some change")
.add("b.txt", "b contents for testing")
.create();
String refspec = "HEAD:refs/heads/master";
PushResult r = Iterables.getOnlyElement(subRepo.git().push()
.setRemote("origin")
.setRefSpecs(new RefSpec(refspec))
.call());
PushResult r =
Iterables.getOnlyElement(
subRepo.git().push().setRemote("origin").setRefSpecs(new RefSpec(refspec)).call());
assertThat(r.getMessages()).doesNotContain("error");
assertThat(r.getRemoteUpdate("refs/heads/master").getStatus())
.isEqualTo(RemoteRefUpdate.Status.OK);
.isEqualTo(RemoteRefUpdate.Status.OK);
assertThat(hasSubmodule(superRepo, "master",
"subscribed-to-project")).isFalse();
assertThat(hasSubmodule(superRepo, "master", "subscribed-to-project")).isFalse();
}
@Test
public void subscriptionDeepRelative() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush(
"nested/subscribed-to-project");
TestRepository<?> subRepo = createProjectWithPush("nested/subscribed-to-project");
// master is allowed to be subscribed to any superprojects branch:
allowMatchingSubmoduleSubscription("nested/subscribed-to-project",
"refs/heads/master", "super-project", null);
allowMatchingSubmoduleSubscription(
"nested/subscribed-to-project", "refs/heads/master", "super-project", null);
pushChangeTo(subRepo, "master");
createRelativeSubmoduleSubscription(superRepo, "master",
"../", "nested/subscribed-to-project", "master");
createRelativeSubmoduleSubscription(
superRepo, "master", "../", "nested/subscribed-to-project", "master");
ObjectId subHEAD = pushChangeTo(subRepo, "master");
expectToHaveSubmoduleState(superRepo, "master",
"nested/subscribed-to-project", subHEAD);
expectToHaveSubmoduleState(superRepo, "master", "nested/subscribed-to-project", subHEAD);
}
}

View File

@ -26,7 +26,7 @@ import com.google.gerrit.extensions.restapi.BinaryResult;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.testutil.ConfigSuite;
import java.util.Map;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
@ -35,11 +35,8 @@ import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.transport.RefSpec;
import org.junit.Test;
import java.util.Map;
@NoHttpd
public class SubmoduleSubscriptionsWholeTopicMergeIT
extends AbstractSubmoduleSubscription {
public class SubmoduleSubscriptionsWholeTopicMergeIT extends AbstractSubmoduleSubscription {
@ConfigSuite.Default
public static Config mergeIfNecessary() {
@ -70,41 +67,67 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
public void subscriptionUpdateOfManyChanges() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/master", "super-project", "refs/heads/master");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
ObjectId subHEAD = subRepo.branch("HEAD").commit().insertChangeId()
.message("some change")
.add("a.txt", "a contents ")
.create();
subRepo.git().push().setRemote("origin").setRefSpecs(
new RefSpec("HEAD:refs/heads/master")).call();
ObjectId subHEAD =
subRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("some change")
.add("a.txt", "a contents ")
.create();
subRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/heads/master"))
.call();
RevCommit c = subRepo.getRevWalk().parseCommit(subHEAD);
RevCommit c1 = subRepo.branch("HEAD").commit().insertChangeId()
.message("first change")
.add("asdf", "asdf\n")
.create();
subRepo.git().push().setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/for/master/" + name("topic-foo")))
.call();
RevCommit c1 =
subRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("first change")
.add("asdf", "asdf\n")
.create();
subRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/for/master/" + name("topic-foo")))
.call();
subRepo.reset(c.getId());
RevCommit c2 = subRepo.branch("HEAD").commit().insertChangeId()
.message("qwerty")
.add("qwerty", "qwerty")
.create();
RevCommit c2 =
subRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("qwerty")
.add("qwerty", "qwerty")
.create();
RevCommit c3 = subRepo.branch("HEAD").commit().insertChangeId()
.message("qwerty followup")
.add("qwerty", "qwerty\nqwerty\n")
.create();
subRepo.git().push().setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/for/master/" + name("topic-foo")))
.call();
RevCommit c3 =
subRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("qwerty followup")
.add("qwerty", "qwerty\nqwerty\n")
.create();
subRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/for/master/" + name("topic-foo")))
.call();
String id1 = getChangeId(subRepo, c1).get();
String id2 = getChangeId(subRepo, c2).get();
@ -114,25 +137,27 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
gApi.changes().id(id3).current().review(ReviewInput.approve());
BinaryResult request = gApi.changes().id(id1).current().submitPreview();
Map<Branch.NameKey, RevTree> preview =
fetchFromBundles(request);
Map<Branch.NameKey, RevTree> preview = fetchFromBundles(request);
gApi.changes().id(id1).current().submit();
ObjectId subRepoId = subRepo.git().fetch().setRemote("origin").call()
.getAdvertisedRef("refs/heads/master").getObjectId();
ObjectId subRepoId =
subRepo
.git()
.fetch()
.setRemote("origin")
.call()
.getAdvertisedRef("refs/heads/master")
.getObjectId();
expectToHaveSubmoduleState(superRepo, "master",
"subscribed-to-project", subRepoId);
expectToHaveSubmoduleState(superRepo, "master", "subscribed-to-project", subRepoId);
// As the submodules have changed commits, the superproject tree will be
// different, so we cannot directly compare the trees here, so make
// assumptions only about the changed branches:
Project.NameKey p1 = new Project.NameKey(name("super-project"));
Project.NameKey p2 = new Project.NameKey(name("subscribed-to-project"));
assertThat(preview).containsKey(
new Branch.NameKey(p1, "refs/heads/master"));
assertThat(preview).containsKey(
new Branch.NameKey(p2, "refs/heads/master"));
assertThat(preview).containsKey(new Branch.NameKey(p1, "refs/heads/master"));
assertThat(preview).containsKey(new Branch.NameKey(p2, "refs/heads/master"));
if ((getSubmitType() == SubmitType.CHERRY_PICK)
|| (getSubmitType() == SubmitType.REBASE_ALWAYS)) {
@ -149,54 +174,85 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
}
@Test
public void subscriptionUpdateIncludingChangeInSuperproject()
throws Exception {
public void subscriptionUpdateIncludingChangeInSuperproject() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
allowMatchingSubmoduleSubscription("subscribed-to-project",
"refs/heads/master", "super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/master", "super-project", "refs/heads/master");
createSubmoduleSubscription(superRepo, "master",
"subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
ObjectId subHEAD = subRepo.branch("HEAD").commit().insertChangeId()
.message("some change")
.add("a.txt", "a contents ")
.create();
subRepo.git().push().setRemote("origin").setRefSpecs(
new RefSpec("HEAD:refs/heads/master")).call();
ObjectId subHEAD =
subRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("some change")
.add("a.txt", "a contents ")
.create();
subRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/heads/master"))
.call();
RevCommit c = subRepo.getRevWalk().parseCommit(subHEAD);
RevCommit c1 = subRepo.branch("HEAD").commit().insertChangeId()
.message("first change")
.add("asdf", "asdf\n")
.create();
subRepo.git().push().setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/for/master/" + name("topic-foo")))
.call();
RevCommit c1 =
subRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("first change")
.add("asdf", "asdf\n")
.create();
subRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/for/master/" + name("topic-foo")))
.call();
subRepo.reset(c.getId());
RevCommit c2 = subRepo.branch("HEAD").commit().insertChangeId()
.message("qwerty")
.add("qwerty", "qwerty")
.create();
RevCommit c2 =
subRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("qwerty")
.add("qwerty", "qwerty")
.create();
RevCommit c3 = subRepo.branch("HEAD").commit().insertChangeId()
.message("qwerty followup")
.add("qwerty", "qwerty\nqwerty\n")
.create();
subRepo.git().push().setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/for/master/" + name("topic-foo")))
.call();
RevCommit c3 =
subRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("qwerty followup")
.add("qwerty", "qwerty\nqwerty\n")
.create();
subRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/for/master/" + name("topic-foo")))
.call();
RevCommit c4 = superRepo.branch("HEAD").commit().insertChangeId()
.message("new change on superproject")
.add("foo", "bar")
.create();
superRepo.git().push().setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/for/master/" + name("topic-foo")))
.call();
RevCommit c4 =
superRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("new change on superproject")
.add("foo", "bar")
.create();
superRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/for/master/" + name("topic-foo")))
.call();
String id1 = getChangeId(subRepo, c1).get();
String id2 = getChangeId(subRepo, c2).get();
@ -208,11 +264,16 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
gApi.changes().id(id4).current().review(ReviewInput.approve());
gApi.changes().id(id1).current().submit();
ObjectId subRepoId = subRepo.git().fetch().setRemote("origin").call()
.getAdvertisedRef("refs/heads/master").getObjectId();
ObjectId subRepoId =
subRepo
.git()
.fetch()
.setRemote("origin")
.call()
.getAdvertisedRef("refs/heads/master")
.getObjectId();
expectToHaveSubmoduleState(superRepo, "master",
"subscribed-to-project", subRepoId);
expectToHaveSubmoduleState(superRepo, "master", "subscribed-to-project", subRepoId);
}
@Test
@ -222,12 +283,12 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
TestRepository<?> sub2 = createProjectWithPush("sub2");
TestRepository<?> sub3 = createProjectWithPush("sub3");
allowMatchingSubmoduleSubscription("sub1", "refs/heads/master",
"super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription("sub2", "refs/heads/master",
"super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription("sub3", "refs/heads/master",
"super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"sub1", "refs/heads/master", "super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"sub2", "refs/heads/master", "super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"sub3", "refs/heads/master", "super-project", "refs/heads/master");
Config config = new Config();
prepareSubmoduleConfigEntry(config, "sub1", "master");
@ -237,12 +298,9 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
ObjectId superPreviousId = pushChangeTo(superRepo, "master");
ObjectId sub1Id = pushChangeTo(sub1, "refs/for/master",
"some message", "same-topic");
ObjectId sub2Id = pushChangeTo(sub2, "refs/for/master",
"some message", "same-topic");
ObjectId sub3Id = pushChangeTo(sub3, "refs/for/master",
"some message", "same-topic");
ObjectId sub1Id = pushChangeTo(sub1, "refs/for/master", "some message", "same-topic");
ObjectId sub2Id = pushChangeTo(sub2, "refs/for/master", "some message", "same-topic");
ObjectId sub3Id = pushChangeTo(sub3, "refs/for/master", "some message", "same-topic");
approve(getChangeId(sub1, sub1Id).get());
approve(getChangeId(sub2, sub2Id).get());
@ -254,11 +312,15 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
expectToHaveSubmoduleState(superRepo, "master", "sub2", sub2, "master");
expectToHaveSubmoduleState(superRepo, "master", "sub3", sub3, "master");
superRepo.git().fetch().setRemote("origin").call()
.getAdvertisedRef("refs/heads/master").getObjectId();
superRepo
.git()
.fetch()
.setRemote("origin")
.call()
.getAdvertisedRef("refs/heads/master")
.getObjectId();
assertWithMessage("submodule subscription update "
+ "should have made one commit")
assertWithMessage("submodule subscription update " + "should have made one commit")
.that(superRepo.getRepository().resolve("origin/master^"))
.isEqualTo(superPreviousId);
}
@ -268,16 +330,14 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
TestRepository<?> superRepo = createProjectWithPush("super-project", false);
TestRepository<?> sub = createProjectWithPush("sub", false);
allowMatchingSubmoduleSubscription("sub", "refs/heads/master",
"super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"sub", "refs/heads/master", "super-project", "refs/heads/master");
createSubmoduleSubscription(superRepo, "master", "sub", "master");
ObjectId subId =
pushChangeTo(sub, "refs/for/master", "some message", "same-topic");
ObjectId subId = pushChangeTo(sub, "refs/for/master", "some message", "same-topic");
ObjectId superId =
pushChangeTo(superRepo, "refs/for/master", "some message", "same-topic");
ObjectId superId = pushChangeTo(superRepo, "refs/for/master", "some message", "same-topic");
String subChangeId = getChangeId(sub, subId).get();
approve(subChangeId);
@ -296,11 +356,9 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
TestRepository<?> superRepo = createProjectWithPush("super-project", false);
TestRepository<?> sub = createProjectWithPush("sub", false);
ObjectId subId =
pushChangeTo(sub, "refs/for/master", "some message", "same-topic");
ObjectId subId = pushChangeTo(sub, "refs/for/master", "some message", "same-topic");
ObjectId superId =
pushChangeTo(superRepo, "refs/for/master", "some message", "same-topic");
ObjectId superId = pushChangeTo(superRepo, "refs/for/master", "some message", "same-topic");
String subChangeId = getChangeId(sub, subId).get();
approve(subChangeId);
@ -318,8 +376,8 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> sub = createProjectWithPush("sub");
allowMatchingSubmoduleSubscription("sub", "refs/heads/master",
"super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"sub", "refs/heads/master", "super-project", "refs/heads/master");
Config config = new Config();
prepareSubmoduleConfigEntry(config, "sub", "master");
@ -337,11 +395,15 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
expectToHaveSubmoduleState(superRepo, "master", "sub", sub, "master");
expectToHaveSubmoduleState(superRepo, "master", "sub-copy", sub, "master");
superRepo.git().fetch().setRemote("origin").call()
.getAdvertisedRef("refs/heads/master").getObjectId();
superRepo
.git()
.fetch()
.setRemote("origin")
.call()
.getAdvertisedRef("refs/heads/master")
.getObjectId();
assertWithMessage("submodule subscription update "
+ "should have made one commit")
assertWithMessage("submodule subscription update " + "should have made one commit")
.that(superRepo.getRepository().resolve("origin/master^"))
.isEqualTo(superPreviousId);
}
@ -351,10 +413,10 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> sub = createProjectWithPush("sub");
allowMatchingSubmoduleSubscription("sub", "refs/heads/master",
"super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription("sub", "refs/heads/dev",
"super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"sub", "refs/heads/master", "super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"sub", "refs/heads/dev", "super-project", "refs/heads/master");
ObjectId devHead = pushChangeTo(sub, "dev");
Config config = new Config();
@ -363,13 +425,12 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
pushSubmoduleConfig(superRepo, "master", config);
ObjectId subMasterId =
pushChangeTo(sub, "refs/for/master", "some message", "b.txt",
"content b", "same-topic");
pushChangeTo(sub, "refs/for/master", "some message", "b.txt", "content b", "same-topic");
sub.reset(devHead);
ObjectId subDevId =
pushChangeTo(sub, "refs/for/dev", "some message in dev", "b.txt",
"content b", "same-topic");
pushChangeTo(
sub, "refs/for/dev", "some message in dev", "b.txt", "content b", "same-topic");
approve(getChangeId(sub, subMasterId).get());
approve(getChangeId(sub, subDevId).get());
@ -381,11 +442,15 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
expectToHaveSubmoduleState(superRepo, "master", "sub-master", sub, "master");
expectToHaveSubmoduleState(superRepo, "master", "sub-dev", sub, "dev");
superRepo.git().fetch().setRemote("origin").call()
.getAdvertisedRef("refs/heads/master").getObjectId();
superRepo
.git()
.fetch()
.setRemote("origin")
.call()
.getAdvertisedRef("refs/heads/master")
.getObjectId();
assertWithMessage("submodule subscription update "
+ "should have made one commit")
assertWithMessage("submodule subscription update " + "should have made one commit")
.that(superRepo.getRepository().resolve("origin/master^"))
.isEqualTo(superPreviousId);
}
@ -396,18 +461,16 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
TestRepository<?> sub = createProjectWithPush("sub");
TestRepository<?> standAlone = createProjectWithPush("standalone");
allowMatchingSubmoduleSubscription("sub", "refs/heads/master",
"super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"sub", "refs/heads/master", "super-project", "refs/heads/master");
createSubmoduleSubscription(superRepo, "master", "sub", "master");
ObjectId superPreviousId = pushChangeTo(superRepo, "master");
ObjectId subId =
pushChangeTo(sub, "refs/for/master", "some message", "same-topic");
ObjectId subId = pushChangeTo(sub, "refs/for/master", "some message", "same-topic");
ObjectId standAloneId =
pushChangeTo(standAlone, "refs/for/master", "some message",
"same-topic");
pushChangeTo(standAlone, "refs/for/master", "some message", "same-topic");
String subChangeId = getChangeId(sub, subId).get();
String standAloneChangeId = getChangeId(standAlone, standAloneId).get();
@ -421,11 +484,15 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
ChangeStatus status = gApi.changes().id(standAloneChangeId).info().status;
assertThat(status).isEqualTo(ChangeStatus.MERGED);
superRepo.git().fetch().setRemote("origin").call()
.getAdvertisedRef("refs/heads/master").getObjectId();
superRepo
.git()
.fetch()
.setRemote("origin")
.call()
.getAdvertisedRef("refs/heads/master")
.getObjectId();
assertWithMessage("submodule subscription update "
+ "should have made one commit")
assertWithMessage("submodule subscription update " + "should have made one commit")
.that(superRepo.getRepository().resolve("origin/master^"))
.isEqualTo(superPreviousId);
}
@ -436,19 +503,16 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
TestRepository<?> midRepo = createProjectWithPush("mid-project");
TestRepository<?> bottomRepo = createProjectWithPush("bottom-project");
allowMatchingSubmoduleSubscription("mid-project", "refs/heads/master",
"top-project", "refs/heads/master");
allowMatchingSubmoduleSubscription("bottom-project", "refs/heads/master",
"mid-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"mid-project", "refs/heads/master", "top-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"bottom-project", "refs/heads/master", "mid-project", "refs/heads/master");
createSubmoduleSubscription(topRepo, "master", "mid-project", "master");
createSubmoduleSubscription(midRepo, "master", "bottom-project", "master");
ObjectId bottomHead =
pushChangeTo(bottomRepo, "refs/for/master",
"some message", "same-topic");
ObjectId topHead =
pushChangeTo(topRepo, "refs/for/master", "some message", "same-topic");
ObjectId bottomHead = pushChangeTo(bottomRepo, "refs/for/master", "some message", "same-topic");
ObjectId topHead = pushChangeTo(topRepo, "refs/for/master", "some message", "same-topic");
String id1 = getChangeId(bottomRepo, bottomHead).get();
String id2 = getChangeId(topRepo, topHead).get();
@ -458,10 +522,8 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
gApi.changes().id(id1).current().submit();
expectToHaveSubmoduleState(midRepo, "master", "bottom-project",
bottomRepo, "master");
expectToHaveSubmoduleState(topRepo, "master", "mid-project",
midRepo, "master");
expectToHaveSubmoduleState(midRepo, "master", "bottom-project", bottomRepo, "master");
expectToHaveSubmoduleState(topRepo, "master", "mid-project", midRepo, "master");
}
@Test
@ -470,12 +532,12 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
TestRepository<?> midRepo = createProjectWithPush("mid-project");
TestRepository<?> bottomRepo = createProjectWithPush("bottom-project");
allowMatchingSubmoduleSubscription("mid-project", "refs/heads/master",
"top-project", "refs/heads/master");
allowMatchingSubmoduleSubscription("bottom-project", "refs/heads/master",
"mid-project", "refs/heads/master");
allowMatchingSubmoduleSubscription("bottom-project", "refs/heads/master",
"top-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"mid-project", "refs/heads/master", "top-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"bottom-project", "refs/heads/master", "mid-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"bottom-project", "refs/heads/master", "top-project", "refs/heads/master");
createSubmoduleSubscription(midRepo, "master", "bottom-project", "master");
Config config = new Config();
@ -483,11 +545,8 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
prepareSubmoduleConfigEntry(config, "mid-project", "master");
pushSubmoduleConfig(topRepo, "master", config);
ObjectId bottomHead =
pushChangeTo(bottomRepo, "refs/for/master",
"some message", "same-topic");
ObjectId topHead =
pushChangeTo(topRepo, "refs/for/master", "some message", "same-topic");
ObjectId bottomHead = pushChangeTo(bottomRepo, "refs/for/master", "some message", "same-topic");
ObjectId topHead = pushChangeTo(topRepo, "refs/for/master", "some message", "same-topic");
String id1 = getChangeId(bottomRepo, bottomHead).get();
String id2 = getChangeId(topRepo, topHead).get();
@ -497,15 +556,11 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
gApi.changes().id(id1).current().submit();
expectToHaveSubmoduleState(midRepo, "master",
"bottom-project", bottomRepo, "master");
expectToHaveSubmoduleState(topRepo, "master",
"mid-project", midRepo, "master");
expectToHaveSubmoduleState(topRepo, "master",
"bottom-project", bottomRepo, "master");
expectToHaveSubmoduleState(midRepo, "master", "bottom-project", bottomRepo, "master");
expectToHaveSubmoduleState(topRepo, "master", "mid-project", midRepo, "master");
expectToHaveSubmoduleState(topRepo, "master", "bottom-project", bottomRepo, "master");
}
private String prepareBranchCircularSubscription() throws Exception {
TestRepository<?> topRepo = createProjectWithPush("top-project");
TestRepository<?> midRepo = createProjectWithPush("mid-project");
@ -515,15 +570,14 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
createSubmoduleSubscription(topRepo, "master", "mid-project", "master");
createSubmoduleSubscription(bottomRepo, "master", "top-project", "master");
allowMatchingSubmoduleSubscription("bottom-project", "refs/heads/master",
"mid-project", "refs/heads/master");
allowMatchingSubmoduleSubscription("mid-project", "refs/heads/master",
"top-project", "refs/heads/master");
allowMatchingSubmoduleSubscription("top-project", "refs/heads/master",
"bottom-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"bottom-project", "refs/heads/master", "mid-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"mid-project", "refs/heads/master", "top-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"top-project", "refs/heads/master", "bottom-project", "refs/heads/master");
ObjectId bottomMasterHead =
pushChangeTo(bottomRepo, "refs/for/master", "some message", "");
ObjectId bottomMasterHead = pushChangeTo(bottomRepo, "refs/for/master", "some message", "");
String changeId = getChangeId(bottomRepo, bottomMasterHead).get();
approve(changeId);
@ -551,24 +605,21 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
allowMatchingSubmoduleSubscription("subscribed-to-project",
"refs/heads/master", "super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription("super-project", "refs/heads/dev",
"subscribed-to-project", "refs/heads/dev");
allowMatchingSubmoduleSubscription(
"subscribed-to-project", "refs/heads/master", "super-project", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"super-project", "refs/heads/dev", "subscribed-to-project", "refs/heads/dev");
pushChangeTo(subRepo, "dev");
pushChangeTo(superRepo, "dev");
createSubmoduleSubscription(superRepo, "master",
"subscribed-to-project", "master");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
createSubmoduleSubscription(subRepo, "dev", "super-project", "dev");
ObjectId subMasterHead =
pushChangeTo(subRepo, "refs/for/master", "b.txt", "content b",
"some message", "same-topic");
ObjectId superDevHead =
pushChangeTo(superRepo, "refs/for/dev",
"some message", "same-topic");
pushChangeTo(
subRepo, "refs/for/master", "b.txt", "content b", "some message", "same-topic");
ObjectId superDevHead = pushChangeTo(superRepo, "refs/for/dev", "some message", "same-topic");
approve(getChangeId(subRepo, subMasterHead).get());
approve(getChangeId(superRepo, superDevHead).get());
@ -576,11 +627,9 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
exception.expectMessage("Project level circular subscriptions detected");
exception.expectMessage("subscribed-to-project");
exception.expectMessage("super-project");
gApi.changes().id(getChangeId(subRepo, subMasterHead).get()).current()
.submit();
gApi.changes().id(getChangeId(subRepo, subMasterHead).get()).current().submit();
assertThat(hasSubmodule(superRepo, "master", "subscribed-to-project"))
.isFalse();
assertThat(hasSubmodule(superRepo, "master", "subscribed-to-project")).isFalse();
assertThat(hasSubmodule(subRepo, "dev", "super-project")).isFalse();
}
@ -596,25 +645,45 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
// create a change for master branch in repo a
ObjectId aHead =
pushChangeTo(repoA, "refs/for/master", "master.txt", "content master A",
"some message in a master.txt", "same-topic");
pushChangeTo(
repoA,
"refs/for/master",
"master.txt",
"content master A",
"some message in a master.txt",
"same-topic");
// create a change for master branch in repo b
ObjectId bHead =
pushChangeTo(repoB, "refs/for/master", "master.txt", "content master B",
"some message in b master.txt", "same-topic");
pushChangeTo(
repoB,
"refs/for/master",
"master.txt",
"content master B",
"some message in b master.txt",
"same-topic");
// create a change for dev branch in repo a
repoA.reset(a0);
ObjectId aDevHead =
pushChangeTo(repoA, "refs/for/dev", "dev.txt", "content dev A",
"some message in a dev.txt", "same-topic");
pushChangeTo(
repoA,
"refs/for/dev",
"dev.txt",
"content dev A",
"some message in a dev.txt",
"same-topic");
// create a change for dev branch in repo b
repoB.reset(b0);
ObjectId bDevHead =
pushChangeTo(repoB, "refs/for/dev", "dev.txt", "content dev B",
"some message in b dev.txt", "same-topic");
pushChangeTo(
repoB,
"refs/for/dev",
"dev.txt",
"content dev B",
"some message in b dev.txt",
"same-topic");
approve(getChangeId(repoA, aHead).get());
approve(getChangeId(repoB, bHead).get());
@ -622,17 +691,13 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
approve(getChangeId(repoB, bDevHead).get());
gApi.changes().id(getChangeId(repoA, aDevHead).get()).current().submit();
assertThat(
getRemoteHead(name("project-a"), "refs/heads/master").getShortMessage())
assertThat(getRemoteHead(name("project-a"), "refs/heads/master").getShortMessage())
.contains("some message in a master.txt");
assertThat(
getRemoteHead(name("project-a"), "refs/heads/dev").getShortMessage())
assertThat(getRemoteHead(name("project-a"), "refs/heads/dev").getShortMessage())
.contains("some message in a dev.txt");
assertThat(
getRemoteHead(name("project-b"), "refs/heads/master").getShortMessage())
assertThat(getRemoteHead(name("project-b"), "refs/heads/master").getShortMessage())
.contains("some message in b master.txt");
assertThat(
getRemoteHead(name("project-b"), "refs/heads/dev").getShortMessage())
assertThat(getRemoteHead(name("project-b"), "refs/heads/dev").getShortMessage())
.contains("some message in b dev.txt");
}
@ -646,25 +711,34 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT
// bootstrap the dev branch
ObjectId b0 = pushChangeTo(repoB, "dev");
allowMatchingSubmoduleSubscription("project-b",
"refs/heads/master", "project-a", "refs/heads/master");
allowMatchingSubmoduleSubscription("project-b", "refs/heads/dev",
"project-a", "refs/heads/dev");
allowMatchingSubmoduleSubscription(
"project-b", "refs/heads/master", "project-a", "refs/heads/master");
allowMatchingSubmoduleSubscription(
"project-b", "refs/heads/dev", "project-a", "refs/heads/dev");
createSubmoduleSubscription(repoA, "master", "project-b", "master");
createSubmoduleSubscription(repoA, "dev", "project-b", "dev");
// create a change for master branch in repo b
ObjectId bHead =
pushChangeTo(repoB, "refs/for/master", "master.txt", "content master B",
"some message in b master.txt", "same-topic");
pushChangeTo(
repoB,
"refs/for/master",
"master.txt",
"content master B",
"some message in b master.txt",
"same-topic");
// create a change for dev branch in repo b
repoB.reset(b0);
ObjectId bDevHead =
pushChangeTo(repoB, "refs/for/dev", "dev.txt", "content dev B",
"some message in b dev.txt", "same-topic");
pushChangeTo(
repoB,
"refs/for/dev",
"dev.txt",
"content dev B",
"some message in b dev.txt",
"same-topic");
approve(getChangeId(repoB, bHead).get());
approve(getChangeId(repoB, bDevHead).get());

View File

@ -21,13 +21,11 @@ import com.google.common.io.Files;
import com.google.gerrit.launcher.GerritLauncher;
import com.google.gerrit.server.notedb.ConfigNotesMigration;
import com.google.gerrit.testutil.TempFileUtil;
import java.io.File;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
public class RebuildNoteDbIT {
private File sitePath;
@ -46,16 +44,22 @@ public class RebuildNoteDbIT {
@Test
public void rebuildEmptySite() throws Exception {
initSite();
Files.append(ConfigNotesMigration.allEnabledConfig().toText(),
Files.append(
ConfigNotesMigration.allEnabledConfig().toText(),
new File(sitePath.toString(), "etc/gerrit.config"),
UTF_8);
runGerrit("RebuildNoteDb", "-d", sitePath.toString(),
"--show-stack-trace");
runGerrit("RebuildNoteDb", "-d", sitePath.toString(), "--show-stack-trace");
}
private void initSite() throws Exception {
runGerrit("init", "-d", sitePath.getPath(),
"--batch", "--no-auto-start", "--skip-plugins", "--show-stack-trace");
runGerrit(
"init",
"-d",
sitePath.getPath(),
"--batch",
"--no-auto-start",
"--skip-plugins",
"--show-stack-trace");
}
private static void runGerrit(String... args) throws Exception {

View File

@ -18,13 +18,11 @@ import static com.google.common.truth.Truth.assertThat;
import com.google.gerrit.launcher.GerritLauncher;
import com.google.gerrit.testutil.TempFileUtil;
import java.io.File;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
public class ReindexIT {
private File sitePath;
@ -43,13 +41,18 @@ public class ReindexIT {
@Test
public void reindexEmptySite() throws Exception {
initSite();
runGerrit("reindex", "-d", sitePath.toString(),
"--show-stack-trace");
runGerrit("reindex", "-d", sitePath.toString(), "--show-stack-trace");
}
private void initSite() throws Exception {
runGerrit("init", "-d", sitePath.getPath(),
"--batch", "--no-auto-start", "--skip-plugins", "--show-stack-trace");
runGerrit(
"init",
"-d",
sitePath.getPath(),
"--batch",
"--no-auto-start",
"--skip-plugins",
"--show-stack-trace");
}
private static void runGerrit(String... args) throws Exception {

View File

@ -20,7 +20,6 @@ import com.google.common.collect.Iterables;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.reviewdb.client.Account;
import java.util.List;
public class AccountAssert {
@ -31,11 +30,9 @@ public class AccountAssert {
assertThat(a.email).isEqualTo(ai.email);
}
public static void assertAccountInfos(List<TestAccount> expected,
List<AccountInfo> actual) {
public static void assertAccountInfos(List<TestAccount> expected, List<AccountInfo> actual) {
Iterable<Account.Id> expectedIds = TestAccount.ids(expected);
Iterable<Account.Id> actualIds = Iterables.transform(
actual, a -> new Account.Id(a._accountId));
Iterable<Account.Id> actualIds = Iterables.transform(actual, a -> new Account.Id(a._accountId));
assertThat(actualIds).containsExactlyElementsIn(expectedIds).inOrder();
for (int i = 0; i < expected.size(); i++) {
AccountAssert.assertAccountInfo(expected.get(i), actual.get(i));

View File

@ -32,24 +32,23 @@ import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.junit.Test;
public class CapabilitiesIT extends AbstractDaemonTest {
@Test
public void capabilitiesUser() throws Exception {
Iterable<String> all = Iterables.filter(
GlobalCapability.getAllNames(),
c -> !ADMINISTRATE_SERVER.equals(c) && !PRIORITY.equals(c));
Iterable<String> all =
Iterables.filter(
GlobalCapability.getAllNames(),
c -> !ADMINISTRATE_SERVER.equals(c) && !PRIORITY.equals(c));
allowGlobalCapabilities(REGISTERED_USERS, all);
try {
RestResponse r =
userRestSession.get("/accounts/self/capabilities");
RestResponse r = userRestSession.get("/accounts/self/capabilities");
r.assertOK();
CapabilityInfo info = (new Gson()).fromJson(r.getReader(),
new TypeToken<CapabilityInfo>() {}.getType());
CapabilityInfo info =
(new Gson()).fromJson(r.getReader(), new TypeToken<CapabilityInfo>() {}.getType());
for (String c : GlobalCapability.getAllNames()) {
if (ADMINISTRATE_SERVER.equals(c)) {
assertThat(info.administrateServer).isFalse();
@ -62,8 +61,10 @@ public class CapabilitiesIT extends AbstractDaemonTest {
assertThat(info.queryLimit.min).isEqualTo((short) 0);
assertThat(info.queryLimit.max).isEqualTo((short) DEFAULT_MAX_QUERY_LIMIT);
} else {
assert_().withFailureMessage(String.format("capability %s was not granted", c))
.that((Boolean) CapabilityInfo.class.getField(c).get(info)).isTrue();
assert_()
.withFailureMessage(String.format("capability %s was not granted", c))
.that((Boolean) CapabilityInfo.class.getField(c).get(info))
.isTrue();
}
}
} finally {
@ -73,11 +74,10 @@ public class CapabilitiesIT extends AbstractDaemonTest {
@Test
public void capabilitiesAdmin() throws Exception {
RestResponse r =
adminRestSession.get("/accounts/self/capabilities");
RestResponse r = adminRestSession.get("/accounts/self/capabilities");
r.assertOK();
CapabilityInfo info = (new Gson()).fromJson(r.getReader(),
new TypeToken<CapabilityInfo>() {}.getType());
CapabilityInfo info =
(new Gson()).fromJson(r.getReader(), new TypeToken<CapabilityInfo>() {}.getType());
for (String c : GlobalCapability.getAllNames()) {
if (BATCH_CHANGES_LIMIT.equals(c)) {
// It does not have default value for any user as it can override the
@ -86,8 +86,7 @@ public class CapabilitiesIT extends AbstractDaemonTest {
} else if (PRIORITY.equals(c)) {
assertThat(info.priority).isFalse();
} else if (QUERY_LIMIT.equals(c)) {
assert_().withFailureMessage("missing queryLimit")
.that(info.queryLimit).isNotNull();
assert_().withFailureMessage("missing queryLimit").that(info.queryLimit).isNotNull();
assertThat(info.queryLimit.min).isEqualTo((short) 0);
assertThat(info.queryLimit.max).isEqualTo((short) DEFAULT_MAX_QUERY_LIMIT);
} else if (ACCESS_DATABASE.equals(c)) {
@ -95,8 +94,10 @@ public class CapabilitiesIT extends AbstractDaemonTest {
} else if (RUN_AS.equals(c)) {
assertThat(info.runAs).isFalse();
} else {
assert_().withFailureMessage(String.format("capability %s was not granted", c))
.that((Boolean) CapabilityInfo.class.getField(c).get(info)).isTrue();
assert_()
.withFailureMessage(String.format("capability %s was not granted", c))
.that((Boolean) CapabilityInfo.class.getField(c).get(info))
.isTrue();
}
}
}

View File

@ -22,20 +22,17 @@ import com.google.gerrit.acceptance.Sandboxed;
import com.google.gerrit.extensions.common.AccountExternalIdInfo;
import com.google.gerrit.reviewdb.client.AccountExternalId;
import com.google.gson.reflect.TypeToken;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
@Sandboxed
public class ExternalIdIT extends AbstractDaemonTest {
@Test
public void getExternalIDs() throws Exception {
Collection<AccountExternalId> expectedIds =
accountCache.get(user.getId()).getExternalIds();
Collection<AccountExternalId> expectedIds = accountCache.get(user.getId()).getExternalIds();
List<AccountExternalIdInfo> expectedIdInfos = new ArrayList<>();
for (AccountExternalId id : expectedIds) {
@ -48,8 +45,9 @@ public class ExternalIdIT extends AbstractDaemonTest {
response.assertOK();
List<AccountExternalIdInfo> results =
newGson().fromJson(response.getReader(),
new TypeToken<List<AccountExternalIdInfo>>() {}.getType());
newGson()
.fromJson(
response.getReader(), new TypeToken<List<AccountExternalIdInfo>>() {}.getType());
Collections.sort(expectedIdInfos);
Collections.sort(results);
@ -59,8 +57,7 @@ public class ExternalIdIT extends AbstractDaemonTest {
@Test
public void deleteExternalIDs() throws Exception {
setApiUser(user);
List<AccountExternalIdInfo> externalIds =
gApi.accounts().self().getExternalIds();
List<AccountExternalIdInfo> externalIds = gApi.accounts().self().getExternalIds();
List<String> toDelete = new ArrayList<>();
List<AccountExternalIdInfo> expectedIds = new ArrayList<>();
@ -74,11 +71,9 @@ public class ExternalIdIT extends AbstractDaemonTest {
assertThat(toDelete).hasSize(1);
RestResponse response = userRestSession.post(
"/accounts/self/external.ids:delete", toDelete);
RestResponse response = userRestSession.post("/accounts/self/external.ids:delete", toDelete);
response.assertNoContent();
List<AccountExternalIdInfo> results =
gApi.accounts().self().getExternalIds();
List<AccountExternalIdInfo> results = gApi.accounts().self().getExternalIds();
// The external ID in WebSession will not be set for tests, resulting that
// "mailto:user@example.com" can be deleted while "username:user" can't.
assertThat(results).hasSize(1);
@ -90,11 +85,10 @@ public class ExternalIdIT extends AbstractDaemonTest {
List<String> toDelete = new ArrayList<>();
String externalIdStr = "username:" + user.username;
toDelete.add(externalIdStr);
RestResponse response = userRestSession.post(
"/accounts/self/external.ids:delete", toDelete);
RestResponse response = userRestSession.post("/accounts/self/external.ids:delete", toDelete);
response.assertConflict();
assertThat(response.getEntityContent()).isEqualTo(
String.format("External id %s cannot be deleted", externalIdStr));
assertThat(response.getEntityContent())
.isEqualTo(String.format("External id %s cannot be deleted", externalIdStr));
}
@Test
@ -102,11 +96,10 @@ public class ExternalIdIT extends AbstractDaemonTest {
List<String> toDelete = new ArrayList<>();
String externalIdStr = "mailto:user@domain.com";
toDelete.add(externalIdStr);
RestResponse response = userRestSession.post(
"/accounts/self/external.ids:delete", toDelete);
RestResponse response = userRestSession.post("/accounts/self/external.ids:delete", toDelete);
response.assertUnprocessableEntity();
assertThat(response.getEntityContent()).isEqualTo(
String.format("External id %s does not exist", externalIdStr));
assertThat(response.getEntityContent())
.isEqualTo(String.format("External id %s does not exist", externalIdStr));
}
private static AccountExternalIdInfo toInfo(AccountExternalId id) {

View File

@ -21,7 +21,6 @@ import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.server.account.GetDetail.AccountDetailInfo;
import org.junit.Test;
public class GetAccountDetailIT extends AbstractDaemonTest {

View File

@ -20,7 +20,6 @@ import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import org.junit.Test;
@NoHttpd
@ -51,8 +50,7 @@ public class GetAccountIT extends AbstractDaemonTest {
testGetAccount("self", admin);
}
private void testGetAccount(String id, TestAccount expectedAccount)
throws Exception {
private void testGetAccount(String id, TestAccount expectedAccount) throws Exception {
assertAccountInfo(expectedAccount, gApi.accounts().id(id).get());
}
}

View File

@ -62,7 +62,6 @@ import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.project.Util;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.inject.Inject;
import org.apache.http.Header;
import org.apache.http.message.BasicHeader;
import org.junit.After;
@ -70,17 +69,13 @@ import org.junit.Before;
import org.junit.Test;
public class ImpersonationIT extends AbstractDaemonTest {
@Inject
private AccountControl.Factory accountControlFactory;
@Inject private AccountControl.Factory accountControlFactory;
@Inject
private ApprovalsUtil approvalsUtil;
@Inject private ApprovalsUtil approvalsUtil;
@Inject
private ChangeMessagesUtil cmUtil;
@Inject private ChangeMessagesUtil cmUtil;
@Inject
private CommentsUtil commentsUtil;
@Inject private CommentsUtil commentsUtil;
private RestSession anonRestSession;
private TestAccount admin2;
@ -105,17 +100,14 @@ public class ImpersonationIT extends AbstractDaemonTest {
public void voteOnBehalfOf() throws Exception {
allowCodeReviewOnBehalfOf();
PushOneCommit.Result r = createChange();
RevisionApi revision = gApi.changes()
.id(r.getChangeId())
.current();
RevisionApi revision = gApi.changes().id(r.getChangeId()).current();
ReviewInput in = ReviewInput.recommend();
in.onBehalfOf = user.id.toString();
in.message = "Message on behalf of";
revision.review(in);
PatchSetApproval psa = Iterables.getOnlyElement(
r.getChange().approvals().values());
PatchSetApproval psa = Iterables.getOnlyElement(r.getChange().approvals().values());
assertThat(psa.getPatchSetId().get()).isEqualTo(1);
assertThat(psa.getLabel()).isEqualTo("Code-Review");
assertThat(psa.getAccountId()).isEqualTo(user.id);
@ -133,17 +125,14 @@ public class ImpersonationIT extends AbstractDaemonTest {
public void voteOnBehalfOfRequiresLabel() throws Exception {
allowCodeReviewOnBehalfOf();
PushOneCommit.Result r = createChange();
RevisionApi revision = gApi.changes()
.id(r.getChangeId())
.current();
RevisionApi revision = gApi.changes().id(r.getChangeId()).current();
ReviewInput in = new ReviewInput();
in.onBehalfOf = user.id.toString();
in.message = "Message on behalf of";
exception.expect(AuthException.class);
exception.expectMessage(
"label required to post review on behalf of \"" + in.onBehalfOf + '"');
exception.expectMessage("label required to post review on behalf of \"" + in.onBehalfOf + '"');
revision.review(in);
}
@ -151,9 +140,7 @@ public class ImpersonationIT extends AbstractDaemonTest {
public void voteOnBehalfOfInvalidLabel() throws Exception {
allowCodeReviewOnBehalfOf();
PushOneCommit.Result r = createChange();
RevisionApi revision = gApi.changes()
.id(r.getChangeId())
.current();
RevisionApi revision = gApi.changes().id(r.getChangeId()).current();
ReviewInput in = new ReviewInput();
in.onBehalfOf = user.id.toString();
@ -161,19 +148,15 @@ public class ImpersonationIT extends AbstractDaemonTest {
in.label("Not-A-Label", 5);
exception.expect(BadRequestException.class);
exception.expectMessage(
"label \"Not-A-Label\" is not a configured label");
exception.expectMessage("label \"Not-A-Label\" is not a configured label");
revision.review(in);
}
@Test
public void voteOnBehalfOfInvalidLabelIgnoredWithoutStrictLabels()
throws Exception {
public void voteOnBehalfOfInvalidLabelIgnoredWithoutStrictLabels() throws Exception {
allowCodeReviewOnBehalfOf();
PushOneCommit.Result r = createChange();
RevisionApi revision = gApi.changes()
.id(r.getChangeId())
.current();
RevisionApi revision = gApi.changes().id(r.getChangeId()).current();
ReviewInput in = new ReviewInput();
in.onBehalfOf = user.id.toString();
@ -183,8 +166,7 @@ public class ImpersonationIT extends AbstractDaemonTest {
revision.review(in);
assertThat(gApi.changes().id(r.getChangeId()).get().labels)
.doesNotContainKey("Not-A-Label");
assertThat(gApi.changes().id(r.getChangeId()).get().labels).doesNotContainKey("Not-A-Label");
}
@Test
@ -195,9 +177,7 @@ public class ImpersonationIT extends AbstractDaemonTest {
saveProjectConfig(project, cfg);
PushOneCommit.Result r = createChange();
RevisionApi revision = gApi.changes()
.id(r.getChangeId())
.current();
RevisionApi revision = gApi.changes().id(r.getChangeId()).current();
ReviewInput in = new ReviewInput();
in.onBehalfOf = user.id.toString();
@ -205,8 +185,7 @@ public class ImpersonationIT extends AbstractDaemonTest {
exception.expect(AuthException.class);
exception.expectMessage(
"not permitted to modify label \"Verified\" on behalf of \""
+ in.onBehalfOf + '"');
"not permitted to modify label \"Verified\" on behalf of \"" + in.onBehalfOf + '"');
revision.review(in);
}
@ -237,8 +216,7 @@ public class ImpersonationIT extends AbstractDaemonTest {
in.comments = ImmutableMap.of(ci.path, ImmutableList.of(ci));
gApi.changes().id(r.getChangeId()).current().review(in);
PatchSetApproval psa = Iterables.getOnlyElement(
r.getChange().approvals().values());
PatchSetApproval psa = Iterables.getOnlyElement(r.getChange().approvals().values());
assertThat(psa.getPatchSetId().get()).isEqualTo(1);
assertThat(psa.getLabel()).isEqualTo("Code-Review");
assertThat(psa.getAccountId()).isEqualTo(user.id);
@ -246,8 +224,7 @@ public class ImpersonationIT extends AbstractDaemonTest {
assertThat(psa.getRealAccountId()).isEqualTo(admin.id);
ChangeData cd = r.getChange();
Comment c = Iterables.getOnlyElement(
commentsUtil.publishedByChange(db, cd.notes()));
Comment c = Iterables.getOnlyElement(commentsUtil.publishedByChange(db, cd.notes()));
assertThat(c.message).isEqualTo(ci.message);
assertThat(c.author.getId()).isEqualTo(user.id);
assertThat(c.getRealAuthor().getId()).isEqualTo(admin.id);
@ -274,8 +251,7 @@ public class ImpersonationIT extends AbstractDaemonTest {
gApi.changes().id(r.getChangeId()).current().review(in);
ChangeData cd = r.getChange();
RobotComment c = Iterables.getOnlyElement(
commentsUtil.robotCommentsByChange(cd.notes()));
RobotComment c = Iterables.getOnlyElement(commentsUtil.robotCommentsByChange(cd.notes()));
assertThat(c.message).isEqualTo(ci.message);
assertThat(c.robotId).isEqualTo(ci.robotId);
assertThat(c.robotRunId).isEqualTo(ci.robotRunId);
@ -311,9 +287,7 @@ public class ImpersonationIT extends AbstractDaemonTest {
public void voteOnBehalfOfMissingUser() throws Exception {
allowCodeReviewOnBehalfOf();
PushOneCommit.Result r = createChange();
RevisionApi revision = gApi.changes()
.id(r.getChangeId())
.current();
RevisionApi revision = gApi.changes().id(r.getChangeId()).current();
ReviewInput in = new ReviewInput();
in.onBehalfOf = "doesnotexist";
@ -325,23 +299,19 @@ public class ImpersonationIT extends AbstractDaemonTest {
}
@Test
public void voteOnBehalfOfFailsWhenUserCannotSeeDestinationRef()
throws Exception {
public void voteOnBehalfOfFailsWhenUserCannotSeeDestinationRef() throws Exception {
blockRead(newGroup);
allowCodeReviewOnBehalfOf();
PushOneCommit.Result r = createChange();
RevisionApi revision = gApi.changes()
.id(r.getChangeId())
.current();
RevisionApi revision = gApi.changes().id(r.getChangeId()).current();
ReviewInput in = new ReviewInput();
in.onBehalfOf = user.id.toString();
in.label("Code-Review", 1);
exception.expect(UnprocessableEntityException.class);
exception.expectMessage(
"on_behalf_of account " + user.id + " cannot see destination ref");
exception.expectMessage("on_behalf_of account " + user.id + " cannot see destination ref");
revision.review(in);
}
@ -353,9 +323,7 @@ public class ImpersonationIT extends AbstractDaemonTest {
assertThat(accountControlFactory.get().canSee(user.id)).isFalse();
PushOneCommit.Result r = createChange();
RevisionApi revision = gApi.changes()
.id(r.getChangeId())
.current();
RevisionApi revision = gApi.changes().id(r.getChangeId()).current();
ReviewInput in = new ReviewInput();
in.onBehalfOf = user.id.toString();
@ -371,21 +339,15 @@ public class ImpersonationIT extends AbstractDaemonTest {
allowSubmitOnBehalfOf();
PushOneCommit.Result r = createChange();
String changeId = project.get() + "~master~" + r.getChangeId();
gApi.changes()
.id(changeId)
.current()
.review(ReviewInput.approve());
gApi.changes().id(changeId).current().review(ReviewInput.approve());
SubmitInput in = new SubmitInput();
in.onBehalfOf = admin2.email;
gApi.changes()
.id(changeId)
.current()
.submit(in);
gApi.changes().id(changeId).current().submit(in);
ChangeData cd = r.getChange();
assertThat(cd.change().getStatus()).isEqualTo(Change.Status.MERGED);
PatchSetApproval submitter = approvalsUtil.getSubmitter(
db, cd.notes(), cd.change().currentPatchSetId());
PatchSetApproval submitter =
approvalsUtil.getSubmitter(db, cd.notes(), cd.change().currentPatchSetId());
assertThat(submitter.getAccountId()).isEqualTo(admin2.id);
assertThat(submitter.getRealAccountId()).isEqualTo(admin.id);
}
@ -395,18 +357,12 @@ public class ImpersonationIT extends AbstractDaemonTest {
allowSubmitOnBehalfOf();
PushOneCommit.Result r = createChange();
String changeId = project.get() + "~master~" + r.getChangeId();
gApi.changes()
.id(changeId)
.current()
.review(ReviewInput.approve());
gApi.changes().id(changeId).current().review(ReviewInput.approve());
SubmitInput in = new SubmitInput();
in.onBehalfOf = "doesnotexist";
exception.expect(UnprocessableEntityException.class);
exception.expectMessage("Account Not Found: doesnotexist");
gApi.changes()
.id(changeId)
.current()
.submit(in);
gApi.changes().id(changeId).current().submit(in);
}
@Test
@ -420,33 +376,22 @@ public class ImpersonationIT extends AbstractDaemonTest {
in.onBehalfOf = admin2.email;
exception.expect(AuthException.class);
exception.expectMessage("submit on behalf of not permitted");
gApi.changes()
.id(project.get() + "~master~" + r.getChangeId())
.current()
.submit(in);
gApi.changes().id(project.get() + "~master~" + r.getChangeId()).current().submit(in);
}
@Test
public void submitOnBehalfOfFailsWhenUserCannotSeeDestinationRef()
throws Exception {
public void submitOnBehalfOfFailsWhenUserCannotSeeDestinationRef() throws Exception {
blockRead(newGroup);
allowSubmitOnBehalfOf();
PushOneCommit.Result r = createChange();
String changeId = project.get() + "~master~" + r.getChangeId();
gApi.changes()
.id(changeId)
.current()
.review(ReviewInput.approve());
gApi.changes().id(changeId).current().review(ReviewInput.approve());
SubmitInput in = new SubmitInput();
in.onBehalfOf = user.email;
exception.expect(UnprocessableEntityException.class);
exception.expectMessage(
"on_behalf_of account " + user.id + " cannot see destination ref");
gApi.changes()
.id(changeId)
.current()
.submit(in);
exception.expectMessage("on_behalf_of account " + user.id + " cannot see destination ref");
gApi.changes().id(changeId).current().submit(in);
}
@GerritConfig(name = "accounts.visibility", value = "SAME_GROUP")
@ -458,28 +403,20 @@ public class ImpersonationIT extends AbstractDaemonTest {
PushOneCommit.Result r = createChange();
String changeId = project.get() + "~master~" + r.getChangeId();
gApi.changes()
.id(changeId)
.current()
.review(ReviewInput.approve());
gApi.changes().id(changeId).current().review(ReviewInput.approve());
SubmitInput in = new SubmitInput();
in.onBehalfOf = user.email;
exception.expect(UnprocessableEntityException.class);
exception.expectMessage("Account Not Found: " + in.onBehalfOf);
gApi.changes()
.id(changeId)
.current()
.submit(in);
gApi.changes().id(changeId).current().submit(in);
}
@Test
public void runAsValidUser() throws Exception {
allowRunAs();
RestResponse res =
adminRestSession.getWithHeader("/accounts/self", runAsHeader(user.id));
RestResponse res = adminRestSession.getWithHeader("/accounts/self", runAsHeader(user.id));
res.assertOK();
AccountInfo account =
newGson().fromJson(res.getEntityContent(), AccountInfo.class);
AccountInfo account = newGson().fromJson(res.getEntityContent(), AccountInfo.class);
assertThat(account._accountId).isEqualTo(user.id.get());
}
@ -487,8 +424,7 @@ public class ImpersonationIT extends AbstractDaemonTest {
@Test
public void runAsDisabledByConfig() throws Exception {
allowRunAs();
RestResponse res =
adminRestSession.getWithHeader("/changes/", runAsHeader(user.id));
RestResponse res = adminRestSession.getWithHeader("/changes/", runAsHeader(user.id));
res.assertForbidden();
assertThat(res.getEntityContent())
.isEqualTo("X-Gerrit-RunAs disabled by auth.enableRunAs = false");
@ -496,31 +432,25 @@ public class ImpersonationIT extends AbstractDaemonTest {
@Test
public void runAsNotPermitted() throws Exception {
RestResponse res =
adminRestSession.getWithHeader("/changes/", runAsHeader(user.id));
RestResponse res = adminRestSession.getWithHeader("/changes/", runAsHeader(user.id));
res.assertForbidden();
assertThat(res.getEntityContent())
.isEqualTo("not permitted to use X-Gerrit-RunAs");
assertThat(res.getEntityContent()).isEqualTo("not permitted to use X-Gerrit-RunAs");
}
@Test
public void runAsNeverPermittedForAnonymousUsers() throws Exception {
allowRunAs();
RestResponse res =
anonRestSession.getWithHeader("/changes/", runAsHeader(user.id));
RestResponse res = anonRestSession.getWithHeader("/changes/", runAsHeader(user.id));
res.assertForbidden();
assertThat(res.getEntityContent())
.isEqualTo("not permitted to use X-Gerrit-RunAs");
assertThat(res.getEntityContent()).isEqualTo("not permitted to use X-Gerrit-RunAs");
}
@Test
public void runAsInvalidUser() throws Exception {
allowRunAs();
RestResponse res = adminRestSession.getWithHeader(
"/changes/", runAsHeader("doesnotexist"));
RestResponse res = adminRestSession.getWithHeader("/changes/", runAsHeader("doesnotexist"));
res.assertForbidden();
assertThat(res.getEntityContent())
.isEqualTo("no account matches X-Gerrit-RunAs");
assertThat(res.getEntityContent()).isEqualTo("no account matches X-Gerrit-RunAs");
}
@Test
@ -543,18 +473,17 @@ public class ImpersonationIT extends AbstractDaemonTest {
ReviewInput in = new ReviewInput();
in.message = "message";
in.drafts = DraftHandling.PUBLISH;
RestResponse res = adminRestSession.postWithHeader(
"/changes/" + r.getChangeId() + "/revisions/current/review", in,
runAsHeader(user.id));
RestResponse res =
adminRestSession.postWithHeader(
"/changes/" + r.getChangeId() + "/revisions/current/review", in, runAsHeader(user.id));
res.assertOK();
ChangeMessageInfo m = Iterables.getLast(
gApi.changes().id(r.getChangeId()).get().messages);
ChangeMessageInfo m = Iterables.getLast(gApi.changes().id(r.getChangeId()).get().messages);
assertThat(m.message).endsWith(in.message);
assertThat(m.author._accountId).isEqualTo(user.id.get());
CommentInfo c = Iterables.getOnlyElement(
gApi.changes().id(r.getChangeId()).comments().get(di.path));
CommentInfo c =
Iterables.getOnlyElement(gApi.changes().id(r.getChangeId()).comments().get(di.path));
assertThat(c.author._accountId).isEqualTo(user.id.get());
assertThat(c.message).isEqualTo(di.message);
@ -577,20 +506,16 @@ public class ImpersonationIT extends AbstractDaemonTest {
in.onBehalfOf = user.id.toString();
in.message = "Message on behalf of";
String endpoint =
"/changes/" + r.getChangeId() + "/revisions/current/review";
RestResponse res =
adminRestSession.postWithHeader(endpoint, in, runAsHeader(user2.id));
String endpoint = "/changes/" + r.getChangeId() + "/revisions/current/review";
RestResponse res = adminRestSession.postWithHeader(endpoint, in, runAsHeader(user2.id));
res.assertForbidden();
assertThat(res.getEntityContent()).isEqualTo(
"label required to post review on behalf of \"" + in.onBehalfOf + '"');
assertThat(res.getEntityContent())
.isEqualTo("label required to post review on behalf of \"" + in.onBehalfOf + '"');
in.label("Code-Review", 1);
adminRestSession.postWithHeader(endpoint, in, runAsHeader(user2.id))
.assertOK();
adminRestSession.postWithHeader(endpoint, in, runAsHeader(user2.id)).assertOK();
PatchSetApproval psa = Iterables.getOnlyElement(
r.getChange().approvals().values());
PatchSetApproval psa = Iterables.getOnlyElement(r.getChange().approvals().values());
assertThat(psa.getPatchSetId().get()).isEqualTo(1);
assertThat(psa.getLabel()).isEqualTo("Code-Review");
assertThat(psa.getAccountId()).isEqualTo(user.id);
@ -609,8 +534,7 @@ public class ImpersonationIT extends AbstractDaemonTest {
LabelType codeReviewType = Util.codeReview();
String forCodeReviewAs = Permission.forLabelAs(codeReviewType.getName());
String heads = "refs/heads/*";
AccountGroup.UUID uuid =
systemGroupBackend.getGroup(REGISTERED_USERS).getUUID();
AccountGroup.UUID uuid = systemGroupBackend.getGroup(REGISTERED_USERS).getUUID();
Util.allow(cfg, forCodeReviewAs, -1, 1, uuid, heads);
saveProjectConfig(project, cfg);
}
@ -618,34 +542,31 @@ public class ImpersonationIT extends AbstractDaemonTest {
private void allowSubmitOnBehalfOf() throws Exception {
ProjectConfig cfg = projectCache.checkedGet(project).getConfig();
String heads = "refs/heads/*";
AccountGroup.UUID uuid =
systemGroupBackend.getGroup(REGISTERED_USERS).getUUID();
AccountGroup.UUID uuid = systemGroupBackend.getGroup(REGISTERED_USERS).getUUID();
Util.allow(cfg, Permission.SUBMIT_AS, uuid, heads);
Util.allow(cfg, Permission.SUBMIT, uuid, heads);
LabelType codeReviewType = Util.codeReview();
Util.allow(cfg, Permission.forLabel(codeReviewType.getName()),
-2, 2, uuid, heads);
Util.allow(cfg, Permission.forLabel(codeReviewType.getName()), -2, 2, uuid, heads);
saveProjectConfig(project, cfg);
}
private void blockRead(GroupInfo group) throws Exception {
ProjectConfig cfg = projectCache.checkedGet(project).getConfig();
Util.block(
cfg, Permission.READ, new AccountGroup.UUID(group.id), "refs/heads/master");
Util.block(cfg, Permission.READ, new AccountGroup.UUID(group.id), "refs/heads/master");
saveProjectConfig(project, cfg);
}
private void allowRunAs() throws Exception {
ProjectConfig cfg = projectCache.checkedGet(allProjects).getConfig();
Util.allow(cfg, GlobalCapability.RUN_AS,
systemGroupBackend.getGroup(ANONYMOUS_USERS).getUUID());
Util.allow(
cfg, GlobalCapability.RUN_AS, systemGroupBackend.getGroup(ANONYMOUS_USERS).getUUID());
saveProjectConfig(allProjects, cfg);
}
private void removeRunAs() throws Exception {
ProjectConfig cfg = projectCache.checkedGet(allProjects).getConfig();
Util.remove(cfg, GlobalCapability.RUN_AS,
systemGroupBackend.getGroup(ANONYMOUS_USERS).getUUID());
Util.remove(
cfg, GlobalCapability.RUN_AS, systemGroupBackend.getGroup(ANONYMOUS_USERS).getUUID());
saveProjectConfig(allProjects, cfg);
}

View File

@ -24,49 +24,38 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.account.PutUsername;
import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
import java.util.Collections;
import org.junit.Test;
import java.util.Collections;
public class PutUsernameIT extends AbstractDaemonTest {
@Inject
private SchemaFactory<ReviewDb> reviewDbProvider;
@Inject private SchemaFactory<ReviewDb> reviewDbProvider;
@Test
public void set() throws Exception {
PutUsername.Input in = new PutUsername.Input();
in.username = "myUsername";
RestResponse r =
adminRestSession.put("/accounts/" + createUser().get() + "/username", in);
RestResponse r = adminRestSession.put("/accounts/" + createUser().get() + "/username", in);
r.assertOK();
assertThat(newGson().fromJson(r.getReader(), String.class)).isEqualTo(
in.username);
assertThat(newGson().fromJson(r.getReader(), String.class)).isEqualTo(in.username);
}
@Test
public void setExisting_Conflict() throws Exception {
PutUsername.Input in = new PutUsername.Input();
in.username = admin.username;
adminRestSession
.put("/accounts/" + createUser().get() + "/username", in)
.assertConflict();
adminRestSession.put("/accounts/" + createUser().get() + "/username", in).assertConflict();
}
@Test
public void setNew_MethodNotAllowed() throws Exception {
PutUsername.Input in = new PutUsername.Input();
in.username = "newUsername";
adminRestSession
.put("/accounts/" + admin.username + "/username", in)
.assertMethodNotAllowed();
adminRestSession.put("/accounts/" + admin.username + "/username", in).assertMethodNotAllowed();
}
@Test
public void delete_MethodNotAllowed() throws Exception {
adminRestSession
.put("/accounts/" + admin.username + "/username")
.assertMethodNotAllowed();
adminRestSession.put("/accounts/" + admin.username + "/username").assertMethodNotAllowed();
}
private Account.Id createUser() throws Exception {

View File

@ -21,11 +21,9 @@ import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.extensions.client.ProjectWatchInfo;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
public class WatchedProjectsIT extends AbstractDaemonTest {
@ -54,8 +52,7 @@ public class WatchedProjectsIT extends AbstractDaemonTest {
List<ProjectWatchInfo> persistedWatchedProjects =
gApi.accounts().self().setWatchedProjects(projectsToWatch);
assertThat(persistedWatchedProjects)
.containsAllIn(projectsToWatch).inOrder();
assertThat(persistedWatchedProjects).containsAllIn(projectsToWatch).inOrder();
}
@Test
@ -86,8 +83,7 @@ public class WatchedProjectsIT extends AbstractDaemonTest {
gApi.accounts().self().deleteWatchedProjects(d);
projectsToWatch.remove(pwi);
List<ProjectWatchInfo> persistedWatchedProjects =
gApi.accounts().self().getWatchedProjects();
List<ProjectWatchInfo> persistedWatchedProjects = gApi.accounts().self().getWatchedProjects();
assertThat(persistedWatchedProjects).doesNotContain(pwi);
assertThat(persistedWatchedProjects).containsAllIn(projectsToWatch);
@ -128,8 +124,7 @@ public class WatchedProjectsIT extends AbstractDaemonTest {
projectsToWatch.add(pwi);
gApi.accounts().self().setWatchedProjects(projectsToWatch);
List<ProjectWatchInfo> persistedWatchedProjects =
gApi.accounts().self().getWatchedProjects();
List<ProjectWatchInfo> persistedWatchedProjects = gApi.accounts().self().getWatchedProjects();
assertThat(persistedWatchedProjects).containsAllIn(projectsToWatch);
}
@ -202,15 +197,13 @@ public class WatchedProjectsIT extends AbstractDaemonTest {
// Perform update
gApi.accounts().self().setWatchedProjects(projectsToWatch);
List<ProjectWatchInfo> watchedProjects =
gApi.accounts().self().getWatchedProjects();
List<ProjectWatchInfo> watchedProjects = gApi.accounts().self().getWatchedProjects();
assertThat(watchedProjects).containsAllIn(projectsToWatch);
}
@Test
public void setAndDeleteWatchedProjectsWithDifferentFilter()
throws Exception {
public void setAndDeleteWatchedProjectsWithDifferentFilter() throws Exception {
String projectName = project.get();
List<ProjectWatchInfo> projectsToWatch = new ArrayList<>();
@ -237,8 +230,7 @@ public class WatchedProjectsIT extends AbstractDaemonTest {
gApi.accounts().self().deleteWatchedProjects(d);
projectsToWatch.remove(pwi);
List<ProjectWatchInfo> persistedWatchedProjects =
gApi.accounts().self().getWatchedProjects();
List<ProjectWatchInfo> persistedWatchedProjects = gApi.accounts().self().getWatchedProjects();
assertThat(persistedWatchedProjects).doesNotContain(pwi);
assertThat(persistedWatchedProjects).containsAllIn(projectsToWatch);

View File

@ -75,7 +75,15 @@ import com.google.gerrit.testutil.ConfigSuite;
import com.google.gerrit.testutil.TestTimeUtil;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
@ -91,16 +99,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
@NoHttpd
public abstract class AbstractSubmit extends AbstractDaemonTest {
@ConfigSuite.Config
@ -108,20 +106,15 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
return submitWholeTopicEnabledConfig();
}
@Inject
private ApprovalsUtil approvalsUtil;
@Inject private ApprovalsUtil approvalsUtil;
@Inject
private Submit submitHandler;
@Inject private Submit submitHandler;
@Inject
private IdentifiedUser.GenericFactory userFactory;
@Inject private IdentifiedUser.GenericFactory userFactory;
@Inject
private BatchUpdate.Factory updateFactory;
@Inject private BatchUpdate.Factory updateFactory;
@Inject
private DynamicSet<OnSubmitValidationListener> onSubmitValidationListeners;
@Inject private DynamicSet<OnSubmitValidationListener> onSubmitValidationListeners;
private RegistrationHandle onSubmitValidatorHandle;
private String systemTimeZone;
@ -144,8 +137,8 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
}
@After
public void removeOnSubmitValidator(){
if (onSubmitValidatorHandle != null){
public void removeOnSubmitValidator() {
if (onSubmitValidatorHandle != null) {
onSubmitValidatorHandle.remove();
}
}
@ -160,8 +153,7 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
BinaryResult request = submitPreview(change.getChangeId());
RevCommit headAfterSubmitPreview = getRemoteHead();
assertThat(headAfterSubmitPreview).isEqualTo(initialHead);
Map<Branch.NameKey, RevTree> actual =
fetchFromBundles(request);
Map<Branch.NameKey, RevTree> actual = fetchFromBundles(request);
assertThat(actual).hasSize(1);
submit(change.getChangeId());
@ -179,8 +171,7 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
assertRefUpdatedEvents();
assertChangeMergedEvents();
Map<Branch.NameKey, RevTree> actual =
fetchFromBundles(request);
Map<Branch.NameKey, RevTree> actual = fetchFromBundles(request);
if ((getSubmitType() == SubmitType.CHERRY_PICK)
|| (getSubmitType() == SubmitType.REBASE_ALWAYS)) {
@ -195,18 +186,15 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
}
@Test
public void submitMultipleChangesOtherMergeConflictPreview()
throws Exception {
public void submitMultipleChangesOtherMergeConflictPreview() throws Exception {
RevCommit initialHead = getRemoteHead();
PushOneCommit.Result change =
createChange("Change 1", "a.txt", "content");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
RevCommit headAfterFirstSubmit = getRemoteHead();
testRepo.reset(initialHead);
PushOneCommit.Result change2 = createChange("Change 2",
"a.txt", "other content");
PushOneCommit.Result change2 = createChange("Change 2", "a.txt", "other content");
PushOneCommit.Result change3 = createChange("Change 3", "d", "d");
PushOneCommit.Result change4 = createChange("Change 4", "e", "e");
// change 2 is not approved, but we ignore labels
@ -220,62 +208,73 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
}
if (getSubmitType() == SubmitType.CHERRY_PICK) {
Map<Branch.NameKey, RevTree> s =
fetchFromBundles(request);
Map<Branch.NameKey, RevTree> s = fetchFromBundles(request);
submit(change4.getChangeId());
assertRevTrees(project, s);
} else if (getSubmitType() == SubmitType.FAST_FORWARD_ONLY) {
assertThat(msg).isEqualTo(
"Failed to submit 3 changes due to the following problems:\n" +
"Change " + change2.getChange().getId() + ": internal error: " +
"change not processed by merge strategy\n" +
"Change " + change3.getChange().getId() + ": internal error: " +
"change not processed by merge strategy\n" +
"Change " + change4.getChange().getId() + ": Project policy " +
"requires all submissions to be a fast-forward. Please " +
"rebase the change locally and upload again for review.");
assertThat(msg)
.isEqualTo(
"Failed to submit 3 changes due to the following problems:\n"
+ "Change "
+ change2.getChange().getId()
+ ": internal error: "
+ "change not processed by merge strategy\n"
+ "Change "
+ change3.getChange().getId()
+ ": internal error: "
+ "change not processed by merge strategy\n"
+ "Change "
+ change4.getChange().getId()
+ ": Project policy "
+ "requires all submissions to be a fast-forward. Please "
+ "rebase the change locally and upload again for review.");
RevCommit headAfterSubmit = getRemoteHead();
assertThat(headAfterSubmit).isEqualTo(headAfterFirstSubmit);
assertRefUpdatedEvents(initialHead, headAfterFirstSubmit);
assertChangeMergedEvents(change.getChangeId(),
headAfterFirstSubmit.name());
assertChangeMergedEvents(change.getChangeId(), headAfterFirstSubmit.name());
} else if ((getSubmitType() == SubmitType.REBASE_IF_NECESSARY)
|| (getSubmitType() == SubmitType.REBASE_ALWAYS)) {
String change2hash = change2.getChange().currentPatchSet()
.getRevision().get();
assertThat(msg).isEqualTo(
"Cannot rebase " + change2hash + ": The change could " +
"not be rebased due to a conflict during merge.");
String change2hash = change2.getChange().currentPatchSet().getRevision().get();
assertThat(msg)
.isEqualTo(
"Cannot rebase "
+ change2hash
+ ": The change could "
+ "not be rebased due to a conflict during merge.");
RevCommit headAfterSubmit = getRemoteHead();
assertThat(headAfterSubmit).isEqualTo(headAfterFirstSubmit);
assertRefUpdatedEvents(initialHead, headAfterFirstSubmit);
assertChangeMergedEvents(change.getChangeId(),
headAfterFirstSubmit.name());
assertChangeMergedEvents(change.getChangeId(), headAfterFirstSubmit.name());
} else {
assertThat(msg).isEqualTo(
"Failed to submit 3 changes due to the following problems:\n" +
"Change " + change2.getChange().getId() + ": Change could not be " +
"merged due to a path conflict. Please rebase the change " +
"locally and upload the rebased commit for review.\n" +
"Change " + change3.getChange().getId() + ": Change could not be " +
"merged due to a path conflict. Please rebase the change " +
"locally and upload the rebased commit for review.\n" +
"Change " + change4.getChange().getId() + ": Change could not be " +
"merged due to a path conflict. Please rebase the change " +
"locally and upload the rebased commit for review.");
assertThat(msg)
.isEqualTo(
"Failed to submit 3 changes due to the following problems:\n"
+ "Change "
+ change2.getChange().getId()
+ ": Change could not be "
+ "merged due to a path conflict. Please rebase the change "
+ "locally and upload the rebased commit for review.\n"
+ "Change "
+ change3.getChange().getId()
+ ": Change could not be "
+ "merged due to a path conflict. Please rebase the change "
+ "locally and upload the rebased commit for review.\n"
+ "Change "
+ change4.getChange().getId()
+ ": Change could not be "
+ "merged due to a path conflict. Please rebase the change "
+ "locally and upload the rebased commit for review.");
RevCommit headAfterSubmit = getRemoteHead();
assertThat(headAfterSubmit).isEqualTo(headAfterFirstSubmit);
assertRefUpdatedEvents(initialHead, headAfterFirstSubmit);
assertChangeMergedEvents(change.getChangeId(),
headAfterFirstSubmit.name());
assertChangeMergedEvents(change.getChangeId(), headAfterFirstSubmit.name());
}
}
@Test
public void submitMultipleChangesPreview() throws Exception {
RevCommit initialHead = getRemoteHead();
PushOneCommit.Result change2 = createChange("Change 2",
"a.txt", "other content");
PushOneCommit.Result change2 = createChange("Change 2", "a.txt", "other content");
PushOneCommit.Result change3 = createChange("Change 3", "d", "d");
PushOneCommit.Result change4 = createChange("Change 4", "e", "e");
// change 2 is not approved, but we ignore labels
@ -285,12 +284,10 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
Map<String, Map<String, Integer>> expected = new HashMap<>();
expected.put(project.get(), new HashMap<String, Integer>());
expected.get(project.get()).put("refs/heads/master", 3);
Map<Branch.NameKey, RevTree> actual =
fetchFromBundles(request);
Map<Branch.NameKey, RevTree> actual = fetchFromBundles(request);
assertThat(actual).containsKey(
new Branch.NameKey(project, "refs/heads/master"));
if (getSubmitType() == SubmitType.CHERRY_PICK){
assertThat(actual).containsKey(new Branch.NameKey(project, "refs/heads/master"));
if (getSubmitType() == SubmitType.CHERRY_PICK) {
// CherryPick ignores dependencies, thus only change and destination
// branch refs are modified.
assertThat(actual).hasSize(2);
@ -325,8 +322,7 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
PushOneCommit.Result result = push.to("refs/for/master");
result.assertOkStatus();
submit(result.getChangeId(), new SubmitInput(), AuthException.class,
"submit not permitted");
submit(result.getChangeId(), new SubmitInput(), AuthException.class, "submit not permitted");
}
@Test
@ -336,8 +332,7 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
ProjectConfig cfg = projectCache.checkedGet(p).getConfig();
Util.block(cfg, Permission.SUBMIT, CHANGE_OWNER, "refs/*");
Util.allow(cfg, Permission.SUBMIT, REGISTERED_USERS, "refs/heads/*");
Util.allow(cfg, Permission.forLabel("Code-Review"), -2, +2,
REGISTERED_USERS, "refs/*");
Util.allow(cfg, Permission.forLabel("Code-Review"), -2, +2, REGISTERED_USERS, "refs/*");
saveProjectConfig(p, cfg);
TestRepository<InMemoryRepository> repo = cloneProject(p, admin);
@ -348,8 +343,7 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
ChangeInfo change = gApi.changes().id(result.getChangeId()).get();
assertThat(change.owner._accountId).isEqualTo(admin.id.get());
submit(result.getChangeId(), new SubmitInput(), AuthException.class,
"submit not permitted");
submit(result.getChangeId(), new SubmitInput(), AuthException.class, "submit not permitted");
setApiUser(user);
submit(result.getChangeId());
@ -362,8 +356,7 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
ProjectConfig cfg = projectCache.checkedGet(p).getConfig();
Util.block(cfg, Permission.SUBMIT, REGISTERED_USERS, "refs/*");
Util.allow(cfg, Permission.SUBMIT, CHANGE_OWNER, "refs/*");
Util.allow(cfg, Permission.forLabel("Code-Review"), -2, +2,
REGISTERED_USERS, "refs/*");
Util.allow(cfg, Permission.forLabel("Code-Review"), -2, +2, REGISTERED_USERS, "refs/*");
saveProjectConfig(p, cfg);
TestRepository<InMemoryRepository> repo = cloneProject(p, admin);
@ -375,8 +368,7 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
assertThat(change.owner._accountId).isEqualTo(admin.id.get());
setApiUser(user);
submit(result.getChangeId(), new SubmitInput(), AuthException.class,
"submit not permitted");
submit(result.getChangeId(), new SubmitInput(), AuthException.class, "submit not permitted");
setApiUser(admin);
submit(result.getChangeId());
@ -388,10 +380,8 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
String topic = "test-topic";
// Create test projects
TestRepository<?> repoA = createProjectWithPush(
"project-a", null, getSubmitType());
TestRepository<?> repoB = createProjectWithPush(
"project-b", null, getSubmitType());
TestRepository<?> repoA = createProjectWithPush("project-a", null, getSubmitType());
TestRepository<?> repoB = createProjectWithPush("project-b", null, getSubmitType());
// Create changes on project-a
PushOneCommit.Result change1 =
@ -425,11 +415,9 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
// Create test project
String projectName = "project-a";
TestRepository<?> repoA = createProjectWithPush(
projectName, null, getSubmitType());
TestRepository<?> repoA = createProjectWithPush(projectName, null, getSubmitType());
RevCommit initialHead =
getRemoteHead(new Project.NameKey(name(projectName)), "master");
RevCommit initialHead = getRemoteHead(new Project.NameKey(name(projectName)), "master");
// Create the dev branch on the test project
BranchInput in = new BranchInput();
@ -466,12 +454,9 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
public void submitWholeTopic() throws Exception {
assume().that(isSubmitWholeTopicEnabled()).isTrue();
String topic = "test-topic";
PushOneCommit.Result change1 =
createChange("Change 1", "a.txt", "content", topic);
PushOneCommit.Result change2 =
createChange("Change 2", "b.txt", "content", topic);
PushOneCommit.Result change3 =
createChange("Change 3", "c.txt", "content", topic);
PushOneCommit.Result change1 = createChange("Change 1", "a.txt", "content", topic);
PushOneCommit.Result change2 = createChange("Change 2", "b.txt", "content", topic);
PushOneCommit.Result change3 = createChange("Change 3", "c.txt", "content", topic);
approve(change1.getChangeId());
approve(change2.getChangeId());
approve(change3.getChangeId());
@ -489,19 +474,18 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
// Check that the repo has the expected commits
List<RevCommit> log = getRemoteLog();
List<String> commitsInRepo = log.stream()
.map(c -> c.getShortMessage())
.collect(Collectors.toList());
int expectedCommitCount = getSubmitType() == SubmitType.MERGE_ALWAYS
? 5 // initial commit + 3 commits + merge commit
: 4; // initial commit + 3 commits
List<String> commitsInRepo =
log.stream().map(c -> c.getShortMessage()).collect(Collectors.toList());
int expectedCommitCount =
getSubmitType() == SubmitType.MERGE_ALWAYS
? 5 // initial commit + 3 commits + merge commit
: 4; // initial commit + 3 commits
assertThat(log).hasSize(expectedCommitCount);
assertThat(commitsInRepo).containsAllOf(
"Initial empty repository", "Change 1", "Change 2", "Change 3");
assertThat(commitsInRepo)
.containsAllOf("Initial empty repository", "Change 1", "Change 2", "Change 3");
if (getSubmitType() == SubmitType.MERGE_ALWAYS) {
assertThat(commitsInRepo).contains(
"Merge changes from topic '" + expectedTopic + "'");
assertThat(commitsInRepo).contains("Merge changes from topic '" + expectedTopic + "'");
}
}
@ -509,9 +493,14 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
public void submitDraftChange() throws Exception {
PushOneCommit.Result draft = createDraftChange();
Change.Id num = draft.getChange().getId();
submitWithConflict(draft.getChangeId(),
submitWithConflict(
draft.getChangeId(),
"Failed to submit 1 change due to the following problems:\n"
+ "Change " + num + ": Change " + num + " is draft");
+ "Change "
+ num
+ ": Change "
+ num
+ " is draft");
}
@Test
@ -520,26 +509,30 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
PushOneCommit.Result draft = amendChangeAsDraft(change.getChangeId());
Change.Id num = draft.getChange().getId();
submitWithConflict(draft.getChangeId(),
submitWithConflict(
draft.getChangeId(),
"Failed to submit 1 change due to the following problems:\n"
+ "Change " + num + ": submit rule error: "
+ "Cannot submit draft patch sets");
+ "Change "
+ num
+ ": submit rule error: "
+ "Cannot submit draft patch sets");
}
@Test
public void submitWithHiddenBranchInSameTopic() throws Exception {
assume().that(isSubmitWholeTopicEnabled()).isTrue();
PushOneCommit.Result visible =
createChange("refs/for/master/" + name("topic"));
PushOneCommit.Result visible = createChange("refs/for/master/" + name("topic"));
Change.Id num = visible.getChange().getId();
createBranch(new Branch.NameKey(project, "hidden"));
PushOneCommit.Result hidden =
createChange("refs/for/hidden/" + name("topic"));
PushOneCommit.Result hidden = createChange("refs/for/hidden/" + name("topic"));
approve(hidden.getChangeId());
blockRead("refs/heads/hidden");
submit(visible.getChangeId(), new SubmitInput(), AuthException.class,
submit(
visible.getChangeId(),
new SubmitInput(),
AuthException.class,
"A change to be submitted with " + num + " is not visible");
}
@ -556,16 +549,17 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
// C0 -- Master
//
ProjectConfig config = projectCache.checkedGet(project).getConfig();
config.getProject().setCreateNewChangeForAllNotInTarget(
InheritableBoolean.TRUE);
config.getProject().setCreateNewChangeForAllNotInTarget(InheritableBoolean.TRUE);
saveProjectConfig(project, config);
PushOneCommit push1 = pushFactory.create(db, admin.getIdent(), testRepo,
PushOneCommit.SUBJECT, "a.txt", "content");
PushOneCommit push1 =
pushFactory.create(
db, admin.getIdent(), testRepo, PushOneCommit.SUBJECT, "a.txt", "content");
PushOneCommit.Result c1 = push1.to("refs/heads/topic");
c1.assertOkStatus();
PushOneCommit push2 = pushFactory.create(db, admin.getIdent(), testRepo,
PushOneCommit.SUBJECT, "b.txt", "anotherContent");
PushOneCommit push2 =
pushFactory.create(
db, admin.getIdent(), testRepo, PushOneCommit.SUBJECT, "b.txt", "anotherContent");
PushOneCommit.Result c2 = push2.to("refs/heads/topic");
c2.assertOkStatus();
@ -588,11 +582,12 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
// I -- master
//
RevCommit master = getRemoteHead(project, "master");
PushOneCommit stableTip = pushFactory.create(db, admin.getIdent(), testRepo,
"Tip of branch stable", "stable.txt", "");
PushOneCommit stableTip =
pushFactory.create(
db, admin.getIdent(), testRepo, "Tip of branch stable", "stable.txt", "");
PushOneCommit.Result stable = stableTip.to("refs/heads/stable");
PushOneCommit mergeCommit = pushFactory.create(db, admin.getIdent(),
testRepo, "The merge commit", "merge.txt", "");
PushOneCommit mergeCommit =
pushFactory.create(db, admin.getIdent(), testRepo, "The merge commit", "merge.txt", "");
mergeCommit.setParents(ImmutableList.of(master, stable.getCommit()));
PushOneCommit.Result mergeReview = mergeCommit.to("refs/for/master");
approve(mergeReview.getChangeId());
@ -671,20 +666,21 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
@Test
public void submitWithValidation() throws Exception {
AtomicBoolean called = new AtomicBoolean(false);
this.addOnSubmitValidationListener(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);
}
}
});
this.addOnSubmitValidationListener(
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());
@ -698,10 +694,8 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
String topic = "test-topic";
// Create test projects
TestRepository<?> repoA =
createProjectWithPush("project-a", null, getSubmitType());
TestRepository<?> repoB =
createProjectWithPush("project-b", null, getSubmitType());
TestRepository<?> repoA = createProjectWithPush("project-a", null, getSubmitType());
TestRepository<?> repoB = createProjectWithPush("project-b", null, getSubmitType());
// Create changes on project-a
PushOneCommit.Result change1 =
@ -715,8 +709,7 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
PushOneCommit.Result change4 =
createChange(repoB, "master", "Change 4", "b.txt", "content", topic);
List<PushOneCommit.Result> changes =
Lists.newArrayList(change1, change2, change3, change4);
List<PushOneCommit.Result> changes = Lists.newArrayList(change1, change2, change3, change4);
for (PushOneCommit.Result change : changes) {
approve(change.getChangeId());
}
@ -725,51 +718,51 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
// Since there are 2 repos, first submit attempt will fail, the second will
// succeed.
List<String> projectsCalled = new ArrayList<>(4);
this.addOnSubmitValidationListener(new OnSubmitValidationListener() {
@Override
public void preBranchUpdate(Arguments args) throws ValidationException {
assertThat(args.getCommands().keySet()).contains("refs/heads/master");
try (RevWalk rw = args.newRevWalk()) {
rw.parseBody(rw.parseCommit(
args.getCommands().get("refs/heads/master").getNewId()));
} catch (IOException e) {
assertThat(e).isNull();
}
projectsCalled.add(args.getProject().get());
if (projectsCalled.size() == 2) {
throw new ValidationException("time to fail");
}
}
});
this.addOnSubmitValidationListener(
new OnSubmitValidationListener() {
@Override
public void preBranchUpdate(Arguments args) throws ValidationException {
assertThat(args.getCommands().keySet()).contains("refs/heads/master");
try (RevWalk rw = args.newRevWalk()) {
rw.parseBody(rw.parseCommit(args.getCommands().get("refs/heads/master").getNewId()));
} catch (IOException e) {
assertThat(e).isNull();
}
projectsCalled.add(args.getProject().get());
if (projectsCalled.size() == 2) {
throw new ValidationException("time to fail");
}
}
});
submitWithConflict(change4.getChangeId(), "time to fail");
assertThat(projectsCalled).containsExactly(name("project-a"),
name("project-b"));
assertThat(projectsCalled).containsExactly(name("project-a"), name("project-b"));
for (PushOneCommit.Result change : changes) {
change.assertChange(Change.Status.NEW, name(topic), admin);
}
submit(change4.getChangeId());
assertThat(projectsCalled).containsExactly(name("project-a"),
name("project-b"), name("project-a"), name("project-b"));
assertThat(projectsCalled)
.containsExactly(
name("project-a"), name("project-b"), name("project-a"), name("project-b"));
for (PushOneCommit.Result change : changes) {
change.assertChange(Change.Status.MERGED, name(topic), admin);
}
}
private void setChangeStatusToNew(PushOneCommit.Result... changes)
throws Exception {
private void setChangeStatusToNew(PushOneCommit.Result... changes) throws Exception {
for (PushOneCommit.Result change : changes) {
try (BatchUpdate bu = updateFactory.create(db, project,
userFactory.create(admin.id), TimeUtil.nowTs())) {
bu.addOp(change.getChange().getId(), new BatchUpdate.Op() {
@Override
public boolean updateChange(ChangeContext ctx) throws OrmException {
ctx.getChange().setStatus(Change.Status.NEW);
ctx.getUpdate(ctx.getChange().currentPatchSetId())
.setStatus(Change.Status.NEW);
return true;
}
});
try (BatchUpdate bu =
updateFactory.create(db, project, userFactory.create(admin.id), TimeUtil.nowTs())) {
bu.addOp(
change.getChange().getId(),
new BatchUpdate.Op() {
@Override
public boolean updateChange(ChangeContext ctx) throws OrmException {
ctx.getChange().setStatus(Change.Status.NEW);
ctx.getUpdate(ctx.getChange().currentPatchSetId()).setStatus(Change.Status.NEW);
return true;
}
});
bu.execute();
}
}
@ -778,18 +771,15 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
private void assertSubmitter(PushOneCommit.Result change) throws Exception {
ChangeInfo info = get(change.getChangeId(), ListChangesOption.MESSAGES);
assertThat(info.messages).isNotNull();
Iterable<String> messages =
Iterables.transform(info.messages, i -> i.message);
Iterable<String> messages = Iterables.transform(info.messages, i -> i.message);
assertThat(messages).hasSize(3);
String last = Iterables.getLast(messages);
if (getSubmitType() == SubmitType.CHERRY_PICK) {
assertThat(last).startsWith(
"Change has been successfully cherry-picked as ");
assertThat(last).startsWith("Change has been successfully cherry-picked as ");
} else if (getSubmitType() == SubmitType.REBASE_ALWAYS) {
assertThat(last).startsWith("Change has been successfully rebased as");
} else {
assertThat(last).isEqualTo(
"Change has been successfully merged by Administrator");
assertThat(last).isEqualTo("Change has been successfully merged by Administrator");
}
}
@ -809,15 +799,16 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
submit(changeId, input, null, null);
}
protected void submitWithConflict(String changeId,
String expectedError) throws Exception {
submit(changeId, new SubmitInput(), ResourceConflictException.class,
expectedError);
protected void submitWithConflict(String changeId, String expectedError) throws Exception {
submit(changeId, new SubmitInput(), ResourceConflictException.class, expectedError);
}
protected void submit(String changeId, SubmitInput input,
protected void submit(
String changeId,
SubmitInput input,
Class<? extends RestApiException> expectedExceptionType,
String expectedExceptionMsg) throws Exception {
String expectedExceptionMsg)
throws Exception {
approve(changeId);
if (expectedExceptionType == null) {
assertSubmittable(changeId);
@ -825,8 +816,7 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
try {
gApi.changes().id(changeId).current().submit(input);
if (expectedExceptionType != null) {
fail("Expected exception of type "
+ expectedExceptionType.getSimpleName());
fail("Expected exception of type " + expectedExceptionType.getSimpleName());
}
} catch (RestApiException e) {
if (expectedExceptionType == null) {
@ -836,11 +826,17 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
// us the stack trace.
if (!expectedExceptionType.isAssignableFrom(e.getClass())
|| !e.getMessage().equals(expectedExceptionMsg)) {
throw new AssertionError("Expected exception of type "
+ expectedExceptionType.getSimpleName() + " with message: \""
+ expectedExceptionMsg + "\" but got exception of type "
+ e.getClass().getSimpleName() + " with message \""
+ e.getMessage() + "\"", e);
throw new AssertionError(
"Expected exception of type "
+ expectedExceptionType.getSimpleName()
+ " with message: \""
+ expectedExceptionMsg
+ "\" but got exception of type "
+ e.getClass().getSimpleName()
+ " with message \""
+ e.getMessage()
+ "\"",
e);
}
return;
}
@ -852,8 +848,7 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
return gApi.changes().id(changeId).current().submitPreview();
}
protected BinaryResult submitPreview(String changeId, String format)
throws Exception {
protected BinaryResult submitPreview(String changeId, String format) throws Exception {
return gApi.changes().id(changeId).current().submitPreview(format);
}
@ -868,25 +863,20 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
}
protected void assertChangeMergedEvents(String... expected) throws Exception {
eventRecorder.assertChangeMergedEvents(
project.get(), "refs/heads/master", expected);
eventRecorder.assertChangeMergedEvents(project.get(), "refs/heads/master", expected);
}
protected void assertRefUpdatedEvents(RevCommit... expected)
protected void assertRefUpdatedEvents(RevCommit... expected) throws Exception {
eventRecorder.assertRefUpdatedEvents(project.get(), "refs/heads/master", expected);
}
protected void assertCurrentRevision(String changeId, int expectedNum, ObjectId expectedId)
throws Exception {
eventRecorder.assertRefUpdatedEvents(
project.get(), "refs/heads/master", expected);
}
protected void assertCurrentRevision(String changeId, int expectedNum,
ObjectId expectedId) throws Exception {
ChangeInfo c = get(changeId, CURRENT_REVISION);
assertThat(c.currentRevision).isEqualTo(expectedId.name());
assertThat(c.revisions.get(expectedId.name())._number).isEqualTo(expectedNum);
try (Repository repo =
repoManager.openRepository(new Project.NameKey(c.project))) {
String refName = new PatchSet.Id(new Change.Id(c._number), expectedNum)
.toRefName();
try (Repository repo = repoManager.openRepository(new Project.NameKey(c.project))) {
String refName = new PatchSet.Id(new Change.Id(c._number), expectedNum).toRefName();
Ref ref = repo.exactRef(refName);
assertThat(ref).named(refName).isNotNull();
assertThat(ref.getObjectId()).isEqualTo(expectedId);
@ -901,14 +891,12 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
assertApproved(changeId, admin);
}
protected void assertApproved(String changeId, TestAccount user)
throws Exception {
protected void assertApproved(String changeId, TestAccount user) throws Exception {
ChangeInfo c = get(changeId, DETAILED_LABELS);
LabelInfo cr = c.labels.get("Code-Review");
assertThat(cr.all).hasSize(1);
assertThat(cr.all.get(0).value).isEqualTo(2);
assertThat(new Account.Id(cr.all.get(0)._accountId))
.isEqualTo(user.getId());
assertThat(new Account.Id(cr.all.get(0)._accountId)).isEqualTo(user.getId());
}
protected void assertMerged(String changeId) throws RestApiException {
@ -916,59 +904,50 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
assertThat(status).isEqualTo(ChangeStatus.MERGED);
}
protected void assertPersonEquals(PersonIdent expected,
PersonIdent actual) {
assertThat(actual.getEmailAddress())
.isEqualTo(expected.getEmailAddress());
assertThat(actual.getName())
.isEqualTo(expected.getName());
assertThat(actual.getTimeZone())
.isEqualTo(expected.getTimeZone());
protected void assertPersonEquals(PersonIdent expected, PersonIdent actual) {
assertThat(actual.getEmailAddress()).isEqualTo(expected.getEmailAddress());
assertThat(actual.getName()).isEqualTo(expected.getName());
assertThat(actual.getTimeZone()).isEqualTo(expected.getTimeZone());
}
protected void assertSubmitter(String changeId, int psId)
throws Exception {
protected void assertSubmitter(String changeId, int psId) throws Exception {
assertSubmitter(changeId, psId, admin);
}
protected void assertSubmitter(String changeId, int psId, TestAccount user)
throws Exception {
Change c =
getOnlyElement(queryProvider.get().byKeyPrefix(changeId)).change();
protected void assertSubmitter(String changeId, int psId, TestAccount user) throws Exception {
Change c = getOnlyElement(queryProvider.get().byKeyPrefix(changeId)).change();
ChangeNotes cn = notesFactory.createChecked(db, c);
PatchSetApproval submitter = approvalsUtil.getSubmitter(db, cn,
new PatchSet.Id(cn.getChangeId(), psId));
PatchSetApproval submitter =
approvalsUtil.getSubmitter(db, cn, new PatchSet.Id(cn.getChangeId(), psId));
assertThat(submitter).isNotNull();
assertThat(submitter.isLegacySubmit()).isTrue();
assertThat(submitter.getAccountId()).isEqualTo(user.getId());
}
protected void assertNoSubmitter(String changeId, int psId)
throws Exception {
Change c =
getOnlyElement(queryProvider.get().byKeyPrefix(changeId)).change();
protected void assertNoSubmitter(String changeId, int psId) throws Exception {
Change c = getOnlyElement(queryProvider.get().byKeyPrefix(changeId)).change();
ChangeNotes cn = notesFactory.createChecked(db, c);
PatchSetApproval submitter = approvalsUtil.getSubmitter(
db, cn, new PatchSet.Id(cn.getChangeId(), psId));
PatchSetApproval submitter =
approvalsUtil.getSubmitter(db, cn, new PatchSet.Id(cn.getChangeId(), psId));
assertThat(submitter).isNull();
}
protected void assertCherryPick(TestRepository<?> testRepo,
boolean contentMerge) throws Exception {
protected void assertCherryPick(TestRepository<?> testRepo, boolean contentMerge)
throws Exception {
assertRebase(testRepo, contentMerge);
RevCommit remoteHead = getRemoteHead();
assertThat(remoteHead.getFooterLines("Reviewed-On")).isNotEmpty();
assertThat(remoteHead.getFooterLines("Reviewed-By")).isNotEmpty();
}
protected void assertRebase(TestRepository<?> testRepo, boolean contentMerge)
throws Exception {
protected void assertRebase(TestRepository<?> testRepo, boolean contentMerge) throws Exception {
Repository repo = testRepo.getRepository();
RevCommit localHead = getHead(repo);
RevCommit remoteHead = getRemoteHead();
assert_().withFailureMessage(
String.format("%s not equal %s", localHead.name(), remoteHead.name()))
.that(localHead.getId()).isNotEqualTo(remoteHead.getId());
assert_()
.withFailureMessage(String.format("%s not equal %s", localHead.name(), remoteHead.name()))
.that(localHead.getId())
.isNotEqualTo(remoteHead.getId());
assertThat(remoteHead.getParentCount()).isEqualTo(1);
if (!contentMerge) {
assertThat(getLatestRemoteDiff()).isEqualTo(getLatestDiff(repo));
@ -976,12 +955,10 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
assertThat(remoteHead.getShortMessage()).isEqualTo(localHead.getShortMessage());
}
protected List<RevCommit> getRemoteLog(Project.NameKey project, String branch)
throws Exception {
protected List<RevCommit> getRemoteLog(Project.NameKey project, String branch) throws Exception {
try (Repository repo = repoManager.openRepository(project);
RevWalk rw = new RevWalk(repo)) {
rw.markStart(rw.parseCommit(
repo.exactRef("refs/heads/" + branch).getObjectId()));
rw.markStart(rw.parseCommit(repo.exactRef("refs/heads/" + branch).getObjectId()));
return Lists.newArrayList(rw);
}
}
@ -990,7 +967,7 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
return getRemoteLog(project, "master");
}
protected void addOnSubmitValidationListener(OnSubmitValidationListener listener){
protected void addOnSubmitValidationListener(OnSubmitValidationListener listener) {
assertThat(onSubmitValidatorHandle).isNull();
onSubmitValidatorHandle = onSubmitValidationListeners.add(listener);
}
@ -1010,8 +987,8 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
}
}
private String getLatestDiff(Repository repo, ObjectId oldTreeId,
ObjectId newTreeId) throws Exception {
private String getLatestDiff(Repository repo, ObjectId oldTreeId, ObjectId newTreeId)
throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try (DiffFormatter fmt = new DiffFormatter(out)) {
fmt.setRepository(repo);

View File

@ -30,7 +30,6 @@ import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.change.Submit.TestSubmitInput;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
@ -43,14 +42,12 @@ public abstract class AbstractSubmitByMerge extends AbstractSubmit {
@Test
public void submitWithMerge() throws Exception {
RevCommit initialHead = getRemoteHead();
PushOneCommit.Result change =
createChange("Change 1", "a.txt", "content");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
RevCommit oldHead = getRemoteHead();
testRepo.reset(initialHead);
PushOneCommit.Result change2 =
createChange("Change 2", "b.txt", "other content");
PushOneCommit.Result change2 = createChange("Change 2", "b.txt", "other content");
submit(change2.getChangeId());
RevCommit head = getRemoteHead();
assertThat(head.getParentCount()).isEqualTo(2);
@ -61,17 +58,14 @@ public abstract class AbstractSubmitByMerge extends AbstractSubmit {
@Test
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
public void submitWithContentMerge() throws Exception {
PushOneCommit.Result change =
createChange("Change 1", "a.txt", "aaa\nbbb\nccc\n");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "aaa\nbbb\nccc\n");
submit(change.getChangeId());
PushOneCommit.Result change2 =
createChange("Change 2", "a.txt", "aaa\nbbb\nccc\nddd\n");
PushOneCommit.Result change2 = createChange("Change 2", "a.txt", "aaa\nbbb\nccc\nddd\n");
submit(change2.getChangeId());
RevCommit oldHead = getRemoteHead();
testRepo.reset(change.getCommit());
PushOneCommit.Result change3 =
createChange("Change 3", "a.txt", "bbb\nccc\n");
PushOneCommit.Result change3 = createChange("Change 3", "a.txt", "bbb\nccc\n");
submit(change3.getChangeId());
RevCommit head = getRemoteHead();
assertThat(head.getParentCount()).isEqualTo(2);
@ -83,20 +77,21 @@ public abstract class AbstractSubmitByMerge extends AbstractSubmit {
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
public void submitWithContentMerge_Conflict() throws Exception {
RevCommit initialHead = getRemoteHead();
PushOneCommit.Result change =
createChange("Change 1", "a.txt", "content");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
RevCommit oldHead = getRemoteHead();
testRepo.reset(initialHead);
PushOneCommit.Result change2 =
createChange("Change 2", "a.txt", "other content");
submitWithConflict(change2.getChangeId(),
"Failed to submit 1 change due to the following problems:\n" +
"Change " + change2.getChange().getId() + ": " +
"Change could not be merged due to a path conflict. " +
"Please rebase the change locally " +
"and upload the rebased commit for review.");
PushOneCommit.Result change2 = createChange("Change 2", "a.txt", "other content");
submitWithConflict(
change2.getChangeId(),
"Failed to submit 1 change due to the following problems:\n"
+ "Change "
+ change2.getChange().getId()
+ ": "
+ "Change could not be merged due to a path conflict. "
+ "Please rebase the change locally "
+ "and upload the rebased commit for review.");
assertThat(getRemoteHead()).isEqualTo(oldHead);
}
@ -114,12 +109,12 @@ public abstract class AbstractSubmitByMerge extends AbstractSubmit {
@TestProjectInput(createEmptyCommit = false)
public void submitMultipleCommitsToEmptyRepoWithOneMerge() throws Exception {
assume().that(isSubmitWholeTopicEnabled()).isTrue();
PushOneCommit.Result change1 = pushFactory.create(
db, admin.getIdent(), testRepo, "Change 1", "a", "a")
.to("refs/for/master/" + name("topic"));
PushOneCommit.Result change1 =
pushFactory
.create(db, admin.getIdent(), testRepo, "Change 1", "a", "a")
.to("refs/for/master/" + name("topic"));
PushOneCommit push2 = pushFactory.create(
db, admin.getIdent(), testRepo, "Change 2", "b", "b");
PushOneCommit push2 = pushFactory.create(db, admin.getIdent(), testRepo, "Change 2", "b", "b");
push2.noParents();
PushOneCommit.Result change2 = push2.to("refs/for/master/" + name("topic"));
change2.assertOkStatus();
@ -136,19 +131,19 @@ public abstract class AbstractSubmitByMerge extends AbstractSubmit {
@Test
public void repairChangeStateAfterFailure() throws Exception {
RevCommit initialHead = getRemoteHead();
PushOneCommit.Result change =
createChange("Change 1", "a.txt", "content");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
RevCommit afterChange1Head = getRemoteHead();
testRepo.reset(initialHead);
PushOneCommit.Result change2 =
createChange("Change 2", "b.txt", "other content");
PushOneCommit.Result change2 = createChange("Change 2", "b.txt", "other content");
Change.Id id2 = change2.getChange().getId();
SubmitInput failAfterRefUpdates =
new TestSubmitInput(new SubmitInput(), true);
submit(change2.getChangeId(), failAfterRefUpdates,
ResourceConflictException.class, "Failing after ref updates");
SubmitInput failAfterRefUpdates = new TestSubmitInput(new SubmitInput(), true);
submit(
change2.getChangeId(),
failAfterRefUpdates,
ResourceConflictException.class,
"Failing after ref updates");
// Bad: ref advanced but change wasn't updated.
PatchSet.Id psId1 = new PatchSet.Id(id2, 1);
@ -179,8 +174,7 @@ public abstract class AbstractSubmitByMerge extends AbstractSubmit {
.isEqualTo("Change has been successfully merged by Administrator");
try (Repository repo = repoManager.openRepository(project)) {
assertThat(repo.exactRef("refs/heads/master").getObjectId())
.isEqualTo(tip);
assertThat(repo.exactRef("refs/heads/master").getObjectId()).isEqualTo(tip);
}
}
@ -191,12 +185,9 @@ public abstract class AbstractSubmitByMerge extends AbstractSubmit {
RevCommit initialHead = getRemoteHead();
// Create a stable branch and bootstrap it.
gApi.projects()
.name(project.get())
.branch("stable")
.create(new BranchInput());
PushOneCommit push = pushFactory.create(
db, user.getIdent(), testRepo, "initial commit", "a.txt", "a");
gApi.projects().name(project.get()).branch("stable").create(new BranchInput());
PushOneCommit push =
pushFactory.create(db, user.getIdent(), testRepo, "initial commit", "a.txt", "a");
PushOneCommit.Result change = push.to("refs/heads/stable");
RevCommit stable = getRemoteHead(project, "stable");
@ -206,44 +197,41 @@ public abstract class AbstractSubmitByMerge extends AbstractSubmit {
assertThat(stable).isEqualTo(change.getCommit());
testRepo.git().fetch().call();
testRepo.git()
.branchCreate()
.setName("stable")
.setStartPoint(stable)
.call();
testRepo.git()
.branchCreate()
.setName("master")
.setStartPoint(master)
.call();
testRepo.git().branchCreate().setName("stable").setStartPoint(stable).call();
testRepo.git().branchCreate().setName("master").setStartPoint(master).call();
// Create a fix in stable branch.
testRepo.reset(stable);
RevCommit fix = testRepo.commit()
.parent(stable)
.message("small fix")
.add("b.txt", "b")
.insertChangeId()
.create();
RevCommit fix =
testRepo
.commit()
.parent(stable)
.message("small fix")
.add("b.txt", "b")
.insertChangeId()
.create();
testRepo.branch("refs/heads/stable").update(fix);
testRepo.git()
testRepo
.git()
.push()
.setRefSpecs(
new RefSpec("refs/heads/stable:refs/for/stable/" + name("topic")))
.setRefSpecs(new RefSpec("refs/heads/stable:refs/for/stable/" + name("topic")))
.call();
// Merge the fix into master.
testRepo.reset(master);
RevCommit merge = testRepo.commit()
.parent(master)
.parent(fix)
.message("Merge stable into master")
.insertChangeId()
.create();
RevCommit merge =
testRepo
.commit()
.parent(master)
.parent(fix)
.message("Merge stable into master")
.insertChangeId()
.create();
testRepo.branch("refs/heads/master").update(merge);
testRepo.git().push()
.setRefSpecs(
new RefSpec("refs/heads/master:refs/for/master/" + name("topic")))
testRepo
.git()
.push()
.setRefSpecs(new RefSpec("refs/heads/master:refs/for/master/" + name("topic")))
.call();
// Submit together.

View File

@ -38,7 +38,6 @@ import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.change.Submit.TestSubmitInput;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.project.Util;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
@ -62,8 +61,13 @@ public abstract class AbstractSubmitByRebase extends AbstractSubmit {
ProjectConfig cfg = projectCache.checkedGet(project).getConfig();
Util.block(cfg, Permission.ADD_PATCH_SET, REGISTERED_USERS, "refs/*");
Util.allow(cfg, Permission.SUBMIT, REGISTERED_USERS, "refs/heads/*");
Util.allow(cfg, Permission.forLabel(Util.codeReview().getName()), -2, 2,
REGISTERED_USERS, "refs/heads/*");
Util.allow(
cfg,
Permission.forLabel(Util.codeReview().getName()),
-2,
2,
REGISTERED_USERS,
"refs/heads/*");
saveProjectConfig(project, cfg);
submitWithRebase(user);
@ -72,57 +76,49 @@ public abstract class AbstractSubmitByRebase extends AbstractSubmit {
private void submitWithRebase(TestAccount submitter) throws Exception {
setApiUser(submitter);
RevCommit initialHead = getRemoteHead();
PushOneCommit.Result change =
createChange("Change 1", "a.txt", "content");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
RevCommit headAfterFirstSubmit = getRemoteHead();
testRepo.reset(initialHead);
PushOneCommit.Result change2 =
createChange("Change 2", "b.txt", "other content");
PushOneCommit.Result change2 = createChange("Change 2", "b.txt", "other content");
submit(change2.getChangeId());
assertRebase(testRepo, false);
RevCommit headAfterSecondSubmit = getRemoteHead();
assertThat(headAfterSecondSubmit.getParent(0))
.isEqualTo(headAfterFirstSubmit);
assertThat(headAfterSecondSubmit.getParent(0)).isEqualTo(headAfterFirstSubmit);
assertApproved(change2.getChangeId(), submitter);
assertCurrentRevision(change2.getChangeId(), 2, headAfterSecondSubmit);
assertSubmitter(change2.getChangeId(), 1, submitter);
assertSubmitter(change2.getChangeId(), 2, submitter);
assertPersonEquals(admin.getIdent(),
headAfterSecondSubmit.getAuthorIdent());
assertPersonEquals(submitter.getIdent(),
headAfterSecondSubmit.getCommitterIdent());
assertPersonEquals(admin.getIdent(), headAfterSecondSubmit.getAuthorIdent());
assertPersonEquals(submitter.getIdent(), headAfterSecondSubmit.getCommitterIdent());
assertRefUpdatedEvents(initialHead, headAfterFirstSubmit,
headAfterFirstSubmit, headAfterSecondSubmit);
assertChangeMergedEvents(change.getChangeId(), headAfterFirstSubmit.name(),
change2.getChangeId(), headAfterSecondSubmit.name());
assertRefUpdatedEvents(
initialHead, headAfterFirstSubmit, headAfterFirstSubmit, headAfterSecondSubmit);
assertChangeMergedEvents(
change.getChangeId(),
headAfterFirstSubmit.name(),
change2.getChangeId(),
headAfterSecondSubmit.name());
}
@Test
public void submitWithRebaseMultipleChanges() throws Exception {
RevCommit initialHead = getRemoteHead();
PushOneCommit.Result change1 =
createChange("Change 1", "a.txt", "content");
PushOneCommit.Result change1 = createChange("Change 1", "a.txt", "content");
submit(change1.getChangeId());
RevCommit headAfterFirstSubmit = getRemoteHead();
if (getSubmitType() == SubmitType.REBASE_ALWAYS) {
assertCurrentRevision(change1.getChangeId(), 2, headAfterFirstSubmit);
} else {
assertThat(headAfterFirstSubmit.name())
.isEqualTo(change1.getCommit().name());
assertThat(headAfterFirstSubmit.name()).isEqualTo(change1.getCommit().name());
}
testRepo.reset(initialHead);
PushOneCommit.Result change2 =
createChange("Change 2", "b.txt", "other content");
assertThat(change2.getCommit().getParent(0))
.isNotEqualTo(change1.getCommit());
PushOneCommit.Result change3 =
createChange("Change 3", "c.txt", "third content");
PushOneCommit.Result change4 =
createChange("Change 4", "d.txt", "fourth content");
PushOneCommit.Result change2 = createChange("Change 2", "b.txt", "other content");
assertThat(change2.getCommit().getParent(0)).isNotEqualTo(change1.getCommit());
PushOneCommit.Result change3 = createChange("Change 3", "c.txt", "third content");
PushOneCommit.Result change4 = createChange("Change 4", "d.txt", "fourth content");
approve(change2.getChangeId());
approve(change3.getChangeId());
submit(change4.getChangeId());
@ -154,33 +150,37 @@ public abstract class AbstractSubmitByRebase extends AbstractSubmit {
assertCurrentRevision(change1.getChangeId(), 1, greatgrandparent);
}
assertRefUpdatedEvents(initialHead, headAfterFirstSubmit,
headAfterFirstSubmit, headAfterSecondSubmit);
assertChangeMergedEvents(change1.getChangeId(), headAfterFirstSubmit.name(),
change2.getChangeId(), headAfterSecondSubmit.name(),
change3.getChangeId(), headAfterSecondSubmit.name(),
change4.getChangeId(), headAfterSecondSubmit.name());
assertRefUpdatedEvents(
initialHead, headAfterFirstSubmit, headAfterFirstSubmit, headAfterSecondSubmit);
assertChangeMergedEvents(
change1.getChangeId(),
headAfterFirstSubmit.name(),
change2.getChangeId(),
headAfterSecondSubmit.name(),
change3.getChangeId(),
headAfterSecondSubmit.name(),
change4.getChangeId(),
headAfterSecondSubmit.name());
}
@Test
public void submitWithRebaseMergeCommit() throws Exception {
/*
* (HEAD, origin/master, origin/HEAD) Merge changes X,Y
|\
| * Merge branch 'master' into origin/master
| |\
| | * SHA Added a
| |/
* | Before
|/
* Initial empty repository
*/
* (HEAD, origin/master, origin/HEAD) Merge changes X,Y
|\
| * Merge branch 'master' into origin/master
| |\
| | * SHA Added a
| |/
* | Before
|/
* Initial empty repository
*/
RevCommit initialHead = getRemoteHead();
PushOneCommit.Result change1 = createChange("Added a", "a.txt", "");
PushOneCommit change2Push = pushFactory.create(db, admin.getIdent(), testRepo,
"Merge to master", "m.txt", "");
PushOneCommit change2Push =
pushFactory.create(db, admin.getIdent(), testRepo, "Merge to master", "m.txt", "");
change2Push.setParents(ImmutableList.of(initialHead, change1.getCommit()));
PushOneCommit.Result change2 = change2Push.to("refs/for/master");
@ -200,7 +200,7 @@ public abstract class AbstractSubmitByRebase extends AbstractSubmit {
RevCommit headParent1 = parse(newHead.getParent(0).getId());
RevCommit headParent2 = parse(newHead.getParent(1).getId());
if (getSubmitType() == SubmitType.REBASE_ALWAYS){
if (getSubmitType() == SubmitType.REBASE_ALWAYS) {
assertCurrentRevision(change3.getChangeId(), 2, headParent1.getId());
} else {
assertThat(change3.getCommit().getId()).isEqualTo(headParent1.getId());
@ -222,17 +222,17 @@ public abstract class AbstractSubmitByRebase extends AbstractSubmit {
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
public void submitWithContentMerge_Conflict() throws Exception {
RevCommit initialHead = getRemoteHead();
PushOneCommit.Result change =
createChange("Change 1", "a.txt", "content");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
RevCommit headAfterFirstSubmit = getRemoteHead();
testRepo.reset(initialHead);
PushOneCommit.Result change2 =
createChange("Change 2", "a.txt", "other content");
submitWithConflict(change2.getChangeId(),
"Cannot rebase " + change2.getCommit().name()
+ ": The change could not be rebased due to a conflict during merge.");
PushOneCommit.Result change2 = createChange("Change 2", "a.txt", "other content");
submitWithConflict(
change2.getChangeId(),
"Cannot rebase "
+ change2.getCommit().name()
+ ": The change could not be rebased due to a conflict during merge.");
RevCommit head = getRemoteHead();
assertThat(head).isEqualTo(headAfterFirstSubmit);
assertCurrentRevision(change2.getChangeId(), 1, change2.getCommit());
@ -245,19 +245,19 @@ public abstract class AbstractSubmitByRebase extends AbstractSubmit {
@Test
public void repairChangeStateAfterFailure() throws Exception {
RevCommit initialHead = getRemoteHead();
PushOneCommit.Result change =
createChange("Change 1", "a.txt", "content");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
RevCommit headAfterFirstSubmit = getRemoteHead();
testRepo.reset(initialHead);
PushOneCommit.Result change2 =
createChange("Change 2", "b.txt", "other content");
PushOneCommit.Result change2 = createChange("Change 2", "b.txt", "other content");
Change.Id id2 = change2.getChange().getId();
SubmitInput failAfterRefUpdates =
new TestSubmitInput(new SubmitInput(), true);
submit(change2.getChangeId(), failAfterRefUpdates,
ResourceConflictException.class, "Failing after ref updates");
SubmitInput failAfterRefUpdates = new TestSubmitInput(new SubmitInput(), true);
submit(
change2.getChangeId(),
failAfterRefUpdates,
ResourceConflictException.class,
"Failing after ref updates");
RevCommit headAfterFailedSubmit = getRemoteHead();
// Bad: ref advanced but change wasn't updated.
@ -279,8 +279,7 @@ public abstract class AbstractSubmitByRebase extends AbstractSubmit {
assertThat(rev2).isNotEqualTo(rev1);
assertThat(rw.parseCommit(rev2).getParent(0)).isEqualTo(headAfterFirstSubmit);
assertThat(repo.exactRef("refs/heads/master").getObjectId())
.isEqualTo(rev2);
assertThat(repo.exactRef("refs/heads/master").getObjectId()).isEqualTo(rev2);
}
submit(change2.getChangeId());
@ -296,17 +295,18 @@ public abstract class AbstractSubmitByRebase extends AbstractSubmit {
assertThat(ps2).isNotNull();
assertThat(ps2.getRevision().get()).isEqualTo(rev2.name());
assertThat(Iterables.getLast(info.messages).message)
.isEqualTo("Change has been successfully rebased as "
+ rev2.name() + " by Administrator");
.isEqualTo("Change has been successfully rebased as " + rev2.name() + " by Administrator");
try (Repository repo = repoManager.openRepository(project)) {
assertThat(repo.exactRef("refs/heads/master").getObjectId())
.isEqualTo(rev2);
assertThat(repo.exactRef("refs/heads/master").getObjectId()).isEqualTo(rev2);
}
assertRefUpdatedEvents(initialHead, headAfterFirstSubmit);
assertChangeMergedEvents(change.getChangeId(), headAfterFirstSubmit.name(),
change2.getChangeId(), headAfterSecondSubmit.name());
assertChangeMergedEvents(
change.getChangeId(),
headAfterFirstSubmit.name(),
change2.getChangeId(),
headAfterSecondSubmit.name());
}
protected RevCommit parse(ObjectId id) throws Exception {
@ -323,14 +323,8 @@ public abstract class AbstractSubmitByRebase extends AbstractSubmit {
RevCommit initialHead = getRemoteHead();
// Create two commits and push.
RevCommit c1 = commitBuilder()
.add("a.txt", "1")
.message("subject: 1")
.create();
RevCommit c2 = commitBuilder()
.add("b.txt", "2")
.message("subject: 2")
.create();
RevCommit c1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
RevCommit c2 = commitBuilder().add("b.txt", "2").message("subject: 2").create();
pushHead(testRepo, "refs/for/master", false);
String id1 = getChangeId(testRepo, c1).get();
@ -348,8 +342,7 @@ public abstract class AbstractSubmitByRebase extends AbstractSubmit {
RevCommit headAfterSubmit = getRemoteHead();
assertRefUpdatedEvents(initialHead, headAfterSubmit);
assertChangeMergedEvents(id2, headAfterSubmit.name(),
id1, headAfterSubmit.name());
assertChangeMergedEvents(id2, headAfterSubmit.name(), id1, headAfterSubmit.name());
}
@Test
@ -370,8 +363,8 @@ public abstract class AbstractSubmitByRebase extends AbstractSubmit {
RevCommit newHead = getRemoteHead();
assertRefUpdatedEvents(initialHead, newHead);
assertChangeMergedEvents(change.getChangeId(), newHead.name(),
change2.getChangeId(), newHead.name());
assertChangeMergedEvents(
change.getChangeId(), newHead.name(), change2.getChangeId(), newHead.name());
}
@Test
@ -381,8 +374,7 @@ public abstract class AbstractSubmitByRebase extends AbstractSubmit {
PushOneCommit.Result change1 = createChange("Change 1", "a.txt", "a");
PushOneCommit.Result change2 = createChange("Change 2", "a.txt", "a");
assertThat(change1.getCommit().getTree())
.isEqualTo(change2.getCommit().getTree());
assertThat(change1.getCommit().getTree()).isEqualTo(change2.getCommit().getTree());
// for rebase if necessary, otherwise, the manual rebase of change2 will
// fail since change1 would be merged as fast forward
@ -411,10 +403,8 @@ public abstract class AbstractSubmitByRebase extends AbstractSubmit {
@Test
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
public void submitChainOneByOne() throws Exception {
PushOneCommit.Result change1 = createChange("subject 1", "fileName 1",
"content 1");
PushOneCommit.Result change2 = createChange("subject 2", "fileName 2",
"content 2");
PushOneCommit.Result change1 = createChange("subject 1", "fileName 1", "content 1");
PushOneCommit.Result change2 = createChange("subject 2", "fileName 2", "content 2");
submit(change1.getChangeId());
submit(change2.getChangeId());
}
@ -423,10 +413,8 @@ public abstract class AbstractSubmitByRebase extends AbstractSubmit {
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
public void submitChainOneByOneManualRebase() throws Exception {
RevCommit initialHead = getRemoteHead();
PushOneCommit.Result change1 = createChange("subject 1", "fileName 1",
"content 1");
PushOneCommit.Result change2 = createChange("subject 2", "fileName 2",
"content 2");
PushOneCommit.Result change1 = createChange("subject 1", "fileName 1", "content 1");
PushOneCommit.Result change2 = createChange("subject 2", "fileName 2", "content 2");
// for rebase if necessary, otherwise, the manual rebase of change2 will
// fail since change1 would be merged as fast forward

View File

@ -37,7 +37,10 @@ import com.google.gerrit.server.change.ChangeJson;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.testutil.ConfigSuite;
import com.google.inject.Inject;
import java.util.EnumSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
@ -45,22 +48,15 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.EnumSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
public class ActionsIT extends AbstractDaemonTest {
@ConfigSuite.Config
public static Config submitWholeTopicEnabled() {
return submitWholeTopicEnabledConfig();
}
@Inject
private ChangeJson.Factory changeJsonFactory;
@Inject private ChangeJson.Factory changeJsonFactory;
@Inject
private DynamicSet<ActionVisitor> actionVisitors;
@Inject private DynamicSet<ActionVisitor> actionVisitors;
private RegistrationHandle visitorHandle;
@ -109,8 +105,8 @@ public class ActionsIT extends AbstractDaemonTest {
assertThat(info.enabled).isNull();
assertThat(info.label).isEqualTo("Submit whole topic");
assertThat(info.method).isEqualTo("POST");
assertThat(info.title).isEqualTo("This change depends on other " +
"changes which are not ready");
assertThat(info.title)
.isEqualTo("This change depends on other " + "changes which are not ready");
} else {
noSubmitWholeTopicAssertions(actions, 1);
@ -227,14 +223,17 @@ public class ActionsIT extends AbstractDaemonTest {
approve(changeId);
// create another change with the same topic
String changeId2 = createChangeWithTopic(testRepo, "foo2", "touching b",
"b.txt", "real content").getChangeId();
String changeId2 =
createChangeWithTopic(testRepo, "foo2", "touching b", "b.txt", "real content")
.getChangeId();
approve(changeId2);
// collide with the other change in the same topic
testRepo.reset("HEAD~2");
String collidingChange = createChangeWithTopic(testRepo, "off_topic",
"rewriting file b", "b.txt", "garbage\ngarbage\ngarbage").getChangeId();
String collidingChange =
createChangeWithTopic(
testRepo, "off_topic", "rewriting file b", "b.txt", "garbage\ngarbage\ngarbage")
.getChangeId();
gApi.changes().id(collidingChange).current().review(ReviewInput.approve());
gApi.changes().id(collidingChange).current().submit();
@ -252,8 +251,7 @@ public class ActionsIT extends AbstractDaemonTest {
}
@Test
public void revisionActionsTwoChangesInTopicWithAncestorReady()
throws Exception {
public void revisionActionsTwoChangesInTopicWithAncestorReady() throws Exception {
String changeId = createChange().getChangeId();
approve(changeId);
approve(changeId);
@ -269,9 +267,11 @@ public class ActionsIT extends AbstractDaemonTest {
assertThat(info.enabled).isTrue();
assertThat(info.label).isEqualTo("Submit whole topic");
assertThat(info.method).isEqualTo("POST");
assertThat(info.title).isEqualTo("Submit all 2 changes of the same " +
"topic (3 changes including ancestors " +
"and other changes related by topic)");
assertThat(info.title)
.isEqualTo(
"Submit all 2 changes of the same "
+ "topic (3 changes including ancestors "
+ "and other changes related by topic)");
} else {
noSubmitWholeTopicAssertions(actions, 2);
}
@ -292,8 +292,7 @@ public class ActionsIT extends AbstractDaemonTest {
noSubmitWholeTopicAssertions(actions, 3);
}
private void noSubmitWholeTopicAssertions(Map<String, ActionInfo> actions,
int nrChanges) {
private void noSubmitWholeTopicAssertions(Map<String, ActionInfo> actions, int nrChanges) {
ActionInfo info = actions.get("submit");
assertThat(info.enabled).isTrue();
if (nrChanges == 1) {
@ -305,22 +304,22 @@ public class ActionsIT extends AbstractDaemonTest {
if (nrChanges == 1) {
assertThat(info.title).isEqualTo("Submit patch set 1 into master");
} else {
assertThat(info.title).isEqualTo(String.format(
"Submit patch set 1 and ancestors (%d changes " +
"altogether) into master", nrChanges));
assertThat(info.title)
.isEqualTo(
String.format(
"Submit patch set 1 and ancestors (%d changes " + "altogether) into master",
nrChanges));
}
}
@Test
public void changeActionVisitor() throws Exception {
String id = createChange().getChangeId();
ChangeInfo origChange =
gApi.changes().id(id).get(EnumSet.of(ListChangesOption.CHANGE_ACTIONS));
ChangeInfo origChange = gApi.changes().id(id).get(EnumSet.of(ListChangesOption.CHANGE_ACTIONS));
class Visitor implements ActionVisitor {
@Override
public boolean visit(String name, ActionInfo actionInfo,
ChangeInfo changeInfo) {
public boolean visit(String name, ActionInfo actionInfo, ChangeInfo changeInfo) {
assertThat(changeInfo).isNotNull();
assertThat(changeInfo._number).isEqualTo(origChange._number);
if (name.equals("followup")) {
@ -333,8 +332,8 @@ public class ActionsIT extends AbstractDaemonTest {
}
@Override
public boolean visit(String name, ActionInfo actionInfo,
ChangeInfo changeInfo, RevisionInfo revisionInfo) {
public boolean visit(
String name, ActionInfo actionInfo, ChangeInfo changeInfo, RevisionInfo revisionInfo) {
throw new UnsupportedOperationException();
}
}
@ -346,10 +345,8 @@ public class ActionsIT extends AbstractDaemonTest {
Visitor v = new Visitor();
visitorHandle = actionVisitors.add(v);
Map<String, ActionInfo> newActions = gApi.changes()
.id(id)
.get(EnumSet.of(ListChangesOption.CHANGE_ACTIONS))
.actions;
Map<String, ActionInfo> newActions =
gApi.changes().id(id).get(EnumSet.of(ListChangesOption.CHANGE_ACTIONS)).actions;
Set<String> expectedNames = new TreeSet<>(origActions.keySet());
expectedNames.remove("followup");
@ -363,19 +360,17 @@ public class ActionsIT extends AbstractDaemonTest {
@Test
public void revisionActionVisitor() throws Exception {
String id = createChange().getChangeId();
ChangeInfo origChange =
gApi.changes().id(id).get(EnumSet.of(ListChangesOption.CHANGE_ACTIONS));
ChangeInfo origChange = gApi.changes().id(id).get(EnumSet.of(ListChangesOption.CHANGE_ACTIONS));
class Visitor implements ActionVisitor {
@Override
public boolean visit(String name, ActionInfo actionInfo,
ChangeInfo changeInfo) {
public boolean visit(String name, ActionInfo actionInfo, ChangeInfo changeInfo) {
return true; // Do nothing; implicitly called for CURRENT_ACTIONS.
}
@Override
public boolean visit(String name, ActionInfo actionInfo,
ChangeInfo changeInfo, RevisionInfo revisionInfo) {
public boolean visit(
String name, ActionInfo actionInfo, ChangeInfo changeInfo, RevisionInfo revisionInfo) {
assertThat(changeInfo).isNotNull();
assertThat(changeInfo._number).isEqualTo(origChange._number);
assertThat(revisionInfo).isNotNull();
@ -390,8 +385,7 @@ public class ActionsIT extends AbstractDaemonTest {
}
}
Map<String, ActionInfo> origActions =
gApi.changes().id(id).current().actions();
Map<String, ActionInfo> origActions = gApi.changes().id(id).current().actions();
assertThat(origActions.keySet()).containsAllOf("cherrypick", "rebase");
assertThat(origActions.get("rebase").label).isEqualTo("Rebase");
@ -400,23 +394,20 @@ public class ActionsIT extends AbstractDaemonTest {
// Test different codepaths within ActionJson...
// ...via revision API.
visitedRevisionActionsAssertions(
origActions, gApi.changes().id(id).current().actions());
visitedRevisionActionsAssertions(origActions, gApi.changes().id(id).current().actions());
// ...via change API with option.
EnumSet<ListChangesOption> opts =
EnumSet.of(CURRENT_ACTIONS, CURRENT_REVISION);
EnumSet<ListChangesOption> opts = EnumSet.of(CURRENT_ACTIONS, CURRENT_REVISION);
ChangeInfo changeInfo = gApi.changes().id(id).get(opts);
RevisionInfo revisionInfo =
Iterables.getOnlyElement(changeInfo.revisions.values());
RevisionInfo revisionInfo = Iterables.getOnlyElement(changeInfo.revisions.values());
visitedRevisionActionsAssertions(origActions, revisionInfo.actions);
// ...via ChangeJson directly.
ChangeData cd = changeDataFactory.create(
db, project, new Change.Id(origChange._number));
revisionInfo = changeJsonFactory.create(opts)
.getRevisionInfo(
cd.changeControl(), Iterables.getOnlyElement(cd.patchSets()));
ChangeData cd = changeDataFactory.create(db, project, new Change.Id(origChange._number));
revisionInfo =
changeJsonFactory
.create(opts)
.getRevisionInfo(cd.changeControl(), Iterables.getOnlyElement(cd.patchSets()));
visitedRevisionActionsAssertions(origActions, revisionInfo.actions);
}
@ -441,30 +432,33 @@ public class ActionsIT extends AbstractDaemonTest {
}
private PushOneCommit.Result createCommitAndPush(
TestRepository<InMemoryRepository> repo, String ref,
String commitMsg, String fileName, String content) throws Exception {
return pushFactory
.create(db, admin.getIdent(), repo, commitMsg, fileName, content)
.to(ref);
TestRepository<InMemoryRepository> repo,
String ref,
String commitMsg,
String fileName,
String content)
throws Exception {
return pushFactory.create(db, admin.getIdent(), repo, commitMsg, fileName, content).to(ref);
}
private PushOneCommit.Result createChangeWithTopic(
TestRepository<InMemoryRepository> repo, String topic,
String commitMsg, String fileName, String content) throws Exception {
TestRepository<InMemoryRepository> repo,
String topic,
String commitMsg,
String fileName,
String content)
throws Exception {
assertThat(topic).isNotEmpty();
return createCommitAndPush(repo, "refs/for/master/" + name(topic),
commitMsg, fileName, content);
return createCommitAndPush(
repo, "refs/for/master/" + name(topic), commitMsg, fileName, content);
}
private PushOneCommit.Result createChangeWithTopic()
throws Exception {
return createChangeWithTopic(testRepo, "foo2",
"a message", "a.txt", "content\n");
private PushOneCommit.Result createChangeWithTopic() throws Exception {
return createChangeWithTopic(testRepo, "foo2", "a message", "a.txt", "content\n");
}
private PushOneCommit.Result createDraftWithTopic()
throws Exception {
return createCommitAndPush(testRepo, "refs/drafts/master/" + name("foo2"),
"a message", "a.txt", "content\n");
private PushOneCommit.Result createDraftWithTopic() throws Exception {
return createCommitAndPush(
testRepo, "refs/drafts/master/" + name("foo2"), "a message", "a.txt", "content\n");
}
}

View File

@ -27,14 +27,12 @@ import com.google.gerrit.extensions.client.ReviewerState;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.testutil.FakeEmailSender.Message;
import com.google.gerrit.testutil.TestTimeUtil;
import java.util.Iterator;
import java.util.List;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.Iterator;
import java.util.List;
@NoHttpd
public class AssigneeIT extends AbstractDaemonTest {
@ -57,8 +55,7 @@ public class AssigneeIT extends AbstractDaemonTest {
@Test
public void addGetAssignee() throws Exception {
PushOneCommit.Result r = createChange();
assertThat(setAssignee(r, user.email)._accountId)
.isEqualTo(user.getId().get());
assertThat(setAssignee(r, user.email)._accountId).isEqualTo(user.getId().get());
assertThat(getAssignee(r)._accountId).isEqualTo(user.getId().get());
assertThat(sender.getMessages()).hasSize(1);
@ -70,8 +67,7 @@ public class AssigneeIT extends AbstractDaemonTest {
public void setNewAssigneeWhenExists() throws Exception {
PushOneCommit.Result r = createChange();
setAssignee(r, user.email);
assertThat(setAssignee(r, user.email)._accountId)
.isEqualTo(user.getId().get());
assertThat(setAssignee(r, user.email)._accountId).isEqualTo(user.getId().get());
}
@Test
@ -100,8 +96,7 @@ public class AssigneeIT extends AbstractDaemonTest {
PushOneCommit.Result r = createChange();
Iterable<AccountInfo> reviewers = getReviewers(r, state);
assertThat(reviewers).isNull();
assertThat(setAssignee(r, user.email)._accountId)
.isEqualTo(user.getId().get());
assertThat(setAssignee(r, user.email)._accountId).isEqualTo(user.getId().get());
reviewers = getReviewers(r, state);
assertThat(reviewers).hasSize(1);
AccountInfo reviewer = Iterables.getFirst(reviewers, null);
@ -112,15 +107,13 @@ public class AssigneeIT extends AbstractDaemonTest {
public void setAlreadyExistingAssignee() throws Exception {
PushOneCommit.Result r = createChange();
setAssignee(r, user.email);
assertThat(setAssignee(r, user.email)._accountId)
.isEqualTo(user.getId().get());
assertThat(setAssignee(r, user.email)._accountId).isEqualTo(user.getId().get());
}
@Test
public void deleteAssignee() throws Exception {
PushOneCommit.Result r = createChange();
assertThat(setAssignee(r, user.email)._accountId)
.isEqualTo(user.getId().get());
assertThat(setAssignee(r, user.email)._accountId).isEqualTo(user.getId().get());
assertThat(deleteAssignee(r)._accountId).isEqualTo(user.getId().get());
assertThat(getAssignee(r)).isNull();
}
@ -135,18 +128,16 @@ public class AssigneeIT extends AbstractDaemonTest {
return gApi.changes().id(r.getChange().getId().get()).getAssignee();
}
private List<AccountInfo> getPastAssignees(PushOneCommit.Result r)
throws Exception {
private List<AccountInfo> getPastAssignees(PushOneCommit.Result r) throws Exception {
return gApi.changes().id(r.getChange().getId().get()).getPastAssignees();
}
private Iterable<AccountInfo> getReviewers(PushOneCommit.Result r,
ReviewerState state) throws Exception {
private Iterable<AccountInfo> getReviewers(PushOneCommit.Result r, ReviewerState state)
throws Exception {
return get(r.getChangeId()).reviewers.get(state);
}
private AccountInfo setAssignee(PushOneCommit.Result r, String identifieer)
throws Exception {
private AccountInfo setAssignee(PushOneCommit.Result r, String identifieer) throws Exception {
AssigneeInput input = new AssigneeInput();
input.assignee = identifieer;
return gApi.changes().id(r.getChange().getId().get()).setAssignee(input);

View File

@ -22,7 +22,6 @@ import com.google.gerrit.acceptance.PushOneCommit.Result;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.projects.TagInput;
import com.google.gerrit.reviewdb.client.Branch;
import org.junit.Test;
@NoHttpd
@ -31,24 +30,22 @@ public class ChangeIncludedInIT extends AbstractDaemonTest {
@Test
public void includedInOpenChange() throws Exception {
Result result = createChange();
assertThat(gApi.changes().id(result.getChangeId()).includedIn().branches)
.isEmpty();
assertThat(gApi.changes().id(result.getChangeId()).includedIn().tags)
.isEmpty();
assertThat(gApi.changes().id(result.getChangeId()).includedIn().branches).isEmpty();
assertThat(gApi.changes().id(result.getChangeId()).includedIn().tags).isEmpty();
}
@Test
public void includedInMergedChange() throws Exception {
Result result = createChange();
gApi.changes().id(result.getChangeId()).revision(result.getCommit().name())
gApi.changes()
.id(result.getChangeId())
.revision(result.getCommit().name())
.review(ReviewInput.approve());
gApi.changes().id(result.getChangeId()).revision(result.getCommit().name())
.submit();
gApi.changes().id(result.getChangeId()).revision(result.getCommit().name()).submit();
assertThat(gApi.changes().id(result.getChangeId()).includedIn().branches)
.containsExactly("master");
assertThat(gApi.changes().id(result.getChangeId()).includedIn().tags)
.isEmpty();
assertThat(gApi.changes().id(result.getChangeId()).includedIn().tags).isEmpty();
grantTagPermissions();
gApi.projects().name(project.get()).tag("test-tag").create(new TagInput());

View File

@ -23,14 +23,12 @@ import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.ChangeMessageInfo;
import com.google.gerrit.testutil.ConfigSuite;
import com.google.gerrit.testutil.TestTimeUtil;
import java.util.Iterator;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Iterator;
@RunWith(ConfigSuite.class)
public class ChangeMessagesIT extends AbstractDaemonTest {
private String systemTimeZone;
@ -61,8 +59,7 @@ public class ChangeMessagesIT extends AbstractDaemonTest {
ChangeInfo c = get(changeId);
assertThat(c.messages).isNotNull();
assertThat(c.messages).hasSize(1);
assertThat(c.messages.iterator().next().message)
.isEqualTo("Uploaded patch set 1.");
assertThat(c.messages.iterator().next().message).isEqualTo("Uploaded patch set 1.");
}
@Test

View File

@ -29,7 +29,6 @@ import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.group.SystemGroupBackend;
import org.junit.Before;
import org.junit.Test;
@ -83,8 +82,9 @@ public class ChangeOwnerIT extends AbstractDaemonTest {
ProjectConfig config = ProjectConfig.read(md);
AccessSection s = config.getAccessSection("refs/heads/*", true);
Permission p = s.getPermission(LABEL + "Code-Review", true);
PermissionRule rule = new PermissionRule(config
.resolve(systemGroupBackend.getGroup(SystemGroupBackend.CHANGE_OWNER)));
PermissionRule rule =
new PermissionRule(
config.resolve(systemGroupBackend.getGroup(SystemGroupBackend.CHANGE_OWNER)));
rule.setMin(-2);
rule.setMax(+2);
p.add(rule);

View File

@ -40,15 +40,13 @@ import com.google.gerrit.server.change.PostReviewers;
import com.google.gerrit.server.mail.Address;
import com.google.gerrit.testutil.FakeEmailSender.Message;
import com.google.gson.stream.JsonReader;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.junit.Test;
public class ChangeReviewersIT extends AbstractDaemonTest {
@Test
@ -60,18 +58,18 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
int largeGroupSize = PostReviewers.DEFAULT_MAX_REVIEWERS + 1;
int mediumGroupSize = PostReviewers.DEFAULT_MAX_REVIEWERS_WITHOUT_CHECK + 1;
List<TestAccount> users =
createAccounts(largeGroupSize, "addGroupAsReviewer");
List<TestAccount> users = createAccounts(largeGroupSize, "addGroupAsReviewer");
List<String> largeGroupUsernames = new ArrayList<>(mediumGroupSize);
for (TestAccount u : users) {
largeGroupUsernames.add(u.username);
}
List<String> mediumGroupUsernames =
largeGroupUsernames.subList(0, mediumGroupSize);
gApi.groups().id(largeGroup).addMembers(
largeGroupUsernames.toArray(new String[largeGroupSize]));
gApi.groups().id(mediumGroup).addMembers(
mediumGroupUsernames.toArray(new String[mediumGroupSize]));
List<String> mediumGroupUsernames = largeGroupUsernames.subList(0, mediumGroupSize);
gApi.groups()
.id(largeGroup)
.addMembers(largeGroupUsernames.toArray(new String[largeGroupSize]));
gApi.groups()
.id(mediumGroup)
.addMembers(mediumGroupUsernames.toArray(new String[mediumGroupSize]));
// Attempt to add overly large group as reviewers.
PushOneCommit.Result r = createChange();
@ -79,8 +77,7 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
AddReviewerResult result = addReviewer(changeId, largeGroup);
assertThat(result.input).isEqualTo(largeGroup);
assertThat(result.confirm).isNull();
assertThat(result.error)
.contains("has too many members to add them all as reviewers");
assertThat(result.error).contains("has too many members to add them all as reviewers");
assertThat(result.reviewers).isNull();
// Attempt to add medium group without confirmation.
@ -88,8 +85,8 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
assertThat(result.input).isEqualTo(mediumGroup);
assertThat(result.confirm).isTrue();
assertThat(result.error)
.contains("has " + mediumGroupSize + " members. Do you want to add them"
+ " all as reviewers?");
.contains(
"has " + mediumGroupSize + " members. Do you want to add them" + " all as reviewers?");
assertThat(result.reviewers).isNull();
// Add medium group with confirmation.
@ -140,8 +137,7 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
Message m = messages.get(0);
assertThat(m.rcpt()).containsExactly(user.emailAddress);
if (notesMigration.readChanges()) {
assertThat(m.body())
.contains(admin.fullName + " has uploaded this change for review.");
assertThat(m.body()).contains(admin.fullName + " has uploaded this change for review.");
} else {
assertThat(m.body()).contains("Hello " + user.fullName + ",\n");
assertThat(m.body()).contains("I'd like you to do a code review.");
@ -164,7 +160,8 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
AddReviewerInput in = new AddReviewerInput();
in.reviewer = createGroup("cc1");
in.state = CC;
gApi.groups().id(in.reviewer)
gApi.groups()
.id(in.reviewer)
.addMembers(firstUsernames.toArray(new String[firstUsernames.size()]));
AddReviewerResult result = addReviewer(changeId, in);
@ -195,14 +192,13 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
assertThat(m.rcpt()).containsExactlyElementsIn(expectedAddresses);
// CC a group that overlaps with some existing reviewers and CCed accounts.
TestAccount reviewer = accounts.create(name("reviewer"),
"addCcGroup-reviewer@example.com", "Reviewer");
TestAccount reviewer =
accounts.create(name("reviewer"), "addCcGroup-reviewer@example.com", "Reviewer");
result = addReviewer(changeId, reviewer.username);
assertThat(result.error).isNull();
sender.clear();
in.reviewer = createGroup("cc2");
gApi.groups().id(in.reviewer)
.addMembers(usernames.toArray(new String[usernames.size()]));
gApi.groups().id(in.reviewer).addMembers(usernames.toArray(new String[usernames.size()]));
gApi.groups().id(in.reviewer).addMembers(reviewer.username);
result = addReviewer(changeId, in);
assertThat(result.input).isEqualTo(in.reviewer);
@ -270,17 +266,16 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
// Post drive-by message as user.
ReviewInput input = new ReviewInput().message("hello");
RestResponse resp = userRestSession.post(
"/changes/" + r.getChangeId() + "/revisions/" +
r.getCommit().getName() + "/review", input);
RestResponse resp =
userRestSession.post(
"/changes/" + r.getChangeId() + "/revisions/" + r.getCommit().getName() + "/review",
input);
ReviewResult result = readContentFromJson(resp, 200, ReviewResult.class);
assertThat(result.labels).isNull();
assertThat(result.reviewers).isNull();
// Verify user is added to CC list.
ChangeInfo c = gApi.changes()
.id(r.getChangeId())
.get();
ChangeInfo c = gApi.changes().id(r.getChangeId()).get();
if (notesMigration.readChanges()) {
assertReviewers(c, REVIEWER);
assertReviewers(c, CC, user);
@ -299,18 +294,17 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
// user adds self as REVIEWER.
ReviewInput input = new ReviewInput().reviewer(user.username);
RestResponse resp = userRestSession.post(
"/changes/" + r.getChangeId() + "/revisions/" +
r.getCommit().getName() + "/review", input);
RestResponse resp =
userRestSession.post(
"/changes/" + r.getChangeId() + "/revisions/" + r.getCommit().getName() + "/review",
input);
ReviewResult result = readContentFromJson(resp, 200, ReviewResult.class);
assertThat(result.labels).isNull();
assertThat(result.reviewers).isNotNull();
assertThat(result.reviewers).hasSize(1);
// Verify reviewer state.
ChangeInfo c = gApi.changes()
.id(r.getChangeId())
.get();
ChangeInfo c = gApi.changes().id(r.getChangeId()).get();
assertReviewers(c, REVIEWER, user);
assertReviewers(c, CC);
LabelInfo label = c.labels.get("Code-Review");
@ -328,18 +322,17 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
// user adds self as CC.
ReviewInput input = new ReviewInput().reviewer(user.username, CC, false);
RestResponse resp = userRestSession.post(
"/changes/" + r.getChangeId() + "/revisions/" +
r.getCommit().getName() + "/review", input);
RestResponse resp =
userRestSession.post(
"/changes/" + r.getChangeId() + "/revisions/" + r.getCommit().getName() + "/review",
input);
ReviewResult result = readContentFromJson(resp, 200, ReviewResult.class);
assertThat(result.labels).isNull();
assertThat(result.reviewers).isNotNull();
assertThat(result.reviewers).hasSize(1);
// Verify reviewer state.
ChangeInfo c = gApi.changes()
.id(r.getChangeId())
.get();
ChangeInfo c = gApi.changes().id(r.getChangeId()).get();
if (notesMigration.readChanges()) {
assertReviewers(c, REVIEWER);
assertReviewers(c, CC, user);
@ -368,9 +361,7 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
PushOneCommit.Result r = createChange();
// Verify reviewer state.
ChangeInfo c = gApi.changes()
.id(r.getChangeId())
.get();
ChangeInfo c = gApi.changes().id(r.getChangeId()).get();
assertReviewers(c, REVIEWER);
assertReviewers(c, CC);
LabelInfo label = c.labels.get("Code-Review");
@ -386,9 +377,7 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
// Verify reviewer state. Both admin and user should be REVIEWERs now,
// because admin gets forced into REVIEWER state by virtue of being owner.
c = gApi.changes()
.id(r.getChangeId())
.get();
c = gApi.changes().id(r.getChangeId()).get();
assertReviewers(c, REVIEWER, admin, user);
assertReviewers(c, CC);
label = c.labels.get("Code-Review");
@ -405,16 +394,15 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
// Comment as user without voting. This should delete the approval and
// then replace it with the default value.
input = new ReviewInput().message("hello");
RestResponse resp = userRestSession.post(
"/changes/" + r.getChangeId() + "/revisions/" +
r.getCommit().getName() + "/review", input);
RestResponse resp =
userRestSession.post(
"/changes/" + r.getChangeId() + "/revisions/" + r.getCommit().getName() + "/review",
input);
result = readContentFromJson(resp, 200, ReviewResult.class);
assertThat(result.labels).isNull();
// Verify reviewer state.
c = gApi.changes()
.id(r.getChangeId())
.get();
c = gApi.changes().id(r.getChangeId()).get();
assertReviewers(c, REVIEWER, admin, user);
assertReviewers(c, CC);
label = c.labels.get("Code-Review");
@ -433,9 +421,8 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
public void reviewAndAddReviewers() throws Exception {
TestAccount observer = accounts.user2();
PushOneCommit.Result r = createChange();
ReviewInput input = ReviewInput.approve()
.reviewer(user.email)
.reviewer(observer.email, CC, false);
ReviewInput input =
ReviewInput.approve().reviewer(user.email).reviewer(observer.email, CC, false);
ReviewResult result = review(r.getChangeId(), r.getCommit().name(), input);
assertThat(result.labels).isNotNull();
@ -444,9 +431,7 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
// Verify reviewer and CC were added. If not in NoteDb read mode, both
// parties will be returned as CCed.
ChangeInfo c = gApi.changes()
.id(r.getChangeId())
.get();
ChangeInfo c = gApi.changes().id(r.getChangeId()).get();
if (notesMigration.readChanges()) {
assertReviewers(c, REVIEWER, admin, user);
assertReviewers(c, CC, observer);
@ -461,17 +446,13 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
assertThat(messages).hasSize(2);
Message m = messages.get(0);
assertThat(m.rcpt())
.containsExactly(user.emailAddress,observer.emailAddress);
assertThat(m.body())
.contains(admin.fullName + " has posted comments on this change.");
assertThat(m.body())
.contains("Change subject: " + PushOneCommit.SUBJECT + "\n");
assertThat(m.rcpt()).containsExactly(user.emailAddress, observer.emailAddress);
assertThat(m.body()).contains(admin.fullName + " has posted comments on this change.");
assertThat(m.body()).contains("Change subject: " + PushOneCommit.SUBJECT + "\n");
assertThat(m.body()).contains("Patch Set 1: Code-Review+2");
m = messages.get(1);
assertThat(m.rcpt())
.containsExactly(user.emailAddress, observer.emailAddress);
assertThat(m.rcpt()).containsExactly(user.emailAddress, observer.emailAddress);
assertThat(m.body()).contains("Hello " + user.fullName + ",\n");
assertThat(m.body()).contains("I'd like you to do a code review.");
}
@ -480,8 +461,7 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
public void reviewAndAddGroupReviewers() throws Exception {
int largeGroupSize = PostReviewers.DEFAULT_MAX_REVIEWERS + 1;
int mediumGroupSize = PostReviewers.DEFAULT_MAX_REVIEWERS_WITHOUT_CHECK + 1;
List<TestAccount> users =
createAccounts(largeGroupSize, "reviewAndAddGroupReviewers");
List<TestAccount> users = createAccounts(largeGroupSize, "reviewAndAddGroupReviewers");
List<String> usernames = new ArrayList<>(largeGroupSize);
for (TestAccount u : users) {
usernames.add(u.username);
@ -489,22 +469,21 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
String largeGroup = createGroup("largeGroup");
String mediumGroup = createGroup("mediumGroup");
gApi.groups().id(largeGroup).addMembers(
usernames.toArray(new String[largeGroupSize]));
gApi.groups().id(mediumGroup).addMembers(
usernames.subList(0, mediumGroupSize)
.toArray(new String[mediumGroupSize]));
gApi.groups().id(largeGroup).addMembers(usernames.toArray(new String[largeGroupSize]));
gApi.groups()
.id(mediumGroup)
.addMembers(usernames.subList(0, mediumGroupSize).toArray(new String[mediumGroupSize]));
TestAccount observer = accounts.user2();
PushOneCommit.Result r = createChange();
// Attempt to add overly large group as reviewers.
ReviewInput input = ReviewInput.approve()
.reviewer(user.email)
.reviewer(observer.email, CC, false)
.reviewer(largeGroup);
ReviewResult result = review(
r.getChangeId(), r.getCommit().name(), input, SC_BAD_REQUEST);
ReviewInput input =
ReviewInput.approve()
.reviewer(user.email)
.reviewer(observer.email, CC, false)
.reviewer(largeGroup);
ReviewResult result = review(r.getChangeId(), r.getCommit().name(), input, SC_BAD_REQUEST);
assertThat(result.labels).isNull();
assertThat(result.reviewers).isNotNull();
assertThat(result.reviewers).hasSize(3);
@ -515,21 +494,19 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
assertThat(reviewerResult.error).contains("has too many members to add them all as reviewers");
// No labels should have changed, and no reviewers/CCs should have been added.
ChangeInfo c = gApi.changes()
.id(r.getChangeId())
.get();
ChangeInfo c = gApi.changes().id(r.getChangeId()).get();
assertThat(c.messages).hasSize(1);
assertThat(c.reviewers.get(REVIEWER)).isNull();
assertThat(c.reviewers.get(CC)).isNull();
// Attempt to add group large enough to require confirmation, without
// confirmation, as reviewers.
input = ReviewInput.approve()
.reviewer(user.email)
.reviewer(observer.email, CC, false)
.reviewer(mediumGroup);
result = review(r.getChangeId(), r.getCommit().name(), input,
SC_BAD_REQUEST);
input =
ReviewInput.approve()
.reviewer(user.email)
.reviewer(observer.email, CC, false)
.reviewer(mediumGroup);
result = review(r.getChangeId(), r.getCommit().name(), input, SC_BAD_REQUEST);
assertThat(result.labels).isNull();
assertThat(result.reviewers).isNotNull();
assertThat(result.reviewers).hasSize(3);
@ -537,29 +514,23 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
assertThat(reviewerResult).isNotNull();
assertThat(reviewerResult.confirm).isTrue();
assertThat(reviewerResult.error)
.contains("has " + mediumGroupSize + " members. Do you want to add them all"
+ " as reviewers?");
.contains(
"has " + mediumGroupSize + " members. Do you want to add them all" + " as reviewers?");
// No labels should have changed, and no reviewers/CCs should have been added.
c = gApi.changes()
.id(r.getChangeId())
.get();
c = gApi.changes().id(r.getChangeId()).get();
assertThat(c.messages).hasSize(1);
assertThat(c.reviewers.get(REVIEWER)).isNull();
assertThat(c.reviewers.get(CC)).isNull();
// Retrying with confirmation should successfully approve and add reviewers/CCs.
input = ReviewInput.approve()
.reviewer(user.email)
.reviewer(mediumGroup, CC, true);
input = ReviewInput.approve().reviewer(user.email).reviewer(mediumGroup, CC, true);
result = review(r.getChangeId(), r.getCommit().name(), input);
assertThat(result.labels).isNotNull();
assertThat(result.reviewers).isNotNull();
assertThat(result.reviewers).hasSize(2);
c = gApi.changes()
.id(r.getChangeId())
.get();
c = gApi.changes().id(r.getChangeId()).get();
assertThat(c.messages).hasSize(2);
if (notesMigration.readChanges()) {
@ -604,32 +575,24 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
Iterator<ReviewerUpdateInfo> it = c.reviewerUpdates.iterator();
ReviewerUpdateInfo reviewerChange = it.next();
assertThat(reviewerChange.state).isEqualTo(CC);
assertThat(reviewerChange.reviewer._accountId).isEqualTo(
user.getId().get());
assertThat(reviewerChange.updatedBy._accountId).isEqualTo(
admin.getId().get());
assertThat(reviewerChange.reviewer._accountId).isEqualTo(user.getId().get());
assertThat(reviewerChange.updatedBy._accountId).isEqualTo(admin.getId().get());
reviewerChange = it.next();
assertThat(reviewerChange.state).isEqualTo(REVIEWER);
assertThat(reviewerChange.reviewer._accountId).isEqualTo(
user.getId().get());
assertThat(reviewerChange.updatedBy._accountId).isEqualTo(
admin.getId().get());
assertThat(reviewerChange.reviewer._accountId).isEqualTo(user.getId().get());
assertThat(reviewerChange.updatedBy._accountId).isEqualTo(admin.getId().get());
reviewerChange = it.next();
assertThat(reviewerChange.state).isEqualTo(REMOVED);
assertThat(reviewerChange.reviewer._accountId).isEqualTo(
user.getId().get());
assertThat(reviewerChange.updatedBy._accountId).isEqualTo(
admin.getId().get());
assertThat(reviewerChange.reviewer._accountId).isEqualTo(user.getId().get());
assertThat(reviewerChange.updatedBy._accountId).isEqualTo(admin.getId().get());
}
@Test
public void addDuplicateReviewers() throws Exception {
PushOneCommit.Result r = createChange();
ReviewInput input = ReviewInput.approve()
.reviewer(user.email)
.reviewer(user.email);
ReviewInput input = ReviewInput.approve().reviewer(user.email).reviewer(user.email);
ReviewResult result = review(r.getChangeId(), r.getCommit().name(), input);
assertThat(result.reviewers).isNotNull();
assertThat(result.reviewers).hasSize(1);
@ -642,21 +605,16 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
@Test
public void addOverlappingGroups() throws Exception {
String emailPrefix = "addOverlappingGroups-";
TestAccount user1 = accounts.create(name("user1"),
emailPrefix + "user1@example.com", "User1");
TestAccount user2 = accounts.create(name("user2"),
emailPrefix + "user2@example.com", "User2");
TestAccount user3 = accounts.create(name("user3"),
emailPrefix + "user3@example.com", "User3");
TestAccount user1 = accounts.create(name("user1"), emailPrefix + "user1@example.com", "User1");
TestAccount user2 = accounts.create(name("user2"), emailPrefix + "user2@example.com", "User2");
TestAccount user3 = accounts.create(name("user3"), emailPrefix + "user3@example.com", "User3");
String group1 = createGroup("group1");
String group2 = createGroup("group2");
gApi.groups().id(group1).addMembers(user1.username, user2.username);
gApi.groups().id(group2).addMembers(user2.username, user3.username);
PushOneCommit.Result r = createChange();
ReviewInput input = ReviewInput.approve()
.reviewer(group1)
.reviewer(group2);
ReviewInput input = ReviewInput.approve().reviewer(group1).reviewer(group2);
ReviewResult result = review(r.getChangeId(), r.getCommit().name(), input);
assertThat(result.reviewers).isNotNull();
assertThat(result.reviewers).hasSize(2);
@ -672,9 +630,7 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
return;
}
r = createChange();
input = ReviewInput.approve()
.reviewer(group1, CC, false)
.reviewer(group2, CC, false);
input = ReviewInput.approve().reviewer(group1, CC, false).reviewer(group2, CC, false);
result = review(r.getChangeId(), r.getCommit().name(), input);
assertThat(result.reviewers).isNotNull();
assertThat(result.reviewers).hasSize(2);
@ -688,9 +644,7 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
// Repeat again with one group REVIEWER, the other CC. The overlapping
// member should end up as a REVIEWER.
r = createChange();
input = ReviewInput.approve()
.reviewer(group1, REVIEWER, false)
.reviewer(group2, CC, false);
input = ReviewInput.approve().reviewer(group1, REVIEWER, false).reviewer(group2, CC, false);
result = review(r.getChangeId(), r.getCommit().name(), input);
assertThat(result.reviewers).isNotNull();
assertThat(result.reviewers).hasSize(2);
@ -703,52 +657,43 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
assertThat(reviewerResult.ccs).hasSize(1);
}
private AddReviewerResult addReviewer(String changeId, String reviewer)
throws Exception {
private AddReviewerResult addReviewer(String changeId, String reviewer) throws Exception {
return addReviewer(changeId, reviewer, SC_OK);
}
private AddReviewerResult addReviewer(
String changeId, String reviewer, int expectedStatus) throws Exception {
private AddReviewerResult addReviewer(String changeId, String reviewer, int expectedStatus)
throws Exception {
AddReviewerInput in = new AddReviewerInput();
in.reviewer = reviewer;
return addReviewer(changeId, in, expectedStatus);
}
private AddReviewerResult addReviewer(String changeId, AddReviewerInput in)
throws Exception {
private AddReviewerResult addReviewer(String changeId, AddReviewerInput in) throws Exception {
return addReviewer(changeId, in, SC_OK);
}
private AddReviewerResult addReviewer(String changeId, AddReviewerInput in,
int expectedStatus) throws Exception {
RestResponse resp =
adminRestSession.post("/changes/" + changeId + "/reviewers", in);
return readContentFromJson(
resp, expectedStatus, AddReviewerResult.class);
}
private RestResponse deleteReviewer(String changeId, TestAccount account)
private AddReviewerResult addReviewer(String changeId, AddReviewerInput in, int expectedStatus)
throws Exception {
return adminRestSession.delete("/changes/" + changeId + "/reviewers/" +
account.getId().get());
RestResponse resp = adminRestSession.post("/changes/" + changeId + "/reviewers", in);
return readContentFromJson(resp, expectedStatus, AddReviewerResult.class);
}
private ReviewResult review(
String changeId, String revisionId, ReviewInput in) throws Exception {
private RestResponse deleteReviewer(String changeId, TestAccount account) throws Exception {
return adminRestSession.delete("/changes/" + changeId + "/reviewers/" + account.getId().get());
}
private ReviewResult review(String changeId, String revisionId, ReviewInput in) throws Exception {
return review(changeId, revisionId, in, SC_OK);
}
private ReviewResult review(
String changeId, String revisionId, ReviewInput in, int expectedStatus)
throws Exception {
RestResponse resp = adminRestSession.post(
"/changes/" + changeId + "/revisions/" + revisionId + "/review", in);
String changeId, String revisionId, ReviewInput in, int expectedStatus) throws Exception {
RestResponse resp =
adminRestSession.post("/changes/" + changeId + "/revisions/" + revisionId + "/review", in);
return readContentFromJson(resp, expectedStatus, ReviewResult.class);
}
private static <T> T readContentFromJson(
RestResponse r, int expectedStatus, Class<T> clazz)
private static <T> T readContentFromJson(RestResponse r, int expectedStatus, Class<T> clazz)
throws Exception {
r.assertStatus(expectedStatus);
JsonReader jsonReader = new JsonReader(r.getReader());
@ -756,8 +701,8 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
return newGson().fromJson(jsonReader, clazz);
}
private static void assertReviewers(ChangeInfo c, ReviewerState reviewerState,
TestAccount... accounts) throws Exception {
private static void assertReviewers(
ChangeInfo c, ReviewerState reviewerState, TestAccount... accounts) throws Exception {
List<TestAccount> accountList = new ArrayList<>(accounts.length);
for (TestAccount a : accounts) {
accountList.add(a);
@ -765,8 +710,8 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
assertReviewers(c, reviewerState, accountList);
}
private static void assertReviewers(ChangeInfo c, ReviewerState reviewerState,
Iterable<TestAccount> accounts) throws Exception {
private static void assertReviewers(
ChangeInfo c, ReviewerState reviewerState, Iterable<TestAccount> accounts) throws Exception {
Collection<AccountInfo> actualAccounts = c.reviewers.get(reviewerState);
if (actualAccounts == null) {
assertThat(accounts.iterator().hasNext()).isFalse();
@ -784,12 +729,11 @@ public class ChangeReviewersIT extends AbstractDaemonTest {
assertThat(actualAccountIds).containsExactlyElementsIn(expectedAccountIds);
}
private List<TestAccount> createAccounts(int n, String emailPrefix)
throws Exception {
private List<TestAccount> createAccounts(int n, String emailPrefix) throws Exception {
List<TestAccount> result = new ArrayList<>(n);
for (int i = 0; i < n; i++) {
result.add(accounts.create(name("u" + i),
emailPrefix + "-" + i + "@example.com", "Full Name " + i));
result.add(
accounts.create(name("u" + i), emailPrefix + "-" + i + "@example.com", "Full Name " + i));
}
return result;
}

View File

@ -33,7 +33,6 @@ import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.project.Util;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
@ -50,8 +49,7 @@ public class ConfigChangeIT extends AbstractDaemonTest {
public void setUp() throws Exception {
ProjectConfig cfg = projectCache.checkedGet(project).getConfig();
Util.allow(cfg, Permission.OWNER, REGISTERED_USERS, "refs/*");
Util.allow(
cfg, Permission.PUSH, REGISTERED_USERS, "refs/for/refs/meta/config");
Util.allow(cfg, Permission.PUSH, REGISTERED_USERS, "refs/for/refs/meta/config");
Util.allow(cfg, Permission.SUBMIT, REGISTERED_USERS, RefNames.REFS_CONFIG);
saveProjectConfig(project, cfg);
@ -85,16 +83,13 @@ public class ConfigChangeIT extends AbstractDaemonTest {
gApi.changes().id(id).current().review(ReviewInput.approve());
gApi.changes().id(id).current().submit();
assertThat(gApi.changes().id(id).info().status)
.isEqualTo(ChangeStatus.MERGED);
assertThat(gApi.projects().name(project.get()).get().description)
.isEqualTo(desc);
assertThat(gApi.changes().id(id).info().status).isEqualTo(ChangeStatus.MERGED);
assertThat(gApi.projects().name(project.get()).get().description).isEqualTo(desc);
fetchRefsMetaConfig();
assertThat(readProjectConfig().getString("project", null, "description"))
.isEqualTo(desc);
assertThat(readProjectConfig().getString("project", null, "description")).isEqualTo(desc);
String changeRev = gApi.changes().id(id).get().currentRevision;
String branchRev = gApi.projects().name(project.get())
.branch(RefNames.REFS_CONFIG).get().revision;
String branchRev =
gApi.projects().name(project.get()).branch(RefNames.REFS_CONFIG).get().revision;
assertThat(changeRev).isEqualTo(branchRev);
return id;
}
@ -110,8 +105,7 @@ public class ConfigChangeIT extends AbstractDaemonTest {
setApiUser(user);
Config cfg = readProjectConfig();
assertThat(cfg.getString("access", null, "inheritFrom"))
.isAnyOf(null, allProjects.get());
assertThat(cfg.getString("access", null, "inheritFrom")).isAnyOf(null, allProjects.get());
cfg.setString("access", null, "inheritFrom", parent.name);
PushOneCommit.Result r = createConfigChange(cfg);
@ -123,28 +117,27 @@ public class ConfigChangeIT extends AbstractDaemonTest {
fail("expected submit to fail");
} catch (ResourceConflictException e) {
int n = gApi.changes().id(id).info()._number;
assertThat(e).hasMessage(
"Failed to submit 1 change due to the following problems:\n"
+ "Change " + n + ": Change contains a project configuration that"
+ " changes the parent project.\n"
+ "The change must be submitted by a Gerrit administrator.");
assertThat(e)
.hasMessage(
"Failed to submit 1 change due to the following problems:\n"
+ "Change "
+ n
+ ": Change contains a project configuration that"
+ " changes the parent project.\n"
+ "The change must be submitted by a Gerrit administrator.");
}
assertThat(gApi.projects().name(project.get()).get().parent)
.isEqualTo(allProjects.get());
assertThat(gApi.projects().name(project.get()).get().parent).isEqualTo(allProjects.get());
fetchRefsMetaConfig();
assertThat(readProjectConfig().getString("access", null, "inheritFrom"))
.isAnyOf(null, allProjects.get());
setApiUser(admin);
gApi.changes().id(id).current().submit();
assertThat(gApi.changes().id(id).info().status)
.isEqualTo(ChangeStatus.MERGED);
assertThat(gApi.projects().name(project.get()).get().parent)
.isEqualTo(parent.name);
assertThat(gApi.changes().id(id).info().status).isEqualTo(ChangeStatus.MERGED);
assertThat(gApi.projects().name(project.get()).get().parent).isEqualTo(parent.name);
fetchRefsMetaConfig();
assertThat(readProjectConfig().getString("access", null, "inheritFrom"))
.isEqualTo(parent.name);
assertThat(readProjectConfig().getString("access", null, "inheritFrom")).isEqualTo(parent.name);
}
@Test
@ -154,32 +147,31 @@ public class ConfigChangeIT extends AbstractDaemonTest {
Project.NameKey parent = createProject("projectToInheritFrom");
Project.NameKey child = createProject("projectWithMalformedConfig");
String config = gApi.projects()
.name(child.get())
.branch(RefNames.REFS_CONFIG).file("project.config").asString();
String config =
gApi.projects()
.name(child.get())
.branch(RefNames.REFS_CONFIG)
.file("project.config")
.asString();
// Append and push malformed project config
String pattern = "[access]\n"
+ "\tinheritFrom = " + allProjects.get() + "\n";
String pattern = "[access]\n" + "\tinheritFrom = " + allProjects.get() + "\n";
String doubleInherit = pattern + "\tinheritFrom = " + parent.get() + "\n";
config = config.replace(pattern, doubleInherit);
TestRepository<InMemoryRepository> childRepo =
cloneProject(child, admin);
TestRepository<InMemoryRepository> childRepo = cloneProject(child, admin);
// Fetch meta ref
GitUtil.fetch(childRepo, RefNames.REFS_CONFIG + ":cfg");
childRepo.reset("cfg");
PushOneCommit push = pushFactory.create(
db, admin.getIdent(), childRepo, "Subject", "project.config",
config);
PushOneCommit push =
pushFactory.create(db, admin.getIdent(), childRepo, "Subject", "project.config", config);
PushOneCommit.Result res = push.to(RefNames.REFS_CONFIG);
res.assertErrorStatus();
res.assertMessage("cannot inherit from multiple projects");
}
private void fetchRefsMetaConfig() throws Exception {
git().fetch().setRefSpecs(new RefSpec("refs/meta/config:refs/meta/config"))
.call();
git().fetch().setRefSpecs(new RefSpec("refs/meta/config:refs/meta/config")).call();
testRepo.reset(RefNames.REFS_CONFIG);
}
@ -195,12 +187,16 @@ public class ConfigChangeIT extends AbstractDaemonTest {
}
private PushOneCommit.Result createConfigChange(Config cfg) throws Exception {
PushOneCommit.Result r = pushFactory.create(
db, user.getIdent(), testRepo,
"Update project config",
"project.config",
cfg.toText())
.to("refs/for/refs/meta/config");
PushOneCommit.Result r =
pushFactory
.create(
db,
user.getIdent(),
testRepo,
"Update project config",
"project.config",
cfg.toText())
.to("refs/for/refs/meta/config");
r.assertOkStatus();
return r;
}

View File

@ -28,7 +28,6 @@ import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit.Result;
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.testutil.ConfigSuite;
import org.apache.http.Header;
import org.apache.http.client.fluent.Request;
import org.apache.http.message.BasicHeader;
@ -40,10 +39,10 @@ public class CorsIT extends AbstractDaemonTest {
public static Config allowExampleDotCom() {
Config cfg = new Config();
cfg.setStringList(
"site", null, "allowOriginRegex",
ImmutableList.of(
"https?://(.+[.])?example[.]com",
"http://friend[.]ly"));
"site",
null,
"allowOriginRegex",
ImmutableList.of("https?://(.+[.])?example[.]com", "http://friend[.]ly"));
return cfg;
}
@ -69,10 +68,9 @@ public class CorsIT extends AbstractDaemonTest {
public void putWithOriginRefused() throws Exception {
Result change = createChange();
String origin = "http://example.com";
RestResponse r = adminRestSession.putWithHeader(
"/changes/" + change.getChangeId() + "/topic",
new BasicHeader(ORIGIN, origin),
"A");
RestResponse r =
adminRestSession.putWithHeader(
"/changes/" + change.getChangeId() + "/topic", new BasicHeader(ORIGIN, origin), "A");
r.assertOK();
checkCors(r, false, origin);
}
@ -82,8 +80,8 @@ public class CorsIT extends AbstractDaemonTest {
Result change = createChange();
String origin = "http://example.com";
Request req = Request.Options(adminRestSession.url()
+ "/a/changes/" + change.getChangeId() + "/detail");
Request req =
Request.Options(adminRestSession.url() + "/a/changes/" + change.getChangeId() + "/detail");
req.addHeader(ORIGIN, origin);
req.addHeader(ACCESS_CONTROL_REQUEST_METHOD, "GET");
req.addHeader(ACCESS_CONTROL_REQUEST_HEADERS, "X-Requested-With");
@ -97,8 +95,8 @@ public class CorsIT extends AbstractDaemonTest {
public void preflightBadOrigin() throws Exception {
Result change = createChange();
Request req = Request.Options(adminRestSession.url()
+ "/a/changes/" + change.getChangeId() + "/detail");
Request req =
Request.Options(adminRestSession.url() + "/a/changes/" + change.getChangeId() + "/detail");
req.addHeader(ORIGIN, "http://evil.attacker");
req.addHeader(ACCESS_CONTROL_REQUEST_METHOD, "GET");
@ -110,8 +108,9 @@ public class CorsIT extends AbstractDaemonTest {
Result change = createChange();
for (String method : new String[] {"POST", "PUT", "DELETE", "PATCH"}) {
Request req = Request.Options(adminRestSession.url()
+ "/a/changes/" + change.getChangeId() + "/detail");
Request req =
Request.Options(
adminRestSession.url() + "/a/changes/" + change.getChangeId() + "/detail");
req.addHeader(ORIGIN, "http://example.com");
req.addHeader(ACCESS_CONTROL_REQUEST_METHOD, method);
adminRestSession.execute(req).assertBadRequest();
@ -122,8 +121,8 @@ public class CorsIT extends AbstractDaemonTest {
public void preflightBadHeader() throws Exception {
Result change = createChange();
Request req = Request.Options(adminRestSession.url()
+ "/a/changes/" + change.getChangeId() + "/detail");
Request req =
Request.Options(adminRestSession.url() + "/a/changes/" + change.getChangeId() + "/detail");
req.addHeader(ORIGIN, "http://example.com");
req.addHeader(ACCESS_CONTROL_REQUEST_METHOD, "GET");
req.addHeader(ACCESS_CONTROL_REQUEST_HEADERS, "X-Gerrit-Auth");
@ -131,8 +130,7 @@ public class CorsIT extends AbstractDaemonTest {
adminRestSession.execute(req).assertBadRequest();
}
private RestResponse check(String url, boolean accept, String origin)
throws Exception {
private RestResponse check(String url, boolean accept, String origin) throws Exception {
Header hdr = new BasicHeader(ORIGIN, origin);
RestResponse r = adminRestSession.getWithHeader(url, hdr);
r.assertOK();

View File

@ -45,7 +45,7 @@ import com.google.gerrit.server.git.ChangeAlreadyMergedException;
import com.google.gerrit.testutil.ConfigSuite;
import com.google.gerrit.testutil.FakeEmailSender.Message;
import com.google.gerrit.testutil.TestTimeUtil;
import java.util.List;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
@ -57,8 +57,6 @@ import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.List;
public class CreateChangeIT extends AbstractDaemonTest {
@ConfigSuite.Config
public static Config allowDraftsDisabled() {
@ -79,8 +77,7 @@ public class CreateChangeIT extends AbstractDaemonTest {
public void createEmptyChange_MissingBranch() throws Exception {
ChangeInput ci = new ChangeInput();
ci.project = project.get();
assertCreateFails(ci, BadRequestException.class,
"branch must be non-empty");
assertCreateFails(ci, BadRequestException.class, "branch must be non-empty");
}
@Test
@ -88,15 +85,13 @@ public class CreateChangeIT extends AbstractDaemonTest {
ChangeInput ci = new ChangeInput();
ci.project = project.get();
ci.branch = "master";
assertCreateFails(ci, BadRequestException.class,
"commit message must be non-empty");
assertCreateFails(ci, BadRequestException.class, "commit message must be non-empty");
}
@Test
public void createEmptyChange_InvalidStatus() throws Exception {
ChangeInput ci = newChangeInput(ChangeStatus.MERGED);
assertCreateFails(ci, BadRequestException.class,
"unsupported change status");
assertCreateFails(ci, BadRequestException.class, "unsupported change status");
}
@Test
@ -117,8 +112,7 @@ public class CreateChangeIT extends AbstractDaemonTest {
assertThat(messages).hasSize(1);
Message m = messages.get(0);
assertThat(m.rcpt()).containsExactly(user.emailAddress);
assertThat(m.body())
.contains(admin.fullName + " has uploaded this change for review.");
assertThat(m.body()).contains(admin.fullName + " has uploaded this change for review.");
// check that watcher is not notified if notify=NONE
sender.clear();
@ -134,9 +128,10 @@ public class CreateChangeIT extends AbstractDaemonTest {
setSignedOffByFooter();
ChangeInfo info = assertCreateSucceeds(newChangeInput(ChangeStatus.NEW));
String message = info.revisions.get(info.currentRevision).commit.message;
assertThat(message).contains(
String.format("%sAdministrator <%s>", SIGNED_OFF_BY_TAG,
admin.getIdent().getEmailAddress()));
assertThat(message)
.contains(
String.format(
"%sAdministrator <%s>", SIGNED_OFF_BY_TAG, admin.getIdent().getEmailAddress()));
}
@Test
@ -149,8 +144,7 @@ public class CreateChangeIT extends AbstractDaemonTest {
public void createNewDraftChangeNotAllowed() throws Exception {
assume().that(isAllowDrafts()).isFalse();
ChangeInput ci = newChangeInput(ChangeStatus.DRAFT);
assertCreateFails(ci, MethodNotAllowedException.class,
"draft workflow is disabled");
assertCreateFails(ci, MethodNotAllowedException.class, "draft workflow is disabled");
}
@Test
@ -160,14 +154,17 @@ public class CreateChangeIT extends AbstractDaemonTest {
ChangeInfo c = assertCreateSucceeds(newChangeInput(ChangeStatus.NEW));
try (Repository repo = repoManager.openRepository(project);
RevWalk rw = new RevWalk(repo)) {
RevCommit commit = rw.parseCommit(
repo.exactRef(changeMetaRef(new Change.Id(c._number))).getObjectId());
RevCommit commit =
rw.parseCommit(repo.exactRef(changeMetaRef(new Change.Id(c._number))).getObjectId());
assertThat(commit.getShortMessage()).isEqualTo("Create change");
PersonIdent expectedAuthor = changeNoteUtil.newIdent(
accountCache.get(admin.id).getAccount(), c.created, serverIdent.get(),
AnonymousCowardNameProvider.DEFAULT);
PersonIdent expectedAuthor =
changeNoteUtil.newIdent(
accountCache.get(admin.id).getAccount(),
c.created,
serverIdent.get(),
AnonymousCowardNameProvider.DEFAULT);
assertThat(commit.getAuthorIdent()).isEqualTo(expectedAuthor);
assertThat(commit.getCommitterIdent())
@ -179,75 +176,89 @@ public class CreateChangeIT extends AbstractDaemonTest {
@Test
public void createMergeChange() throws Exception {
changeInTwoBranches("branchA", "a.txt", "branchB", "b.txt");
ChangeInput in =
newMergeChangeInput("branchA", "branchB", "");
ChangeInput in = newMergeChangeInput("branchA", "branchB", "");
assertCreateSucceeds(in);
}
@Test
public void createMergeChange_Conflicts() throws Exception {
changeInTwoBranches("branchA", "shared.txt", "branchB", "shared.txt");
ChangeInput in =
newMergeChangeInput("branchA", "branchB", "");
ChangeInput in = newMergeChangeInput("branchA", "branchB", "");
assertCreateFails(in, RestApiException.class, "merge conflict");
}
@Test
public void createMergeChange_Conflicts_Ours() throws Exception {
changeInTwoBranches("branchA", "shared.txt", "branchB", "shared.txt");
ChangeInput in =
newMergeChangeInput("branchA", "branchB", "ours");
ChangeInput in = newMergeChangeInput("branchA", "branchB", "ours");
assertCreateSucceeds(in);
}
@Test
public void invalidSource() throws Exception {
changeInTwoBranches("branchA", "a.txt", "branchB", "b.txt");
ChangeInput in =
newMergeChangeInput("branchA", "invalid", "");
assertCreateFails(in, BadRequestException.class,
"Cannot resolve 'invalid' to a commit");
ChangeInput in = newMergeChangeInput("branchA", "invalid", "");
assertCreateFails(in, BadRequestException.class, "Cannot resolve 'invalid' to a commit");
}
@Test
public void invalidStrategy() throws Exception {
changeInTwoBranches("branchA", "a.txt", "branchB", "b.txt");
ChangeInput in =
newMergeChangeInput("branchA", "branchB", "octopus");
assertCreateFails(in, BadRequestException.class,
"invalid merge strategy: octopus");
ChangeInput in = newMergeChangeInput("branchA", "branchB", "octopus");
assertCreateFails(in, BadRequestException.class, "invalid merge strategy: octopus");
}
@Test
public void alreadyMerged() throws Exception {
ObjectId c0 = testRepo.branch("HEAD").commit().insertChangeId()
.message("first commit")
.add("a.txt", "a contents ")
.create();
testRepo.git().push().setRemote("origin").setRefSpecs(
new RefSpec("HEAD:refs/heads/master")).call();
ObjectId c0 =
testRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("first commit")
.add("a.txt", "a contents ")
.create();
testRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/heads/master"))
.call();
testRepo.branch("HEAD").commit().insertChangeId()
testRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("second commit")
.add("b.txt", "b contents ")
.create();
testRepo.git().push().setRemote("origin").setRefSpecs(
new RefSpec("HEAD:refs/heads/master")).call();
testRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/heads/master"))
.call();
ChangeInput in =
newMergeChangeInput("master", c0.getName(), "");
assertCreateFails(in, ChangeAlreadyMergedException.class,
"'" + c0.getName() + "' has already been merged");
ChangeInput in = newMergeChangeInput("master", c0.getName(), "");
assertCreateFails(
in, ChangeAlreadyMergedException.class, "'" + c0.getName() + "' has already been merged");
}
@Test
public void onlyContentMerged() throws Exception {
testRepo.branch("HEAD").commit().insertChangeId()
testRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("first commit")
.add("a.txt", "a contents ")
.create();
testRepo.git().push().setRemote("origin").setRefSpecs(
new RefSpec("HEAD:refs/heads/master")).call();
testRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/heads/master"))
.call();
// create a change, and cherrypick into master
PushOneCommit.Result cId = createChange();
@ -255,8 +266,7 @@ public class CreateChangeIT extends AbstractDaemonTest {
CherryPickInput cpi = new CherryPickInput();
cpi.destination = "master";
cpi.message = "cherry pick the commit";
ChangeApi orig = gApi.changes()
.id(cId.getChangeId());
ChangeApi orig = gApi.changes().id(cId.getChangeId());
ChangeApi cherry = orig.current().cherryPick(cpi);
cherry.current().review(ReviewInput.approve());
cherry.current().submit();
@ -264,8 +274,7 @@ public class CreateChangeIT extends AbstractDaemonTest {
ObjectId remoteId = getRemoteHead();
assertThat(remoteId).isNotEqualTo(commitId);
ChangeInput in =
newMergeChangeInput("master", commitId.getName(), "");
ChangeInput in = newMergeChangeInput("master", commitId.getName(), "");
assertCreateSucceeds(in);
}
@ -293,8 +302,8 @@ public class CreateChangeIT extends AbstractDaemonTest {
return out;
}
private void assertCreateFails(ChangeInput in,
Class<? extends RestApiException> errType, String errSubstring)
private void assertCreateFails(
ChangeInput in, Class<? extends RestApiException> errType, String errSubstring)
throws Exception {
exception.expect(errType);
exception.expectMessage(errSubstring);
@ -310,23 +319,19 @@ public class CreateChangeIT extends AbstractDaemonTest {
// TODO(davido): Expose setting of account preferences in the API
private void setSignedOffByFooter() throws Exception {
RestResponse r = adminRestSession.get("/accounts/" + admin.email
+ "/preferences");
RestResponse r = adminRestSession.get("/accounts/" + admin.email + "/preferences");
r.assertOK();
GeneralPreferencesInfo i =
newGson().fromJson(r.getReader(), GeneralPreferencesInfo.class);
GeneralPreferencesInfo i = newGson().fromJson(r.getReader(), GeneralPreferencesInfo.class);
i.signedOffBy = true;
r = adminRestSession.put("/accounts/" + admin.email + "/preferences", i);
r.assertOK();
GeneralPreferencesInfo o = newGson().fromJson(r.getReader(),
GeneralPreferencesInfo.class);
GeneralPreferencesInfo o = newGson().fromJson(r.getReader(), GeneralPreferencesInfo.class);
assertThat(o.signedOffBy).isTrue();
}
private ChangeInput newMergeChangeInput(String targetBranch, String sourceRef,
String strategy) {
private ChangeInput newMergeChangeInput(String targetBranch, String sourceRef, String strategy) {
// create a merge change from branchA to master in gerrit
ChangeInput in = new ChangeInput();
in.project = project.get();
@ -342,13 +347,13 @@ public class CreateChangeIT extends AbstractDaemonTest {
return in;
}
private void changeInTwoBranches(String branchA, String fileA, String branchB,
String fileB) throws Exception {
private void changeInTwoBranches(String branchA, String fileA, String branchB, String fileB)
throws Exception {
// create a initial commit in master
Result initialCommit = pushFactory
.create(db, user.getIdent(), testRepo, "initial commit", "readme.txt",
"initial commit")
.to("refs/heads/master");
Result initialCommit =
pushFactory
.create(db, user.getIdent(), testRepo, "initial commit", "readme.txt", "initial commit")
.to("refs/heads/master");
initialCommit.assertOkStatus();
// create two new branches
@ -356,14 +361,15 @@ public class CreateChangeIT extends AbstractDaemonTest {
createBranch(new Branch.NameKey(project, branchB));
// create a commit in branchA
Result changeA = pushFactory
.create(db, user.getIdent(), testRepo, "change A", fileA, "A content")
.to("refs/heads/" + branchA);
Result changeA =
pushFactory
.create(db, user.getIdent(), testRepo, "change A", fileA, "A content")
.to("refs/heads/" + branchA);
changeA.assertOkStatus();
// create a commit in branchB
PushOneCommit commitB = pushFactory
.create(db, user.getIdent(), testRepo, "change B", fileB, "B content");
PushOneCommit commitB =
pushFactory.create(db, user.getIdent(), testRepo, "change B", fileB, "B content");
commitB.setParent(initialCommit.getCommit());
Result changeB = commitB.to("refs/heads/" + branchB);
changeB.assertOkStatus();

View File

@ -39,20 +39,17 @@ import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.inject.Inject;
import java.util.HashMap;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.junit.Test;
import java.util.HashMap;
@NoHttpd
public class DeleteDraftPatchSetIT extends AbstractDaemonTest {
@Inject
private AllUsersName allUsers;
@Inject private AllUsersName allUsers;
@Test
public void deletePatchSetNotDraft() throws Exception {
@ -145,8 +142,7 @@ public class DeleteDraftPatchSetIT extends AbstractDaemonTest {
cd = getChange(changeId);
assertThat(cd.patchSets()).hasSize(1);
assertThat(Iterables.getOnlyElement(cd.patchSets()).getId().get())
.isEqualTo(2);
assertThat(Iterables.getOnlyElement(cd.patchSets()).getId().get()).isEqualTo(2);
// Other entities based on deleted patch sets are also deleted.
for (ChangeMessage m : cd.messages()) {
@ -180,8 +176,7 @@ public class DeleteDraftPatchSetIT extends AbstractDaemonTest {
cd = getChange(changeId);
assertThat(cd.patchSets()).hasSize(1);
assertThat(Iterables.getOnlyElement(cd.patchSets()).getId().get())
.isEqualTo(1);
assertThat(Iterables.getOnlyElement(cd.patchSets()).getId().get()).isEqualTo(1);
// Other entities based on deleted patch sets are also deleted.
for (ChangeMessage m : cd.messages()) {
@ -197,50 +192,34 @@ public class DeleteDraftPatchSetIT extends AbstractDaemonTest {
String ref = "refs/drafts/master";
// Clone repository
TestRepository<InMemoryRepository> testRepo =
cloneProject(project, admin);
TestRepository<InMemoryRepository> testRepo = cloneProject(project, admin);
// Create change
PushOneCommit push = pushFactory.create(
db, admin.getIdent(), testRepo);
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo);
PushOneCommit.Result r1 = push.to(ref);
r1.assertOkStatus();
String revPs1 = r1.getChange().currentPatchSet().getRevision().get();
// Push draft patch set
PushOneCommit.Result r2 = amendChange(
r1.getChangeId(), ref, admin, testRepo);
PushOneCommit.Result r2 = amendChange(r1.getChangeId(), ref, admin, testRepo);
r2.assertOkStatus();
String revPs2 = r2.getChange().currentPatchSet().getRevision().get();
assertThat(
gApi.changes()
.id(r1.getChange().getId().get()).get()
.currentRevision)
assertThat(gApi.changes().id(r1.getChange().getId().get()).get().currentRevision)
.isEqualTo(revPs2);
// Remove draft patch set
gApi.changes()
.id(r1.getChange().getId().get())
.revision(revPs2)
.delete();
gApi.changes().id(r1.getChange().getId().get()).revision(revPs2).delete();
assertThat(
gApi.changes()
.id(r1.getChange().getId().get()).get()
.currentRevision)
assertThat(gApi.changes().id(r1.getChange().getId().get()).get().currentRevision)
.isEqualTo(revPs1);
// Push new draft patch set
PushOneCommit.Result r3 = amendChange(
r1.getChangeId(), ref, admin, testRepo);
PushOneCommit.Result r3 = amendChange(r1.getChangeId(), ref, admin, testRepo);
r3.assertOkStatus();
String revPs3 = r2.getChange().currentPatchSet().getRevision().get();
assertThat(
gApi.changes()
.id(r1.getChange().getId().get()).get()
.currentRevision)
assertThat(gApi.changes().id(r1.getChange().getId().get()).get().currentRevision)
.isEqualTo(revPs3);
// Check that all patch sets have different SHA1s
@ -248,8 +227,7 @@ public class DeleteDraftPatchSetIT extends AbstractDaemonTest {
assertThat(revPs2).doesNotMatch(revPs3);
}
private Ref getDraftRef(TestAccount account, Change.Id changeId)
throws Exception {
private Ref getDraftRef(TestAccount account, Change.Id changeId) throws Exception {
try (Repository repo = repoManager.openRepository(allUsers)) {
return repo.exactRef(RefNames.refsDraftComments(changeId, account.id));
}
@ -264,8 +242,15 @@ public class DeleteDraftPatchSetIT extends AbstractDaemonTest {
private String createDraftChangeWith2PS() throws Exception {
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo);
Result result = push.to("refs/drafts/master");
push = pushFactory.create(db, admin.getIdent(), testRepo, PushOneCommit.SUBJECT,
"b.txt", "4711", result.getChangeId());
push =
pushFactory.create(
db,
admin.getIdent(),
testRepo,
PushOneCommit.SUBJECT,
"b.txt",
"4711",
result.getChangeId());
return push.to("refs/drafts/master").getChangeId();
}

View File

@ -29,12 +29,10 @@ import com.google.gerrit.extensions.common.ChangeMessageInfo;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.testutil.FakeEmailSender;
import com.google.gson.reflect.TypeToken;
import org.junit.Test;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.junit.Test;
public class DeleteVoteIT extends AbstractDaemonTest {
@Test
@ -49,10 +47,7 @@ public class DeleteVoteIT extends AbstractDaemonTest {
private void deleteVote(boolean onRevisionLevel) throws Exception {
PushOneCommit.Result r = createChange();
gApi.changes()
.id(r.getChangeId())
.revision(r.getCommit().name())
.review(ReviewInput.approve());
gApi.changes().id(r.getChangeId()).revision(r.getCommit().name()).review(ReviewInput.approve());
PushOneCommit.Result r2 = amendChange(r.getChangeId());
@ -60,10 +55,13 @@ public class DeleteVoteIT extends AbstractDaemonTest {
recommend(r.getChangeId());
sender.clear();
String endPoint = "/changes/" + r.getChangeId()
+ (onRevisionLevel ? ("/revisions/" + r2.getCommit().getName()) : "")
+ "/reviewers/" + user.getId().toString()
+ "/votes/Code-Review";
String endPoint =
"/changes/"
+ r.getChangeId()
+ (onRevisionLevel ? ("/revisions/" + r2.getCommit().getName()) : "")
+ "/reviewers/"
+ user.getId().toString()
+ "/votes/Code-Review";
RestResponse response = adminRestSession.delete(endPoint);
response.assertNoContent();
@ -72,35 +70,33 @@ public class DeleteVoteIT extends AbstractDaemonTest {
assertThat(messages).hasSize(1);
FakeEmailSender.Message msg = messages.get(0);
assertThat(msg.rcpt()).containsExactly(user.emailAddress);
assertThat(msg.body()).contains(
admin.fullName + " has removed a vote on this change.\n");
assertThat(msg.body()).contains("Removed Code-Review+1 by "
+ user.fullName + " <" + user.email + ">" + "\n");
assertThat(msg.body()).contains(admin.fullName + " has removed a vote on this change.\n");
assertThat(msg.body())
.contains("Removed Code-Review+1 by " + user.fullName + " <" + user.email + ">" + "\n");
endPoint = "/changes/" + r.getChangeId()
+ (onRevisionLevel ? ("/revisions/" + r2.getCommit().getName()) : "")
+ "/reviewers/" + user.getId().toString()
+ "/votes";
endPoint =
"/changes/"
+ r.getChangeId()
+ (onRevisionLevel ? ("/revisions/" + r2.getCommit().getName()) : "")
+ "/reviewers/"
+ user.getId().toString()
+ "/votes";
response = adminRestSession.get(endPoint);
response.assertOK();
Map<String, Short> m = newGson().fromJson(response.getReader(),
new TypeToken<Map<String, Short>>() {}.getType());
Map<String, Short> m =
newGson().fromJson(response.getReader(), new TypeToken<Map<String, Short>>() {}.getType());
assertThat(m).containsExactly("Code-Review", Short.valueOf((short)0));
assertThat(m).containsExactly("Code-Review", Short.valueOf((short) 0));
ChangeInfo c = gApi.changes()
.id(r.getChangeId())
.get();
ChangeInfo c = gApi.changes().id(r.getChangeId()).get();
ChangeMessageInfo message = Iterables.getLast(c.messages);
assertThat(message.author._accountId).isEqualTo(admin.getId().get());
assertThat(message.message).isEqualTo(
"Removed Code-Review+1 by User <user@example.com>\n");
assertThat(message.message).isEqualTo("Removed Code-Review+1 by User <user@example.com>\n");
assertThat(getReviewers(c.reviewers.get(REVIEWER)))
.containsExactlyElementsIn(
ImmutableSet.of(admin.getId(), user.getId()));
.containsExactlyElementsIn(ImmutableSet.of(admin.getId(), user.getId()));
}
private Iterable<Account.Id> getReviewers(Collection<AccountInfo> r) {

View File

@ -43,14 +43,12 @@ import com.google.gerrit.server.git.BatchUpdate;
import com.google.gerrit.server.notedb.PatchSetState;
import com.google.gerrit.testutil.ConfigSuite;
import com.google.inject.Inject;
import org.eclipse.jgit.lib.Config;
import org.junit.Test;
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.jgit.lib.Config;
import org.junit.Test;
public class DraftChangeIT extends AbstractDaemonTest {
@ConfigSuite.Config
@ -58,8 +56,7 @@ public class DraftChangeIT extends AbstractDaemonTest {
return allowDraftsDisabledConfig();
}
@Inject
private BatchUpdate.Factory updateFactory;
@Inject private BatchUpdate.Factory updateFactory;
@Test
public void deleteDraftChange() throws Exception {
@ -86,31 +83,24 @@ public class DraftChangeIT extends AbstractDaemonTest {
Change.Id id = changeResult.getChange().getId();
// The user needs to be able to see the draft change (which reviewers can).
gApi.changes()
.id(changeId)
.addReviewer(user.fullName);
gApi.changes().id(changeId).addReviewer(user.fullName);
setApiUser(user);
exception.expect(AuthException.class);
exception.expectMessage(String.format(
"Deleting change %s is not permitted", id));
gApi.changes()
.id(changeId)
.delete();
exception.expectMessage(String.format("Deleting change %s is not permitted", id));
gApi.changes().id(changeId).delete();
}
@Test
@TestProjectInput(cloneAs = "user")
public void deleteDraftChangeWhenDraftsNotAllowedAsNormalUser()
throws Exception {
public void deleteDraftChangeWhenDraftsNotAllowedAsNormalUser() throws Exception {
assume().that(isAllowDrafts()).isFalse();
setApiUser(user);
// We can't create a draft change while the draft workflow is disabled.
// For this reason, we create a normal change and modify the database.
PushOneCommit.Result changeResult =
pushFactory.create(db, user.getIdent(), testRepo)
.to("refs/for/master");
pushFactory.create(db, user.getIdent(), testRepo).to("refs/for/master");
Change.Id id = changeResult.getChange().getId();
markChangeAsDraft(id);
setDraftStatusOfPatchSetsOfChange(id, true);
@ -118,9 +108,7 @@ public class DraftChangeIT extends AbstractDaemonTest {
String changeId = changeResult.getChangeId();
exception.expect(MethodNotAllowedException.class);
exception.expectMessage("Draft workflow is disabled");
gApi.changes()
.id(changeId)
.delete();
gApi.changes().id(changeId).delete();
}
@Test
@ -132,8 +120,7 @@ public class DraftChangeIT extends AbstractDaemonTest {
// We can't create a draft change while the draft workflow is disabled.
// For this reason, we create a normal change and modify the database.
PushOneCommit.Result changeResult =
pushFactory.create(db, user.getIdent(), testRepo)
.to("refs/for/master");
pushFactory.create(db, user.getIdent(), testRepo).to("refs/for/master");
Change.Id id = changeResult.getChange().getId();
markChangeAsDraft(id);
setDraftStatusOfPatchSetsOfChange(id, true);
@ -146,9 +133,7 @@ public class DraftChangeIT extends AbstractDaemonTest {
try {
setApiUser(admin);
gApi.changes()
.id(changeId)
.delete();
gApi.changes().id(changeId).delete();
} finally {
removePermission(Permission.DELETE_DRAFTS, project, "refs/*");
removePermission(Permission.VIEW_DRAFTS, project, "refs/*");
@ -168,11 +153,9 @@ public class DraftChangeIT extends AbstractDaemonTest {
String changeId = changeResult.getChangeId();
exception.expect(ResourceConflictException.class);
exception.expectMessage(String.format(
"Cannot delete draft change %s: patch set 1 is not a draft", id));
gApi.changes()
.id(changeId)
.delete();
exception.expectMessage(
String.format("Cannot delete draft change %s: patch set 1 is not a draft", id));
gApi.changes().id(changeId).delete();
}
@Test
@ -243,8 +226,7 @@ public class DraftChangeIT extends AbstractDaemonTest {
assertThat(label.all.get(0).value).isEqualTo(1);
}
private static RestResponse deleteChange(String changeId,
RestSession s) throws Exception {
private static RestResponse deleteChange(String changeId, RestSession s) throws Exception {
return s.delete("/changes/" + changeId);
}
@ -253,59 +235,52 @@ public class DraftChangeIT extends AbstractDaemonTest {
}
private RestResponse publishPatchSet(String changeId) throws Exception {
PatchSet patchSet = Iterables.getOnlyElement(
queryProvider.get().byKeyPrefix(changeId)).currentPatchSet();
return adminRestSession.post("/changes/"
+ changeId
+ "/revisions/"
+ patchSet.getRevision().get()
+ "/publish");
PatchSet patchSet =
Iterables.getOnlyElement(queryProvider.get().byKeyPrefix(changeId)).currentPatchSet();
return adminRestSession.post(
"/changes/" + changeId + "/revisions/" + patchSet.getRevision().get() + "/publish");
}
private void markChangeAsDraft(Change.Id id) throws Exception {
try (BatchUpdate batchUpdate = updateFactory
.create(db, project, atrScope.get().getUser(), TimeUtil.nowTs())) {
try (BatchUpdate batchUpdate =
updateFactory.create(db, project, atrScope.get().getUser(), TimeUtil.nowTs())) {
batchUpdate.addOp(id, new MarkChangeAsDraftUpdateOp());
batchUpdate.execute();
}
ChangeStatus changeStatus = gApi.changes()
.id(id.get())
.get()
.status;
ChangeStatus changeStatus = gApi.changes().id(id.get()).get().status;
assertThat(changeStatus).isEqualTo(ChangeStatus.DRAFT);
}
private void setDraftStatusOfPatchSetsOfChange(Change.Id id,
boolean draftStatus) throws Exception {
try (BatchUpdate batchUpdate = updateFactory
.create(db, project, atrScope.get().getUser(), TimeUtil.nowTs())) {
private void setDraftStatusOfPatchSetsOfChange(Change.Id id, boolean draftStatus)
throws Exception {
try (BatchUpdate batchUpdate =
updateFactory.create(db, project, atrScope.get().getUser(), TimeUtil.nowTs())) {
batchUpdate.addOp(id, new DraftStatusOfPatchSetsUpdateOp(draftStatus));
batchUpdate.execute();
}
Boolean expectedDraftStatus = draftStatus ? Boolean.TRUE : null;
List<Boolean> patchSetDraftStatuses = getPatchSetDraftStatuses(id);
patchSetDraftStatuses.forEach(status ->
assertThat(status).isEqualTo(expectedDraftStatus));
patchSetDraftStatuses.forEach(status -> assertThat(status).isEqualTo(expectedDraftStatus));
}
private List<Boolean> getPatchSetDraftStatuses(Change.Id id)
throws Exception {
Collection<RevisionInfo> revisionInfos = gApi.changes()
.id(id.get())
.get(EnumSet.of(ListChangesOption.ALL_REVISIONS))
.revisions
.values();
return revisionInfos.stream()
private List<Boolean> getPatchSetDraftStatuses(Change.Id id) throws Exception {
Collection<RevisionInfo> revisionInfos =
gApi.changes()
.id(id.get())
.get(EnumSet.of(ListChangesOption.ALL_REVISIONS))
.revisions
.values();
return revisionInfos
.stream()
.map(revisionInfo -> revisionInfo.draft)
.collect(Collectors.toList());
}
private class MarkChangeAsDraftUpdateOp extends BatchUpdate.Op {
@Override
public boolean updateChange(BatchUpdate.ChangeContext ctx)
throws Exception {
public boolean updateChange(BatchUpdate.ChangeContext ctx) throws Exception {
Change change = ctx.getChange();
// Change status in database.
@ -327,8 +302,7 @@ public class DraftChangeIT extends AbstractDaemonTest {
}
@Override
public boolean updateChange(BatchUpdate.ChangeContext ctx)
throws Exception {
public boolean updateChange(BatchUpdate.ChangeContext ctx) throws Exception {
Collection<PatchSet> patchSets = psUtil.byChange(db, ctx.getNotes());
// Change status in database.
@ -336,13 +310,12 @@ public class DraftChangeIT extends AbstractDaemonTest {
db.patchSets().update(patchSets);
// Change status in NoteDb.
PatchSetState patchSetState = draftStatus ? PatchSetState.DRAFT
: PatchSetState.PUBLISHED;
patchSets.stream()
PatchSetState patchSetState = draftStatus ? PatchSetState.DRAFT : PatchSetState.PUBLISHED;
patchSets
.stream()
.map(PatchSet::getId)
.map(ctx::getUpdate)
.forEach(changeUpdate ->
changeUpdate.setPatchSetState(patchSetState));
.forEach(changeUpdate -> changeUpdate.setPatchSetState(patchSetState));
return true;
}

View File

@ -28,7 +28,6 @@ import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.extensions.api.changes.HashtagsInput;
import com.google.gerrit.extensions.common.ChangeMessageInfo;
import com.google.gerrit.testutil.TestTimeUtil;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
@ -245,48 +244,37 @@ public class HashtagsIT extends AbstractDaemonTest {
assertMessage(r, "Hashtag added: MyHashtag");
}
private IterableSubject assertThatGet(PushOneCommit.Result r)
throws Exception {
return assertThat(gApi.changes()
.id(r.getChange().getId().get())
.getHashtags());
private IterableSubject assertThatGet(PushOneCommit.Result r) throws Exception {
return assertThat(gApi.changes().id(r.getChange().getId().get()).getHashtags());
}
private void addHashtags(PushOneCommit.Result r, String... toAdd)
throws Exception {
private void addHashtags(PushOneCommit.Result r, String... toAdd) throws Exception {
HashtagsInput input = new HashtagsInput();
input.add = Sets.newHashSet(toAdd);
gApi.changes()
.id(r.getChange().getId().get())
.setHashtags(input);
gApi.changes().id(r.getChange().getId().get()).setHashtags(input);
}
private void removeHashtags(PushOneCommit.Result r, String... toRemove)
throws Exception {
private void removeHashtags(PushOneCommit.Result r, String... toRemove) throws Exception {
HashtagsInput input = new HashtagsInput();
input.remove = Sets.newHashSet(toRemove);
gApi.changes()
.id(r.getChange().getId().get())
.setHashtags(input);
gApi.changes().id(r.getChange().getId().get()).setHashtags(input);
}
private void assertMessage(PushOneCommit.Result r, String expectedMessage)
throws Exception {
private void assertMessage(PushOneCommit.Result r, String expectedMessage) throws Exception {
assertThat(getLastMessage(r).message).isEqualTo(expectedMessage);
}
private void assertNoNewMessageSince(PushOneCommit.Result r,
ChangeMessageInfo expected) throws Exception {
private void assertNoNewMessageSince(PushOneCommit.Result r, ChangeMessageInfo expected)
throws Exception {
checkNotNull(expected);
ChangeMessageInfo last = getLastMessage(r);
assertThat(last.message).isEqualTo(expected.message);
assertThat(last.id).isEqualTo(expected.id);
}
private ChangeMessageInfo getLastMessage(PushOneCommit.Result r)
throws Exception {
ChangeMessageInfo lastMessage = Iterables.getLast(
gApi.changes().id(r.getChange().getId().get()).get().messages, null);
private ChangeMessageInfo getLastMessage(PushOneCommit.Result r) throws Exception {
ChangeMessageInfo lastMessage =
Iterables.getLast(gApi.changes().id(r.getChange().getId().get()).get().messages, null);
assertThat(lastMessage).named(lastMessage.message).isNotNull();
return lastMessage;
}

View File

@ -15,24 +15,19 @@
package com.google.gerrit.acceptance.rest.change;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import org.junit.Test;
public class IndexChangeIT extends AbstractDaemonTest {
@Test
public void indexChange() throws Exception {
String changeId = createChange().getChangeId();
adminRestSession
.post("/changes/" + changeId + "/index/")
.assertNoContent();
adminRestSession.post("/changes/" + changeId + "/index/").assertNoContent();
}
@Test
public void indexChangeOnNonVisibleBranch() throws Exception {
String changeId = createChange().getChangeId();
blockRead("refs/heads/master");
userRestSession
.post("/changes/" + changeId + "/index/")
.assertNotFound();
userRestSession.post("/changes/" + changeId + "/index/").assertNotFound();
}
}

View File

@ -24,12 +24,10 @@ import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.extensions.common.ChangeInfo;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
@NoHttpd
public class ListChangesOptionsIT extends AbstractDaemonTest {
@ -46,12 +44,12 @@ public class ListChangesOptionsIT extends AbstractDaemonTest {
results.add(push("new contents 2", changeId));
}
private PushOneCommit.Result push(String content, String baseChangeId)
throws Exception {
private PushOneCommit.Result push(String content, String baseChangeId) throws Exception {
String subject = "Change subject";
String fileName = "a.txt";
PushOneCommit push = pushFactory.create(
db, admin.getIdent(), testRepo, subject, fileName, content, baseChangeId);
PushOneCommit push =
pushFactory.create(
db, admin.getIdent(), testRepo, subject, fileName, content, baseChangeId);
PushOneCommit.Result r = push.to("refs/for/master");
r.assertOkStatus();
return r;
@ -68,8 +66,7 @@ public class ListChangesOptionsIT extends AbstractDaemonTest {
public void currentRevision() throws Exception {
ChangeInfo c = get(changeId, CURRENT_REVISION);
assertThat(c.currentRevision).isEqualTo(commitId(2));
assertThat(c.revisions.keySet()).containsAllIn(
ImmutableSet.of(commitId(2)));
assertThat(c.revisions.keySet()).containsAllIn(ImmutableSet.of(commitId(2)));
assertThat(c.revisions.get(commitId(2))._number).isEqualTo(3);
}
@ -78,8 +75,7 @@ public class ListChangesOptionsIT extends AbstractDaemonTest {
ChangeInfo c = get(changeId, CURRENT_REVISION, MESSAGES);
assertThat(c.revisions).hasSize(1);
assertThat(c.currentRevision).isEqualTo(commitId(2));
assertThat(c.revisions.keySet()).containsAllIn(
ImmutableSet.of(commitId(2)));
assertThat(c.revisions.keySet()).containsAllIn(ImmutableSet.of(commitId(2)));
assertThat(c.revisions.get(commitId(2))._number).isEqualTo(3);
}
@ -87,8 +83,8 @@ public class ListChangesOptionsIT extends AbstractDaemonTest {
public void allRevisions() throws Exception {
ChangeInfo c = get(changeId, ALL_REVISIONS);
assertThat(c.currentRevision).isEqualTo(commitId(2));
assertThat(c.revisions.keySet()).containsAllIn(
ImmutableSet.of(commitId(0), commitId(1), commitId(2)));
assertThat(c.revisions.keySet())
.containsAllIn(ImmutableSet.of(commitId(0), commitId(1), commitId(2)));
assertThat(c.revisions.get(commitId(0))._number).isEqualTo(1);
assertThat(c.revisions.get(commitId(1))._number).isEqualTo(2);
assertThat(c.revisions.get(commitId(2))._number).isEqualTo(3);

View File

@ -34,7 +34,6 @@ import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.project.Util;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.revwalk.RevCommit;
@ -46,8 +45,7 @@ public class MoveChangeIT extends AbstractDaemonTest {
public void moveChangeWithShortRef() throws Exception {
// Move change to a different branch using short ref name
PushOneCommit.Result r = createChange();
Branch.NameKey newBranch =
new Branch.NameKey(r.getChange().change().getProject(), "moveTest");
Branch.NameKey newBranch = new Branch.NameKey(r.getChange().change().getProject(), "moveTest");
createBranch(newBranch);
move(r.getChangeId(), newBranch.getShortName());
assertThat(r.getChange().change().getDest()).isEqualTo(newBranch);
@ -57,8 +55,7 @@ public class MoveChangeIT extends AbstractDaemonTest {
public void moveChangeWithFullRef() throws Exception {
// Move change to a different branch using full ref name
PushOneCommit.Result r = createChange();
Branch.NameKey newBranch =
new Branch.NameKey(r.getChange().change().getProject(), "moveTest");
Branch.NameKey newBranch = new Branch.NameKey(r.getChange().change().getProject(), "moveTest");
createBranch(newBranch);
move(r.getChangeId(), newBranch.get());
assertThat(r.getChange().change().getDest()).isEqualTo(newBranch);
@ -68,8 +65,7 @@ public class MoveChangeIT extends AbstractDaemonTest {
public void moveChangeWithMessage() throws Exception {
// Provide a message using --message flag
PushOneCommit.Result r = createChange();
Branch.NameKey newBranch =
new Branch.NameKey(r.getChange().change().getProject(), "moveTest");
Branch.NameKey newBranch = new Branch.NameKey(r.getChange().change().getProject(), "moveTest");
createBranch(newBranch);
String moveMessage = "Moving for the move test";
move(r.getChangeId(), newBranch.get(), moveMessage);
@ -78,8 +74,7 @@ public class MoveChangeIT extends AbstractDaemonTest {
expectedMessage.append("Change destination moved from master to moveTest");
expectedMessage.append("\n\n");
expectedMessage.append(moveMessage);
assertThat(r.getChange().messages().get(1).getMessage())
.isEqualTo(expectedMessage.toString());
assertThat(r.getChange().messages().get(1).getMessage()).isEqualTo(expectedMessage.toString());
}
@Test
@ -95,14 +90,16 @@ public class MoveChangeIT extends AbstractDaemonTest {
public void moveChangeToSameChangeId() throws Exception {
// Move change to a branch with existing change with same change ID
PushOneCommit.Result r = createChange();
Branch.NameKey newBranch =
new Branch.NameKey(r.getChange().change().getProject(), "moveTest");
Branch.NameKey newBranch = new Branch.NameKey(r.getChange().change().getProject(), "moveTest");
createBranch(newBranch);
int changeNum = r.getChange().change().getChangeId();
createChange(newBranch.get(), r.getChangeId());
exception.expect(ResourceConflictException.class);
exception.expectMessage("Destination " + newBranch.getShortName()
+ " has a different change with same change key " + r.getChangeId());
exception.expectMessage(
"Destination "
+ newBranch.getShortName()
+ " has a different change with same change key "
+ r.getChangeId());
move(changeNum, newBranch.get());
}
@ -110,11 +107,10 @@ public class MoveChangeIT extends AbstractDaemonTest {
public void moveChangeToNonExistentRef() throws Exception {
// Move change to a non-existing branch
PushOneCommit.Result r = createChange();
Branch.NameKey newBranch = new Branch.NameKey(
r.getChange().change().getProject(), "does_not_exist");
Branch.NameKey newBranch =
new Branch.NameKey(r.getChange().change().getProject(), "does_not_exist");
exception.expect(ResourceConflictException.class);
exception.expectMessage("Destination " + newBranch.get()
+ " not found in the project");
exception.expectMessage("Destination " + newBranch.get() + " not found in the project");
move(r.getChangeId(), newBranch.get());
}
@ -122,8 +118,7 @@ public class MoveChangeIT extends AbstractDaemonTest {
public void moveClosedChange() throws Exception {
// Move a change which is not open
PushOneCommit.Result r = createChange();
Branch.NameKey newBranch =
new Branch.NameKey(r.getChange().change().getProject(), "moveTest");
Branch.NameKey newBranch = new Branch.NameKey(r.getChange().change().getProject(), "moveTest");
createBranch(newBranch);
merge(r);
exception.expect(ResourceConflictException.class);
@ -140,17 +135,16 @@ public class MoveChangeIT extends AbstractDaemonTest {
TestRepository<?>.CommitBuilder commitBuilder =
testRepo.branch("HEAD").commit().insertChangeId();
commitBuilder
.parent(r1.getCommit())
.parent(r2.getCommit())
.message("Move change Merge Commit")
.author(admin.getIdent())
.committer(new PersonIdent(admin.getIdent(), testRepo.getDate()));
.parent(r1.getCommit())
.parent(r2.getCommit())
.message("Move change Merge Commit")
.author(admin.getIdent())
.committer(new PersonIdent(admin.getIdent(), testRepo.getDate()));
RevCommit c = commitBuilder.create();
pushHead(testRepo, "refs/for/master", false, false);
// Try to move the merge commit to another branch
Branch.NameKey newBranch =
new Branch.NameKey(r1.getChange().change().getProject(), "moveTest");
Branch.NameKey newBranch = new Branch.NameKey(r1.getChange().change().getProject(), "moveTest");
createBranch(newBranch);
exception.expect(ResourceConflictException.class);
exception.expectMessage("Merge commit cannot be moved");
@ -164,7 +158,8 @@ public class MoveChangeIT extends AbstractDaemonTest {
Branch.NameKey newBranch =
new Branch.NameKey(r.getChange().change().getProject(), "blocked_branch");
createBranch(newBranch);
block(Permission.PUSH,
block(
Permission.PUSH,
systemGroupBackend.getGroup(REGISTERED_USERS).getUUID(),
"refs/for/" + newBranch.get());
exception.expect(AuthException.class);
@ -176,10 +171,10 @@ public class MoveChangeIT extends AbstractDaemonTest {
public void moveChangeFromBranchWithoutAbandonPerms() throws Exception {
// Move change for which user does not have abandon permissions
PushOneCommit.Result r = createChange();
Branch.NameKey newBranch =
new Branch.NameKey(r.getChange().change().getProject(), "moveTest");
Branch.NameKey newBranch = new Branch.NameKey(r.getChange().change().getProject(), "moveTest");
createBranch(newBranch);
block(Permission.ABANDON,
block(
Permission.ABANDON,
systemGroupBackend.getGroup(REGISTERED_USERS).getUUID(),
r.getChange().change().getDest().get());
setApiUser(user);
@ -198,20 +193,15 @@ public class MoveChangeIT extends AbstractDaemonTest {
int changeNum = r.getChange().change().getChangeId();
// Create a branch with that same commit
Branch.NameKey newBranch =
new Branch.NameKey(r.getChange().change().getProject(), "moveTest");
Branch.NameKey newBranch = new Branch.NameKey(r.getChange().change().getProject(), "moveTest");
BranchInput bi = new BranchInput();
bi.revision = r.getCommit().name();
gApi.projects()
.name(newBranch.getParentKey().get())
.branch(newBranch.get())
.create(bi);
gApi.projects().name(newBranch.getParentKey().get()).branch(newBranch.get()).create(bi);
// Try to move the change to the branch with the same commit
exception.expect(ResourceConflictException.class);
exception
.expectMessage("Current patchset revision is reachable from tip of "
+ newBranch.get());
exception.expectMessage(
"Current patchset revision is reachable from tip of " + newBranch.get());
move(changeNum, newBranch.get());
}
@ -219,17 +209,15 @@ public class MoveChangeIT extends AbstractDaemonTest {
public void moveChangeWithCurrentPatchSetLocked() throws Exception {
// Move change that is locked
PushOneCommit.Result r = createChange();
Branch.NameKey newBranch =
new Branch.NameKey(r.getChange().change().getProject(), "moveTest");
Branch.NameKey newBranch = new Branch.NameKey(r.getChange().change().getProject(), "moveTest");
createBranch(newBranch);
ProjectConfig cfg = projectCache.checkedGet(project).getConfig();
LabelType patchSetLock = Util.patchSetLock();
cfg.getLabelSections().put(patchSetLock.getName(), patchSetLock);
AccountGroup.UUID registeredUsers =
systemGroupBackend.getGroup(REGISTERED_USERS).getUUID();
Util.allow(cfg, Permission.forLabel(patchSetLock.getName()), 0, 1, registeredUsers,
"refs/heads/*");
AccountGroup.UUID registeredUsers = systemGroupBackend.getGroup(REGISTERED_USERS).getUUID();
Util.allow(
cfg, Permission.forLabel(patchSetLock.getName()), 0, 1, registeredUsers, "refs/heads/*");
saveProjectConfig(cfg);
grant(Permission.LABEL + "Patch-Set-Lock", project, "refs/heads/*");
revision(r).review(new ReviewInput().label("Patch-Set-Lock", 1));
@ -239,28 +227,23 @@ public class MoveChangeIT extends AbstractDaemonTest {
move(r.getChangeId(), newBranch.get());
}
private void move(int changeNum, String destination)
throws RestApiException {
private void move(int changeNum, String destination) throws RestApiException {
gApi.changes().id(changeNum).move(destination);
}
private void move(String changeId, String destination)
throws RestApiException {
private void move(String changeId, String destination) throws RestApiException {
gApi.changes().id(changeId).move(destination);
}
private void move(String changeId, String destination, String message)
throws RestApiException {
private void move(String changeId, String destination, String message) throws RestApiException {
MoveInput in = new MoveInput();
in.destinationBranch = destination;
in.message = message;
gApi.changes().id(changeId).move(in);
}
private PushOneCommit.Result createChange(String branch, String changeId)
throws Exception {
PushOneCommit push =
pushFactory.create(db, admin.getIdent(), testRepo, changeId);
private PushOneCommit.Result createChange(String branch, String changeId) throws Exception {
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo, changeId);
PushOneCommit.Result result = push.to("refs/for/" + branch);
result.assertOkStatus();
return result;

View File

@ -36,18 +36,15 @@ import com.google.gerrit.server.change.Submit.TestSubmitInput;
import com.google.gerrit.server.git.ChangeMessageModifier;
import com.google.gerrit.server.git.strategy.CommitMergeStatus;
import com.google.inject.Inject;
import java.util.List;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.junit.Test;
import java.util.List;
public class SubmitByCherryPickIT extends AbstractSubmit {
@Inject
private DynamicSet<ChangeMessageModifier> changeMessageModifiers;
@Inject private DynamicSet<ChangeMessageModifier> changeMessageModifiers;
@Override
protected SubmitType getSubmitType() {
@ -61,8 +58,7 @@ public class SubmitByCherryPickIT extends AbstractSubmit {
submit(change.getChangeId());
assertCherryPick(testRepo, false);
RevCommit newHead = getRemoteHead();
assertThat(newHead.getParent(0))
.isEqualTo(change.getCommit().getParent(0));
assertThat(newHead.getParent(0)).isEqualTo(change.getCommit().getParent(0));
assertRefUpdatedEvents(initialHead, newHead);
assertChangeMergedEvents(change.getChangeId(), newHead.name());
@ -71,14 +67,12 @@ public class SubmitByCherryPickIT extends AbstractSubmit {
@Test
public void submitWithCherryPick() throws Exception {
RevCommit initialHead = getRemoteHead();
PushOneCommit.Result change =
createChange("Change 1", "a.txt", "content");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
RevCommit headAfterFirstSubmit = getRemoteHead();
testRepo.reset(initialHead);
PushOneCommit.Result change2 =
createChange("Change 2", "b.txt", "other content");
PushOneCommit.Result change2 = createChange("Change 2", "b.txt", "other content");
submit(change2.getChangeId());
assertCherryPick(testRepo, false);
RevCommit newHead = getRemoteHead();
@ -90,23 +84,26 @@ public class SubmitByCherryPickIT extends AbstractSubmit {
assertPersonEquals(admin.getIdent(), newHead.getAuthorIdent());
assertPersonEquals(admin.getIdent(), newHead.getCommitterIdent());
assertRefUpdatedEvents(initialHead, headAfterFirstSubmit,
headAfterFirstSubmit, newHead);
assertChangeMergedEvents(change.getChangeId(), headAfterFirstSubmit.name(),
change2.getChangeId(), newHead.name());
assertRefUpdatedEvents(initialHead, headAfterFirstSubmit, headAfterFirstSubmit, newHead);
assertChangeMergedEvents(
change.getChangeId(), headAfterFirstSubmit.name(), change2.getChangeId(), newHead.name());
}
@Test
public void changeMessageOnSubmit() throws Exception {
PushOneCommit.Result change = createChange();
RegistrationHandle handle =
changeMessageModifiers.add(new ChangeMessageModifier() {
@Override
public String onSubmit(String newCommitMessage, RevCommit original,
RevCommit mergeTip, Branch.NameKey destination) {
return newCommitMessage + "Custom: " + destination.get();
}
});
changeMessageModifiers.add(
new ChangeMessageModifier() {
@Override
public String onSubmit(
String newCommitMessage,
RevCommit original,
RevCommit mergeTip,
Branch.NameKey destination) {
return newCommitMessage + "Custom: " + destination.get();
}
});
try {
submit(change.getChangeId());
} finally {
@ -114,8 +111,7 @@ public class SubmitByCherryPickIT extends AbstractSubmit {
}
testRepo.git().fetch().setRemote("origin").call();
ChangeInfo info = get(change.getChangeId());
RevCommit c = testRepo.getRevWalk()
.parseCommit(ObjectId.fromString(info.currentRevision));
RevCommit c = testRepo.getRevWalk().parseCommit(ObjectId.fromString(info.currentRevision));
testRepo.getRevWalk().parseBody(c);
assertThat(c.getFooterLines("Custom")).containsExactly("refs/heads/master");
assertThat(c.getFooterLines(FooterConstants.REVIEWED_ON)).hasSize(1);
@ -125,53 +121,58 @@ public class SubmitByCherryPickIT extends AbstractSubmit {
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
public void submitWithContentMerge() throws Exception {
RevCommit initialHead = getRemoteHead();
PushOneCommit.Result change =
createChange("Change 1", "a.txt", "aaa\nbbb\nccc\n");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "aaa\nbbb\nccc\n");
submit(change.getChangeId());
RevCommit headAfterFirstSubmit = getRemoteHead();
PushOneCommit.Result change2 =
createChange("Change 2", "a.txt", "aaa\nbbb\nccc\nddd\n");
PushOneCommit.Result change2 = createChange("Change 2", "a.txt", "aaa\nbbb\nccc\nddd\n");
submit(change2.getChangeId());
RevCommit headAfterSecondSubmit = getRemoteHead();
testRepo.reset(change.getCommit());
PushOneCommit.Result change3 =
createChange("Change 3", "a.txt", "bbb\nccc\n");
PushOneCommit.Result change3 = createChange("Change 3", "a.txt", "bbb\nccc\n");
submit(change3.getChangeId());
assertCherryPick(testRepo, true);
RevCommit headAfterThirdSubmit = getRemoteHead();
assertThat(headAfterThirdSubmit.getParent(0))
.isEqualTo(headAfterSecondSubmit);
assertThat(headAfterThirdSubmit.getParent(0)).isEqualTo(headAfterSecondSubmit);
assertApproved(change3.getChangeId());
assertCurrentRevision(change3.getChangeId(), 2, headAfterThirdSubmit);
assertSubmitter(change2.getChangeId(), 1);
assertSubmitter(change2.getChangeId(), 2);
assertRefUpdatedEvents(initialHead, headAfterFirstSubmit,
headAfterFirstSubmit, headAfterSecondSubmit,
headAfterSecondSubmit, headAfterThirdSubmit);
assertChangeMergedEvents(change.getChangeId(), headAfterFirstSubmit.name(),
change2.getChangeId(), headAfterSecondSubmit.name(),
change3.getChangeId(), headAfterThirdSubmit.name());
assertRefUpdatedEvents(
initialHead,
headAfterFirstSubmit,
headAfterFirstSubmit,
headAfterSecondSubmit,
headAfterSecondSubmit,
headAfterThirdSubmit);
assertChangeMergedEvents(
change.getChangeId(),
headAfterFirstSubmit.name(),
change2.getChangeId(),
headAfterSecondSubmit.name(),
change3.getChangeId(),
headAfterThirdSubmit.name());
}
@Test
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
public void submitWithContentMerge_Conflict() throws Exception {
RevCommit initialHead = getRemoteHead();
PushOneCommit.Result change =
createChange("Change 1", "a.txt", "content");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
RevCommit newHead = getRemoteHead();
testRepo.reset(initialHead);
PushOneCommit.Result change2 =
createChange("Change 2", "a.txt", "other content");
submitWithConflict(change2.getChangeId(),
"Failed to submit 1 change due to the following problems:\n" +
"Change " + change2.getChange().getId() + ": Change could not be " +
"merged due to a path conflict. Please rebase the change locally and " +
"upload the rebased commit for review.");
PushOneCommit.Result change2 = createChange("Change 2", "a.txt", "other content");
submitWithConflict(
change2.getChangeId(),
"Failed to submit 1 change due to the following problems:\n"
+ "Change "
+ change2.getChange().getId()
+ ": Change could not be "
+ "merged due to a path conflict. Please rebase the change locally and "
+ "upload the rebased commit for review.");
assertThat(getRemoteHead()).isEqualTo(newHead);
assertCurrentRevision(change2.getChangeId(), 1, change2.getCommit());
@ -184,48 +185,49 @@ public class SubmitByCherryPickIT extends AbstractSubmit {
@Test
public void submitOutOfOrder() throws Exception {
RevCommit initialHead = getRemoteHead();
PushOneCommit.Result change =
createChange("Change 1", "a.txt", "content");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
RevCommit headAfterFirstSubmit = getRemoteHead();
testRepo.reset(initialHead);
createChange("Change 2", "b.txt", "other content");
PushOneCommit.Result change3 =
createChange("Change 3", "c.txt", "different content");
PushOneCommit.Result change3 = createChange("Change 3", "c.txt", "different content");
submit(change3.getChangeId());
assertCherryPick(testRepo, false);
RevCommit headAfterSecondSubmit = getRemoteHead();
assertThat(headAfterSecondSubmit.getParent(0))
.isEqualTo(headAfterFirstSubmit);
assertThat(headAfterSecondSubmit.getParent(0)).isEqualTo(headAfterFirstSubmit);
assertApproved(change3.getChangeId());
assertCurrentRevision(change3.getChangeId(), 2, headAfterSecondSubmit);
assertSubmitter(change3.getChangeId(), 1);
assertSubmitter(change3.getChangeId(), 2);
assertRefUpdatedEvents(initialHead, headAfterFirstSubmit,
headAfterFirstSubmit, headAfterSecondSubmit);
assertChangeMergedEvents(change.getChangeId(), headAfterFirstSubmit.name(),
change3.getChangeId(), headAfterSecondSubmit.name());
assertRefUpdatedEvents(
initialHead, headAfterFirstSubmit, headAfterFirstSubmit, headAfterSecondSubmit);
assertChangeMergedEvents(
change.getChangeId(),
headAfterFirstSubmit.name(),
change3.getChangeId(),
headAfterSecondSubmit.name());
}
@Test
public void submitOutOfOrder_Conflict() throws Exception {
RevCommit initialHead = getRemoteHead();
PushOneCommit.Result change =
createChange("Change 1", "a.txt", "content");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
RevCommit newHead = getRemoteHead();
testRepo.reset(initialHead);
createChange("Change 2", "b.txt", "other content");
PushOneCommit.Result change3 =
createChange("Change 3", "b.txt", "different content");
submitWithConflict(change3.getChangeId(),
"Failed to submit 1 change due to the following problems:\n" +
"Change " + change3.getChange().getId() + ": Change could not be " +
"merged due to a path conflict. Please rebase the change locally and " +
"upload the rebased commit for review.");
PushOneCommit.Result change3 = createChange("Change 3", "b.txt", "different content");
submitWithConflict(
change3.getChangeId(),
"Failed to submit 1 change due to the following problems:\n"
+ "Change "
+ change3.getChange().getId()
+ ": Change could not be "
+ "merged due to a path conflict. Please rebase the change locally and "
+ "upload the rebased commit for review.");
assertThat(getRemoteHead()).isEqualTo(newHead);
assertCurrentRevision(change3.getChangeId(), 1, change3.getCommit());
@ -253,8 +255,7 @@ public class SubmitByCherryPickIT extends AbstractSubmit {
submit(change3.getChangeId());
List<RevCommit> log = getRemoteLog();
assertThat(log.get(0).getShortMessage()).isEqualTo(
change3.getCommit().getShortMessage());
assertThat(log.get(0).getShortMessage()).isEqualTo(change3.getCommit().getShortMessage());
assertThat(log.get(1).getId()).isEqualTo(initialHead.getId());
assertNew(change.getChangeId());
@ -283,20 +284,21 @@ public class SubmitByCherryPickIT extends AbstractSubmit {
// change is the new tip.
List<RevCommit> log = getRemoteLog();
assertThat(log.get(0).getShortMessage()).isEqualTo(
change.getCommit().getShortMessage());
assertThat(log.get(0).getShortMessage()).isEqualTo(change.getCommit().getShortMessage());
assertThat(log.get(0).getParent(0)).isEqualTo(log.get(1));
assertThat(log.get(1).getShortMessage()).isEqualTo(
change2.getCommit().getShortMessage());
assertThat(log.get(1).getShortMessage()).isEqualTo(change2.getCommit().getShortMessage());
assertThat(log.get(1).getParent(0)).isEqualTo(log.get(2));
assertThat(log.get(2).getId()).isEqualTo(initialHead.getId());
assertRefUpdatedEvents(initialHead, headAfterFirstSubmit,
headAfterFirstSubmit, headAfterSecondSubmit);
assertChangeMergedEvents(change2.getChangeId(), headAfterFirstSubmit.name(),
change.getChangeId(), headAfterSecondSubmit.name());
assertRefUpdatedEvents(
initialHead, headAfterFirstSubmit, headAfterFirstSubmit, headAfterSecondSubmit);
assertChangeMergedEvents(
change2.getChangeId(),
headAfterFirstSubmit.name(),
change.getChangeId(),
headAfterSecondSubmit.name());
}
@Test
@ -310,11 +312,14 @@ public class SubmitByCherryPickIT extends AbstractSubmit {
// Submit fails; change2 contains the delta "b1" -> "b2", which cannot be
// applied against tip.
submitWithConflict(change2.getChangeId(),
"Failed to submit 1 change due to the following problems:\n" +
"Change " + change2.getChange().getId() + ": Change could not be " +
"merged due to a path conflict. Please rebase the change locally and " +
"upload the rebased commit for review.");
submitWithConflict(
change2.getChangeId(),
"Failed to submit 1 change due to the following problems:\n"
+ "Change "
+ change2.getChange().getId()
+ ": Change could not be "
+ "merged due to a path conflict. Please rebase the change locally and "
+ "upload the rebased commit for review.");
ChangeInfo info3 = get(change2.getChangeId(), ListChangesOption.MESSAGES);
assertThat(info3.status).isEqualTo(ChangeStatus.NEW);
@ -374,26 +379,29 @@ public class SubmitByCherryPickIT extends AbstractSubmit {
.isEqualTo(CommitMergeStatus.SKIPPED_IDENTICAL_TREE.getMessage());
assertRefUpdatedEvents(initialHead, headAfterFirstSubmit);
assertChangeMergedEvents(change1.getChangeId(), headAfterFirstSubmit.name(),
change2.getChangeId(), headAfterFirstSubmit.name());
assertChangeMergedEvents(
change1.getChangeId(),
headAfterFirstSubmit.name(),
change2.getChangeId(),
headAfterFirstSubmit.name());
}
@Test
public void repairChangeStateAfterFailure() throws Exception {
RevCommit initialHead = getRemoteHead();
PushOneCommit.Result change =
createChange("Change 1", "a.txt", "content");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
RevCommit headAfterFirstSubmit = getRemoteHead();
testRepo.reset(initialHead);
PushOneCommit.Result change2 =
createChange("Change 2", "b.txt", "other content");
PushOneCommit.Result change2 = createChange("Change 2", "b.txt", "other content");
Change.Id id2 = change2.getChange().getId();
SubmitInput failAfterRefUpdates =
new TestSubmitInput(new SubmitInput(), true);
submit(change2.getChangeId(), failAfterRefUpdates,
ResourceConflictException.class, "Failing after ref updates");
SubmitInput failAfterRefUpdates = new TestSubmitInput(new SubmitInput(), true);
submit(
change2.getChangeId(),
failAfterRefUpdates,
ResourceConflictException.class,
"Failing after ref updates");
RevCommit headAfterFailedSubmit = getRemoteHead();
// Bad: ref advanced but change wasn't updated.
@ -413,11 +421,9 @@ public class SubmitByCherryPickIT extends AbstractSubmit {
rev2 = repo.exactRef(psId2.toRefName()).getObjectId();
assertThat(rev2).isNotNull();
assertThat(rev2).isNotEqualTo(rev1);
assertThat(rw.parseCommit(rev2).getParent(0))
.isEqualTo(headAfterFirstSubmit);
assertThat(rw.parseCommit(rev2).getParent(0)).isEqualTo(headAfterFirstSubmit);
assertThat(repo.exactRef("refs/heads/master").getObjectId())
.isEqualTo(rev2);
assertThat(repo.exactRef("refs/heads/master").getObjectId()).isEqualTo(rev2);
}
submit(change2.getChangeId());
@ -433,16 +439,18 @@ public class SubmitByCherryPickIT extends AbstractSubmit {
assertThat(ps2).isNotNull();
assertThat(ps2.getRevision().get()).isEqualTo(rev2.name());
assertThat(Iterables.getLast(info.messages).message)
.isEqualTo("Change has been successfully cherry-picked as "
+ rev2.name() + " by Administrator");
.isEqualTo(
"Change has been successfully cherry-picked as " + rev2.name() + " by Administrator");
try (Repository repo = repoManager.openRepository(project)) {
assertThat(repo.exactRef("refs/heads/master").getObjectId())
.isEqualTo(rev2);
assertThat(repo.exactRef("refs/heads/master").getObjectId()).isEqualTo(rev2);
}
assertRefUpdatedEvents(initialHead, headAfterFirstSubmit);
assertChangeMergedEvents(change.getChangeId(), headAfterFirstSubmit.name(),
change2.getChangeId(), headAfterSecondSubmit.name());
assertChangeMergedEvents(
change.getChangeId(),
headAfterFirstSubmit.name(),
change2.getChangeId(),
headAfterSecondSubmit.name());
}
}

View File

@ -30,7 +30,7 @@ import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.change.Submit.TestSubmitInput;
import java.util.Map;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
@ -38,8 +38,6 @@ import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.PushResult;
import org.junit.Test;
import java.util.Map;
public class SubmitByFastForwardIT extends AbstractSubmit {
@Override
@ -89,9 +87,8 @@ public class SubmitByFastForwardIT extends AbstractSubmit {
assertSubmittedTogether(id3, id3, id2, id1);
assertRefUpdatedEvents(initialHead, updatedHead);
assertChangeMergedEvents(id1, updatedHead.name(),
id2, updatedHead.name(),
id3, updatedHead.name());
assertChangeMergedEvents(
id1, updatedHead.name(), id2, updatedHead.name(), id3, updatedHead.name());
}
@Test
@ -101,9 +98,12 @@ public class SubmitByFastForwardIT extends AbstractSubmit {
PushOneCommit.Result change2 = createChange();
Change.Id id1 = change1.getPatchSetId().getParentKey();
submitWithConflict(change2.getChangeId(),
submitWithConflict(
change2.getChangeId(),
"Failed to submit 2 changes due to the following problems:\n"
+ "Change " + id1 + ": needs Code-Review");
+ "Change "
+ id1
+ ": needs Code-Review");
RevCommit updatedHead = getRemoteHead();
assertThat(updatedHead.getId()).isEqualTo(initialHead.getId());
@ -114,14 +114,12 @@ public class SubmitByFastForwardIT extends AbstractSubmit {
@Test
public void submitFastForwardNotPossible_Conflict() throws Exception {
RevCommit initialHead = getRemoteHead();
PushOneCommit.Result change =
createChange("Change 1", "a.txt", "content");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
RevCommit headAfterFirstSubmit = getRemoteHead();
testRepo.reset(initialHead);
PushOneCommit.Result change2 =
createChange("Change 2", "b.txt", "other content");
PushOneCommit.Result change2 = createChange("Change 2", "b.txt", "other content");
approve(change2.getChangeId());
Map<String, ActionInfo> actions = getActions(change2.getChangeId());
@ -130,11 +128,14 @@ public class SubmitByFastForwardIT extends AbstractSubmit {
ActionInfo info = actions.get("submit");
assertThat(info.enabled).isNull();
submitWithConflict(change2.getChangeId(),
"Failed to submit 1 change due to the following problems:\n" +
"Change " + change2.getChange().getId() + ": Project policy requires " +
"all submissions to be a fast-forward. Please rebase the change " +
"locally and upload again for review.");
submitWithConflict(
change2.getChangeId(),
"Failed to submit 1 change due to the following problems:\n"
+ "Change "
+ change2.getChange().getId()
+ ": Project policy requires "
+ "all submissions to be a fast-forward. Please rebase the change "
+ "locally and upload again for review.");
assertThat(getRemoteHead()).isEqualTo(headAfterFirstSubmit);
assertSubmitter(change.getChangeId(), 1);
@ -146,10 +147,12 @@ public class SubmitByFastForwardIT extends AbstractSubmit {
public void repairChangeStateAfterFailure() throws Exception {
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
Change.Id id = change.getChange().getId();
SubmitInput failAfterRefUpdates =
new TestSubmitInput(new SubmitInput(), true);
submit(change.getChangeId(), failAfterRefUpdates,
ResourceConflictException.class, "Failing after ref updates");
SubmitInput failAfterRefUpdates = new TestSubmitInput(new SubmitInput(), true);
submit(
change.getChangeId(),
failAfterRefUpdates,
ResourceConflictException.class,
"Failing after ref updates");
// Bad: ref advanced but change wasn't updated.
PatchSet.Id psId = new PatchSet.Id(id, 1);
@ -162,8 +165,7 @@ public class SubmitByFastForwardIT extends AbstractSubmit {
RevWalk rw = new RevWalk(repo)) {
rev = repo.exactRef(psId.toRefName()).getObjectId();
assertThat(rev).isNotNull();
assertThat(repo.exactRef("refs/heads/master").getObjectId())
.isEqualTo(rev);
assertThat(repo.exactRef("refs/heads/master").getObjectId()).isEqualTo(rev);
}
submit(change.getChangeId());
@ -176,8 +178,7 @@ public class SubmitByFastForwardIT extends AbstractSubmit {
.isEqualTo("Change has been successfully merged by Administrator");
try (Repository repo = repoManager.openRepository(project)) {
assertThat(repo.exactRef("refs/heads/master").getObjectId())
.isEqualTo(rev);
assertThat(repo.exactRef("refs/heads/master").getObjectId()).isEqualTo(rev);
}
assertRefUpdatedEvents();
@ -191,15 +192,11 @@ public class SubmitByFastForwardIT extends AbstractSubmit {
grant(Permission.CREATE, project, "refs/heads/*");
grant(Permission.PUSH, project, "refs/heads/experimental");
RevCommit c1 = commitBuilder()
.add("b.txt", "1")
.message("commit at tip")
.create();
RevCommit c1 = commitBuilder().add("b.txt", "1").message("commit at tip").create();
String id1 = GitUtil.getChangeId(testRepo, c1).get();
PushResult r1 = pushHead(testRepo, "refs/for/master", false);
assertThat(r1.getRemoteUpdate("refs/for/master").getNewObjectId())
.isEqualTo(c1.getId());
assertThat(r1.getRemoteUpdate("refs/for/master").getNewObjectId()).isEqualTo(c1.getId());
PushResult r2 = pushHead(testRepo, "refs/heads/experimental", false);
assertThat(r2.getRemoteUpdate("refs/heads/experimental").getNewObjectId())

View File

@ -18,7 +18,6 @@ import static com.google.common.truth.Truth.assertThat;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.extensions.client.SubmitType;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Test;
@ -57,12 +56,11 @@ public class SubmitByMergeAlwaysIT extends AbstractSubmitByMerge {
// The remote head should now be a merge of the previous head
// and "Change 1"
RevCommit headAfterFirstSubmit = getRemoteLog().get(0);
assertThat(headAfterFirstSubmit.getParent(1).getShortMessage()).isEqualTo(
change.getCommit().getShortMessage());
assertThat(headAfterFirstSubmit.getParent(0).getShortMessage()).isEqualTo(
initialHead.getShortMessage());
assertThat(headAfterFirstSubmit.getParent(0).getId()).isEqualTo(
initialHead.getId());
assertThat(headAfterFirstSubmit.getParent(1).getShortMessage())
.isEqualTo(change.getCommit().getShortMessage());
assertThat(headAfterFirstSubmit.getParent(0).getShortMessage())
.isEqualTo(initialHead.getShortMessage());
assertThat(headAfterFirstSubmit.getParent(0).getId()).isEqualTo(initialHead.getId());
// Submit three changes at the same time
PushOneCommit.Result change2 = createChange("Change 2", "c", "c");
@ -79,21 +77,24 @@ public class SubmitByMergeAlwaysIT extends AbstractSubmitByMerge {
// The remote head should now be a merge of the new head after
// the previous submit, and "Change 4".
RevCommit headAfterSecondSubmit = getRemoteLog().get(0);
assertThat(headAfterSecondSubmit.getParent(1).getShortMessage()).isEqualTo(
change4.getCommit().getShortMessage());
assertThat(headAfterSecondSubmit.getParent(0).getShortMessage()).isEqualTo(
headAfterFirstSubmit.getShortMessage());
assertThat(headAfterSecondSubmit.getParent(0).getId()).isEqualTo(
headAfterFirstSubmit.getId());
assertThat(headAfterSecondSubmit.getParent(1).getShortMessage())
.isEqualTo(change4.getCommit().getShortMessage());
assertThat(headAfterSecondSubmit.getParent(0).getShortMessage())
.isEqualTo(headAfterFirstSubmit.getShortMessage());
assertThat(headAfterSecondSubmit.getParent(0).getId()).isEqualTo(headAfterFirstSubmit.getId());
assertPersonEquals(admin.getIdent(), headAfterSecondSubmit.getAuthorIdent());
assertPersonEquals(serverIdent.get(),
headAfterSecondSubmit.getCommitterIdent());
assertPersonEquals(serverIdent.get(), headAfterSecondSubmit.getCommitterIdent());
assertRefUpdatedEvents(initialHead, headAfterFirstSubmit,
headAfterFirstSubmit, headAfterSecondSubmit);
assertChangeMergedEvents(change.getChangeId(), headAfterFirstSubmit.name(),
change2.getChangeId(), headAfterSecondSubmit.name(),
change3.getChangeId(), headAfterSecondSubmit.name(),
change4.getChangeId(), headAfterSecondSubmit.name());
assertRefUpdatedEvents(
initialHead, headAfterFirstSubmit, headAfterFirstSubmit, headAfterSecondSubmit);
assertChangeMergedEvents(
change.getChangeId(),
headAfterFirstSubmit.name(),
change2.getChangeId(),
headAfterSecondSubmit.name(),
change3.getChangeId(),
headAfterSecondSubmit.name(),
change4.getChangeId(),
headAfterSecondSubmit.name());
}
}

View File

@ -29,16 +29,6 @@ import com.google.gerrit.extensions.restapi.BinaryResult;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Project;
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.transport.RefSpec;
import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@ -47,6 +37,14 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.transport.RefSpec;
import org.junit.Test;
public class SubmitByMergeIfNecessaryIT extends AbstractSubmitByMerge {
@ -90,10 +88,9 @@ public class SubmitByMergeIfNecessaryIT extends AbstractSubmitByMerge {
submit(change2.getChangeId());
RevCommit headAfterFirstSubmit = getRemoteLog().get(0);
assertThat(headAfterFirstSubmit.getShortMessage()).isEqualTo(
change2.getCommit().getShortMessage());
assertThat(headAfterFirstSubmit.getParent(0).getId()).isEqualTo(
initialHead.getId());
assertThat(headAfterFirstSubmit.getShortMessage())
.isEqualTo(change2.getCommit().getShortMessage());
assertThat(headAfterFirstSubmit.getParent(0).getId()).isEqualTo(initialHead.getId());
assertPersonEquals(admin.getIdent(), headAfterFirstSubmit.getAuthorIdent());
assertPersonEquals(admin.getIdent(), headAfterFirstSubmit.getCommitterIdent());
@ -103,10 +100,10 @@ public class SubmitByMergeIfNecessaryIT extends AbstractSubmitByMerge {
submit(change5.getChangeId());
RevCommit headAfterSecondSubmit = getRemoteLog().get(0);
assertThat(headAfterSecondSubmit.getParent(1).getShortMessage()).isEqualTo(
change5.getCommit().getShortMessage());
assertThat(headAfterSecondSubmit.getParent(0).getShortMessage()).isEqualTo(
change2.getCommit().getShortMessage());
assertThat(headAfterSecondSubmit.getParent(1).getShortMessage())
.isEqualTo(change5.getCommit().getShortMessage());
assertThat(headAfterSecondSubmit.getParent(0).getShortMessage())
.isEqualTo(change2.getCommit().getShortMessage());
assertPersonEquals(admin.getIdent(), headAfterSecondSubmit.getAuthorIdent());
assertPersonEquals(serverIdent.get(), headAfterSecondSubmit.getCommitterIdent());
@ -116,12 +113,17 @@ public class SubmitByMergeIfNecessaryIT extends AbstractSubmitByMerge {
// The two submit operations should have resulted in two ref-update events
// and three change-merged events.
assertRefUpdatedEvents(initialHead, headAfterFirstSubmit,
headAfterFirstSubmit, headAfterSecondSubmit);
assertChangeMergedEvents(change2.getChangeId(), headAfterFirstSubmit.name(),
change3.getChangeId(), headAfterSecondSubmit.name(),
change4.getChangeId(), headAfterSecondSubmit.name(),
change5.getChangeId(), headAfterSecondSubmit.name());
assertRefUpdatedEvents(
initialHead, headAfterFirstSubmit, headAfterFirstSubmit, headAfterSecondSubmit);
assertChangeMergedEvents(
change2.getChangeId(),
headAfterFirstSubmit.name(),
change3.getChangeId(),
headAfterSecondSubmit.name(),
change4.getChangeId(),
headAfterSecondSubmit.name(),
change5.getChangeId(),
headAfterSecondSubmit.name());
}
@Test
@ -137,23 +139,31 @@ public class SubmitByMergeIfNecessaryIT extends AbstractSubmitByMerge {
TestRepository<?> repo2 = cloneProject(p2);
TestRepository<?> repo3 = cloneProject(p3);
PushOneCommit.Result change1a = createChange(repo1, "master",
"An ancestor of the change we want to submit",
"a.txt", "1", "dependent-topic");
PushOneCommit.Result change1b = createChange(repo1, "master",
"We're interested in submitting this change",
"a.txt", "2", "topic-to-submit");
PushOneCommit.Result change1a =
createChange(
repo1,
"master",
"An ancestor of the change we want to submit",
"a.txt",
"1",
"dependent-topic");
PushOneCommit.Result change1b =
createChange(
repo1,
"master",
"We're interested in submitting this change",
"a.txt",
"2",
"topic-to-submit");
PushOneCommit.Result change2a = createChange(repo2, "master",
"indirection level 1",
"a.txt", "1", "topic-indirect");
PushOneCommit.Result change2b = createChange(repo2, "master",
"should go in with first change",
"a.txt", "2", "dependent-topic");
PushOneCommit.Result change2a =
createChange(repo2, "master", "indirection level 1", "a.txt", "1", "topic-indirect");
PushOneCommit.Result change2b =
createChange(
repo2, "master", "should go in with first change", "a.txt", "2", "dependent-topic");
PushOneCommit.Result change3 = createChange(repo3, "master",
"indirection level 2",
"a.txt", "1", "topic-indirect");
PushOneCommit.Result change3 =
createChange(repo3, "master", "indirection level 2", "a.txt", "1", "topic-indirect");
approve(change1a.getChangeId());
approve(change2a.getChangeId());
@ -162,43 +172,34 @@ public class SubmitByMergeIfNecessaryIT extends AbstractSubmitByMerge {
// get a preview before submitting:
BinaryResult request = submitPreview(change1b.getChangeId());
Map<Branch.NameKey, RevTree> preview =
fetchFromBundles(request);
Map<Branch.NameKey, RevTree> preview = fetchFromBundles(request);
submit(change1b.getChangeId());
RevCommit tip1 = getRemoteLog(p1, "master").get(0);
RevCommit tip2 = getRemoteLog(p2, "master").get(0);
RevCommit tip3 = getRemoteLog(p3, "master").get(0);
RevCommit tip1 = getRemoteLog(p1, "master").get(0);
RevCommit tip2 = getRemoteLog(p2, "master").get(0);
RevCommit tip3 = getRemoteLog(p3, "master").get(0);
assertThat(tip1.getShortMessage()).isEqualTo(
change1b.getCommit().getShortMessage());
assertThat(tip1.getShortMessage()).isEqualTo(change1b.getCommit().getShortMessage());
if (isSubmitWholeTopicEnabled()) {
assertThat(tip2.getShortMessage()).isEqualTo(
change2b.getCommit().getShortMessage());
assertThat(tip3.getShortMessage()).isEqualTo(
change3.getCommit().getShortMessage());
assertThat(tip2.getShortMessage()).isEqualTo(change2b.getCommit().getShortMessage());
assertThat(tip3.getShortMessage()).isEqualTo(change3.getCommit().getShortMessage());
// check that the preview matched what happened:
assertThat(preview).hasSize(3);
assertThat(preview).containsKey(
new Branch.NameKey(p1, "refs/heads/master"));
assertThat(preview).containsKey(new Branch.NameKey(p1, "refs/heads/master"));
assertRevTrees(p1, preview);
assertThat(preview).containsKey(
new Branch.NameKey(p2, "refs/heads/master"));
assertThat(preview).containsKey(new Branch.NameKey(p2, "refs/heads/master"));
assertRevTrees(p2, preview);
assertThat(preview).containsKey(
new Branch.NameKey(p3, "refs/heads/master"));
assertThat(preview).containsKey(new Branch.NameKey(p3, "refs/heads/master"));
assertRevTrees(p3, preview);
} else {
assertThat(tip2.getShortMessage()).isEqualTo(
initialHead2.getShortMessage());
assertThat(tip3.getShortMessage()).isEqualTo(
initialHead3.getShortMessage());
assertThat(tip2.getShortMessage()).isEqualTo(initialHead2.getShortMessage());
assertThat(tip3.getShortMessage()).isEqualTo(initialHead3.getShortMessage());
assertThat(preview).hasSize(1);
assertThat(preview.get(new Branch.NameKey(p1, "refs/heads/master"))).isNotNull();
}
@ -218,34 +219,41 @@ public class SubmitByMergeIfNecessaryIT extends AbstractSubmitByMerge {
RevCommit initialHead2 = getRemoteHead(p2, "master");
RevCommit initialHead3 = getRemoteHead(p3, "master");
PushOneCommit.Result change1a = createChange(repo1, "master",
"An ancestor of the change we want to submit",
"a.txt", "1", "dependent-topic");
PushOneCommit.Result change1b = createChange(repo1, "master",
"we're interested to submit this change",
"a.txt", "2", "topic-to-submit");
PushOneCommit.Result change1a =
createChange(
repo1,
"master",
"An ancestor of the change we want to submit",
"a.txt",
"1",
"dependent-topic");
PushOneCommit.Result change1b =
createChange(
repo1,
"master",
"we're interested to submit this change",
"a.txt",
"2",
"topic-to-submit");
PushOneCommit.Result change2a = createChange(repo2, "master",
"indirection level 2a",
"a.txt", "1", "topic-indirect");
PushOneCommit.Result change2b = createChange(repo2, "master",
"should go in with first change",
"a.txt", "2", "dependent-topic");
PushOneCommit.Result change2a =
createChange(repo2, "master", "indirection level 2a", "a.txt", "1", "topic-indirect");
PushOneCommit.Result change2b =
createChange(
repo2, "master", "should go in with first change", "a.txt", "2", "dependent-topic");
PushOneCommit.Result change3 = createChange(repo3, "master",
"indirection level 2b",
"a.txt", "1", "topic-indirect");
PushOneCommit.Result change3 =
createChange(repo3, "master", "indirection level 2b", "a.txt", "1", "topic-indirect");
// Create a merge conflict for change3 which is only indirectly related
// via topics.
repo3.reset(initialHead3);
PushOneCommit.Result change3Conflict = createChange(repo3, "master",
"conflicting change",
"a.txt", "2\n2", "conflicting-topic");
PushOneCommit.Result change3Conflict =
createChange(repo3, "master", "conflicting change", "a.txt", "2\n2", "conflicting-topic");
submit(change3Conflict.getChangeId());
RevCommit tipConflict = getRemoteLog(p3, "master").get(0);
assertThat(tipConflict.getShortMessage()).isEqualTo(
change3Conflict.getCommit().getShortMessage());
assertThat(tipConflict.getShortMessage())
.isEqualTo(change3Conflict.getCommit().getShortMessage());
approve(change1a.getChangeId());
approve(change2a.getChangeId());
@ -254,10 +262,12 @@ public class SubmitByMergeIfNecessaryIT extends AbstractSubmitByMerge {
if (isSubmitWholeTopicEnabled()) {
String msg =
"Failed to submit 5 changes due to the following problems:\n" +
"Change " + change3.getChange().getId() + ": Change could not be " +
"merged due to a path conflict. Please rebase the change locally " +
"and upload the rebased commit for review.";
"Failed to submit 5 changes due to the following problems:\n"
+ "Change "
+ change3.getChange().getId()
+ ": Change could not be "
+ "merged due to a path conflict. Please rebase the change locally "
+ "and upload the rebased commit for review.";
// Get a preview before submitting:
try {
@ -274,27 +284,21 @@ public class SubmitByMergeIfNecessaryIT extends AbstractSubmitByMerge {
submit(change1b.getChangeId());
}
RevCommit tip1 = getRemoteLog(p1, "master").get(0);
RevCommit tip2 = getRemoteLog(p2, "master").get(0);
RevCommit tip3 = getRemoteLog(p3, "master").get(0);
RevCommit tip1 = getRemoteLog(p1, "master").get(0);
RevCommit tip2 = getRemoteLog(p2, "master").get(0);
RevCommit tip3 = getRemoteLog(p3, "master").get(0);
if (isSubmitWholeTopicEnabled()) {
assertThat(tip1.getShortMessage()).isEqualTo(
initialHead1.getShortMessage());
assertThat(tip2.getShortMessage()).isEqualTo(
initialHead2.getShortMessage());
assertThat(tip3.getShortMessage()).isEqualTo(
change3Conflict.getCommit().getShortMessage());
assertThat(tip1.getShortMessage()).isEqualTo(initialHead1.getShortMessage());
assertThat(tip2.getShortMessage()).isEqualTo(initialHead2.getShortMessage());
assertThat(tip3.getShortMessage()).isEqualTo(change3Conflict.getCommit().getShortMessage());
assertNoSubmitter(change1a.getChangeId(), 1);
assertNoSubmitter(change2a.getChangeId(), 1);
assertNoSubmitter(change2b.getChangeId(), 1);
assertNoSubmitter(change3.getChangeId(), 1);
} else {
assertThat(tip1.getShortMessage()).isEqualTo(
change1b.getCommit().getShortMessage());
assertThat(tip2.getShortMessage()).isEqualTo(
initialHead2.getShortMessage());
assertThat(tip3.getShortMessage()).isEqualTo(
change3Conflict.getCommit().getShortMessage());
assertThat(tip1.getShortMessage()).isEqualTo(change1b.getCommit().getShortMessage());
assertThat(tip2.getShortMessage()).isEqualTo(initialHead2.getShortMessage());
assertThat(tip3.getShortMessage()).isEqualTo(change3Conflict.getCommit().getShortMessage());
assertNoSubmitter(change2a.getChangeId(), 1);
assertNoSubmitter(change2b.getChangeId(), 1);
assertNoSubmitter(change3.getChangeId(), 1);
@ -305,105 +309,112 @@ public class SubmitByMergeIfNecessaryIT extends AbstractSubmitByMerge {
public void submitWithMergedAncestorsOnOtherBranch() throws Exception {
RevCommit initialHead = getRemoteHead();
PushOneCommit.Result change1 = createChange(testRepo, "master",
"base commit",
"a.txt", "1", "");
PushOneCommit.Result change1 =
createChange(testRepo, "master", "base commit", "a.txt", "1", "");
submit(change1.getChangeId());
RevCommit headAfterFirstSubmit = getRemoteHead();
gApi.projects()
.name(project.get())
.branch("branch")
.create(new BranchInput());
gApi.projects().name(project.get()).branch("branch").create(new BranchInput());
PushOneCommit.Result change2 = createChange(testRepo, "master",
"We want to commit this to master first",
"a.txt", "2", "");
PushOneCommit.Result change2 =
createChange(
testRepo, "master", "We want to commit this to master first", "a.txt", "2", "");
submit(change2.getChangeId());
RevCommit headAfterSecondSubmit = getRemoteLog(project, "master").get(0);
assertThat(headAfterSecondSubmit.getShortMessage()).isEqualTo(
change2.getCommit().getShortMessage());
assertThat(headAfterSecondSubmit.getShortMessage())
.isEqualTo(change2.getCommit().getShortMessage());
RevCommit tip2 = getRemoteLog(project, "branch").get(0);
assertThat(tip2.getShortMessage()).isEqualTo(
change1.getCommit().getShortMessage());
assertThat(tip2.getShortMessage()).isEqualTo(change1.getCommit().getShortMessage());
PushOneCommit.Result change3 = createChange(testRepo, "branch",
"This commit is based on master, which includes change2, "
+ "but is targeted at branch, which doesn't include it.",
"a.txt", "3", "");
PushOneCommit.Result change3 =
createChange(
testRepo,
"branch",
"This commit is based on master, which includes change2, "
+ "but is targeted at branch, which doesn't include it.",
"a.txt",
"3",
"");
submit(change3.getChangeId());
List<RevCommit> log3 = getRemoteLog(project, "branch");
assertThat(log3.get(0).getShortMessage()).isEqualTo(
change3.getCommit().getShortMessage());
assertThat(log3.get(1).getShortMessage()).isEqualTo(
change2.getCommit().getShortMessage());
assertThat(log3.get(0).getShortMessage()).isEqualTo(change3.getCommit().getShortMessage());
assertThat(log3.get(1).getShortMessage()).isEqualTo(change2.getCommit().getShortMessage());
assertRefUpdatedEvents(initialHead, headAfterFirstSubmit,
headAfterFirstSubmit, headAfterSecondSubmit);
assertChangeMergedEvents(change1.getChangeId(), headAfterFirstSubmit.name(),
change2.getChangeId(), headAfterSecondSubmit.name());
assertRefUpdatedEvents(
initialHead, headAfterFirstSubmit, headAfterFirstSubmit, headAfterSecondSubmit);
assertChangeMergedEvents(
change1.getChangeId(),
headAfterFirstSubmit.name(),
change2.getChangeId(),
headAfterSecondSubmit.name());
}
@Test
public void submitWithOpenAncestorsOnOtherBranch() throws Exception {
RevCommit initialHead = getRemoteHead();
PushOneCommit.Result change1 = createChange(testRepo, "master",
"base commit",
"a.txt", "1", "");
PushOneCommit.Result change1 =
createChange(testRepo, "master", "base commit", "a.txt", "1", "");
submit(change1.getChangeId());
RevCommit headAfterFirstSubmit = getRemoteHead();
gApi.projects()
.name(project.get())
.branch("branch")
.create(new BranchInput());
gApi.projects().name(project.get()).branch("branch").create(new BranchInput());
PushOneCommit.Result change2 = createChange(testRepo, "master",
"We want to commit this to master first",
"a.txt", "2", "");
PushOneCommit.Result change2 =
createChange(
testRepo, "master", "We want to commit this to master first", "a.txt", "2", "");
approve(change2.getChangeId());
RevCommit tip1 = getRemoteLog(project, "master").get(0);
assertThat(tip1.getShortMessage()).isEqualTo(
change1.getCommit().getShortMessage());
assertThat(tip1.getShortMessage()).isEqualTo(change1.getCommit().getShortMessage());
RevCommit tip2 = getRemoteLog(project, "branch").get(0);
assertThat(tip2.getShortMessage()).isEqualTo(
change1.getCommit().getShortMessage());
assertThat(tip2.getShortMessage()).isEqualTo(change1.getCommit().getShortMessage());
PushOneCommit.Result change3a = createChange(testRepo, "branch",
"This commit is based on change2 pending for master, "
+ "but is targeted itself at branch, which doesn't include it.",
"a.txt", "3", "a-topic-here");
PushOneCommit.Result change3a =
createChange(
testRepo,
"branch",
"This commit is based on change2 pending for master, "
+ "but is targeted itself at branch, which doesn't include it.",
"a.txt",
"3",
"a-topic-here");
Project.NameKey p3 = createProject("project-related-to-change3");
TestRepository<?> repo3 = cloneProject(p3);
RevCommit repo3Head = getRemoteHead(p3, "master");
PushOneCommit.Result change3b = createChange(repo3, "master",
"some accompanying changes for change3a in another repo "
+ "tied together via topic",
"a.txt", "1", "a-topic-here");
PushOneCommit.Result change3b =
createChange(
repo3,
"master",
"some accompanying changes for change3a in another repo " + "tied together via topic",
"a.txt",
"1",
"a-topic-here");
approve(change3b.getChangeId());
String cnt = isSubmitWholeTopicEnabled() ? "2 changes" : "1 change";
submitWithConflict(change3a.getChangeId(),
"Failed to submit " + cnt + " due to the following problems:\n"
+ "Change " + change3a.getChange().getId() + ": depends on change that"
+ " was not submitted");
submitWithConflict(
change3a.getChangeId(),
"Failed to submit "
+ cnt
+ " due to the following problems:\n"
+ "Change "
+ change3a.getChange().getId()
+ ": depends on change that"
+ " was not submitted");
RevCommit tipbranch = getRemoteLog(project, "branch").get(0);
assertThat(tipbranch.getShortMessage()).isEqualTo(
change1.getCommit().getShortMessage());
assertThat(tipbranch.getShortMessage()).isEqualTo(change1.getCommit().getShortMessage());
RevCommit tipmaster = getRemoteLog(p3, "master").get(0);
assertThat(tipmaster.getShortMessage()).isEqualTo(
repo3Head.getShortMessage());
assertThat(tipmaster.getShortMessage()).isEqualTo(repo3Head.getShortMessage());
assertRefUpdatedEvents(initialHead, headAfterFirstSubmit);
assertChangeMergedEvents(change1.getChangeId(), headAfterFirstSubmit.name());
@ -417,28 +428,22 @@ public class SubmitByMergeIfNecessaryIT extends AbstractSubmitByMerge {
// Then we create a change to be applied to master, which is
// then cherry picked back to stable. The stable branch will
// be merged up into master again.
gApi.projects()
.name(project.get())
.branch("stable")
.create(new BranchInput());
gApi.projects().name(project.get()).branch("stable").create(new BranchInput());
// Push a change to master
PushOneCommit push =
pushFactory.create(db, user.getIdent(), testRepo,
"small fix", "a.txt", "2");
pushFactory.create(db, user.getIdent(), testRepo, "small fix", "a.txt", "2");
PushOneCommit.Result change = push.to("refs/for/master");
submit(change.getChangeId());
RevCommit headAfterFirstSubmit = getRemoteLog(project, "master").get(0);
assertThat(headAfterFirstSubmit.getShortMessage()).isEqualTo(
change.getCommit().getShortMessage());
assertThat(headAfterFirstSubmit.getShortMessage())
.isEqualTo(change.getCommit().getShortMessage());
// Now cherry pick to stable
CherryPickInput in = new CherryPickInput();
in.destination = "stable";
in.message = "This goes to stable as well\n"
+ headAfterFirstSubmit.getFullMessage();
ChangeApi orig = gApi.changes()
.id(change.getChangeId());
in.message = "This goes to stable as well\n" + headAfterFirstSubmit.getFullMessage();
ChangeApi orig = gApi.changes().id(change.getChangeId());
String cherryId = orig.current().cherryPick(in).id();
gApi.changes().id(cherryId).current().review(ReviewInput.approve());
gApi.changes().id(cherryId).current().submit();
@ -447,62 +452,47 @@ public class SubmitByMergeIfNecessaryIT extends AbstractSubmitByMerge {
RevCommit stable = getRemoteHead(project, "stable");
RevCommit master = getRemoteHead(project, "master");
testRepo.git().fetch().call();
testRepo.git()
.branchCreate()
.setName("stable")
.setStartPoint(stable)
.call();
testRepo.git()
.branchCreate()
.setName("master")
.setStartPoint(master)
.call();
testRepo.git().branchCreate().setName("stable").setStartPoint(stable).call();
testRepo.git().branchCreate().setName("master").setStartPoint(master).call();
RevCommit merge = testRepo.commit()
.parent(master)
.parent(stable)
.message("Merge stable into master")
.insertChangeId()
.create();
RevCommit merge =
testRepo
.commit()
.parent(master)
.parent(stable)
.message("Merge stable into master")
.insertChangeId()
.create();
testRepo.branch("refs/heads/master").update(merge);
testRepo.git().push()
.setRefSpecs(new RefSpec("refs/heads/master:refs/for/master"))
.call();
testRepo.git().push().setRefSpecs(new RefSpec("refs/heads/master:refs/for/master")).call();
String changeId = GitUtil.getChangeId(testRepo, merge).get();
approve(changeId);
submit(changeId);
RevCommit headAfterSecondSubmit = getRemoteLog(project, "master").get(0);
assertThat(headAfterSecondSubmit.getShortMessage())
.isEqualTo(merge.getShortMessage());
assertThat(headAfterSecondSubmit.getShortMessage()).isEqualTo(merge.getShortMessage());
assertRefUpdatedEvents(initialHead, headAfterFirstSubmit,
headAfterFirstSubmit, headAfterSecondSubmit);
assertRefUpdatedEvents(
initialHead, headAfterFirstSubmit, headAfterFirstSubmit, headAfterSecondSubmit);
assertChangeMergedEvents(
change.getChangeId(), headAfterFirstSubmit.name(),
changeId, headAfterSecondSubmit.name());
change.getChangeId(), headAfterFirstSubmit.name(), changeId, headAfterSecondSubmit.name());
}
@Test
public void openChangeForTargetBranchPreventsMerge() throws Exception {
gApi.projects()
.name(project.get())
.branch("stable")
.create(new BranchInput());
gApi.projects().name(project.get()).branch("stable").create(new BranchInput());
// Propose a change for master, but leave it open for master!
PushOneCommit change =
pushFactory.create(db, user.getIdent(), testRepo,
"small fix", "a.txt", "2");
pushFactory.create(db, user.getIdent(), testRepo, "small fix", "a.txt", "2");
PushOneCommit.Result change2result = change.to("refs/for/master");
// Now cherry pick to stable
CherryPickInput in = new CherryPickInput();
in.destination = "stable";
in.message = "it goes to stable branch";
ChangeApi orig = gApi.changes()
.id(change2result.getChangeId());
ChangeApi orig = gApi.changes().id(change2result.getChangeId());
ChangeApi cherry = orig.current().cherryPick(in);
cherry.current().review(ReviewInput.approve());
cherry.current().submit();
@ -510,12 +500,13 @@ public class SubmitByMergeIfNecessaryIT extends AbstractSubmitByMerge {
// Create a commit locally
testRepo.git().fetch().setRefSpecs(new RefSpec("refs/heads/stable")).call();
PushOneCommit.Result change3 = createChange(testRepo, "stable",
"test","a.txt", "3", "");
submitWithConflict(change3.getChangeId(),
"Failed to submit 1 change due to the following problems:\n" +
"Change " + change3.getPatchSetId().getParentKey().get() +
": depends on change that was not submitted");
PushOneCommit.Result change3 = createChange(testRepo, "stable", "test", "a.txt", "3", "");
submitWithConflict(
change3.getChangeId(),
"Failed to submit 1 change due to the following problems:\n"
+ "Change "
+ change3.getPatchSetId().getParentKey().get()
+ ": depends on change that was not submitted");
assertRefUpdatedEvents();
assertChangeMergedEvents();
@ -534,9 +525,11 @@ public class SubmitByMergeIfNecessaryIT extends AbstractSubmitByMerge {
gApi.changes().id(draftResult.getChangeId()).delete();
// approve and submit the change
submitWithConflict(changeResult.getChangeId(),
submitWithConflict(
changeResult.getChangeId(),
"Failed to submit 1 change due to the following problems:\n"
+ "Change " + changeResult.getChange().getId()
+ "Change "
+ changeResult.getChange().getId()
+ ": depends on change that was not submitted");
assertRefUpdatedEvents();
@ -548,8 +541,7 @@ public class SubmitByMergeIfNecessaryIT extends AbstractSubmitByMerge {
Project.NameKey p1 = createProject("project-name");
TestRepository<?> repo1 = cloneProject(p1);
PushOneCommit.Result change1 = createChange(repo1, "master",
"test", "a.txt", "1", "topic");
PushOneCommit.Result change1 = createChange(repo1, "master", "test", "a.txt", "1", "topic");
approve(change1.getChangeId());
// get a preview before submitting:
@ -562,10 +554,10 @@ public class SubmitByMergeIfNecessaryIT extends AbstractSubmitByMerge {
InputStream is = new GZIPInputStream(new FileInputStream(tempfile));
List<String> untarredFiles = new ArrayList<>();
try (TarArchiveInputStream tarInputStream = (TarArchiveInputStream)
new ArchiveStreamFactory().createArchiveInputStream("tar", is)) {
try (TarArchiveInputStream tarInputStream =
(TarArchiveInputStream) new ArchiveStreamFactory().createArchiveInputStream("tar", is)) {
TarArchiveEntry entry = null;
while ((entry = (TarArchiveEntry)tarInputStream.getNextEntry()) != null) {
while ((entry = (TarArchiveEntry) tarInputStream.getNextEntry()) != null) {
untarredFiles.add(entry.getName());
}
}

View File

@ -27,16 +27,13 @@ import com.google.gerrit.extensions.registration.RegistrationHandle;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.server.git.ChangeMessageModifier;
import com.google.inject.Inject;
import java.util.List;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Test;
import java.util.List;
public class SubmitByRebaseAlwaysIT extends AbstractSubmitByRebase {
@Inject
private DynamicSet<ChangeMessageModifier> changeMessageModifiers;
@Inject private DynamicSet<ChangeMessageModifier> changeMessageModifiers;
@Override
protected SubmitType getSubmitType() {
@ -69,12 +66,8 @@ public class SubmitByRebaseAlwaysIT extends AbstractSubmitByRebase {
PushOneCommit.Result change1 = createChange();
PushOneCommit.Result change2 = createChange();
assertThat(
getCurrentCommit(change1).getFooterLines(FooterConstants.REVIEWED_BY))
.isEmpty();
assertThat(
getCurrentCommit(change2).getFooterLines(FooterConstants.REVIEWED_BY))
.isEmpty();
assertThat(getCurrentCommit(change1).getFooterLines(FooterConstants.REVIEWED_BY)).isEmpty();
assertThat(getCurrentCommit(change2).getFooterLines(FooterConstants.REVIEWED_BY)).isEmpty();
// change1 is a fast-forward, but should be rebased in cherry pick style
// anyway, making change2 not a fast-forward, requiring a rebase.
@ -92,17 +85,21 @@ public class SubmitByRebaseAlwaysIT extends AbstractSubmitByRebase {
PushOneCommit.Result change2 = createChange();
RegistrationHandle handle =
changeMessageModifiers.add(new ChangeMessageModifier() {
@Override
public String onSubmit(String newCommitMessage, RevCommit original,
RevCommit mergeTip, Branch.NameKey destination) {
List<String> custom = mergeTip.getFooterLines("Custom");
if (!custom.isEmpty()) {
newCommitMessage += "Custom-Parent: " + custom.get(0) + "\n";
}
return newCommitMessage + "Custom: " + destination.get();
}
});
changeMessageModifiers.add(
new ChangeMessageModifier() {
@Override
public String onSubmit(
String newCommitMessage,
RevCommit original,
RevCommit mergeTip,
Branch.NameKey destination) {
List<String> custom = mergeTip.getFooterLines("Custom");
if (!custom.isEmpty()) {
newCommitMessage += "Custom-Parent: " + custom.get(0) + "\n";
}
return newCommitMessage + "Custom: " + destination.get();
}
});
try {
// change1 is a fast-forward, but should be rebased in cherry pick style
// anyway, making change2 not a fast-forward, requiring a rebase.
@ -120,20 +117,17 @@ public class SubmitByRebaseAlwaysIT extends AbstractSubmitByRebase {
.containsExactly("refs/heads/master");
}
private void assertLatestRevisionHasFooters(PushOneCommit.Result change)
throws Exception {
private void assertLatestRevisionHasFooters(PushOneCommit.Result change) throws Exception {
RevCommit c = getCurrentCommit(change);
assertThat(c.getFooterLines(FooterConstants.CHANGE_ID)).isNotEmpty();
assertThat(c.getFooterLines(FooterConstants.REVIEWED_BY)).isNotEmpty();
assertThat(c.getFooterLines(FooterConstants.REVIEWED_ON)).isNotEmpty();
}
private RevCommit getCurrentCommit(PushOneCommit.Result change)
throws Exception {
private RevCommit getCurrentCommit(PushOneCommit.Result change) throws Exception {
testRepo.git().fetch().setRemote("origin").call();
ChangeInfo info = get(change.getChangeId());
RevCommit c = testRepo.getRevWalk()
.parseCommit(ObjectId.fromString(info.currentRevision));
RevCommit c = testRepo.getRevWalk().parseCommit(ObjectId.fromString(info.currentRevision));
testRepo.getRevWalk().parseBody(c);
return c;
}

View File

@ -20,7 +20,6 @@ import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.TestProjectInput;
import com.google.gerrit.extensions.client.InheritableBoolean;
import com.google.gerrit.extensions.client.SubmitType;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Test;
@ -53,33 +52,37 @@ public class SubmitByRebaseIfNecessaryIT extends AbstractSubmitByRebase {
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
public void submitWithContentMerge() throws Exception {
RevCommit initialHead = getRemoteHead();
PushOneCommit.Result change =
createChange("Change 1", "a.txt", "aaa\nbbb\nccc\n");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "aaa\nbbb\nccc\n");
submit(change.getChangeId());
RevCommit headAfterFirstSubmit = getRemoteHead();
PushOneCommit.Result change2 =
createChange("Change 2", "a.txt", "aaa\nbbb\nccc\nddd\n");
PushOneCommit.Result change2 = createChange("Change 2", "a.txt", "aaa\nbbb\nccc\nddd\n");
submit(change2.getChangeId());
RevCommit headAfterSecondSubmit = getRemoteHead();
testRepo.reset(change.getCommit());
PushOneCommit.Result change3 =
createChange("Change 3", "a.txt", "bbb\nccc\n");
PushOneCommit.Result change3 = createChange("Change 3", "a.txt", "bbb\nccc\n");
submit(change3.getChangeId());
assertRebase(testRepo, true);
RevCommit headAfterThirdSubmit = getRemoteHead();
assertThat(headAfterThirdSubmit.getParent(0))
.isEqualTo(headAfterSecondSubmit);
assertThat(headAfterThirdSubmit.getParent(0)).isEqualTo(headAfterSecondSubmit);
assertApproved(change3.getChangeId());
assertCurrentRevision(change3.getChangeId(), 2, headAfterThirdSubmit);
assertSubmitter(change3.getChangeId(), 1);
assertSubmitter(change3.getChangeId(), 2);
assertRefUpdatedEvents(initialHead, headAfterFirstSubmit,
headAfterFirstSubmit, headAfterSecondSubmit,
headAfterSecondSubmit, headAfterThirdSubmit);
assertChangeMergedEvents(change.getChangeId(), headAfterFirstSubmit.name(),
change2.getChangeId(), headAfterSecondSubmit.name(),
change3.getChangeId(), headAfterThirdSubmit.name());
assertRefUpdatedEvents(
initialHead,
headAfterFirstSubmit,
headAfterFirstSubmit,
headAfterSecondSubmit,
headAfterSecondSubmit,
headAfterThirdSubmit);
assertChangeMergedEvents(
change.getChangeId(),
headAfterFirstSubmit.name(),
change2.getChangeId(),
headAfterSecondSubmit.name(),
change3.getChangeId(),
headAfterThirdSubmit.name());
}
}

View File

@ -31,7 +31,10 @@ import com.google.gerrit.testutil.ConfigSuite;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
@ -40,18 +43,11 @@ import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@NoHttpd
public class SubmitResolvingMergeCommitIT extends AbstractDaemonTest {
@Inject
private Provider<MergeSuperSet> mergeSuperSet;
@Inject private Provider<MergeSuperSet> mergeSuperSet;
@Inject
private Submit submit;
@Inject private Submit submit;
@ConfigSuite.Default
public static Config submitWholeTopicEnabled() {
@ -71,15 +67,15 @@ public class SubmitResolvingMergeCommitIT extends AbstractDaemonTest {
*/
PushOneCommit.Result a = createChange("A");
PushOneCommit.Result b = createChange("B", "new.txt", "No conflict line",
ImmutableList.of(a.getCommit()));
PushOneCommit.Result b =
createChange("B", "new.txt", "No conflict line", ImmutableList.of(a.getCommit()));
PushOneCommit.Result c = createChange("C", ImmutableList.of(b.getCommit()));
PushOneCommit.Result d = createChange("D", ImmutableList.of(c.getCommit()));
PushOneCommit.Result e = createChange("E", ImmutableList.of(a.getCommit()));
PushOneCommit.Result f = createChange("F", ImmutableList.of(e.getCommit()));
PushOneCommit.Result g = createChange("G", "new.txt", "Conflicting line",
ImmutableList.of(f.getCommit()));
PushOneCommit.Result g =
createChange("G", "new.txt", "Conflicting line", ImmutableList.of(f.getCommit()));
PushOneCommit.Result h = createChange("H", ImmutableList.of(g.getCommit()));
approve(a.getChangeId());
@ -98,8 +94,9 @@ public class SubmitResolvingMergeCommitIT extends AbstractDaemonTest {
assertNotMergeable(g.getChange());
assertNotMergeable(h.getChange());
PushOneCommit.Result m = createChange("M", "new.txt", "Resolved conflict",
ImmutableList.of(d.getCommit(), h.getCommit()));
PushOneCommit.Result m =
createChange(
"M", "new.txt", "Resolved conflict", ImmutableList.of(d.getCommit(), h.getCommit()));
approve(m.getChangeId());
assertChangeSetMergeable(m.getChange(), true);
@ -127,17 +124,18 @@ public class SubmitResolvingMergeCommitIT extends AbstractDaemonTest {
*/
PushOneCommit.Result a = createChange("A");
PushOneCommit.Result b = createChange("B", "new.txt", "No conflict line",
ImmutableList.of(a.getCommit()));
PushOneCommit.Result c = createChange("C", "new.txt", "No conflict line #2",
ImmutableList.of(b.getCommit()));
PushOneCommit.Result b =
createChange("B", "new.txt", "No conflict line", ImmutableList.of(a.getCommit()));
PushOneCommit.Result c =
createChange("C", "new.txt", "No conflict line #2", ImmutableList.of(b.getCommit()));
PushOneCommit.Result d = createChange("D", ImmutableList.of(c.getCommit()));
PushOneCommit.Result e = createChange("E", "new.txt", "Conflicting line",
ImmutableList.of(a.getCommit()));
PushOneCommit.Result f = createChange("F", "new.txt", "Resolved conflict",
ImmutableList.of(b.getCommit(), e.getCommit()));
PushOneCommit.Result g = createChange("G", "new.txt", "Conflicting line #2",
ImmutableList.of(f.getCommit()));
PushOneCommit.Result e =
createChange("E", "new.txt", "Conflicting line", ImmutableList.of(a.getCommit()));
PushOneCommit.Result f =
createChange(
"F", "new.txt", "Resolved conflict", ImmutableList.of(b.getCommit(), e.getCommit()));
PushOneCommit.Result g =
createChange("G", "new.txt", "Conflicting line #2", ImmutableList.of(f.getCommit()));
assertMergeable(e.getChange());
@ -188,37 +186,50 @@ public class SubmitResolvingMergeCommitIT extends AbstractDaemonTest {
String project2Name = name("Project2");
gApi.projects().create(project1Name);
gApi.projects().create(project2Name);
TestRepository<InMemoryRepository> project1 =
cloneProject(new Project.NameKey(project1Name));
TestRepository<InMemoryRepository> project2 =
cloneProject(new Project.NameKey(project2Name));
TestRepository<InMemoryRepository> project1 = cloneProject(new Project.NameKey(project1Name));
TestRepository<InMemoryRepository> project2 = cloneProject(new Project.NameKey(project2Name));
PushOneCommit.Result a = createChange(project1, "A");
PushOneCommit.Result b = createChange(project1, "B", "new.txt",
"No conflict line", ImmutableList.of(a.getCommit()));
PushOneCommit.Result c = createChange(project1, "C", "new.txt",
"No conflict line #2", ImmutableList.of(b.getCommit()));
PushOneCommit.Result b =
createChange(project1, "B", "new.txt", "No conflict line", ImmutableList.of(a.getCommit()));
PushOneCommit.Result c =
createChange(
project1, "C", "new.txt", "No conflict line #2", ImmutableList.of(b.getCommit()));
approve(a.getChangeId());
approve(b.getChangeId());
approve(c.getChangeId());
submit(c.getChangeId());
PushOneCommit.Result e = createChange(project1, "E", "new.txt",
"Conflicting line", ImmutableList.of(a.getCommit()));
PushOneCommit.Result f = createChange(project1, "F", "new.txt",
"Resolved conflict", ImmutableList.of(b.getCommit(), e.getCommit()));
PushOneCommit.Result g = createChange(project1, "G", "new.txt",
"Conflicting line #2", ImmutableList.of(f.getCommit()),
"refs/for/master/" + name("topic1"));
PushOneCommit.Result e =
createChange(project1, "E", "new.txt", "Conflicting line", ImmutableList.of(a.getCommit()));
PushOneCommit.Result f =
createChange(
project1,
"F",
"new.txt",
"Resolved conflict",
ImmutableList.of(b.getCommit(), e.getCommit()));
PushOneCommit.Result g =
createChange(
project1,
"G",
"new.txt",
"Conflicting line #2",
ImmutableList.of(f.getCommit()),
"refs/for/master/" + name("topic1"));
PushOneCommit.Result h = createChange(project2, "H");
PushOneCommit.Result i = createChange(project2, "I", "new.txt",
"No conflict line", ImmutableList.of(h.getCommit()));
PushOneCommit.Result j = createChange(project2, "J", "new.txt",
"Conflicting line", ImmutableList.of(h.getCommit()));
PushOneCommit.Result i =
createChange(project2, "I", "new.txt", "No conflict line", ImmutableList.of(h.getCommit()));
PushOneCommit.Result j =
createChange(project2, "J", "new.txt", "Conflicting line", ImmutableList.of(h.getCommit()));
PushOneCommit.Result k =
createChange(project2, "K", "new.txt", "Sadly conflicting topic-wise",
createChange(
project2,
"K",
"new.txt",
"Sadly conflicting topic-wise",
ImmutableList.of(i.getCommit(), j.getCommit()),
"refs/for/master/" + name("topic1"));
@ -236,7 +247,11 @@ public class SubmitResolvingMergeCommitIT extends AbstractDaemonTest {
assertChangeSetMergeable(k.getChange(), false);
PushOneCommit.Result l =
createChange(project1, "L", "new.txt", "Resolving conflicts again",
createChange(
project1,
"L",
"new.txt",
"Resolving conflicts again",
ImmutableList.of(c.getCommit(), g.getCommit()),
"refs/for/master/" + name("topic1"));
@ -263,18 +278,19 @@ public class SubmitResolvingMergeCommitIT extends AbstractDaemonTest {
*/
PushOneCommit.Result a = createChange("A");
PushOneCommit.Result b = createChange("B", "new.txt", "No conflict line",
ImmutableList.of(a.getCommit()));
PushOneCommit.Result b =
createChange("B", "new.txt", "No conflict line", ImmutableList.of(a.getCommit()));
approve(a.getChangeId());
approve(b.getChangeId());
submit(b.getChangeId());
PushOneCommit.Result c = createChange("C", "new.txt", "Create conflicts",
ImmutableList.of(a.getCommit()));
PushOneCommit.Result c =
createChange("C", "new.txt", "Create conflicts", ImmutableList.of(a.getCommit()));
PushOneCommit.Result e = createChange("E", ImmutableList.of(c.getCommit()));
PushOneCommit.Result d = createChange("D", "new.txt", "Resolves conflicts",
ImmutableList.of(c.getCommit(), e.getCommit()));
PushOneCommit.Result d =
createChange(
"D", "new.txt", "Resolves conflicts", ImmutableList.of(c.getCommit(), e.getCommit()));
approve(c.getChangeId());
approve(e.getChangeId());
@ -284,17 +300,12 @@ public class SubmitResolvingMergeCommitIT extends AbstractDaemonTest {
}
private void submit(String changeId) throws Exception {
gApi.changes()
.id(changeId)
.current()
.submit();
gApi.changes().id(changeId).current().submit();
}
private void assertChangeSetMergeable(ChangeData change, boolean expected)
throws MissingObjectException, IncorrectObjectTypeException, IOException,
OrmException {
ChangeSet cs =
mergeSuperSet.get().completeChangeSet(db, change.change(), user(admin));
throws MissingObjectException, IncorrectObjectTypeException, IOException, OrmException {
ChangeSet cs = mergeSuperSet.get().completeChangeSet(db, change.change(), user(admin));
assertThat(submit.unmergeableChanges(cs).isEmpty()).isEqualTo(expected);
}
@ -309,18 +320,18 @@ public class SubmitResolvingMergeCommitIT extends AbstractDaemonTest {
}
private void assertMerged(String changeId) throws Exception {
assertThat(gApi
.changes()
.id(changeId)
.get()
.status).isEqualTo(ChangeStatus.MERGED);
assertThat(gApi.changes().id(changeId).get().status).isEqualTo(ChangeStatus.MERGED);
}
private PushOneCommit.Result createChange(TestRepository<?> repo,
String subject, String fileName, String content, List<RevCommit> parents,
String ref) throws Exception {
PushOneCommit push = pushFactory.create(db, admin.getIdent(), repo,
subject, fileName, content);
private PushOneCommit.Result createChange(
TestRepository<?> repo,
String subject,
String fileName,
String content,
List<RevCommit> parents,
String ref)
throws Exception {
PushOneCommit push = pushFactory.create(db, admin.getIdent(), repo, subject, fileName, content);
if (!parents.isEmpty()) {
push.setParents(parents);
@ -336,33 +347,34 @@ public class SubmitResolvingMergeCommitIT extends AbstractDaemonTest {
return result;
}
private PushOneCommit.Result createChange(TestRepository<?> repo,
String subject) throws Exception {
return createChange(repo, subject, "x", "x", new ArrayList<RevCommit>(),
"refs/for/master");
private PushOneCommit.Result createChange(TestRepository<?> repo, String subject)
throws Exception {
return createChange(repo, subject, "x", "x", new ArrayList<RevCommit>(), "refs/for/master");
}
private PushOneCommit.Result createChange(TestRepository<?> repo,
String subject, String fileName, String content, List<RevCommit> parents)
throws Exception {
return createChange(repo, subject, fileName, content, parents,
"refs/for/master");
private PushOneCommit.Result createChange(
TestRepository<?> repo,
String subject,
String fileName,
String content,
List<RevCommit> parents)
throws Exception {
return createChange(repo, subject, fileName, content, parents, "refs/for/master");
}
@Override
protected PushOneCommit.Result createChange(String subject) throws Exception {
return createChange(testRepo, subject, "", "",
Collections.<RevCommit> emptyList(), "refs/for/master");
return createChange(
testRepo, subject, "", "", Collections.<RevCommit>emptyList(), "refs/for/master");
}
private PushOneCommit.Result createChange(String subject,
List<RevCommit> parents) throws Exception {
private PushOneCommit.Result createChange(String subject, List<RevCommit> parents)
throws Exception {
return createChange(testRepo, subject, "", "", parents, "refs/for/master");
}
private PushOneCommit.Result createChange(String subject, String fileName,
String content, List<RevCommit> parents) throws Exception {
return createChange(testRepo, subject, fileName, content, parents,
"refs/for/master");
private PushOneCommit.Result createChange(
String subject, String fileName, String content, List<RevCommit> parents) throws Exception {
return createChange(testRepo, subject, fileName, content, parents, "refs/for/master");
}
}

View File

@ -39,21 +39,17 @@ import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.group.CreateGroup;
import com.google.gerrit.server.group.GroupsCollection;
import com.google.inject.Inject;
import org.junit.Before;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.Before;
import org.junit.Test;
@Sandboxed
public class SuggestReviewersIT extends AbstractDaemonTest {
@Inject
private CreateGroup.Factory createGroupFactory;
@Inject private CreateGroup.Factory createGroupFactory;
@Inject
private GroupsCollection groups;
@Inject private GroupsCollection groups;
private AccountGroup group1;
private AccountGroup group2;
@ -80,8 +76,7 @@ public class SuggestReviewersIT extends AbstractDaemonTest {
@GerritConfig(name = "accounts.visibility", value = "NONE")
public void suggestReviewersNoResult1() throws Exception {
String changeId = createChange().getChangeId();
List<SuggestedReviewerInfo> reviewers =
suggestReviewers(changeId, name("u"), 6);
List<SuggestedReviewerInfo> reviewers = suggestReviewers(changeId, name("u"), 6);
assertThat(reviewers).isEmpty();
}
@ -90,22 +85,20 @@ public class SuggestReviewersIT extends AbstractDaemonTest {
@GerritConfig(name = "accounts.visibility", value = "NONE")
public void suggestReviewersNoResult2() throws Exception {
String changeId = createChange().getChangeId();
List<SuggestedReviewerInfo> reviewers =
suggestReviewers(changeId, name("u"), 6);
List<SuggestedReviewerInfo> reviewers = suggestReviewers(changeId, name("u"), 6);
assertThat(reviewers).isEmpty();
}
@Test
public void suggestReviewersChange() throws Exception {
String changeId = createChange().getChangeId();
List<SuggestedReviewerInfo> reviewers =
suggestReviewers(changeId, name("u"), 6);
assertReviewers(reviewers, ImmutableList.of(user1, user2, user3),
ImmutableList.of(group1, group2, group3));
List<SuggestedReviewerInfo> reviewers = suggestReviewers(changeId, name("u"), 6);
assertReviewers(
reviewers, ImmutableList.of(user1, user2, user3), ImmutableList.of(group1, group2, group3));
reviewers = suggestReviewers(changeId, name("u"), 5);
assertReviewers(reviewers, ImmutableList.of(user1, user2, user3),
ImmutableList.of(group1, group2));
assertReviewers(
reviewers, ImmutableList.of(user1, user2, user3), ImmutableList.of(group1, group2));
reviewers = suggestReviewers(changeId, group3.getName(), 10);
assertReviewers(reviewers, ImmutableList.of(), ImmutableList.of(group3));
@ -117,8 +110,8 @@ public class SuggestReviewersIT extends AbstractDaemonTest {
assertThat(reviewers).hasSize(1);
assertThat(reviewers.get(0).account).isNotNull();
assertThat(ImmutableList.of(reviewers.get(0).account._accountId))
.containsAnyIn(ImmutableList.of(user1, user2, user3).stream()
.map(u -> u.id.get()).collect(toList()));
.containsAnyIn(
ImmutableList.of(user1, user2, user3).stream().map(u -> u.id.get()).collect(toList()));
}
@Test
@ -129,8 +122,7 @@ public class SuggestReviewersIT extends AbstractDaemonTest {
reviewers = suggestReviewers(changeId, user2.username, 2);
assertThat(reviewers).hasSize(1);
assertThat(Iterables.getOnlyElement(reviewers).account.name)
.isEqualTo(user2.fullName);
assertThat(Iterables.getOnlyElement(reviewers).account.name).isEqualTo(user2.fullName);
setApiUser(user1);
reviewers = suggestReviewers(changeId, user2.fullName, 2);
@ -139,14 +131,12 @@ public class SuggestReviewersIT extends AbstractDaemonTest {
setApiUser(user2);
reviewers = suggestReviewers(changeId, user2.username, 2);
assertThat(reviewers).hasSize(1);
assertThat(Iterables.getOnlyElement(reviewers).account.name)
.isEqualTo(user2.fullName);
assertThat(Iterables.getOnlyElement(reviewers).account.name).isEqualTo(user2.fullName);
setApiUser(user3);
reviewers = suggestReviewers(changeId, user2.username, 2);
assertThat(reviewers).hasSize(1);
assertThat(Iterables.getOnlyElement(reviewers).account.name)
.isEqualTo(user2.fullName);
assertThat(Iterables.getOnlyElement(reviewers).account.name).isEqualTo(user2.fullName);
}
@Test
@ -172,20 +162,17 @@ public class SuggestReviewersIT extends AbstractDaemonTest {
assertThat(reviewers).isEmpty();
setApiUser(user1); // Clear cached group info.
allowGlobalCapabilities(group1.getGroupUUID(),
GlobalCapability.VIEW_ALL_ACCOUNTS);
allowGlobalCapabilities(group1.getGroupUUID(), GlobalCapability.VIEW_ALL_ACCOUNTS);
reviewers = suggestReviewers(changeId, user2.username, 2);
assertThat(reviewers).hasSize(1);
assertThat(Iterables.getOnlyElement(reviewers).account.name)
.isEqualTo(user2.fullName);
assertThat(Iterables.getOnlyElement(reviewers).account.name).isEqualTo(user2.fullName);
}
@Test
@GerritConfig(name = "suggest.maxSuggestedReviewers", value = "2")
public void suggestReviewersMaxNbrSuggestions() throws Exception {
String changeId = createChange().getChangeId();
List<SuggestedReviewerInfo> reviewers =
suggestReviewers(changeId, name("user"), 5);
List<SuggestedReviewerInfo> reviewers = suggestReviewers(changeId, name("user"), 5);
assertThat(reviewers).hasSize(2);
}
@ -245,16 +232,14 @@ public class SuggestReviewersIT extends AbstractDaemonTest {
public void suggestReviewersWithoutLimitOptionSpecified() throws Exception {
String changeId = createChange().getChangeId();
String query = user3.username;
List<SuggestedReviewerInfo> suggestedReviewerInfos = gApi.changes()
.id(changeId)
.suggestReviewers(query)
.get();
List<SuggestedReviewerInfo> suggestedReviewerInfos =
gApi.changes().id(changeId).suggestReviewers(query).get();
assertThat(suggestedReviewerInfos).hasSize(1);
}
@Test
@GerritConfig(name = "addreviewer.maxAllowed", value="2")
@GerritConfig(name = "addreviewer.maxWithoutConfirmation", value="1")
@GerritConfig(name = "addreviewer.maxAllowed", value = "2")
@GerritConfig(name = "addreviewer.maxWithoutConfirmation", value = "1")
public void suggestReviewersGroupSizeConsiderations() throws Exception {
AccountGroup largeGroup = group("large");
AccountGroup mediumGroup = group("medium");
@ -290,7 +275,7 @@ public class SuggestReviewersIT extends AbstractDaemonTest {
}
@Test
public void defaultReviewerSuggestion() throws Exception{
public void defaultReviewerSuggestion() throws Exception {
TestAccount user1 = user("customuser1", "User1");
TestAccount reviewer1 = user("customuser2", "User2");
TestAccount reviewer2 = user("customuser3", "User3");
@ -312,42 +297,30 @@ public class SuggestReviewersIT extends AbstractDaemonTest {
setApiUser(user1);
String changeId3 = createChangeFromApi();
List<SuggestedReviewerInfo> reviewers =
suggestReviewers(changeId3, null, 4);
assertThat(
reviewers.stream()
.map(r -> r.account._accountId)
.collect(Collectors.toList()))
.containsExactly(
reviewer1.id.get(),
reviewer2.id.get())
List<SuggestedReviewerInfo> reviewers = suggestReviewers(changeId3, null, 4);
assertThat(reviewers.stream().map(r -> r.account._accountId).collect(Collectors.toList()))
.containsExactly(reviewer1.id.get(), reviewer2.id.get())
.inOrder();
// check that existing reviewers are filtered out
gApi.changes().id(changeId3).addReviewer(reviewer1.email);
reviewers =
suggestReviewers(changeId3, null, 4);
assertThat(
reviewers.stream()
.map(r -> r.account._accountId)
.collect(Collectors.toList()))
.containsExactly(
reviewer2.id.get())
reviewers = suggestReviewers(changeId3, null, 4);
assertThat(reviewers.stream().map(r -> r.account._accountId).collect(Collectors.toList()))
.containsExactly(reviewer2.id.get())
.inOrder();
}
@Test
public void defaultReviewerSuggestionOnFirstChange() throws Exception{
public void defaultReviewerSuggestionOnFirstChange() throws Exception {
TestAccount user1 = user("customuser1", "User1");
setApiUser(user1);
List<SuggestedReviewerInfo> reviewers =
suggestReviewers(createChange().getChangeId(), "", 4);
List<SuggestedReviewerInfo> reviewers = suggestReviewers(createChange().getChangeId(), "", 4);
assertThat(reviewers).isEmpty();
}
@Test
@GerritConfig(name = "suggest.maxSuggestedReviewers", value = "10")
public void reviewerRanking() throws Exception{
public void reviewerRanking() throws Exception {
// Assert that user are ranked by the number of times they have applied a
// a label to a change (highest), added comments (medium) or owned a
// change (low).
@ -384,22 +357,15 @@ public class SuggestReviewersIT extends AbstractDaemonTest {
// ranking
setApiUser(userWhoLooksForSuggestions);
List<SuggestedReviewerInfo> reviewers =
suggestReviewers(createChangeFromApi(), "Pri", 4);
assertThat(
reviewers.stream()
.map(r -> r.account._accountId)
.collect(Collectors.toList()))
List<SuggestedReviewerInfo> reviewers = suggestReviewers(createChangeFromApi(), "Pri", 4);
assertThat(reviewers.stream().map(r -> r.account._accountId).collect(Collectors.toList()))
.containsExactly(
reviewer1.id.get(),
reviewer2.id.get(),
userWhoOwns.id.get(),
userWhoComments.id.get())
reviewer1.id.get(), reviewer2.id.get(), userWhoOwns.id.get(), userWhoComments.id.get())
.inOrder();
}
@Test
public void reviewerRankingProjectIsolation() throws Exception{
public void reviewerRankingProjectIsolation() throws Exception {
// Create new project
Project.NameKey newProject = createProject("test");
@ -428,54 +394,38 @@ public class SuggestReviewersIT extends AbstractDaemonTest {
reviewChange(changeId3);
setApiUser(userWhoOwns);
List<SuggestedReviewerInfo> reviewers =
suggestReviewers(createChangeFromApi(), "Prim", 4);
List<SuggestedReviewerInfo> reviewers = suggestReviewers(createChangeFromApi(), "Prim", 4);
// Assert that reviewer1 is on top, even though reviewer2 has more reviews
// in other projects
assertThat(
reviewers.stream()
.map(r -> r.account._accountId)
.collect(Collectors.toList()))
assertThat(reviewers.stream().map(r -> r.account._accountId).collect(Collectors.toList()))
.containsExactly(reviewer1.id.get(), reviewer2.id.get())
.inOrder();
}
private List<SuggestedReviewerInfo> suggestReviewers(String changeId,
String query) throws Exception {
return gApi.changes()
.id(changeId)
.suggestReviewers(query)
.get();
private List<SuggestedReviewerInfo> suggestReviewers(String changeId, String query)
throws Exception {
return gApi.changes().id(changeId).suggestReviewers(query).get();
}
private List<SuggestedReviewerInfo> suggestReviewers(String changeId,
String query, int n) throws Exception {
return gApi.changes()
.id(changeId)
.suggestReviewers(query)
.withLimit(n)
.get();
private List<SuggestedReviewerInfo> suggestReviewers(String changeId, String query, int n)
throws Exception {
return gApi.changes().id(changeId).suggestReviewers(query).withLimit(n).get();
}
private AccountGroup group(String name) throws Exception {
GroupInfo group = createGroupFactory.create(name(name))
.apply(TopLevelResource.INSTANCE, null);
GroupInfo group = createGroupFactory.create(name(name)).apply(TopLevelResource.INSTANCE, null);
GroupDescription.Basic d = groups.parseInternal(Url.decode(group.id));
return GroupDescriptions.toAccountGroup(d);
}
private TestAccount user(String name, String fullName, String emailName,
AccountGroup... groups) throws Exception {
String[] groupNames = Arrays.stream(groups)
.map(AccountGroup::getName)
.toArray(String[]::new);
return accounts.create(name(name), name(emailName) + "@example.com",
fullName, groupNames);
private TestAccount user(String name, String fullName, String emailName, AccountGroup... groups)
throws Exception {
String[] groupNames = Arrays.stream(groups).map(AccountGroup::getName).toArray(String[]::new);
return accounts.create(name(name), name(emailName) + "@example.com", fullName, groupNames);
}
private TestAccount user(String name, String fullName, AccountGroup... groups)
throws Exception {
private TestAccount user(String name, String fullName, AccountGroup... groups) throws Exception {
return user(name, fullName, name, groups);
}
@ -485,12 +435,11 @@ public class SuggestReviewersIT extends AbstractDaemonTest {
gApi.changes().id(changeId).current().review(ri);
}
private String createChangeFromApi() throws RestApiException{
private String createChangeFromApi() throws RestApiException {
return createChangeFromApi(project);
}
private String createChangeFromApi(Project.NameKey project)
throws RestApiException{
private String createChangeFromApi(Project.NameKey project) throws RestApiException {
ChangeInput ci = new ChangeInput();
ci.project = project.get();
ci.subject = "Test change at" + System.nanoTime();
@ -498,25 +447,24 @@ public class SuggestReviewersIT extends AbstractDaemonTest {
return gApi.changes().create(ci).get().changeId;
}
private void assertReviewers(List<SuggestedReviewerInfo> actual,
List<TestAccount> expectedUsers, List<AccountGroup> expectedGroups) {
List<Integer> actualAccountIds = actual.stream()
.filter(i -> i.account != null)
.map(i -> i.account._accountId)
.collect(toList());
private void assertReviewers(
List<SuggestedReviewerInfo> actual,
List<TestAccount> expectedUsers,
List<AccountGroup> expectedGroups) {
List<Integer> actualAccountIds =
actual
.stream()
.filter(i -> i.account != null)
.map(i -> i.account._accountId)
.collect(toList());
assertThat(actualAccountIds)
.containsExactlyElementsIn(
expectedUsers.stream().map(u -> u.id.get()).collect(toList()));
.containsExactlyElementsIn(expectedUsers.stream().map(u -> u.id.get()).collect(toList()));
List<String> actualGroupIds = actual.stream()
.filter(i -> i.group != null)
.map(i -> i.group.id)
.collect(toList());
List<String> actualGroupIds =
actual.stream().filter(i -> i.group != null).map(i -> i.group.id).collect(toList());
assertThat(actualGroupIds)
.containsExactlyElementsIn(
expectedGroups.stream()
.map(g -> g.getGroupUUID().get())
.collect(toList()))
expectedGroups.stream().map(g -> g.getGroupUUID().get()).collect(toList()))
.inOrder();
}
}

View File

@ -17,7 +17,6 @@ package com.google.gerrit.acceptance.rest.change;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit.Result;
import com.google.gerrit.acceptance.RestResponse;
import org.junit.Test;
public class TopicIT extends AbstractDaemonTest {

View File

@ -24,10 +24,8 @@ import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.server.config.ListCaches.CacheInfo;
import com.google.gerrit.server.config.PostCaches;
import org.junit.Test;
import java.util.Arrays;
import org.junit.Test;
public class CacheOperationsIT extends AbstractDaemonTest {
@ -47,15 +45,15 @@ public class CacheOperationsIT extends AbstractDaemonTest {
@Test
public void flushAll_Forbidden() throws Exception {
userRestSession.post("/config/server/caches/",
new PostCaches.Input(FLUSH_ALL)).assertForbidden();
userRestSession
.post("/config/server/caches/", new PostCaches.Input(FLUSH_ALL))
.assertForbidden();
}
@Test
public void flushAll_BadRequest() throws Exception {
adminRestSession
.post("/config/server/caches/",
new PostCaches.Input(FLUSH_ALL, Arrays.asList("projects")))
.post("/config/server/caches/", new PostCaches.Input(FLUSH_ALL, Arrays.asList("projects")))
.assertBadRequest();
}
@ -63,14 +61,16 @@ public class CacheOperationsIT extends AbstractDaemonTest {
public void flush() throws Exception {
RestResponse r = adminRestSession.getOK("/config/server/caches/project_list");
CacheInfo cacheInfo = newGson().fromJson(r.getReader(), CacheInfo.class);
assertThat(cacheInfo.entries.mem).isGreaterThan((long)0);
assertThat(cacheInfo.entries.mem).isGreaterThan((long) 0);
r = adminRestSession.getOK("/config/server/caches/projects");
cacheInfo = newGson().fromJson(r.getReader(), CacheInfo.class);
assertThat(cacheInfo.entries.mem).isGreaterThan((long)1);
assertThat(cacheInfo.entries.mem).isGreaterThan((long) 1);
r = adminRestSession.postOK("/config/server/caches/",
new PostCaches.Input(FLUSH, Arrays.asList("accounts", "project_list")));
r =
adminRestSession.postOK(
"/config/server/caches/",
new PostCaches.Input(FLUSH, Arrays.asList("accounts", "project_list")));
r.consume();
r = adminRestSession.getOK("/config/server/caches/project_list");
@ -79,57 +79,56 @@ public class CacheOperationsIT extends AbstractDaemonTest {
r = adminRestSession.getOK("/config/server/caches/projects");
cacheInfo = newGson().fromJson(r.getReader(), CacheInfo.class);
assertThat(cacheInfo.entries.mem).isGreaterThan((long)1);
assertThat(cacheInfo.entries.mem).isGreaterThan((long) 1);
}
@Test
public void flush_Forbidden() throws Exception {
userRestSession
.post("/config/server/caches/",
new PostCaches.Input(FLUSH, Arrays.asList("projects")))
.post("/config/server/caches/", new PostCaches.Input(FLUSH, Arrays.asList("projects")))
.assertForbidden();
}
@Test
public void flush_BadRequest() throws Exception {
adminRestSession
.post("/config/server/caches/",
new PostCaches.Input(FLUSH))
.assertBadRequest();
adminRestSession.post("/config/server/caches/", new PostCaches.Input(FLUSH)).assertBadRequest();
}
@Test
public void flush_UnprocessableEntity() throws Exception {
RestResponse r = adminRestSession.getOK("/config/server/caches/projects");
CacheInfo cacheInfo = newGson().fromJson(r.getReader(), CacheInfo.class);
assertThat(cacheInfo.entries.mem).isGreaterThan((long)0);
assertThat(cacheInfo.entries.mem).isGreaterThan((long) 0);
r = adminRestSession.post("/config/server/caches/",
new PostCaches.Input(FLUSH, Arrays.asList("projects", "unprocessable")));
r =
adminRestSession.post(
"/config/server/caches/",
new PostCaches.Input(FLUSH, Arrays.asList("projects", "unprocessable")));
r.assertUnprocessableEntity();
r.consume();
r = adminRestSession.getOK("/config/server/caches/projects");
cacheInfo = newGson().fromJson(r.getReader(), CacheInfo.class);
assertThat(cacheInfo.entries.mem).isGreaterThan((long)0);
assertThat(cacheInfo.entries.mem).isGreaterThan((long) 0);
}
@Test
public void flushWebSessions_Forbidden() throws Exception {
allowGlobalCapabilities(REGISTERED_USERS,
GlobalCapability.FLUSH_CACHES, GlobalCapability.VIEW_CACHES);
allowGlobalCapabilities(
REGISTERED_USERS, GlobalCapability.FLUSH_CACHES, GlobalCapability.VIEW_CACHES);
try {
RestResponse r = userRestSession.postOK("/config/server/caches/",
new PostCaches.Input(FLUSH, Arrays.asList("projects")));
RestResponse r =
userRestSession.postOK(
"/config/server/caches/", new PostCaches.Input(FLUSH, Arrays.asList("projects")));
r.consume();
userRestSession
.post("/config/server/caches/",
new PostCaches.Input(FLUSH, Arrays.asList("web_sessions")))
.post(
"/config/server/caches/", new PostCaches.Input(FLUSH, Arrays.asList("web_sessions")))
.assertForbidden();
} finally {
removeGlobalCapabilities(REGISTERED_USERS,
GlobalCapability.FLUSH_CACHES, GlobalCapability.VIEW_CACHES);
removeGlobalCapabilities(
REGISTERED_USERS, GlobalCapability.FLUSH_CACHES, GlobalCapability.VIEW_CACHES);
}
}
}

Some files were not shown because too many files have changed in this diff Show More