blob: e75dd22591d41600e1bf8386394dc6c774293c61 [file] [log] [blame]
/*
* Copyright (c) 2019, Google LLC and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.internal.transport.connectivity;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.verify;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.transport.PackParser;
import org.eclipse.jgit.transport.ReceiveCommand;
import org.eclipse.jgit.transport.ConnectivityChecker;
import org.eclipse.jgit.transport.ConnectivityChecker.ConnectivityCheckInfo;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
public class IterativeConnectivityCheckerTest {
@Rule
public MockitoRule rule = MockitoJUnit.rule();
private ObjectId branchHeadObjectId;
private ObjectId openRewiewObjectId;
private ObjectId newCommitObjectId;
private ObjectId otherHaveObjectId = ObjectId
.fromString("DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF");
private Set<ObjectId> advertisedHaves;
@Mock
private ConnectivityChecker connectivityCheckerDelegate;
@Mock
private ProgressMonitor pm;
@Mock
private PackParser parser;
private RevCommit branchHeadCommitObject;
private RevCommit openReviewCommitObject;
private RevCommit newCommitObject;
private ConnectivityCheckInfo connectivityCheckInfo;
private IterativeConnectivityChecker connectivityChecker;
private TestRepository tr;
@Before
public void setUp() throws Exception {
tr = new TestRepository<>(
new InMemoryRepository(new DfsRepositoryDescription("test")));
connectivityChecker = new IterativeConnectivityChecker(
connectivityCheckerDelegate);
connectivityCheckInfo = new ConnectivityCheckInfo();
connectivityCheckInfo.setParser(parser);
connectivityCheckInfo.setRepository(tr.getRepository());
connectivityCheckInfo.setWalk(tr.getRevWalk());
branchHeadCommitObject = tr.commit().create();
branchHeadObjectId = branchHeadCommitObject.getId();
openReviewCommitObject = tr.commit().create();
openRewiewObjectId = openReviewCommitObject.getId();
advertisedHaves = wrap(branchHeadObjectId, openRewiewObjectId,
otherHaveObjectId);
}
@Test
public void testSuccessfulNewBranchBasedOnOld() throws Exception {
createNewCommit(branchHeadCommitObject);
connectivityCheckInfo.setCommands(
Collections.singletonList(createNewBrachCommand()));
connectivityChecker.checkConnectivity(connectivityCheckInfo,
advertisedHaves, pm);
verify(connectivityCheckerDelegate).checkConnectivity(
connectivityCheckInfo,
wrap(branchHeadObjectId /* as direct parent */),
pm);
}
@Test
public void testSuccessfulNewBranchBasedOnOldWithTip() throws Exception {
createNewCommit(branchHeadCommitObject);
connectivityCheckInfo.setCommands(
Collections.singletonList(createNewBrachCommand()));
connectivityChecker.setForcedHaves(wrap(openRewiewObjectId));
connectivityChecker.checkConnectivity(connectivityCheckInfo,
advertisedHaves, pm);
verify(connectivityCheckerDelegate).checkConnectivity(
connectivityCheckInfo,
wrap(branchHeadObjectId /* as direct parent */,
openRewiewObjectId),
pm);
}
@Test
public void testSuccessfulNewBranchMerge() throws Exception {
createNewCommit(branchHeadCommitObject, openReviewCommitObject);
connectivityCheckInfo.setCommands(
Collections.singletonList(createNewBrachCommand()));
connectivityChecker.checkConnectivity(connectivityCheckInfo,
advertisedHaves, pm);
verify(connectivityCheckerDelegate).checkConnectivity(
connectivityCheckInfo,
wrap(branchHeadObjectId /* as direct parent */,
openRewiewObjectId),
pm);
}
@Test
public void testSuccessfulNewBranchBasedOnNewWithTip() throws Exception {
createNewCommit();
connectivityCheckInfo.setCommands(
Collections.singletonList(createNewBrachCommand()));
connectivityChecker.setForcedHaves(wrap(openRewiewObjectId));
connectivityChecker.checkConnectivity(connectivityCheckInfo,
advertisedHaves, pm);
verify(connectivityCheckerDelegate).checkConnectivity(
connectivityCheckInfo, wrap(openRewiewObjectId), pm);
}
@Test
public void testSuccessfulPushOldBranch() throws Exception {
createNewCommit(branchHeadCommitObject);
connectivityCheckInfo.setCommands(
Collections.singletonList(pushOldBranchCommand()));
connectivityChecker.checkConnectivity(connectivityCheckInfo,
advertisedHaves, pm);
verify(connectivityCheckerDelegate).checkConnectivity(
connectivityCheckInfo, wrap(branchHeadObjectId /* as direct parent */),
pm);
}
@Test
public void testSuccessfulPushOldBranchMergeCommit() throws Exception {
createNewCommit(branchHeadCommitObject, openReviewCommitObject);
connectivityCheckInfo.setCommands(
Collections.singletonList(pushOldBranchCommand()));
connectivityChecker.checkConnectivity(connectivityCheckInfo,
advertisedHaves, pm);
verify(connectivityCheckerDelegate).checkConnectivity(
connectivityCheckInfo,
wrap(branchHeadObjectId /* as direct parent */,
openRewiewObjectId),
pm);
}
@Test
public void testNoChecksIfCantFindSubset() throws Exception {
createNewCommit();
connectivityCheckInfo.setCommands(
Collections.singletonList(createNewBrachCommand()));
connectivityChecker.checkConnectivity(connectivityCheckInfo,
advertisedHaves, pm);
verify(connectivityCheckerDelegate)
.checkConnectivity(connectivityCheckInfo, advertisedHaves, pm);
}
@Test
public void testReiterateInCaseNotSuccessful() throws Exception {
createNewCommit(branchHeadCommitObject);
connectivityCheckInfo.setCommands(
Collections.singletonList(createNewBrachCommand()));
doThrow(new MissingObjectException(branchHeadCommitObject,
Constants.OBJ_COMMIT)).when(connectivityCheckerDelegate)
.checkConnectivity(connectivityCheckInfo,
wrap(branchHeadObjectId /* as direct parent */), pm);
connectivityChecker.checkConnectivity(connectivityCheckInfo,
advertisedHaves, pm);
verify(connectivityCheckerDelegate)
.checkConnectivity(connectivityCheckInfo, advertisedHaves, pm);
}
@Test
public void testDependOnGrandparent() throws Exception {
RevCommit grandparent = tr.commit(new RevCommit[] {});
RevCommit parent = tr.commit(grandparent);
createNewCommit(parent);
branchHeadCommitObject = tr.commit(grandparent);
branchHeadObjectId = branchHeadCommitObject.getId();
tr.getRevWalk().dispose();
connectivityCheckInfo.setCommands(
Collections.singletonList(createNewBrachCommand()));
connectivityChecker.checkConnectivity(connectivityCheckInfo,
advertisedHaves, pm);
verify(connectivityCheckerDelegate)
.checkConnectivity(connectivityCheckInfo, advertisedHaves, pm);
}
private static Set<ObjectId> wrap(ObjectId... objectIds) {
return new HashSet<>(Arrays.asList(objectIds));
}
private ReceiveCommand createNewBrachCommand() {
return new ReceiveCommand(ObjectId.zeroId(), newCommitObjectId,
"totally/a/new/branch");
}
private ReceiveCommand pushOldBranchCommand() {
return new ReceiveCommand(branchHeadObjectId, newCommitObjectId,
"push/to/an/old/branch");
}
private void createNewCommit(RevCommit... parents) throws Exception {
newCommitObject = tr.commit(parents);
newCommitObjectId = newCommitObject.getId();
}
}