blob: 417ce61df2e929ee693893ffce89d4cbf1795f62 [file] [log] [blame]
/*
* Copyright (C) 2023, Dariusz Luksza <dariusz.luksza@gmail.com> 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.transport;
import static org.junit.Assert.fail;
import static org.eclipse.jgit.lib.Constants.HEAD;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.internal.storage.file.GC;
import org.eclipse.jgit.internal.storage.file.Pack;
import org.eclipse.jgit.internal.storage.pack.PackExt;
import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.junit.TestRepository.CommitBuilder;
import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.transport.UploadPack.RequestPolicy;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class UploadPackHandleDeletedPackFileTest
extends LocalDiskRepositoryTestCase {
private FileRepository server;
private TestRepository<FileRepository> remote;
private Repository client;
private RevCommit head;
@Parameter
public boolean emptyCommit;
@Parameters(name="empty commit: {0}")
public static Collection<Boolean[]> initTestData() {
return Arrays.asList(
new Boolean[][] { { Boolean.TRUE }, { Boolean.FALSE } });
}
@Before
@Override
public void setUp() throws Exception {
super.setUp();
server = createBareRepository();
server.getConfig().setString("protocol", null, "version", "2");
remote = new TestRepository<>(server);
client = new InMemoryRepository(new DfsRepositoryDescription("client"));
setupServerRepo();
head = server.parseCommit(server.resolve(HEAD));
}
@Test
public void testV2PackFileRemovedDuringUploadPack() throws Exception {
doRemovePackFileDuringUploadPack(PackExt.PACK);
}
@Test
public void testV2IdxFileRemovedDuringUploadPack() throws Exception {
doRemovePackFileDuringUploadPack(PackExt.INDEX);
}
@Test
public void testV2BitmapFileRemovedDuringUploadPack() throws Exception {
doRemovePackFileDuringUploadPack(PackExt.BITMAP_INDEX);
}
private void doRemovePackFileDuringUploadPack(PackExt packExt)
throws Exception {
Object ctx = new Object();
TestProtocol testProtocol = new TestProtocol<>(
(Object req, Repository db) -> {
UploadPack up = new UploadPack(db);
up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT);
Collection<Pack> packs = server.getObjectDatabase()
.getPacks();
assertEquals("single pack expected", 1, packs.size());
Pack pack = packs.iterator().next();
try {
addNewCommit();
new GC(remote.getRepository()).gc();
pack.getPackFile().create(packExt).delete();
} catch (Exception e) {
fail("GC or pack file removal failed");
}
return up;
}, null);
URIish uri = testProtocol.register(ctx, server);
try (Transport tn = testProtocol.open(uri, client, "server")) {
tn.fetch(NullProgressMonitor.INSTANCE,
Collections.singletonList(new RefSpec(head.name())));
assertTrue(client.getObjectDatabase().has(head));
}
}
private void addNewCommit() throws Exception {
CommitBuilder commit = remote.commit().message("2");
if (!emptyCommit) {
commit = commit.add("test2.txt", remote.blob("2"));
}
remote.update("master", commit.parent(head).create());
}
private void setupServerRepo() throws Exception {
RevCommit commit0 = remote.commit().message("0")
.add("test.txt", remote.blob("0"))
.create();
remote.update("master", commit0);
new GC(remote.getRepository()).gc(); // create pack files
head = remote.commit().message("1").parent(commit0)
.add("test1.txt", remote.blob("1"))
.create();
remote.update("master", head);
}
}