summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.test
diff options
context:
space:
mode:
authorMatthias Sohn <matthias.sohn@sap.com>2023-08-30 16:43:08 +0200
committerMatthias Sohn <matthias.sohn@sap.com>2023-08-30 16:43:08 +0200
commit2e2e58d59f1546a791983e2b28adb99c71a93a34 (patch)
treee271bafe57718add342e23d552bdf0d710e7a807 /org.eclipse.jgit.test
parentabe155ea94af563110326a44d538fdb4f0af8bba (diff)
parent2be8bf2b37177256e5183f26b7ccd13e104daf5f (diff)
downloadjgit-2e2e58d59f1546a791983e2b28adb99c71a93a34.tar.gz
jgit-2e2e58d59f1546a791983e2b28adb99c71a93a34.zip
Merge branch 'master' into stable-6.7
* master: Remove the cbi-snapshots Maven repository Update Orbit to orbit-aggregation/release/4.29.0 Add target platform for Eclipse 2023-09 (4.29) Use release p2 repo for Eclipse 2023-06 (4.28) Update tycho to 4.0.2 Update jmh to 1.37 Update bouncycastle to 1.76 Fix some tests in ConfigTest Handle global git config $XDG_CONFIG_HOME/git/config IO: use JDK convenience methods org.eclipse.jgit.junit.ssh/.settings/.api_filters: fix unclosed tags ReadChangedPathFilter: fix Non-externalized string literal warning Introduce core.packedIndexGitUseStrongRefs config key DfsReader: Make PackLoadListener interface visible to subclasses DfsGarbageCollector: provide commit graph stats DfsGarbageCollector: put only GC commits into the commit graph DfsReader: Expose when indices are loaded Change-Id: Idd78a0a1bc3cd3db5edb475e235c13354d9087a9
Diffstat (limited to 'org.eclipse.jgit.test')
-rw-r--r--org.eclipse.jgit.test/META-INF/MANIFEST.MF4
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java46
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackFileTest.java91
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsReaderTest.java142
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackTest.java2
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java16
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/UserConfigFileTest.java301
7 files changed, 562 insertions, 40 deletions
diff --git a/org.eclipse.jgit.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
index d4d84bcd90..3ae2d6b5dc 100644
--- a/org.eclipse.jgit.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
@@ -7,6 +7,8 @@ Bundle-Version: 6.7.0.qualifier
Bundle-Localization: plugin
Bundle-Vendor: %Bundle-Vendor
Bundle-RequiredExecutionEnvironment: JavaSE-11
+Require-Bundle: org.hamcrest.core;bundle-version="[1.3.0,2.0.0)",
+ org.hamcrest.library;bundle-version="[1.3.0,2.0.0)"
Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)",
net.bytebuddy.agent;version="[1.9.0,2.0.0)",
net.bytebuddy.dynamic.loading;version="[1.9.0,2.0.0)",
@@ -75,8 +77,6 @@ Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)",
org.eclipse.jgit.util;version="[6.7.0,6.8.0)",
org.eclipse.jgit.util.io;version="[6.7.0,6.8.0)",
org.eclipse.jgit.util.sha1;version="[6.7.0,6.8.0)",
- org.hamcrest;version="[1.1.0,3.0.0)",
- org.hamcrest.collection;version="[1.1.0,3.0.0)",
org.junit;version="[4.13,5.0.0)",
org.junit.experimental.theories;version="[4.13,5.0.0)",
org.junit.function;version="[4.13.0,5.0.0)",
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java
index 405e12677e..05360dc052 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java
@@ -20,6 +20,7 @@ import java.util.Collections;
import java.util.concurrent.TimeUnit;
import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph;
+import org.eclipse.jgit.internal.storage.commitgraph.CommitGraphWriter;
import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource;
import org.eclipse.jgit.internal.storage.reftable.RefCursor;
import org.eclipse.jgit.internal.storage.reftable.ReftableConfig;
@@ -979,7 +980,7 @@ public class DfsGarbageCollectorTest {
}
@Test
- public void produceCommitGraphAllRefsIncludedFromDisk() throws Exception {
+ public void produceCommitGraphOnlyHeadsAndTags() throws Exception {
String tag = "refs/tags/tag1";
String head = "refs/heads/head1";
String nonHead = "refs/something/nonHead";
@@ -1001,19 +1002,20 @@ public class DfsGarbageCollectorTest {
CommitGraph cg = gcPack.getCommitGraph(reader);
assertNotNull(cg);
- assertTrue("all commits in commit graph", cg.getCommitCnt() == 3);
+ assertTrue("Only heads and tags reachable commits in commit graph",
+ cg.getCommitCnt() == 2);
// GC packed
assertTrue("tag referenced commit is in graph",
cg.findGraphPosition(rootCommitTagged) != -1);
assertTrue("head referenced commit is in graph",
cg.findGraphPosition(headTip) != -1);
- // GC_REST packed
- assertTrue("nonHead referenced commit is in graph",
- cg.findGraphPosition(nonHeadTip) != -1);
+ // GC_REST not in commit graph
+ assertEquals("nonHead referenced commit is NOT in graph",
+ -1, cg.findGraphPosition(nonHeadTip));
}
@Test
- public void produceCommitGraphAllRefsIncludedFromCache() throws Exception {
+ public void produceCommitGraphOnlyHeadsAndTagsIncludedFromCache() throws Exception {
String tag = "refs/tags/tag1";
String head = "refs/heads/head1";
String nonHead = "refs/something/nonHead";
@@ -1043,15 +1045,16 @@ public class DfsGarbageCollectorTest {
assertTrue("commit graph read time is recorded",
reader.stats.readCommitGraphMicros > 0);
- assertTrue("all commits in commit graph", cachedCG.getCommitCnt() == 3);
+ assertTrue("Only heads and tags reachable commits in commit graph",
+ cachedCG.getCommitCnt() == 2);
// GC packed
assertTrue("tag referenced commit is in graph",
cachedCG.findGraphPosition(rootCommitTagged) != -1);
assertTrue("head referenced commit is in graph",
cachedCG.findGraphPosition(headTip) != -1);
- // GC_REST packed
- assertTrue("nonHead referenced commit is in graph",
- cachedCG.findGraphPosition(nonHeadTip) != -1);
+ // GC_REST not in commit graph
+ assertEquals("nonHead referenced commit is not in graph",
+ -1, cachedCG.findGraphPosition(nonHeadTip));
}
@Test
@@ -1102,6 +1105,22 @@ public class DfsGarbageCollectorTest {
}
@Test
+ public void produceCommitGraphAndBloomFilter() throws Exception {
+ String head = "refs/heads/head1";
+
+ git.branch(head).commit().message("0").noParents().create();
+
+ gcWithCommitGraphAndBloomFilter();
+
+ assertEquals(1, odb.getPacks().length);
+ DfsPackFile pack = odb.getPacks()[0];
+ DfsPackDescription desc = pack.getPackDescription();
+ CommitGraphWriter.Stats stats = desc.getCommitGraphStats();
+ assertNotNull(stats);
+ assertEquals(1, stats.getChangedPathFiltersComputed());
+ }
+
+ @Test
public void objectSizeIdx_reachableBlob_bigEnough_indexed() throws Exception {
String master = "refs/heads/master";
RevCommit root = git.branch(master).commit().message("root").noParents()
@@ -1175,6 +1194,13 @@ public class DfsGarbageCollectorTest {
run(gc);
}
+ private void gcWithCommitGraphAndBloomFilter() throws IOException {
+ DfsGarbageCollector gc = new DfsGarbageCollector(repo);
+ gc.setWriteCommitGraph(true);
+ gc.setWriteBloomFilter(true);
+ run(gc);
+ }
+
private void gcWithObjectSizeIndex(int threshold) throws IOException {
DfsGarbageCollector gc = new DfsGarbageCollector(repo);
gc.getPackConfig().setMinBytesForObjSizeIndex(threshold);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackFileTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackFileTest.java
index 298812d6ed..82fc56347e 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackFileTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackFileTest.java
@@ -18,8 +18,12 @@ import static org.junit.Assert.assertTrue;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
import java.util.zip.Deflater;
+import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource;
+import org.eclipse.jgit.internal.storage.dfs.DfsReader.PackLoadListener;
import org.eclipse.jgit.internal.storage.pack.PackExt;
import org.eclipse.jgit.internal.storage.pack.PackOutputStream;
import org.eclipse.jgit.internal.storage.pack.PackWriter;
@@ -130,6 +134,93 @@ public class DfsPackFileTest {
assertFalse(pack.hasObjectSizeIndex(reader));
}
+ private static class TestPackLoadListener implements PackLoadListener {
+ final Map<PackExt, Integer> indexLoadCount = new HashMap<>();
+
+ int blockLoadCount;
+
+ @Override
+ public void onIndexLoad(String packName, PackSource src, PackExt ext,
+ long size, Object loadedIdx) {
+ indexLoadCount.merge(ext, 1, Integer::sum);
+ }
+
+ @Override
+ public void onBlockLoad(String packName, PackSource src, PackExt ext, long position,
+ DfsBlockData dfsBlockData) {
+ blockLoadCount += 1;
+ }
+ }
+
+ @Test
+ public void testIndexLoadCallback_indexNotInCache() throws IOException {
+ bypassCache = false;
+ clearCache = true;
+ setObjectSizeIndexMinBytes(-1);
+ setupPack(512, 800);
+
+ TestPackLoadListener tal = new TestPackLoadListener();
+ DfsReader reader = db.getObjectDatabase().newReader();
+ reader.addPackLoadListener(tal);
+ DfsPackFile pack = db.getObjectDatabase().getPacks()[0];
+ pack.getPackIndex(reader);
+
+ assertEquals(1, tal.indexLoadCount.get(PackExt.INDEX).intValue());
+ }
+
+ @Test
+ public void testIndexLoadCallback_indexInCache() throws IOException {
+ bypassCache = false;
+ clearCache = false;
+ setObjectSizeIndexMinBytes(-1);
+ setupPack(512, 800);
+
+ TestPackLoadListener tal = new TestPackLoadListener();
+ DfsReader reader = db.getObjectDatabase().newReader();
+ reader.addPackLoadListener(tal);
+ DfsPackFile pack = db.getObjectDatabase().getPacks()[0];
+ pack.getPackIndex(reader);
+ pack.getPackIndex(reader);
+ pack.getPackIndex(reader);
+
+ assertEquals(1, tal.indexLoadCount.get(PackExt.INDEX).intValue());
+ }
+
+ @Test
+ public void testIndexLoadCallback_multipleReads() throws IOException {
+ bypassCache = false;
+ clearCache = true;
+ setObjectSizeIndexMinBytes(-1);
+ setupPack(512, 800);
+
+ TestPackLoadListener tal = new TestPackLoadListener();
+ DfsReader reader = db.getObjectDatabase().newReader();
+ reader.addPackLoadListener(tal);
+ DfsPackFile pack = db.getObjectDatabase().getPacks()[0];
+ pack.getPackIndex(reader);
+ pack.getPackIndex(reader);
+ pack.getPackIndex(reader);
+
+ assertEquals(1, tal.indexLoadCount.get(PackExt.INDEX).intValue());
+ }
+
+
+ @Test
+ public void testBlockLoadCallback_loadInCache() throws IOException {
+ bypassCache = false;
+ clearCache = true;
+ setObjectSizeIndexMinBytes(-1);
+ setupPack(512, 800);
+
+ TestPackLoadListener tal = new TestPackLoadListener();
+ DfsReader reader = db.getObjectDatabase().newReader();
+ reader.addPackLoadListener(tal);
+ DfsPackFile pack = db.getObjectDatabase().getPacks()[0];
+ ObjectId anObject = pack.getPackIndex(reader).getObjectId(0);
+ pack.get(reader, anObject).getBytes();
+ assertEquals(2, tal.blockLoadCount);
+ }
+
private ObjectId setupPack(int bs, int ps) throws IOException {
DfsBlockCacheConfig cfg = new DfsBlockCacheConfig().setBlockSize(bs)
.setBlockLimit(bs * 100).setStreamRatio(bypassCache ? 0F : 1F);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsReaderTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsReaderTest.java
index 4dd7ba494f..8fc9a0adf9 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsReaderTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsReaderTest.java
@@ -11,15 +11,20 @@ package org.eclipse.jgit.internal.storage.dfs;
import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_MIN_BYTES_OBJ_SIZE_INDEX;
import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_PACK_SECTION;
+import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertEquals;
import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource;
+import org.eclipse.jgit.internal.storage.dfs.DfsReader.PackLoadListener;
+import org.eclipse.jgit.internal.storage.pack.PackExt;
import org.eclipse.jgit.junit.JGitTestUtil;
import org.eclipse.jgit.junit.TestRng;
-import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.junit.Before;
@@ -40,31 +45,31 @@ public class DfsReaderTest {
ObjectId obj = insertBlobWithSize(200);
try (DfsReader ctx = db.getObjectDatabase().newReader()) {
assertFalse("limit < threshold < obj",
- ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 50));
+ ctx.isNotLargerThan(obj, OBJ_BLOB, 50));
assertEquals(1, ctx.stats.isNotLargerThanCallCount);
assertEquals(1, ctx.stats.objectSizeIndexHit);
assertEquals(0, ctx.stats.objectSizeIndexMiss);
assertFalse("limit = threshold < obj",
- ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 100));
+ ctx.isNotLargerThan(obj, OBJ_BLOB, 100));
assertEquals(2, ctx.stats.isNotLargerThanCallCount);
assertEquals(2, ctx.stats.objectSizeIndexHit);
assertEquals(0, ctx.stats.objectSizeIndexMiss);
assertFalse("threshold < limit < obj",
- ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 150));
+ ctx.isNotLargerThan(obj, OBJ_BLOB, 150));
assertEquals(3, ctx.stats.isNotLargerThanCallCount);
assertEquals(3, ctx.stats.objectSizeIndexHit);
assertEquals(0, ctx.stats.objectSizeIndexMiss);
assertTrue("threshold < limit = obj",
- ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 200));
+ ctx.isNotLargerThan(obj, OBJ_BLOB, 200));
assertEquals(4, ctx.stats.isNotLargerThanCallCount);
assertEquals(4, ctx.stats.objectSizeIndexHit);
assertEquals(0, ctx.stats.objectSizeIndexMiss);
assertTrue("threshold < obj < limit",
- ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 250));
+ ctx.isNotLargerThan(obj, OBJ_BLOB, 250));
assertEquals(5, ctx.stats.isNotLargerThanCallCount);
assertEquals(5, ctx.stats.objectSizeIndexHit);
assertEquals(0, ctx.stats.objectSizeIndexMiss);
@@ -80,31 +85,31 @@ public class DfsReaderTest {
ObjectId obj = insertBlobWithSize(50);
try (DfsReader ctx = db.getObjectDatabase().newReader()) {
assertFalse("limit < obj < threshold",
- ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 10));
+ ctx.isNotLargerThan(obj, OBJ_BLOB, 10));
assertEquals(1, ctx.stats.isNotLargerThanCallCount);
assertEquals(0, ctx.stats.objectSizeIndexHit);
assertEquals(1, ctx.stats.objectSizeIndexMiss);
assertTrue("limit = obj < threshold",
- ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 50));
+ ctx.isNotLargerThan(obj, OBJ_BLOB, 50));
assertEquals(2, ctx.stats.isNotLargerThanCallCount);
assertEquals(0, ctx.stats.objectSizeIndexHit);
assertEquals(2, ctx.stats.objectSizeIndexMiss);
assertTrue("obj < limit < threshold",
- ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 80));
+ ctx.isNotLargerThan(obj, OBJ_BLOB, 80));
assertEquals(3, ctx.stats.isNotLargerThanCallCount);
assertEquals(0, ctx.stats.objectSizeIndexHit);
assertEquals(3, ctx.stats.objectSizeIndexMiss);
assertTrue("obj < limit = threshold",
- ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 100));
+ ctx.isNotLargerThan(obj, OBJ_BLOB, 100));
assertEquals(4, ctx.stats.isNotLargerThanCallCount);
assertEquals(0, ctx.stats.objectSizeIndexHit);
assertEquals(4, ctx.stats.objectSizeIndexMiss);
assertTrue("obj < threshold < limit",
- ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 120));
+ ctx.isNotLargerThan(obj, OBJ_BLOB, 120));
assertEquals(5, ctx.stats.isNotLargerThanCallCount);
assertEquals(0, ctx.stats.objectSizeIndexHit);
assertEquals(5, ctx.stats.objectSizeIndexMiss);
@@ -116,11 +121,11 @@ public class DfsReaderTest {
setObjectSizeIndexMinBytes(100);
ObjectId obj = insertBlobWithSize(10);
try (DfsReader ctx = db.getObjectDatabase().newReader()) {
- assertFalse(ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 0));
- assertTrue(ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 10));
- assertTrue(ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 40));
- assertTrue(ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 50));
- assertTrue(ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 100));
+ assertFalse(ctx.isNotLargerThan(obj, OBJ_BLOB, 0));
+ assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 10));
+ assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 40));
+ assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 50));
+ assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 100));
assertEquals(5, ctx.stats.isNotLargerThanCallCount);
assertEquals(5, ctx.stats.objectSizeIndexMiss);
@@ -133,11 +138,11 @@ public class DfsReaderTest {
setObjectSizeIndexMinBytes(-1);
ObjectId obj = insertBlobWithSize(10);
try (DfsReader ctx = db.getObjectDatabase().newReader()) {
- assertFalse(ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 0));
- assertTrue(ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 10));
- assertTrue(ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 40));
- assertTrue(ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 50));
- assertTrue(ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 100));
+ assertFalse(ctx.isNotLargerThan(obj, OBJ_BLOB, 0));
+ assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 10));
+ assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 40));
+ assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 50));
+ assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 100));
assertEquals(5, ctx.stats.isNotLargerThanCallCount);
assertEquals(0, ctx.stats.objectSizeIndexMiss);
@@ -145,12 +150,103 @@ public class DfsReaderTest {
}
}
+ @Test
+ public void packLoadListener_noInvocations() throws IOException {
+ insertBlobWithSize(100);
+ try (DfsReader ctx = db.getObjectDatabase().newReader()) {
+ CounterPackLoadListener listener = new CounterPackLoadListener();
+ ctx.addPackLoadListener(listener);
+ assertEquals(null, listener.callsPerExt.get(PackExt.INDEX));
+ }
+ }
+
+ @Test
+ public void packLoadListener_has_openIdx() throws IOException {
+ ObjectId obj = insertBlobWithSize(100);
+ try (DfsReader ctx = db.getObjectDatabase().newReader()) {
+ CounterPackLoadListener listener = new CounterPackLoadListener();
+ ctx.addPackLoadListener(listener);
+ boolean has = ctx.has(obj);
+ assertTrue(has);
+ assertEquals(Integer.valueOf(1), listener.callsPerExt.get(PackExt.INDEX));
+ }
+ }
+
+ @Test
+ public void packLoadListener_notLargerThan_openMultipleIndices() throws IOException {
+ setObjectSizeIndexMinBytes(100);
+ ObjectId obj = insertBlobWithSize(200);
+ try (DfsReader ctx = db.getObjectDatabase().newReader()) {
+ CounterPackLoadListener listener = new CounterPackLoadListener();
+ ctx.addPackLoadListener(listener);
+ boolean notLargerThan = ctx.isNotLargerThan(obj, OBJ_BLOB, 1000);
+ assertTrue(notLargerThan);
+ assertEquals(Integer.valueOf(1), listener.callsPerExt.get(PackExt.INDEX));
+ assertEquals(Integer.valueOf(1), listener.callsPerExt.get(PackExt.OBJECT_SIZE_INDEX));
+ }
+ }
+
+ @Test
+ public void packLoadListener_has_openMultipleIndices() throws IOException {
+ setObjectSizeIndexMinBytes(100);
+ insertBlobWithSize(200);
+ insertBlobWithSize(230);
+ insertBlobWithSize(100);
+ try (DfsReader ctx = db.getObjectDatabase().newReader()) {
+ CounterPackLoadListener listener = new CounterPackLoadListener();
+ ctx.addPackLoadListener(listener);
+ ObjectId oid = ObjectId.fromString("aa48de2aa61d9dffa8a05439dc115fe82f10f129");
+ boolean has = ctx.has(oid);
+ assertFalse(has);
+ // Open 3 indices trying to find the pack
+ assertEquals(Integer.valueOf(3), listener.callsPerExt.get(PackExt.INDEX));
+ }
+ }
+
+
+ @Test
+ public void packLoadListener_has_repeatedCalls_openMultipleIndices() throws IOException {
+ // Two objects NOT in the repo
+ ObjectId oid = ObjectId.fromString("aa48de2aa61d9dffa8a05439dc115fe82f10f129");
+ ObjectId oid2 = ObjectId.fromString("aa48de2aa61d9dffa8a05439dc115fe82f10f130");
+
+ setObjectSizeIndexMinBytes(100);
+ insertBlobWithSize(200);
+ insertBlobWithSize(230);
+ insertBlobWithSize(100);
+ CounterPackLoadListener listener = new CounterPackLoadListener();
+ try (DfsReader ctx = db.getObjectDatabase().newReader()) {
+ ctx.addPackLoadListener(listener);
+ boolean has = ctx.has(oid);
+ ctx.has(oid);
+ ctx.has(oid2);
+ assertFalse(has);
+ // The 3 indices were loaded only once each
+ assertEquals(Integer.valueOf(3), listener.callsPerExt.get(PackExt.INDEX));
+ }
+ }
+
+ private static class CounterPackLoadListener implements PackLoadListener {
+ final Map<PackExt, Integer> callsPerExt = new HashMap<>();
+
+ @Override
+ public void onIndexLoad(String packName, PackSource src, PackExt ext, long size,
+ Object loadedIdx) {
+ callsPerExt.merge(ext, 1, Integer::sum);
+ }
+
+ @Override
+ public void onBlockLoad(String packName, PackSource src, PackExt ext,
+ long size, DfsBlockData dfsBlockData) {
+ }
+ }
+
private ObjectId insertBlobWithSize(int size)
throws IOException {
TestRng testRng = new TestRng(JGitTestUtil.getName());
ObjectId oid;
try (ObjectInserter ins = db.newObjectInserter()) {
- oid = ins.insert(Constants.OBJ_BLOB,
+ oid = ins.insert(OBJ_BLOB,
testRng.nextBytes(size));
ins.flush();
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackTest.java
index a3596541fe..e1509456e5 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackTest.java
@@ -261,7 +261,7 @@ public class PackTest extends LocalDiskRepositoryTestCase {
new PackIndexWriterV1(f).write(list, footer);
}
- Pack pack = new Pack(packName, null);
+ Pack pack = new Pack(repo.getConfig(), packName, null);
try {
pack.get(wc, b);
fail("expected LargeObjectException.ExceedsByteArrayLimit");
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
index 8f9d105319..36cf77bb01 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
@@ -1482,7 +1482,9 @@ public class ConfigTest {
File workTree = tmp.newFolder("dummy-worktree");
File tempFile = tmp.newFile("testCommitTemplate-");
- Repository repo = FileRepositoryBuilder.create(workTree);
+ Repository repo = FileRepositoryBuilder
+ .create(new File(workTree, ".git"));
+ repo.create();
String templateContent = "content of the template";
JGitTestUtil.write(tempFile, templateContent);
String expectedTemplatePath = tempFile.getPath();
@@ -1532,7 +1534,9 @@ public class ConfigTest {
throws ConfigInvalidException, IOException {
Config config = new Config(null);
File workTree = tmp.newFolder("dummy-worktree");
- Repository repo = FileRepositoryBuilder.create(workTree);
+ Repository repo = FileRepositoryBuilder
+ .create(new File(workTree, ".git"));
+ repo.create();
File tempFile = tmp.newFile("testCommitTemplate-");
String templateContent = "content of the template";
JGitTestUtil.write(tempFile, templateContent);
@@ -1554,7 +1558,9 @@ public class ConfigTest {
Config config = new Config(null);
File workTree = tmp.newFolder("dummy-worktree");
File tempFile = tmp.newFile("testCommitTemplate-");
- Repository repo = FileRepositoryBuilder.create(workTree);
+ Repository repo = FileRepositoryBuilder
+ .create(new File(workTree, ".git"));
+ repo.create();
String templateContent = "content of the template";
JGitTestUtil.write(tempFile, templateContent);
config = parse("[i18n]\n\tcommitEncoding = invalidEcoding\n"
@@ -1569,7 +1575,9 @@ public class ConfigTest {
Config config = new Config(null);
File workTree = tmp.newFolder("dummy-worktree");
File tempFile = tmp.newFile("testCommitTemplate-");
- Repository repo = FileRepositoryBuilder.create(workTree);
+ Repository repo = FileRepositoryBuilder
+ .create(new File(workTree, ".git"));
+ repo.create();
String templateContent = "content of the template";
JGitTestUtil.write(tempFile, templateContent);
// commit message encoding
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/UserConfigFileTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/UserConfigFileTest.java
new file mode 100644
index 0000000000..7d212d540f
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/UserConfigFileTest.java
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2023, Thomas Wolf <twolf@apache.org> 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
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.storage.file;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.eclipse.jgit.util.FS;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+public class UserConfigFileTest {
+
+ @Rule
+ public TemporaryFolder tmp = new TemporaryFolder();
+
+ @Test
+ public void testParentOnlyLoad() throws Exception {
+ Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+ Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+ Path user = tmp.getRoot().toPath().resolve("user.cfg");
+ UserConfigFile config = new UserConfigFile(null, user.toFile(),
+ xdg.toFile(), FS.DETECTED);
+ config.load();
+ assertEquals("Archibald Ulysses Thor",
+ config.getString("user", null, "name"));
+ }
+
+ @Test
+ public void testLoadBoth() throws Exception {
+ Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+ Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+ Path user = tmp.getRoot().toPath().resolve("user.cfg");
+ Files.writeString(user, "[user]\n\temail = a.u.thor@example.com");
+ UserConfigFile config = new UserConfigFile(null, user.toFile(),
+ xdg.toFile(), FS.DETECTED);
+ config.load();
+ assertEquals("Archibald Ulysses Thor",
+ config.getString("user", null, "name"));
+ assertEquals("a.u.thor@example.com",
+ config.getString("user", null, "email"));
+ }
+
+ @Test
+ public void testOverwriteChild() throws Exception {
+ Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+ Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+ Path user = tmp.getRoot().toPath().resolve("user.cfg");
+ Files.writeString(user, "[user]\n\temail = a.u.thor@example.com");
+ UserConfigFile config = new UserConfigFile(null, user.toFile(),
+ xdg.toFile(), FS.DETECTED);
+ config.load();
+ assertEquals("Archibald Ulysses Thor",
+ config.getString("user", null, "name"));
+ assertEquals("a.u.thor@example.com",
+ config.getString("user", null, "email"));
+ config.setString("user", null, "name", "A U Thor");
+ assertEquals("A U Thor", config.getString("user", null, "name"));
+ config.save();
+ UserConfigFile config2 = new UserConfigFile(null, user.toFile(),
+ xdg.toFile(), FS.DETECTED);
+ config2.load();
+ assertEquals("A U Thor", config2.getString("user", null, "name"));
+ assertEquals("a.u.thor@example.com",
+ config.getString("user", null, "email"));
+ FileBasedConfig cfg = new FileBasedConfig(null, xdg.toFile(),
+ FS.DETECTED);
+ cfg.load();
+ assertEquals("Archibald Ulysses Thor",
+ cfg.getString("user", null, "name"));
+ assertNull(cfg.getString("user", null, "email"));
+ }
+
+ @Test
+ public void testUnset() throws Exception {
+ Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+ Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+ Path user = tmp.getRoot().toPath().resolve("user.cfg");
+ Files.writeString(user, "[user]\n\temail = a.u.thor@example.com");
+ UserConfigFile config = new UserConfigFile(null, user.toFile(),
+ xdg.toFile(), FS.DETECTED);
+ config.load();
+ assertEquals("Archibald Ulysses Thor",
+ config.getString("user", null, "name"));
+ assertEquals("a.u.thor@example.com",
+ config.getString("user", null, "email"));
+ config.setString("user", null, "name", "A U Thor");
+ assertEquals("A U Thor", config.getString("user", null, "name"));
+ config.unset("user", null, "name");
+ assertEquals("Archibald Ulysses Thor",
+ config.getString("user", null, "name"));
+ assertEquals("a.u.thor@example.com",
+ config.getString("user", null, "email"));
+ config.save();
+ UserConfigFile config2 = new UserConfigFile(null, user.toFile(),
+ xdg.toFile(), FS.DETECTED);
+ config2.load();
+ assertEquals("Archibald Ulysses Thor",
+ config2.getString("user", null, "name"));
+ assertEquals("a.u.thor@example.com",
+ config.getString("user", null, "email"));
+ FileBasedConfig cfg = new FileBasedConfig(null, user.toFile(),
+ FS.DETECTED);
+ cfg.load();
+ assertNull(cfg.getString("user", null, "name"));
+ assertEquals("a.u.thor@example.com",
+ cfg.getString("user", null, "email"));
+ }
+
+ @Test
+ public void testUnsetSection() throws Exception {
+ Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+ Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+ Path user = tmp.getRoot().toPath().resolve("user.cfg");
+ Files.writeString(user, "[user]\n\temail = a.u.thor@example.com");
+ UserConfigFile config = new UserConfigFile(null, user.toFile(),
+ xdg.toFile(), FS.DETECTED);
+ config.load();
+ assertEquals("Archibald Ulysses Thor",
+ config.getString("user", null, "name"));
+ assertEquals("a.u.thor@example.com",
+ config.getString("user", null, "email"));
+ config.unsetSection("user", null);
+ assertEquals("Archibald Ulysses Thor",
+ config.getString("user", null, "name"));
+ config.save();
+ assertTrue(Files.readString(user).strip().isEmpty());
+ }
+
+ @Test
+ public void testNoChild() throws Exception {
+ Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+ Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+ Path user = tmp.getRoot().toPath().resolve("user.cfg");
+ UserConfigFile config = new UserConfigFile(null, user.toFile(),
+ xdg.toFile(), FS.DETECTED);
+ config.load();
+ assertEquals("Archibald Ulysses Thor",
+ config.getString("user", null, "name"));
+ assertNull(config.getString("user", null, "email"));
+ config.setString("user", null, "email", "a.u.thor@example.com");
+ assertEquals("a.u.thor@example.com",
+ config.getString("user", null, "email"));
+ config.save();
+ assertFalse(Files.exists(user));
+ UserConfigFile config2 = new UserConfigFile(null, user.toFile(),
+ xdg.toFile(), FS.DETECTED);
+ config2.load();
+ assertEquals("Archibald Ulysses Thor",
+ config2.getString("user", null, "name"));
+ assertEquals("a.u.thor@example.com",
+ config2.getString("user", null, "email"));
+ }
+
+ @Test
+ public void testNoFiles() throws Exception {
+ Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+ Path user = tmp.getRoot().toPath().resolve("user.cfg");
+ UserConfigFile config = new UserConfigFile(null, user.toFile(),
+ xdg.toFile(), FS.DETECTED);
+ config.load();
+ assertNull(config.getString("user", null, "name"));
+ assertNull(config.getString("user", null, "email"));
+ config.setString("user", null, "name", "Archibald Ulysses Thor");
+ config.setString("user", null, "email", "a.u.thor@example.com");
+ assertEquals("Archibald Ulysses Thor",
+ config.getString("user", null, "name"));
+ assertEquals("a.u.thor@example.com",
+ config.getString("user", null, "email"));
+ config.save();
+ assertTrue(Files.exists(user));
+ assertFalse(Files.exists(xdg));
+ UserConfigFile config2 = new UserConfigFile(null, user.toFile(),
+ xdg.toFile(), FS.DETECTED);
+ config2.load();
+ assertEquals("Archibald Ulysses Thor",
+ config2.getString("user", null, "name"));
+ assertEquals("a.u.thor@example.com",
+ config2.getString("user", null, "email"));
+ }
+
+ @Test
+ public void testSetInXdg() throws Exception {
+ Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+ Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+ Path user = tmp.getRoot().toPath().resolve("user.cfg");
+ UserConfigFile config = new UserConfigFile(null, user.toFile(),
+ xdg.toFile(), FS.DETECTED);
+ config.load();
+ assertEquals("Archibald Ulysses Thor",
+ config.getString("user", null, "name"));
+ config.setString("user", null, "email", "a.u.thor@example.com");
+ config.save();
+ assertFalse(Files.exists(user));
+ FileBasedConfig cfg = new FileBasedConfig(null, xdg.toFile(),
+ FS.DETECTED);
+ cfg.load();
+ assertEquals("Archibald Ulysses Thor",
+ cfg.getString("user", null, "name"));
+ assertEquals("a.u.thor@example.com",
+ cfg.getString("user", null, "email"));
+ }
+
+ @Test
+ public void testUserConfigCreated() throws Exception {
+ Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+ Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+ Path user = tmp.getRoot().toPath().resolve("user.cfg");
+ Thread.sleep(3000); // Avoid racily clean isOutdated() below.
+ UserConfigFile config = new UserConfigFile(null, user.toFile(),
+ xdg.toFile(), FS.DETECTED);
+ config.load();
+ assertEquals("Archibald Ulysses Thor",
+ config.getString("user", null, "name"));
+ Files.writeString(user,
+ "[user]\n\temail = a.u.thor@example.com\n\tname = A U Thor");
+ assertEquals("Archibald Ulysses Thor",
+ config.getString("user", null, "name"));
+ assertTrue(config.isOutdated());
+ config.load();
+ assertEquals("A U Thor", config.getString("user", null, "name"));
+ assertEquals("a.u.thor@example.com",
+ config.getString("user", null, "email"));
+ }
+
+ @Test
+ public void testUserConfigDeleted() throws Exception {
+ Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+ Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+ Path user = tmp.getRoot().toPath().resolve("user.cfg");
+ Files.writeString(user,
+ "[user]\n\temail = a.u.thor@example.com\n\tname = A U Thor");
+ Thread.sleep(3000); // Avoid racily clean isOutdated() below.
+ UserConfigFile config = new UserConfigFile(null, user.toFile(),
+ xdg.toFile(), FS.DETECTED);
+ config.load();
+ assertEquals("A U Thor", config.getString("user", null, "name"));
+ assertEquals("a.u.thor@example.com",
+ config.getString("user", null, "email"));
+ Files.delete(user);
+ assertEquals("A U Thor", config.getString("user", null, "name"));
+ assertEquals("a.u.thor@example.com",
+ config.getString("user", null, "email"));
+ assertTrue(config.isOutdated());
+ config.load();
+ assertEquals("Archibald Ulysses Thor",
+ config.getString("user", null, "name"));
+ assertNull(config.getString("user", null, "email"));
+ }
+
+ @Test
+ public void testXdgConfigDeleted() throws Exception {
+ Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+ Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+ Path user = tmp.getRoot().toPath().resolve("user.cfg");
+ Thread.sleep(3000); // Avoid racily clean isOutdated() below.
+ UserConfigFile config = new UserConfigFile(null, user.toFile(),
+ xdg.toFile(), FS.DETECTED);
+ config.load();
+ assertEquals("Archibald Ulysses Thor",
+ config.getString("user", null, "name"));
+ Files.delete(xdg);
+ assertEquals("Archibald Ulysses Thor",
+ config.getString("user", null, "name"));
+ assertTrue(config.isOutdated());
+ config.load();
+ assertNull(config.getString("user", null, "name"));
+ }
+
+ @Test
+ public void testXdgConfigDeletedUserConfigExists() throws Exception {
+ Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+ Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+ Path user = tmp.getRoot().toPath().resolve("user.cfg");
+ Files.writeString(user,
+ "[user]\n\temail = a.u.thor@example.com\n\tname = A U Thor");
+ Thread.sleep(3000); // Avoid racily clean isOutdated() below.
+ UserConfigFile config = new UserConfigFile(null, user.toFile(),
+ xdg.toFile(), FS.DETECTED);
+ config.load();
+ assertEquals("A U Thor", config.getString("user", null, "name"));
+ Files.delete(xdg);
+ assertTrue(config.isOutdated());
+ config.load();
+ assertEquals("A U Thor", config.getString("user", null, "name"));
+ }
+
+}