mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-04 00:20:55 +07:00
272 lines
11 KiB
Java
272 lines
11 KiB
Java
package org.jetbrains.idea.svn17;
|
|
|
|
import com.intellij.openapi.util.Pair;
|
|
import com.intellij.openapi.util.Ref;
|
|
import com.intellij.openapi.util.io.FileUtil;
|
|
import com.intellij.openapi.vcs.changes.committed.ChangesBunch;
|
|
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
|
|
import com.intellij.testFramework.fixtures.CodeInsightFixtureTestCase;
|
|
import org.jetbrains.idea.svn17.history.*;
|
|
import org.tmatesoft.svn.core.SVNException;
|
|
import org.tmatesoft.svn.core.SVNLogEntry;
|
|
import org.tmatesoft.svn.core.wc.SVNRevision;
|
|
|
|
import java.util.*;
|
|
|
|
public class SvnCachingRevisionsTest extends CodeInsightFixtureTestCase {
|
|
private SvnRepositoryLocation myLocation;
|
|
private LoadedRevisionsCache17 myInternalManager;
|
|
private final static String URL = "file:///C:/repo/trunk";
|
|
private final static String ROOT = "file:///C:/repo";
|
|
private final static String AUTHOR = "author";
|
|
private final static int PAGE = 5;
|
|
|
|
@Override
|
|
protected void setUp() throws Exception {
|
|
super.setUp();
|
|
myLocation = new SvnRepositoryLocation(URL);
|
|
myInternalManager = LoadedRevisionsCache17.getInstance(myFixture.getProject());
|
|
}
|
|
|
|
@Override
|
|
protected void tearDown() throws Exception {
|
|
FileUtil.delete(SvnApplicationSettings17.getLoadedRevisionsDir(myFixture.getProject()));
|
|
super.tearDown();
|
|
}
|
|
|
|
private SvnChangeList createList(final long revision) {
|
|
return new SvnChangeList(null, myLocation,
|
|
new SVNLogEntry(Collections.emptyMap(), revision, AUTHOR, new Date(System.currentTimeMillis()), ""), ROOT);
|
|
}
|
|
|
|
private class MockSvnLogLoader implements SvnLogLoader {
|
|
private final List<Long> myRevisions;
|
|
|
|
private MockSvnLogLoader(final List<Long> revisions) {
|
|
myRevisions = revisions;
|
|
}
|
|
|
|
@Override
|
|
public List<CommittedChangeList> loadInterval(final SVNRevision fromIncluding, final SVNRevision toIncluding, final int maxCount,
|
|
final boolean includingYoungest, final boolean includeOldest) throws SVNException {
|
|
long young = fromIncluding.getNumber();
|
|
young = (young == -1) ? myRevisions.get(myRevisions.size() - 1) : young;
|
|
final long old = toIncluding.getNumber();
|
|
|
|
final List<CommittedChangeList> result = new ArrayList<CommittedChangeList>();
|
|
|
|
int cnt = -1;
|
|
// from back
|
|
for (int i = myRevisions.size() - 1; i >= 0; -- i) {
|
|
final Long current = myRevisions.get(i);
|
|
if ((cnt == -1) && (current <= young)) {
|
|
cnt = 0;
|
|
}
|
|
if (cnt >= 0) {
|
|
++ cnt;
|
|
}
|
|
if ((young > current) || (includingYoungest && (young == current))) {
|
|
if ((old < current) || (includeOldest && (old == current))) {
|
|
result.add(createList(current));
|
|
}
|
|
}
|
|
if (cnt == maxCount) {
|
|
break;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
|
|
private LiveProvider createLiveProvider(final List<Long> liveRevisions) {
|
|
return new LiveProvider(null, myLocation, liveRevisions.get(liveRevisions.size() - 1), new MockSvnLogLoader(liveRevisions));
|
|
}
|
|
|
|
private void checkBounds(final Pair<Long, Long> bounds, final long startRevision, final int step) {
|
|
assert (bounds.first - startRevision) % step == 0;
|
|
assert (bounds.second - startRevision) % step == 0;
|
|
}
|
|
|
|
private class MockCachedProvider extends CachedProvider {
|
|
private MockCachedProvider(final Iterator<ChangesBunch> iterator, final Origin origin) {
|
|
super(iterator, origin);
|
|
}
|
|
|
|
@Override
|
|
public void doCacheUpdate(final List<List<Fragment>> fragments) {
|
|
assert false;
|
|
}
|
|
}
|
|
|
|
private Iterator<ChangesBunch> createCommittedIterator(final int bunchSize, final List<Long> revisions) {
|
|
final List<ChangesBunch> list = new ArrayList<ChangesBunch>();
|
|
for (int i = revisions.size() - 1; i >= 0; i -= bunchSize) {
|
|
final int j = (bunchSize > i) ? -1 : (i - bunchSize);
|
|
final List<CommittedChangeList> subList = new ArrayList<CommittedChangeList>();
|
|
for (int k = i; k > j; -- k) {
|
|
subList.add(createList(revisions.get(k)));
|
|
}
|
|
list.add(new ChangesBunch(subList, (j != -1)));
|
|
if (j == -1) {
|
|
break;
|
|
}
|
|
}
|
|
return list.iterator();
|
|
}
|
|
|
|
private void performTest(final long startRevision, final int step, final Pair<Long, Long> committedBounds,
|
|
final List<Pair<Long, Long>> internalBounds, final long endRevision) throws Exception {
|
|
assert ((endRevision - startRevision) % step) == 0;
|
|
if (committedBounds != null) {
|
|
checkBounds(committedBounds, startRevision, step);
|
|
}
|
|
for (Pair<Long, Long> bound : internalBounds) {
|
|
checkBounds(bound, startRevision, step);
|
|
}
|
|
|
|
final List<Long> liveRevisions = new ArrayList<Long>();
|
|
final List<Long> committedRevisions = new ArrayList<Long>();
|
|
for (long i = startRevision; i <= endRevision; i += step) {
|
|
liveRevisions.add(i);
|
|
if (committedBounds != null) {
|
|
if ((committedBounds.first <= i) && (committedBounds.second >= i)) {
|
|
committedRevisions.add(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
// each pair corresponds to interval
|
|
final List<Long> internalRevisions = new ArrayList<Long>();
|
|
LoadedRevisionsCache17.Bunch bindTo = null;
|
|
for (int i = 0; i < internalBounds.size(); i++) {
|
|
final Pair<Long, Long> bound = internalBounds.get(i);
|
|
final boolean consistent = (i != 0) && (internalBounds.get(i - 1).second + step == bound.first);
|
|
final List<Long> revisions = new ArrayList<Long>();
|
|
for (long j = bound.first; j <= bound.second; j += step) {
|
|
revisions.add(j);
|
|
internalRevisions.add(j);
|
|
}
|
|
bindTo = putToInternalCache(revisions, consistent, bindTo);
|
|
}
|
|
|
|
assert Collections.disjoint(committedRevisions, internalRevisions);
|
|
|
|
final LiveProvider liveProvider = createLiveProvider(liveRevisions);
|
|
final CachedProvider committedProvider = committedRevisions.isEmpty() ? null :
|
|
new MockCachedProvider(createCommittedIterator(PAGE, committedRevisions), Origin.VISUAL);
|
|
final CachedProvider internalProvider = internalRevisions.isEmpty() ? null :
|
|
new MockCachedProvider(myInternalManager.iterator(myLocation.getURL()), Origin.INTERNAL);
|
|
|
|
final BunchFactory factory = new BunchFactory(internalProvider, committedProvider, liveProvider);
|
|
Ref<Boolean> myYoungestRead = new Ref<Boolean>(Boolean.FALSE);
|
|
long i = endRevision;
|
|
for (; i >= startRevision; i -= step * PAGE) {
|
|
assert (! Boolean.TRUE.equals(myYoungestRead.get()));
|
|
final List<Fragment> fragments = factory.goBack(PAGE, myYoungestRead);
|
|
debugFragments(i, fragments);
|
|
checkFragments(i, internalRevisions, committedRevisions, fragments, step);
|
|
}
|
|
// otherwise end of live stream is not jet detected (additional request is required)
|
|
assert (! (i + step < startRevision) ^ Boolean.TRUE.equals(myYoungestRead.get()));
|
|
}
|
|
|
|
private void checkFragments(final long earlyRevision, final List<Long> internally, final List<Long> committed,
|
|
final List<Fragment> fragments, final int step) {
|
|
final List<Long> expectedRevisions = new ArrayList<Long>();
|
|
for (long i = earlyRevision; i > (earlyRevision - PAGE * step); i -= step) {
|
|
expectedRevisions.add(i);
|
|
}
|
|
|
|
for (Fragment fragment : fragments) {
|
|
final Origin currentOrigin = fragment.getOrigin();
|
|
for (CommittedChangeList list : fragment.getList()) {
|
|
assert ! expectedRevisions.isEmpty();
|
|
final long expected = expectedRevisions.remove(0);
|
|
assert expected == list.getNumber();
|
|
assert (Origin.INTERNAL.equals(currentOrigin) && (internally.contains(expected))) ||
|
|
(Origin.VISUAL.equals(currentOrigin) && (committed.contains(expected))) ||
|
|
(Origin.LIVE.equals(currentOrigin) && (! internally.contains(expected)) && (! committed.contains(expected)));
|
|
}
|
|
}
|
|
}
|
|
|
|
private void debugFragments(final long earlyRevision, final List<Fragment> fragments) {
|
|
//System.out.println("Loaded for start revision: " + earlyRevision);
|
|
//for (Fragment fragment : fragments) {
|
|
// System.out.println(fragment.getOrigin().toString() + " from: " + fragment.getList().get(0).getNumber() +
|
|
// " to: " + fragment.getList().get(fragment.getList().size() - 1).getNumber());
|
|
//}
|
|
//System.out.println();
|
|
}
|
|
|
|
private List<CommittedChangeList> revisionsToLists(final List<Long> revisions) {
|
|
final List<CommittedChangeList> lists = new ArrayList<CommittedChangeList>();
|
|
for (Long revision : revisions) {
|
|
lists.add(createList(revision));
|
|
}
|
|
return lists;
|
|
}
|
|
|
|
private LoadedRevisionsCache17.Bunch putToInternalCache(final List<Long> revisions, final boolean consistent, final LoadedRevisionsCache17.Bunch bindTo) {
|
|
final List<CommittedChangeList> lists = revisionsToLists(revisions);
|
|
Collections.reverse(lists);
|
|
return myInternalManager.put(lists, consistent, bindTo);
|
|
}
|
|
|
|
public void testJustLiveProvider() throws Exception {
|
|
performTest(11, 2, null, Collections.<Pair<Long, Long>>emptyList(), 121);
|
|
}
|
|
|
|
public void testLiveAndSimpleInternalProvider() throws Exception {
|
|
for (int i = 0; i < 2 * PAGE; i+=2) {
|
|
performTest(11, 2, null, Collections.singletonList(new Pair<Long, Long>(109L, 117L)), 121 + i);
|
|
}
|
|
}
|
|
|
|
public void testLiveAndSimpleCommittedProvider() throws Exception {
|
|
for (int i = 0; i < 2 * PAGE; i+=2) {
|
|
performTest(11, 2, new Pair<Long, Long>(19L, 117L), Collections.<Pair<Long, Long>>emptyList(), 121 + i);
|
|
}
|
|
}
|
|
|
|
public void testLiveAndTwoInternalsProvider() throws Exception {
|
|
for (int i = 0; i < 2 * PAGE; i+=2) {
|
|
performTest(11, 2, null, Arrays.asList(new Pair<Long, Long>(101L, 111L), new Pair<Long, Long>(113L, 117L)), 121 + i);
|
|
}
|
|
}
|
|
|
|
public void testCommittedAndSeveralInternalsProvider() throws Exception {
|
|
for (int i = 0; i < 2 * PAGE; i+=2) {
|
|
performTest(11, 2, new Pair<Long, Long>(11L, 17L), Arrays.asList(new Pair<Long, Long>(19L, 23L), new Pair<Long, Long>(25L, 37L + i)), 37 + i);
|
|
}
|
|
}
|
|
|
|
public void testAllThreeProviders() throws Exception {
|
|
for (int i = 0; i < 2 * PAGE; i+=2) {
|
|
performTest(11, 2, new Pair<Long, Long>(11L, 17L), Arrays.asList(new Pair<Long, Long>(23L, 37L), new Pair<Long, Long>(45L, 57L)), 87 + i);
|
|
}
|
|
}
|
|
|
|
public void testShift() throws Exception {
|
|
for (int i = 0; i < 2 * PAGE; i+=2) {
|
|
performTest(11, 2, new Pair<Long, Long>(11L, 15L), Arrays.asList(new Pair<Long, Long>(17L, 25L), new Pair<Long, Long>(27L, 35L)), 37 + i);
|
|
}
|
|
}
|
|
|
|
public void testShortLive() throws Exception {
|
|
performTest(11, 2, null, Collections.<Pair<Long, Long>>emptyList(), 13);
|
|
}
|
|
|
|
public void testShortInternal() throws Exception {
|
|
performTest(11, 2, null, Collections.singletonList(new Pair<Long, Long>(11L, 15L)), 15);
|
|
}
|
|
|
|
public void testShortCommitted() throws Exception {
|
|
performTest(11, 2, new Pair<Long, Long>(11L, 15L), Collections.<Pair<Long, Long>>emptyList(), 15);
|
|
}
|
|
|
|
public void testThreeByOne() throws Exception {
|
|
performTest(11, 2, new Pair<Long, Long>(11L, 11L), Collections.singletonList(new Pair<Long, Long>(13L, 13L)), 15);
|
|
}
|
|
}
|