| // Copyright (C) 2014 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.testing; | |
| import static com.google.common.base.MoreObjects.firstNonNull; | |
| import com.google.common.collect.Ordering; | |
| import com.google.gerrit.entities.Account; | |
| import com.google.gerrit.entities.BranchNameKey; | |
| import com.google.gerrit.entities.Change; | |
| import com.google.gerrit.entities.PatchSet; | |
| import com.google.gerrit.entities.PatchSetInfo; | |
| import com.google.gerrit.entities.Project; | |
| import com.google.gerrit.extensions.config.FactoryModule; | |
| import com.google.gerrit.server.CurrentUser; | |
| import com.google.gerrit.server.git.GitRepositoryManager; | |
| import com.google.gerrit.server.notedb.AbstractChangeNotes; | |
| import com.google.gerrit.server.notedb.ChangeNotes; | |
| import com.google.gerrit.server.notedb.ChangeUpdate; | |
| import com.google.gerrit.server.util.time.TimeUtil; | |
| import com.google.inject.Injector; | |
| import java.time.ZoneId; | |
| import java.util.Optional; | |
| import java.util.concurrent.atomic.AtomicInteger; | |
| import org.eclipse.jgit.junit.TestRepository; | |
| import org.eclipse.jgit.lib.ObjectId; | |
| import org.eclipse.jgit.lib.PersonIdent; | |
| import org.eclipse.jgit.lib.Ref; | |
| import org.eclipse.jgit.lib.Repository; | |
| /** | |
| * Utility functions to create and manipulate Change, ChangeUpdate, and ChangeControl objects for | |
| * testing. | |
| */ | |
| public class TestChanges { | |
| private static final AtomicInteger nextChangeId = new AtomicInteger(1); | |
| public static Change newChange(Project.NameKey project, Account.Id userId) { | |
| return newChange(project, userId, nextChangeId.getAndIncrement()); | |
| } | |
| public static Change newChange(Project.NameKey project, Account.Id userId, int id) { | |
| Change.Id changeId = Change.id(id); | |
| Change c = | |
| new Change( | |
| Change.key("Iabcd1234abcd1234abcd1234abcd1234abcd1234"), | |
| changeId, | |
| userId, | |
| BranchNameKey.create(project, "master"), | |
| TimeUtil.now()); | |
| incrementPatchSet(c); | |
| return c; | |
| } | |
| public static PatchSet newPatchSet(PatchSet.Id id, ObjectId revision, Account.Id userId) { | |
| return newPatchSet(id, revision.name(), userId); | |
| } | |
| public static PatchSet newPatchSet(PatchSet.Id id, String revision, Account.Id userId) { | |
| return PatchSet.builder() | |
| .id(id) | |
| .commitId(ObjectId.fromString(revision)) | |
| .uploader(userId) | |
| .realUploader(userId) | |
| .createdOn(TimeUtil.now()) | |
| .build(); | |
| } | |
| public static ChangeUpdate newUpdate( | |
| Injector injector, Change c, Optional<CurrentUser> user, boolean shouldExist) | |
| throws Exception { | |
| injector = | |
| injector.createChildInjector( | |
| new FactoryModule() { | |
| @Override | |
| public void configure() { | |
| if (user.isPresent()) { | |
| // user may be already bound in injector | |
| bind(CurrentUser.class).toInstance(user.get()); | |
| } | |
| } | |
| }); | |
| CurrentUser currentUser = injector.getProvider(CurrentUser.class).get(); | |
| ChangeUpdate update = | |
| injector | |
| .getInstance(ChangeUpdate.Factory.class) | |
| .create( | |
| new ChangeNotes( | |
| injector.getInstance(AbstractChangeNotes.Args.class), c, shouldExist, null) | |
| .load(), | |
| currentUser, | |
| TimeUtil.now(), | |
| Ordering.natural()); | |
| ChangeNotes notes = update.getNotes(); | |
| boolean hasPatchSets = notes.getPatchSets() != null && !notes.getPatchSets().isEmpty(); | |
| if (hasPatchSets) { | |
| return update; | |
| } | |
| // Change doesn't exist yet. NoteDb requires that there be a commit for the | |
| // first patch set, so create one. | |
| GitRepositoryManager repoManager = injector.getInstance(GitRepositoryManager.class); | |
| try (Repository repo = repoManager.openRepository(c.getProject()); | |
| TestRepository<Repository> tr = new TestRepository<>(repo)) { | |
| PersonIdent ident = | |
| currentUser | |
| .asIdentifiedUser() | |
| .newCommitterIdent(update.getWhen(), ZoneId.systemDefault()); | |
| TestRepository<Repository>.CommitBuilder cb = | |
| tr.commit() | |
| .author(ident) | |
| .committer(ident) | |
| .message(firstNonNull(c.getSubject(), "Test change")); | |
| Ref parent = repo.exactRef(c.getDest().branch()); | |
| if (parent != null) { | |
| cb.parent(tr.getRevWalk().parseCommit(parent.getObjectId())); | |
| } | |
| update.setBranch(c.getDest().branch()); | |
| update.setChangeId(c.getKey().get()); | |
| update.setCommit(tr.getRevWalk(), cb.create()); | |
| return update; | |
| } | |
| } | |
| public static void incrementPatchSet(Change change) { | |
| PatchSet.Id curr = change.currentPatchSetId(); | |
| PatchSetInfo ps = | |
| new PatchSetInfo(PatchSet.id(change.getId(), curr != null ? curr.get() + 1 : 1)); | |
| ps.setSubject("Change subject"); | |
| change.setCurrentPatchSet(ps); | |
| } | |
| } |