Add test for multiple VersionedMetaDatas in one BatchRefUpdate

Add an additional sanity check to BatchMetaDataUpdate that would have
helped me when I wrote the test incorrectly the first time.

Change-Id: I1dc68afffeeeae71a4d13899a249621f88f50ddb
This commit is contained in:
Dave Borowitz
2017-11-09 09:40:06 -05:00
parent c4309d433d
commit 8136f51c63
2 changed files with 100 additions and 16 deletions

View File

@@ -14,6 +14,8 @@
package com.google.gerrit.server.git;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.base.MoreObjects;
import java.io.BufferedReader;
import java.io.IOException;
@@ -276,6 +278,7 @@ public abstract class VersionedMetaData {
@Override
public void write(VersionedMetaData config, CommitBuilder commit) throws IOException {
checkSameRef(config);
if (!doSave(config, commit)) {
return;
}
@@ -319,6 +322,18 @@ public abstract class VersionedMetaData {
srcTree = res;
}
private void checkSameRef(VersionedMetaData other) {
String thisRef = VersionedMetaData.this.getRefName();
String otherRef = other.getRefName();
checkArgument(
otherRef.equals(thisRef),
"cannot add %s for %s to %s on %s",
other.getClass().getSimpleName(),
otherRef,
BatchMetaDataUpdate.class.getSimpleName(),
thisRef);
}
@Override
public RevCommit createRef(String refName) throws IOException {
if (Objects.equals(src, revision)) {

View File

@@ -17,13 +17,16 @@ package com.google.gerrit.server.git;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Streams;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.VersionedMetaData.BatchMetaDataUpdate;
import com.google.gerrit.server.update.RefUpdateUtil;
import com.google.gerrit.testing.TestTimeUtil;
import java.io.IOException;
import java.util.Arrays;
@@ -33,6 +36,7 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.PersonIdent;
@@ -41,6 +45,7 @@ import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevSort;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.ReceiveCommand;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -51,6 +56,7 @@ public class VersionedMetaDataTest {
// VersionedMetaData/BatchMetaDataUpdate/MetaDataUpdate that is easier to use correctly.
private static final TimeZone TZ = TimeZone.getTimeZone("America/Los_Angeles");
private static final String DEFAULT_REF = "refs/meta/config";
private Project.NameKey project;
private Repository repo;
@@ -125,11 +131,11 @@ public class VersionedMetaDataTest {
MyMetaData d = load(0);
d.setIncrement(1);
try (BatchMetaDataUpdate batch = d.openUpdate(newMetaDataUpdate())) {
batch.write(d, newMetaDataUpdate().getCommitBuilder());
batch.write(d, newCommitBuilder());
assertMyMetaData(0); // Batch not yet committed.
d.setIncrement(2);
batch.write(d, newMetaDataUpdate().getCommitBuilder());
batch.write(d, newCommitBuilder());
batch.commit();
}
@@ -141,44 +147,101 @@ public class VersionedMetaDataTest {
MyMetaData d = load(0);
d.setIncrement(1);
try (BatchMetaDataUpdate batch = d.openUpdate(newMetaDataUpdate())) {
batch.write(d, newMetaDataUpdate().getCommitBuilder());
batch.write(d, newCommitBuilder());
assertMyMetaData(0); // Batch not yet committed.
d.setIncrement(0);
batch.write(d, newMetaDataUpdate().getCommitBuilder());
batch.write(d, newCommitBuilder());
assertMyMetaData(0); // Batch not yet committed.
d.setIncrement(3);
batch.write(d, newMetaDataUpdate().getCommitBuilder());
batch.write(d, newCommitBuilder());
batch.commit();
}
assertMyMetaData(4, "Increment conf.value by 1", "Increment conf.value by 3");
}
@Test
public void sharedBatchRefUpdate() throws Exception {
MyMetaData d1 = load("refs/meta/1", 0);
MyMetaData d2 = load("refs/meta/2", 0);
BatchRefUpdate bru = repo.getRefDatabase().newBatchUpdate();
try (BatchMetaDataUpdate batch1 = d1.openUpdate(newMetaDataUpdate(bru));
BatchMetaDataUpdate batch2 = d2.openUpdate(newMetaDataUpdate(bru))) {
d1.setIncrement(1);
batch1.write(d1, newCommitBuilder());
d2.setIncrement(2000);
batch2.write(d2, newCommitBuilder());
d1.setIncrement(3);
batch1.write(d1, newCommitBuilder());
d2.setIncrement(4000);
batch2.write(d2, newCommitBuilder());
batch1.commit();
batch2.commit();
}
assertMyMetaData(d1.getRefName(), 0);
assertMyMetaData(d2.getRefName(), 0);
assertThat(bru.getCommands().stream().map(ReceiveCommand::getRefName))
.containsExactly("refs/meta/1", "refs/meta/2");
try (RevWalk rw = new RevWalk(repo)) {
RefUpdateUtil.executeChecked(bru, rw);
}
assertMyMetaData(d1.getRefName(), 4, "Increment conf.value by 1", "Increment conf.value by 3");
assertMyMetaData(
d2.getRefName(), 6000, "Increment conf.value by 2000", "Increment conf.value by 4000");
}
private MyMetaData load(int expectedValue) throws Exception {
MyMetaData d = new MyMetaData();
return load(DEFAULT_REF, expectedValue);
}
private MyMetaData load(String ref, int expectedValue) throws Exception {
MyMetaData d = new MyMetaData(ref);
d.load(repo);
assertThat(d.getValue()).isEqualTo(expectedValue);
return d;
}
private MetaDataUpdate newMetaDataUpdate() {
MetaDataUpdate u = new MetaDataUpdate(GitReferenceUpdated.DISABLED, project, repo, null);
PersonIdent author = new PersonIdent("J. Author", "author@example.com", TimeUtil.nowTs(), TZ);
u.getCommitBuilder().setAuthor(author);
u.getCommitBuilder()
.setCommitter(
new PersonIdent(
"M. Committer", "committer@example.com", author.getWhen(), author.getTimeZone()));
return newMetaDataUpdate(null);
}
private MetaDataUpdate newMetaDataUpdate(@Nullable BatchRefUpdate bru) {
MetaDataUpdate u = new MetaDataUpdate(GitReferenceUpdated.DISABLED, project, repo, bru);
CommitBuilder cb = newCommitBuilder();
u.getCommitBuilder().setAuthor(cb.getAuthor());
u.getCommitBuilder().setCommitter(cb.getCommitter());
return u;
}
private void assertMyMetaData(int expectedValue, String... expectedLog) throws Exception {
MyMetaData d = load(expectedValue);
private CommitBuilder newCommitBuilder() {
CommitBuilder cb = new CommitBuilder();
PersonIdent author = new PersonIdent("J. Author", "author@example.com", TimeUtil.nowTs(), TZ);
cb.setAuthor(author);
cb.setCommitter(
new PersonIdent(
"M. Committer", "committer@example.com", author.getWhen(), author.getTimeZone()));
return cb;
}
private void assertMyMetaData(String ref, int expectedValue, String... expectedLog)
throws Exception {
MyMetaData d = load(ref, expectedValue);
assertThat(log(d)).containsExactlyElementsIn(Arrays.asList(expectedLog)).inOrder();
}
private void assertMyMetaData(int expectedValue, String... expectedLog) throws Exception {
assertMyMetaData(DEFAULT_REF, expectedValue, expectedLog);
}
private ImmutableList<String> log(MyMetaData d) throws Exception {
try (RevWalk rw = new RevWalk(repo)) {
Ref ref = repo.exactRef(d.getRefName());
@@ -197,9 +260,15 @@ public class VersionedMetaDataTest {
private static final String SECTION = "conf";
private static final String NAME = "value";
private final String ref;
MyMetaData(String ref) {
this.ref = ref;
}
@Override
protected String getRefName() {
return "refs/my/config";
return ref;
}
private int curr;