diff options
Diffstat (limited to 'javatests/com/google/gerrit/server/schema/GroupRebuilderTest.java')
-rw-r--r-- | javatests/com/google/gerrit/server/schema/GroupRebuilderTest.java | 747 |
1 files changed, 747 insertions, 0 deletions
diff --git a/javatests/com/google/gerrit/server/schema/GroupRebuilderTest.java b/javatests/com/google/gerrit/server/schema/GroupRebuilderTest.java new file mode 100644 index 0000000000..bf6953afcd --- /dev/null +++ b/javatests/com/google/gerrit/server/schema/GroupRebuilderTest.java @@ -0,0 +1,747 @@ +// Copyright (C) 2017 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.server.schema; + +import static com.google.common.collect.ImmutableList.toImmutableList; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assert_; +import static com.google.gerrit.extensions.common.testing.CommitInfoSubject.assertThat; +import static com.google.gerrit.reviewdb.client.RefNames.REFS_GROUPNAMES; + +import com.google.common.collect.ImmutableList; +import com.google.gerrit.common.Nullable; +import com.google.gerrit.common.data.GroupDescription; +import com.google.gerrit.common.data.GroupReference; +import com.google.gerrit.extensions.common.CommitInfo; +import com.google.gerrit.reviewdb.client.Account; +import com.google.gerrit.reviewdb.client.AccountGroup; +import com.google.gerrit.reviewdb.client.AccountGroupById; +import com.google.gerrit.reviewdb.client.AccountGroupByIdAud; +import com.google.gerrit.reviewdb.client.AccountGroupMember; +import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit; +import com.google.gerrit.reviewdb.client.RefNames; +import com.google.gerrit.server.config.AllUsersName; +import com.google.gerrit.server.config.AllUsersNameProvider; +import com.google.gerrit.server.group.db.AuditLogFormatter; +import com.google.gerrit.server.group.db.AuditLogReader; +import com.google.gerrit.server.group.db.GroupNameNotes; +import com.google.gerrit.server.update.RefUpdateUtil; +import com.google.gerrit.server.util.time.TimeUtil; +import com.google.gerrit.testing.GerritBaseTests; +import com.google.gerrit.testing.GitTestUtil; +import com.google.gerrit.testing.InMemoryRepositoryManager; +import com.google.gerrit.testing.TestTimeUtil; +import com.google.gwtorm.server.OrmDuplicateKeyException; +import java.sql.Timestamp; +import java.util.Optional; +import java.util.TimeZone; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.IntStream; +import org.eclipse.jgit.lib.BatchRefUpdate; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectInserter; +import org.eclipse.jgit.lib.PersonIdent; +import org.eclipse.jgit.lib.Repository; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class GroupRebuilderTest extends GerritBaseTests { + private static final TimeZone TZ = TimeZone.getTimeZone("America/Los_Angeles"); + private static final String SERVER_ID = "server-id"; + private static final String SERVER_NAME = "Gerrit Server"; + private static final String SERVER_EMAIL = "noreply@gerritcodereview.com"; + + private AtomicInteger idCounter; + private AllUsersName allUsersName; + private Repository repo; + private GroupRebuilder rebuilder; + private GroupBundle.Factory bundleFactory; + + @Before + public void setUp() throws Exception { + TestTimeUtil.resetWithClockStep(1, TimeUnit.SECONDS); + idCounter = new AtomicInteger(); + allUsersName = new AllUsersName(AllUsersNameProvider.DEFAULT); + repo = new InMemoryRepositoryManager().createRepository(allUsersName); + rebuilder = + new GroupRebuilder( + GroupRebuilderTest.newPersonIdent(), + allUsersName, + // Note that the expected name/email values in tests are not necessarily realistic, + // since they use these trivial name/email functions. + getAuditLogFormatter()); + bundleFactory = new GroupBundle.Factory(new AuditLogReader(SERVER_ID, allUsersName)); + } + + @After + public void tearDown() { + TestTimeUtil.useSystemTime(); + } + + @Test + public void minimalGroupFields() throws Exception { + AccountGroup g = newGroup("a"); + GroupBundle b = builder().group(g).build(); + + rebuilder.rebuild(repo, b, null); + + assertMigratedCleanly(reload(g), b); + ImmutableList<CommitInfo> log = log(g); + assertThat(log).hasSize(1); + assertCommit(log.get(0), "Create group", SERVER_NAME, SERVER_EMAIL); + assertThat(logGroupNames()).isEmpty(); + } + + @Test + public void allGroupFields() throws Exception { + AccountGroup g = newGroup("a"); + g.setDescription("Description"); + g.setOwnerGroupUUID(new AccountGroup.UUID("owner")); + g.setVisibleToAll(true); + GroupBundle b = builder().group(g).build(); + + rebuilder.rebuild(repo, b, null); + + assertMigratedCleanly(reload(g), b); + ImmutableList<CommitInfo> log = log(g); + assertThat(log).hasSize(1); + assertServerCommit(log.get(0), "Create group"); + } + + @Test + public void emptyGroupName() throws Exception { + AccountGroup g = newGroup(""); + GroupBundle b = builder().group(g).build(); + + rebuilder.rebuild(repo, b, null); + + GroupBundle noteDbBundle = reload(g); + assertMigratedCleanly(noteDbBundle, b); + assertThat(noteDbBundle.group().getName()).isEmpty(); + } + + @Test + public void nullGroupDescription() throws Exception { + AccountGroup g = newGroup("a"); + g.setDescription(null); + assertThat(g.getDescription()).isNull(); + GroupBundle b = builder().group(g).build(); + + rebuilder.rebuild(repo, b, null); + + GroupBundle noteDbBundle = reload(g); + assertMigratedCleanly(noteDbBundle, b); + assertThat(noteDbBundle.group().getDescription()).isNull(); + } + + @Test + public void emptyGroupDescription() throws Exception { + AccountGroup g = newGroup("a"); + g.setDescription(""); + assertThat(g.getDescription()).isEmpty(); + GroupBundle b = builder().group(g).build(); + + rebuilder.rebuild(repo, b, null); + + GroupBundle noteDbBundle = reload(g); + assertMigratedCleanly(noteDbBundle, b); + assertThat(noteDbBundle.group().getDescription()).isNull(); + } + + @Test + public void membersAndSubgroups() throws Exception { + AccountGroup g = newGroup("a"); + GroupBundle b = + builder() + .group(g) + .members(member(g, 1), member(g, 2)) + .byId(byId(g, "x"), byId(g, "y")) + .build(); + + rebuilder.rebuild(repo, b, null); + + assertMigratedCleanly(reload(g), b); + ImmutableList<CommitInfo> log = log(g); + assertThat(log).hasSize(2); + assertServerCommit(log.get(0), "Create group"); + assertServerCommit( + log.get(1), + "Update group\n" + + "\n" + + "Add-group: Group x <x>\n" + + "Add-group: Group y <y>\n" + + "Add: Account 1 <1@server-id>\n" + + "Add: Account 2 <2@server-id>"); + } + + @Test + public void memberAudit() throws Exception { + AccountGroup g = newGroup("a"); + Timestamp t1 = TimeUtil.nowTs(); + Timestamp t2 = TimeUtil.nowTs(); + Timestamp t3 = TimeUtil.nowTs(); + GroupBundle b = + builder() + .group(g) + .members(member(g, 1)) + .memberAudit(addMember(g, 1, 8, t2), addAndRemoveMember(g, 2, 8, t1, 9, t3)) + .build(); + + rebuilder.rebuild(repo, b, null); + + assertMigratedCleanly(reload(g), b); + ImmutableList<CommitInfo> log = log(g); + assertThat(log).hasSize(4); + assertServerCommit(log.get(0), "Create group"); + assertCommit( + log.get(1), "Update group\n\nAdd: Account 2 <2@server-id>", "Account 8", "8@server-id"); + assertCommit( + log.get(2), "Update group\n\nAdd: Account 1 <1@server-id>", "Account 8", "8@server-id"); + assertCommit( + log.get(3), "Update group\n\nRemove: Account 2 <2@server-id>", "Account 9", "9@server-id"); + } + + @Test + public void memberAuditLegacyRemoved() throws Exception { + AccountGroup g = newGroup("a"); + GroupBundle b = + builder() + .group(g) + .members(member(g, 2)) + .memberAudit( + addAndLegacyRemoveMember(g, 1, 8, TimeUtil.nowTs()), + addMember(g, 2, 8, TimeUtil.nowTs())) + .build(); + + rebuilder.rebuild(repo, b, null); + + assertMigratedCleanly(reload(g), b); + ImmutableList<CommitInfo> log = log(g); + assertThat(log).hasSize(4); + assertServerCommit(log.get(0), "Create group"); + assertCommit( + log.get(1), "Update group\n\nAdd: Account 1 <1@server-id>", "Account 8", "8@server-id"); + assertCommit( + log.get(2), "Update group\n\nRemove: Account 1 <1@server-id>", "Account 8", "8@server-id"); + assertCommit( + log.get(3), "Update group\n\nAdd: Account 2 <2@server-id>", "Account 8", "8@server-id"); + } + + @Test + public void unauditedMembershipsAddedAtEnd() throws Exception { + AccountGroup g = newGroup("a"); + GroupBundle b = + builder() + .group(g) + .members(member(g, 1), member(g, 2), member(g, 3)) + .memberAudit(addMember(g, 1, 8, TimeUtil.nowTs())) + .build(); + + rebuilder.rebuild(repo, b, null); + + assertMigratedCleanly(reload(g), b); + ImmutableList<CommitInfo> log = log(g); + assertThat(log).hasSize(3); + assertServerCommit(log.get(0), "Create group"); + assertCommit( + log.get(1), "Update group\n\nAdd: Account 1 <1@server-id>", "Account 8", "8@server-id"); + assertServerCommit( + log.get(2), "Update group\n\nAdd: Account 2 <2@server-id>\nAdd: Account 3 <3@server-id>"); + } + + @Test + public void byIdAudit() throws Exception { + AccountGroup g = newGroup("a"); + Timestamp t1 = TimeUtil.nowTs(); + Timestamp t2 = TimeUtil.nowTs(); + Timestamp t3 = TimeUtil.nowTs(); + GroupBundle b = + builder() + .group(g) + .byId(byId(g, "x")) + .byIdAudit(addById(g, "x", 8, t2), addAndRemoveById(g, "y", 8, t1, 9, t3)) + .build(); + + rebuilder.rebuild(repo, b, null); + + assertMigratedCleanly(reload(g), b); + ImmutableList<CommitInfo> log = log(g); + assertThat(log).hasSize(4); + assertServerCommit(log.get(0), "Create group"); + assertCommit(log.get(1), "Update group\n\nAdd-group: Group y <y>", "Account 8", "8@server-id"); + assertCommit(log.get(2), "Update group\n\nAdd-group: Group x <x>", "Account 8", "8@server-id"); + assertCommit( + log.get(3), "Update group\n\nRemove-group: Group y <y>", "Account 9", "9@server-id"); + } + + @Test + public void unauditedByIdAddedAtEnd() throws Exception { + AccountGroup g = newGroup("a"); + GroupBundle b = + builder() + .group(g) + .byId(byId(g, "x"), byId(g, "y"), byId(g, "z")) + .byIdAudit(addById(g, "x", 8, TimeUtil.nowTs())) + .build(); + + rebuilder.rebuild(repo, b, null); + + assertMigratedCleanly(reload(g), b); + ImmutableList<CommitInfo> log = log(g); + assertThat(log).hasSize(3); + assertServerCommit(log.get(0), "Create group"); + assertCommit(log.get(1), "Update group\n\nAdd-group: Group x <x>", "Account 8", "8@server-id"); + assertServerCommit( + log.get(2), "Update group\n\nAdd-group: Group y <y>\nAdd-group: Group z <z>"); + } + + @Test + public void auditsAtSameTimestampBrokenDownByType() throws Exception { + AccountGroup g = newGroup("a"); + Timestamp ts = TimeUtil.nowTs(); + int user = 8; + GroupBundle b = + builder() + .group(g) + .members(member(g, 1), member(g, 2)) + .memberAudit( + addMember(g, 1, user, ts), + addMember(g, 2, user, ts), + addAndRemoveMember(g, 3, user, ts, user, ts)) + .byId(byId(g, "x"), byId(g, "y")) + .byIdAudit( + addById(g, "x", user, ts), + addById(g, "y", user, ts), + addAndRemoveById(g, "z", user, ts, user, ts)) + .build(); + + rebuilder.rebuild(repo, b, null); + + assertMigratedCleanly(reload(g), b); + ImmutableList<CommitInfo> log = log(g); + assertThat(log).hasSize(5); + assertServerCommit(log.get(0), "Create group"); + assertCommit( + log.get(1), + "Update group\n" + + "\n" + + "Add: Account 1 <1@server-id>\n" + + "Add: Account 2 <2@server-id>\n" + + "Add: Account 3 <3@server-id>", + "Account 8", + "8@server-id"); + assertCommit( + log.get(2), "Update group\n\nRemove: Account 3 <3@server-id>", "Account 8", "8@server-id"); + assertCommit( + log.get(3), + "Update group\n" + + "\n" + + "Add-group: Group x <x>\n" + + "Add-group: Group y <y>\n" + + "Add-group: Group z <z>", + "Account 8", + "8@server-id"); + assertCommit( + log.get(4), "Update group\n\nRemove-group: Group z <z>", "Account 8", "8@server-id"); + } + + @Test + public void auditsAtSameTimestampBrokenDownByUserAndType() throws Exception { + AccountGroup g = newGroup("a"); + Timestamp ts = TimeUtil.nowTs(); + int user1 = 8; + int user2 = 9; + + GroupBundle b = + builder() + .group(g) + .members(member(g, 1), member(g, 2), member(g, 3)) + .memberAudit( + addMember(g, 1, user1, ts), addMember(g, 2, user2, ts), addMember(g, 3, user1, ts)) + .byId(byId(g, "x"), byId(g, "y"), byId(g, "z")) + .byIdAudit( + addById(g, "x", user1, ts), addById(g, "y", user2, ts), addById(g, "z", user1, ts)) + .build(); + + rebuilder.rebuild(repo, b, null); + + assertMigratedCleanly(reload(g), b); + ImmutableList<CommitInfo> log = log(g); + assertThat(log).hasSize(5); + assertServerCommit(log.get(0), "Create group"); + assertCommit( + log.get(1), + "Update group\n" + "\n" + "Add: Account 1 <1@server-id>\n" + "Add: Account 3 <3@server-id>", + "Account 8", + "8@server-id"); + assertCommit( + log.get(2), + "Update group\n\nAdd-group: Group x <x>\nAdd-group: Group z <z>", + "Account 8", + "8@server-id"); + assertCommit( + log.get(3), "Update group\n\nAdd: Account 2 <2@server-id>", "Account 9", "9@server-id"); + assertCommit(log.get(4), "Update group\n\nAdd-group: Group y <y>", "Account 9", "9@server-id"); + } + + @Test + public void fixupCommitPostDatesAllAuditEventsEvenIfAuditEventsAreInTheFuture() throws Exception { + AccountGroup g = newGroup("a"); + IntStream.range(0, 20).forEach(i -> TimeUtil.nowTs()); + Timestamp future = TimeUtil.nowTs(); + TestTimeUtil.resetWithClockStep(1, TimeUnit.SECONDS); + + GroupBundle b = + builder() + .group(g) + .byId(byId(g, "x"), byId(g, "y"), byId(g, "z")) + .byIdAudit(addById(g, "x", 8, future)) + .build(); + + rebuilder.rebuild(repo, b, null); + + assertMigratedCleanly(reload(g), b); + ImmutableList<CommitInfo> log = log(g); + assertThat(log).hasSize(3); + assertServerCommit(log.get(0), "Create group"); + assertCommit(log.get(1), "Update group\n\nAdd-group: Group x <x>", "Account 8", "8@server-id"); + assertServerCommit( + log.get(2), "Update group\n\nAdd-group: Group y <y>\nAdd-group: Group z <z>"); + + assertThat(log.stream().map(c -> c.committer.date).collect(toImmutableList())) + .named("%s", log) + .isOrdered(); + assertThat(TimeUtil.nowTs()).isLessThan(future); + } + + @Test + public void redundantMemberAuditsAreIgnored() throws Exception { + AccountGroup g = newGroup("a"); + Timestamp t1 = TimeUtil.nowTs(); + Timestamp t2 = TimeUtil.nowTs(); + Timestamp t3 = TimeUtil.nowTs(); + Timestamp t4 = TimeUtil.nowTs(); + Timestamp t5 = TimeUtil.nowTs(); + GroupBundle b = + builder() + .group(g) + .members(member(g, 2)) + .memberAudit( + addMember(g, 1, 8, t1), + addMember(g, 1, 8, t1), + addMember(g, 1, 8, t3), + addMember(g, 1, 9, t4), + addAndRemoveMember(g, 1, 8, t2, 9, t5), + addAndLegacyRemoveMember(g, 2, 9, t3), + addMember(g, 2, 8, t1), + addMember(g, 2, 9, t4), + addMember(g, 1, 8, t5)) + .build(); + + rebuilder.rebuild(repo, b, null); + + assertMigratedCleanly(reload(g), b); + ImmutableList<CommitInfo> log = log(g); + assertThat(log).hasSize(5); + assertServerCommit(log.get(0), "Create group"); + assertCommit( + log.get(1), + "Update group\n\nAdd: Account 1 <1@server-id>\nAdd: Account 2 <2@server-id>", + "Account 8", + "8@server-id"); + assertCommit( + log.get(2), "Update group\n\nRemove: Account 2 <2@server-id>", "Account 9", "9@server-id"); + assertCommit( + log.get(3), "Update group\n\nAdd: Account 2 <2@server-id>", "Account 9", "9@server-id"); + assertCommit( + log.get(4), "Update group\n\nRemove: Account 1 <1@server-id>", "Account 9", "9@server-id"); + } + + @Test + public void additionsAndRemovalsWithinSameSecondCanBeMigrated() throws Exception { + TestTimeUtil.resetWithClockStep(1, TimeUnit.MILLISECONDS); + AccountGroup g = newGroup("a"); + Timestamp t1 = TimeUtil.nowTs(); + Timestamp t2 = TimeUtil.nowTs(); + Timestamp t3 = TimeUtil.nowTs(); + Timestamp t4 = TimeUtil.nowTs(); + Timestamp t5 = TimeUtil.nowTs(); + GroupBundle b = + builder() + .group(g) + .members(member(g, 1)) + .memberAudit( + addAndLegacyRemoveMember(g, 1, 8, t1), + addMember(g, 1, 10, t2), + addAndRemoveMember(g, 1, 8, t3, 9, t4), + addMember(g, 1, 8, t5)) + .build(); + + rebuilder.rebuild(repo, b, null); + + assertMigratedCleanly(reload(g), b); + ImmutableList<CommitInfo> log = log(g); + assertThat(log).hasSize(6); + assertServerCommit(log.get(0), "Create group"); + assertCommit( + log.get(1), "Update group\n\nAdd: Account 1 <1@server-id>", "Account 8", "8@server-id"); + assertCommit( + log.get(2), "Update group\n\nRemove: Account 1 <1@server-id>", "Account 8", "8@server-id"); + assertCommit( + log.get(3), "Update group\n\nAdd: Account 1 <1@server-id>", "Account 10", "10@server-id"); + assertCommit( + log.get(4), "Update group\n\nRemove: Account 1 <1@server-id>", "Account 9", "9@server-id"); + assertCommit( + log.get(5), "Update group\n\nAdd: Account 1 <1@server-id>", "Account 8", "8@server-id"); + } + + @Test + public void redundantByIdAuditsAreIgnored() throws Exception { + AccountGroup g = newGroup("a"); + Timestamp t1 = TimeUtil.nowTs(); + Timestamp t2 = TimeUtil.nowTs(); + Timestamp t3 = TimeUtil.nowTs(); + Timestamp t4 = TimeUtil.nowTs(); + Timestamp t5 = TimeUtil.nowTs(); + GroupBundle b = + builder() + .group(g) + .byId() + .byIdAudit( + addById(g, "x", 8, t1), + addById(g, "x", 8, t3), + addById(g, "x", 9, t4), + addAndRemoveById(g, "x", 8, t2, 9, t5)) + .build(); + + rebuilder.rebuild(repo, b, null); + + assertMigratedCleanly(reload(g), b); + ImmutableList<CommitInfo> log = log(g); + assertThat(log).hasSize(3); + assertServerCommit(log.get(0), "Create group"); + assertCommit(log.get(1), "Update group\n\nAdd-group: Group x <x>", "Account 8", "8@server-id"); + assertCommit( + log.get(2), "Update group\n\nRemove-group: Group x <x>", "Account 9", "9@server-id"); + } + + @Test + public void combineWithBatchGroupNameNotes() throws Exception { + AccountGroup g1 = newGroup("a"); + AccountGroup g2 = newGroup("b"); + GroupReference gr1 = new GroupReference(g1.getGroupUUID(), g1.getName()); + GroupReference gr2 = new GroupReference(g2.getGroupUUID(), g2.getName()); + + GroupBundle b1 = builder().group(g1).build(); + GroupBundle b2 = builder().group(g2).build(); + + BatchRefUpdate bru = repo.getRefDatabase().newBatchUpdate(); + + rebuilder.rebuild(repo, b1, bru); + rebuilder.rebuild(repo, b2, bru); + try (ObjectInserter inserter = repo.newObjectInserter()) { + ImmutableList<GroupReference> refs = ImmutableList.of(gr1, gr2); + GroupNameNotes.updateAllGroups(repo, inserter, bru, refs, newPersonIdent()); + inserter.flush(); + } + + assertThat(log(g1)).isEmpty(); + assertThat(log(g2)).isEmpty(); + assertThat(logGroupNames()).isEmpty(); + + RefUpdateUtil.executeChecked(bru, repo); + + assertThat(log(g1)).hasSize(1); + assertThat(log(g2)).hasSize(1); + assertThat(logGroupNames()).hasSize(1); + assertMigratedCleanly(reload(g1), b1); + assertMigratedCleanly(reload(g2), b2); + + assertThat(GroupNameNotes.loadAllGroups(repo)).containsExactly(gr1, gr2); + } + + @Test + public void groupNamesWithLeadingAndTrailingWhitespace() throws Exception { + for (String leading : ImmutableList.of("", " ", " ")) { + for (String trailing : ImmutableList.of("", " ", " ")) { + AccountGroup g = newGroup(leading + "a" + trailing); + GroupBundle b = builder().group(g).build(); + rebuilder.rebuild(repo, b, null); + assertMigratedCleanly(reload(g), b); + } + } + } + + @Test + public void disallowExisting() throws Exception { + AccountGroup g = newGroup("a"); + GroupBundle b = builder().group(g).build(); + + rebuilder.rebuild(repo, b, null); + assertMigratedCleanly(reload(g), b); + String refName = RefNames.refsGroups(g.getGroupUUID()); + ObjectId oldId = repo.exactRef(refName).getObjectId(); + + try { + rebuilder.rebuild(repo, b, null); + assert_().fail("expected OrmDuplicateKeyException"); + } catch (OrmDuplicateKeyException e) { + // Expected. + } + + assertThat(repo.exactRef(refName).getObjectId()).isEqualTo(oldId); + } + + private GroupBundle reload(AccountGroup g) throws Exception { + return bundleFactory.fromNoteDb(allUsersName, repo, g.getGroupUUID()); + } + + private void assertMigratedCleanly(GroupBundle noteDbBundle, GroupBundle expectedReviewDbBundle) { + assertThat(GroupBundle.compareWithAudits(expectedReviewDbBundle, noteDbBundle)).isEmpty(); + } + + private AccountGroup newGroup(String name) { + int id = idCounter.incrementAndGet(); + return new AccountGroup( + new AccountGroup.NameKey(name), + new AccountGroup.Id(id), + new AccountGroup.UUID(name.trim() + "-" + id), + TimeUtil.nowTs()); + } + + private AccountGroupMember member(AccountGroup g, int accountId) { + return new AccountGroupMember(new AccountGroupMember.Key(new Account.Id(accountId), g.getId())); + } + + private AccountGroupMemberAudit addMember( + AccountGroup g, int accountId, int adder, Timestamp addedOn) { + return new AccountGroupMemberAudit(member(g, accountId), new Account.Id(adder), addedOn); + } + + private AccountGroupMemberAudit addAndLegacyRemoveMember( + AccountGroup g, int accountId, int adder, Timestamp addedOn) { + AccountGroupMemberAudit a = addMember(g, accountId, adder, addedOn); + a.removedLegacy(); + return a; + } + + private AccountGroupMemberAudit addAndRemoveMember( + AccountGroup g, + int accountId, + int adder, + Timestamp addedOn, + int removedBy, + Timestamp removedOn) { + AccountGroupMemberAudit a = addMember(g, accountId, adder, addedOn); + a.removed(new Account.Id(removedBy), removedOn); + return a; + } + + private AccountGroupByIdAud addById( + AccountGroup g, String subgroupUuid, int adder, Timestamp addedOn) { + return new AccountGroupByIdAud(byId(g, subgroupUuid), new Account.Id(adder), addedOn); + } + + private AccountGroupByIdAud addAndRemoveById( + AccountGroup g, + String subgroupUuid, + int adder, + Timestamp addedOn, + int removedBy, + Timestamp removedOn) { + AccountGroupByIdAud a = addById(g, subgroupUuid, adder, addedOn); + a.removed(new Account.Id(removedBy), removedOn); + return a; + } + + private AccountGroupById byId(AccountGroup g, String subgroupUuid) { + return new AccountGroupById( + new AccountGroupById.Key(g.getId(), new AccountGroup.UUID(subgroupUuid))); + } + + private ImmutableList<CommitInfo> log(AccountGroup g) throws Exception { + return GitTestUtil.log(repo, RefNames.refsGroups(g.getGroupUUID())); + } + + private ImmutableList<CommitInfo> logGroupNames() throws Exception { + return GitTestUtil.log(repo, REFS_GROUPNAMES); + } + + private static GroupBundle.Builder builder() { + return GroupBundle.builder().source(GroupBundle.Source.REVIEW_DB); + } + + private static PersonIdent newPersonIdent() { + return new PersonIdent(SERVER_NAME, SERVER_EMAIL, TimeUtil.nowTs(), TZ); + } + + private static void assertServerCommit(CommitInfo commitInfo, String expectedMessage) { + assertCommit(commitInfo, expectedMessage, SERVER_NAME, SERVER_EMAIL); + } + + private static void assertCommit( + CommitInfo commitInfo, String expectedMessage, String expectedName, String expectedEmail) { + assertThat(commitInfo).message().isEqualTo(expectedMessage); + assertThat(commitInfo).author().name().isEqualTo(expectedName); + assertThat(commitInfo).author().email().isEqualTo(expectedEmail); + + // Committer should always be the server, regardless of author. + assertThat(commitInfo).committer().name().isEqualTo(SERVER_NAME); + assertThat(commitInfo).committer().email().isEqualTo(SERVER_EMAIL); + assertThat(commitInfo).committer().date().isEqualTo(commitInfo.author.date); + assertThat(commitInfo).committer().tz().isEqualTo(commitInfo.author.tz); + } + + private static AuditLogFormatter getAuditLogFormatter() { + return AuditLogFormatter.create( + GroupRebuilderTest::getAccount, GroupRebuilderTest::getGroup, SERVER_ID); + } + + private static Optional<Account> getAccount(Account.Id id) { + Account account = new Account(id, TimeUtil.nowTs()); + account.setFullName("Account " + id); + return Optional.of(account); + } + + private static Optional<GroupDescription.Basic> getGroup(AccountGroup.UUID uuid) { + GroupDescription.Basic group = + new GroupDescription.Basic() { + @Override + public AccountGroup.UUID getGroupUUID() { + return uuid; + } + + @Override + public String getName() { + return "Group " + uuid; + } + + @Nullable + @Override + public String getEmailAddress() { + return null; + } + + @Nullable + @Override + public String getUrl() { + return null; + } + }; + return Optional.of(group); + } +} |