summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/keuin/kbackupfabric/ConfigInitializer.java8
-rw-r--r--src/main/java/com/keuin/kbackupfabric/KBConfiguration.java33
-rw-r--r--src/main/java/com/keuin/kbackupfabric/autobackup/AutoBackupScheduler.java50
-rw-r--r--src/main/java/com/keuin/kbackupfabric/autobackup/PlayerActivityTracker.java15
-rw-r--r--src/main/java/com/keuin/kbackupfabric/backup/incremental/ObjectCollectionIterator.java3
-rw-r--r--src/main/java/com/keuin/kbackupfabric/backup/incremental/identifier/SingleHashIdentifier.java10
-rw-r--r--src/main/java/com/keuin/kbackupfabric/backup/incremental/manager/IncrementalBackupStorageManager.java51
-rw-r--r--src/main/java/com/keuin/kbackupfabric/event/handler/ConcretePlayerConnectEventHandler.java22
-rw-r--r--src/test/java/com/keuin/kbackupfabric/backup/incremental/ObjectCollectionIteratorTest.java49
-rw-r--r--src/test/java/com/keuin/kbackupfabric/backup/incremental/identifier/SingleHashIdentifierTest.java35
-rw-r--r--src/test/java/com/keuin/kbackupfabric/backup/incremental/manager/IncrementalBackupStorageManagerTest.java201
11 files changed, 459 insertions, 18 deletions
diff --git a/src/main/java/com/keuin/kbackupfabric/ConfigInitializer.java b/src/main/java/com/keuin/kbackupfabric/ConfigInitializer.java
new file mode 100644
index 0000000..770c1cd
--- /dev/null
+++ b/src/main/java/com/keuin/kbackupfabric/ConfigInitializer.java
@@ -0,0 +1,8 @@
+package com.keuin.kbackupfabric;
+
+/**
+ * Initialize classes using config from disk.
+ */
+public class ConfigInitializer {
+
+}
diff --git a/src/main/java/com/keuin/kbackupfabric/KBConfiguration.java b/src/main/java/com/keuin/kbackupfabric/KBConfiguration.java
new file mode 100644
index 0000000..3744430
--- /dev/null
+++ b/src/main/java/com/keuin/kbackupfabric/KBConfiguration.java
@@ -0,0 +1,33 @@
+package com.keuin.kbackupfabric;
+
+/**
+ * Global plugin configuration.
+ */
+public class KBConfiguration {
+ // auto backup interval in seconds. Set this to a negative value to disable auto backup.
+ private final int autoBackupIntervalSeconds;
+ // name of backup created automatically. By default it is `auto-backup`
+ private final String autoBackupName;
+ // if no player has logged in since previous backup, we skip this backup
+ private final boolean skipAutoBackupIfNoPlayerLoggedIn;
+
+ public KBConfiguration() {
+ autoBackupIntervalSeconds = -1; // disabled by default
+ autoBackupName = "auto-backup";
+ skipAutoBackupIfNoPlayerLoggedIn = false;
+ }
+
+ public KBConfiguration(int autoBackupIntervalSeconds, String autoBackupName, boolean skipAutoBackupIfNoPlayerLoggedIn) {
+ this.autoBackupIntervalSeconds = autoBackupIntervalSeconds;
+ this.autoBackupName = autoBackupName;
+ this.skipAutoBackupIfNoPlayerLoggedIn = skipAutoBackupIfNoPlayerLoggedIn;
+ }
+
+ public int getAutoBackupIntervalSeconds() {
+ return autoBackupIntervalSeconds;
+ }
+
+ public String getAutoBackupName() {
+ return autoBackupName;
+ }
+}
diff --git a/src/main/java/com/keuin/kbackupfabric/autobackup/AutoBackupScheduler.java b/src/main/java/com/keuin/kbackupfabric/autobackup/AutoBackupScheduler.java
new file mode 100644
index 0000000..c35a35d
--- /dev/null
+++ b/src/main/java/com/keuin/kbackupfabric/autobackup/AutoBackupScheduler.java
@@ -0,0 +1,50 @@
+package com.keuin.kbackupfabric.autobackup;
+
+import java.util.Optional;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.logging.Logger;
+
+public class AutoBackupScheduler {
+
+ private Timer timer = null;
+ private final Logger logger = Logger.getLogger(AutoBackupScheduler.class.getName());
+ private boolean skipIfNoPlayerLoggedIn;
+ private final PlayerActivityTracker playerActivityTracker;
+
+ public AutoBackupScheduler(int intervalSeconds, boolean skipIfNoPlayerLoggedIn, PlayerActivityTracker playerActivityTracker) {
+ this.skipIfNoPlayerLoggedIn = skipIfNoPlayerLoggedIn;
+ this.playerActivityTracker = playerActivityTracker;
+ if (intervalSeconds > 0)
+ setInterval(intervalSeconds);
+ }
+
+ public synchronized void setInterval(int intervalSeconds) {
+ Optional.ofNullable(timer).ifPresent(Timer::cancel);
+ Timer newTimer = new Timer("AutoBackupTimer");
+ newTimer.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ toggleBackup();
+ }
+ }, 0L, intervalSeconds * 1000L);
+ timer = newTimer;
+ }
+
+ public void setSkipIfNoPlayerLoggedIn(boolean skipIfNoPlayerLoggedIn) {
+ this.skipIfNoPlayerLoggedIn = skipIfNoPlayerLoggedIn;
+ }
+
+ public synchronized void stop() {
+ timer.cancel();
+ timer = null;
+ }
+
+ private void toggleBackup() {
+ if (playerActivityTracker.getCheckpoint() || !skipIfNoPlayerLoggedIn) {
+ logger.info("Interval backup event is triggered.");
+ // TODO: perform a backup
+ }
+ }
+
+}
diff --git a/src/main/java/com/keuin/kbackupfabric/autobackup/PlayerActivityTracker.java b/src/main/java/com/keuin/kbackupfabric/autobackup/PlayerActivityTracker.java
new file mode 100644
index 0000000..ef2b85e
--- /dev/null
+++ b/src/main/java/com/keuin/kbackupfabric/autobackup/PlayerActivityTracker.java
@@ -0,0 +1,15 @@
+package com.keuin.kbackupfabric.autobackup;
+
+public interface PlayerActivityTracker {
+ /**
+ * Update the checkpoint, return accumulated result.
+ *
+ * @return if there is at least one player logged in since last checkpoint.
+ */
+ boolean getCheckpoint();
+
+ /**
+ * Mark dirty. In the next checkpoint, the backup will be performed.
+ */
+ void setCheckpoint();
+}
diff --git a/src/main/java/com/keuin/kbackupfabric/backup/incremental/ObjectCollectionIterator.java b/src/main/java/com/keuin/kbackupfabric/backup/incremental/ObjectCollectionIterator.java
index 248d36d..7e523bc 100644
--- a/src/main/java/com/keuin/kbackupfabric/backup/incremental/ObjectCollectionIterator.java
+++ b/src/main/java/com/keuin/kbackupfabric/backup/incremental/ObjectCollectionIterator.java
@@ -6,9 +6,6 @@ import java.util.List;
import java.util.NoSuchElementException;
public class ObjectCollectionIterator implements Iterator<ObjectElement> {
-
- // TODO: test this
-
private Iterator<ObjectElement> currentIterator;
private final List<ObjectCollection2> cols = new LinkedList<>();
diff --git a/src/main/java/com/keuin/kbackupfabric/backup/incremental/identifier/SingleHashIdentifier.java b/src/main/java/com/keuin/kbackupfabric/backup/incremental/identifier/SingleHashIdentifier.java
index 9fd61c8..b3afa7f 100644
--- a/src/main/java/com/keuin/kbackupfabric/backup/incremental/identifier/SingleHashIdentifier.java
+++ b/src/main/java/com/keuin/kbackupfabric/backup/incremental/identifier/SingleHashIdentifier.java
@@ -37,11 +37,11 @@ public abstract class SingleHashIdentifier implements ObjectIdentifier {
}
@Override
- public boolean equals(Object obj) {
- if (!(obj instanceof SingleHashIdentifier)) {
- return false;
- }
- return Arrays.equals(hash, ((SingleHashIdentifier) obj).hash);
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ SingleHashIdentifier that = (SingleHashIdentifier) o;
+ return Arrays.equals(hash, that.hash) && type.equals(that.type);
}
@Override
diff --git a/src/main/java/com/keuin/kbackupfabric/backup/incremental/manager/IncrementalBackupStorageManager.java b/src/main/java/com/keuin/kbackupfabric/backup/incremental/manager/IncrementalBackupStorageManager.java
index 0b15a84..18e0e58 100644
--- a/src/main/java/com/keuin/kbackupfabric/backup/incremental/manager/IncrementalBackupStorageManager.java
+++ b/src/main/java/com/keuin/kbackupfabric/backup/incremental/manager/IncrementalBackupStorageManager.java
@@ -3,8 +3,10 @@ package com.keuin.kbackupfabric.backup.incremental.manager;
import com.keuin.kbackupfabric.backup.incremental.ObjectCollection2;
import com.keuin.kbackupfabric.backup.incremental.ObjectCollectionIterator;
import com.keuin.kbackupfabric.backup.incremental.ObjectElement;
+import com.keuin.kbackupfabric.backup.incremental.identifier.ObjectIdentifier;
import com.keuin.kbackupfabric.util.FilesystemUtil;
import com.keuin.kbackupfabric.util.PrintUtil;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
@@ -31,7 +33,34 @@ public class IncrementalBackupStorageManager {
}
/**
- * Add a object collection to storage base.
+ * Check whether the storage contains a copy of file with given identifier.
+ *
+ * @param identifier the identifier.
+ * @return whether the file exists.
+ */
+ public boolean contains(@NotNull ObjectIdentifier identifier) {
+ Objects.requireNonNull(identifier);
+ return new File(backupStorageBase.toFile(), identifier.getIdentification()).isFile();
+ }
+
+ /**
+ * Check whether the storage contains all files in the given collection.
+ *
+ * @param collection the collection.
+ * @return whether all files exists.
+ */
+ public boolean contains(@NotNull ObjectCollection2 collection) {
+ Objects.requireNonNull(collection);
+ for (ObjectCollectionIterator it = new ObjectCollectionIterator(collection); it.hasNext(); ) {
+ ObjectElement ele = it.next();
+ if (!contains(ele.getIdentifier()))
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Add a object collection to storage base and copy files to the storage.
*
* @param collection the collection.
* @return objects copied to the base.
@@ -93,20 +122,22 @@ public class IncrementalBackupStorageManager {
Iterable<ObjectCollection2> otherExistingCollections) {
// TODO: test this
Iterator<ObjectElement> iter = new ObjectCollectionIterator(collection);
- Set<ObjectElement> unusedElementSet = new HashSet<>();
- iter.forEachRemaining(unusedElementSet::add);
- otherExistingCollections.forEach(col -> new ObjectCollectionIterator(col).forEachRemaining(unusedElementSet::remove));
- AtomicInteger deleteCount = new AtomicInteger();
- unusedElementSet.forEach(ele -> {
- File file = new File(backupStorageBase.toFile(), ele.getIdentifier().getIdentification());
+ Set<ObjectIdentifier> identifierSet = new HashSet<>();
+ iter.forEachRemaining(ele -> identifierSet.add(ele.getIdentifier()));
+ otherExistingCollections.forEach(col -> new ObjectCollectionIterator(col)
+ .forEachRemaining(ele -> identifierSet.remove(ele.getIdentifier())));
+ int deleteCount = 0;
+ for (ObjectIdentifier id : identifierSet) {
+ Objects.requireNonNull(id);
+ File file = new File(backupStorageBase.toFile(), id.getIdentification());
if (file.exists()) {
if (file.delete())
- deleteCount.incrementAndGet();
+ ++deleteCount;
else
LOGGER.warning("Failed to delete unused file " + file.getName());
}
- });
- return deleteCount.get();
+ }
+ return deleteCount;
}
/**
diff --git a/src/main/java/com/keuin/kbackupfabric/event/handler/ConcretePlayerConnectEventHandler.java b/src/main/java/com/keuin/kbackupfabric/event/handler/ConcretePlayerConnectEventHandler.java
new file mode 100644
index 0000000..171d80d
--- /dev/null
+++ b/src/main/java/com/keuin/kbackupfabric/event/handler/ConcretePlayerConnectEventHandler.java
@@ -0,0 +1,22 @@
+package com.keuin.kbackupfabric.event.handler;
+
+import com.keuin.kbackupfabric.autobackup.PlayerActivityTracker;
+import com.keuin.kbackupfabric.event.OnPlayerConnect;
+import com.keuin.kbackupfabric.notification.DistinctNotifiable;
+import com.keuin.kbackupfabric.notification.NotificationManager;
+import net.minecraft.network.ClientConnection;
+import net.minecraft.server.network.ServerPlayerEntity;
+
+public class ConcretePlayerConnectEventHandler implements OnPlayerConnect.PlayerConnectEventCallback {
+ private final PlayerActivityTracker playerActivityTracker;
+
+ public ConcretePlayerConnectEventHandler(PlayerActivityTracker playerActivityTracker) {
+ this.playerActivityTracker = playerActivityTracker;
+ }
+
+ @Override
+ public void onPlayerConnect(ClientConnection connection, ServerPlayerEntity player) {
+ playerActivityTracker.setCheckpoint();
+ NotificationManager.INSTANCE.notifyPlayer(DistinctNotifiable.fromServerPlayerEntity(player));
+ }
+}
diff --git a/src/test/java/com/keuin/kbackupfabric/backup/incremental/ObjectCollectionIteratorTest.java b/src/test/java/com/keuin/kbackupfabric/backup/incremental/ObjectCollectionIteratorTest.java
new file mode 100644
index 0000000..8404eb1
--- /dev/null
+++ b/src/test/java/com/keuin/kbackupfabric/backup/incremental/ObjectCollectionIteratorTest.java
@@ -0,0 +1,49 @@
+package com.keuin.kbackupfabric.backup.incremental;
+
+import com.keuin.kbackupfabric.backup.incremental.identifier.FileIdentifierProvider;
+import com.keuin.kbackupfabric.backup.incremental.identifier.ObjectIdentifier;
+import com.keuin.kbackupfabric.backup.incremental.identifier.Sha256Identifier;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.*;
+
+public class ObjectCollectionIteratorTest {
+ @Test
+ public void testObjectCollectionIterator() throws IOException {
+ final String testRoot = "testfile/ObjectCollectionIteratorTest/col1";
+ ObjectCollection2 col =
+ new ObjectCollectionFactory<>
+ (Sha256Identifier::fromFile, 1, 10)
+ .fromDirectory(new File(testRoot));
+ ObjectCollectionIterator iter = new ObjectCollectionIterator(col);
+ Set<ObjectIdentifier> idSet = new HashSet<>();
+ Set<String> nameSet = new HashSet<>();
+ iter.forEachRemaining(ele -> {
+ idSet.add(ele.getIdentifier());
+ nameSet.add(ele.getName());
+ });
+ assertEquals(new HashSet<>(Arrays.asList("1", "2", "3", "a", "b", "c", "d", "e", "f", "z1", "z2", "z3")), nameSet);
+ Set<String> desiredIdSet = new HashSet<>(Arrays.asList(
+ "S2-092FCFBBCFCA3B5BE7AE1B5E58538E92C35AB273AE13664FED0D67484C8E78A6",
+ "S2-A2BBDB2DE53523B8099B37013F251546F3D65DBE7A0774FA41AF0A4176992FD4",
+ "S2-A3A5E715F0CC574A73C3F9BEBB6BC24F32FFD5B67B387244C2C909DA779A1478",
+ "S2-0263829989B6FD954F72BAAF2FC64BC2E2F01D692D4DE72986EA808F6E99813F",
+ "S2-53C234E5E8472B6AC51C1AE1CAB3FE06FAD053BEB8EBFD8977B010655BFDD3C3",
+ "S2-D8FF994D310BD1F7582DC285366C3292DEB6A8F2EC64A4E7D0B3004190200034",
+ "S2-8D74BEEC1BE996322AD76813BAFB92D40839895D6DD7EE808B17CA201EAC98BE",
+ "S2-4355A46B19D348DC2F57C046F8EF63D4538EBB936000F3C9EE954A27460DD865",
+ "S2-87428FC522803D31065E7BCE3CF03FE475096631E5E07BBD7A0FDE60C4CF25C7",
+ "S2-1121CFCCD5913F0A63FEC40A6FFD44EA64F9DC135C66634BA001D10BCF4302A2",
+ "S2-AE6C381493F88DA4351218C39BE5287541C9F9D4312A941E431EB4371BC515B7",
+ "S2-5E1B3B203B8D9C1FE1424420B5D56A8244880E1A7539EB7E88B035EC0257FAFE"
+ ));
+ assertEquals(desiredIdSet, idSet.stream().map(ObjectIdentifier::getIdentification).collect(Collectors.toSet()));
+ }
+} \ No newline at end of file
diff --git a/src/test/java/com/keuin/kbackupfabric/backup/incremental/identifier/SingleHashIdentifierTest.java b/src/test/java/com/keuin/kbackupfabric/backup/incremental/identifier/SingleHashIdentifierTest.java
new file mode 100644
index 0000000..4e15095
--- /dev/null
+++ b/src/test/java/com/keuin/kbackupfabric/backup/incremental/identifier/SingleHashIdentifierTest.java
@@ -0,0 +1,35 @@
+package com.keuin.kbackupfabric.backup.incremental.identifier;
+
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.junit.Assert.*;
+
+public class SingleHashIdentifierTest {
+
+ @Test
+ public void testEquals() {
+ SingleHashIdentifier id1 = new ConcreteSingleHashIdentifier(new byte[]{1, 2, 3, 4}, "ahash");
+ SingleHashIdentifier id2 = new ConcreteSingleHashIdentifier(new byte[]{1, 2, 3, 4}, "ahash");
+ SingleHashIdentifier id3 = new ConcreteSingleHashIdentifier(new byte[]{1, 2, 3}, "ahash");
+ SingleHashIdentifier id4 = new ConcreteSingleHashIdentifier(new byte[]{1, 2, 3, 4}, "a");
+ assertEquals(id1, id1);
+ assertEquals(id1, id2);
+ assertNotEquals(id1, id3);
+ assertNotEquals(id1, id4);
+ assertNotEquals(id3, id4);
+ }
+
+ private static class ConcreteSingleHashIdentifier extends SingleHashIdentifier {
+ protected ConcreteSingleHashIdentifier(byte[] hash, String type) {
+ super(hash, type);
+ }
+
+ @Override
+ protected byte[] hash(File file) throws IOException {
+ return new byte[0];
+ }
+ }
+} \ No newline at end of file
diff --git a/src/test/java/com/keuin/kbackupfabric/backup/incremental/manager/IncrementalBackupStorageManagerTest.java b/src/test/java/com/keuin/kbackupfabric/backup/incremental/manager/IncrementalBackupStorageManagerTest.java
new file mode 100644
index 0000000..2a9420a
--- /dev/null
+++ b/src/test/java/com/keuin/kbackupfabric/backup/incremental/manager/IncrementalBackupStorageManagerTest.java
@@ -0,0 +1,201 @@
+package com.keuin.kbackupfabric.backup.incremental.manager;
+
+import com.keuin.kbackupfabric.backup.incremental.ObjectCollection2;
+import com.keuin.kbackupfabric.backup.incremental.ObjectCollectionFactory;
+import com.keuin.kbackupfabric.backup.incremental.ObjectCollectionIterator;
+import com.keuin.kbackupfabric.backup.incremental.identifier.ObjectIdentifier;
+import com.keuin.kbackupfabric.backup.incremental.identifier.Sha256Identifier;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.*;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class IncrementalBackupStorageManagerTest {
+
+ private static final String testRoot = "testfile/IncrementalBackupStorageManagerTest";
+ private static final String srcRoot = testRoot + "/src";
+ private static final String destRoot = testRoot + "/dest";
+
+ private final Map<String, ObjectIdentifier> files = new HashMap<>();
+
+ private static void deleteDirectoryTree(Path directory) throws IOException {
+ if (!directory.toFile().exists())
+ return;
+ if (!directory.toFile().isDirectory() && !directory.toFile().delete())
+ throw new IOException("failed to delete file " + directory);
+
+ Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+ Files.delete(file);
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
+ Files.delete(dir);
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+
+ private static ObjectIdentifier addFile(String fileName) throws IOException {
+ final File root = new File(srcRoot);
+ final File dest = new File(root, fileName);
+ final Random rnd = new Random();
+ if (dest.exists()) {
+ deleteDirectoryTree(dest.toPath());
+ }
+ try (FileOutputStream fos = new FileOutputStream(dest)) {
+ fos.write(rnd.nextInt());
+ }
+ return Sha256Identifier.fromFile(dest);
+ }
+
+ private static void randomlyDeleteFiles(int count) throws IOException {
+ if (count == 0)
+ return;
+ if (count < 0)
+ throw new IllegalArgumentException("negative count");
+ int[] c = new int[]{0};
+ Random rnd = new Random();
+ Files.walk(new File(srcRoot).toPath(), 1).map(p -> rnd.nextBoolean() ? p : null)
+ .filter(Objects::nonNull).forEach(p -> {
+ if (c[0]++ != count) {
+ if (!p.toFile().delete() && p.toFile().isFile())
+ throw new RuntimeException("Failed to delete file " + p);
+ }
+ });
+ }
+
+ private static String getRandomString(int length) {
+ String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ Random random = new Random();
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < length; i++) {
+ int number = random.nextInt(62);
+ sb.append(str.charAt(number));
+ }
+ return sb.toString();
+ }
+
+ @Before
+ public void initialize() throws IOException {
+ // init directory structure
+ final File rootFile = new File(testRoot);
+ deleteDirectoryTree(rootFile.toPath());
+ assertTrue(rootFile.mkdir());
+ assertTrue(new File(srcRoot).mkdir());
+ assertTrue(new File(destRoot).mkdir());
+ assertTrue(rootFile.isDirectory());
+ assertTrue(new File(srcRoot).isDirectory());
+ assertTrue(new File(destRoot).isDirectory());
+
+ // add some random files
+ files.clear();
+ for (int i = 0; i < 100; i++) {
+ String fileName = getRandomString(20);
+ files.put(fileName, addFile(fileName));
+ }
+ }
+
+ @After
+ public void clean() throws IOException {
+ deleteDirectoryTree(new File(testRoot).toPath());
+ }
+
+ @Test
+ public void testDeleteAll() throws IOException {
+ ObjectCollection2 col = new ObjectCollectionFactory<>(Sha256Identifier::fromFile,
+ 1, 1)
+ .fromDirectory(new File(srcRoot));
+ IncrementalBackupStorageManager manager =
+ new IncrementalBackupStorageManager(new File(destRoot).toPath());
+ manager.addObjectCollection(col, new File(srcRoot));
+ assertTrue(manager.contains(col));
+ manager.deleteObjectCollection(col);
+ new ObjectCollectionIterator(col).forEachRemaining(
+ ele -> assertFalse(manager.contains(ele.getIdentifier())));
+ }
+
+ @Test
+ public void testDeleteNone() throws IOException {
+ ObjectCollection2 col = new ObjectCollectionFactory<>(Sha256Identifier::fromFile,
+ 1, 1)
+ .fromDirectory(new File(srcRoot));
+ IncrementalBackupStorageManager manager =
+ new IncrementalBackupStorageManager(new File(destRoot).toPath());
+ manager.addObjectCollection(col, new File(srcRoot));
+ assertTrue(manager.contains(col));
+ manager.deleteObjectCollection(col, Collections.singleton(col));
+ new ObjectCollectionIterator(col).forEachRemaining(
+ ele -> assertTrue(manager.contains(ele.getIdentifier())));
+ }
+
+ @Test
+ public void testDeleteSub() throws IOException {
+ // create partial collection
+ ObjectCollection2 col = new ObjectCollectionFactory<>(Sha256Identifier::fromFile,
+ 1, 1)
+ .fromDirectory(new File(srcRoot));
+ IncrementalBackupStorageManager manager =
+ new IncrementalBackupStorageManager(new File(destRoot).toPath());
+ manager.addObjectCollection(col, new File(srcRoot));
+ assertTrue(manager.contains(col));
+ manager.deleteObjectCollection(col);
+ new ObjectCollectionIterator(col).forEachRemaining(
+ ele -> assertFalse(manager.contains(ele.getIdentifier())));
+
+ // expand
+ randomlyDeleteFiles(25);
+ for (int i = 0; i < 50; i++) {
+ String fileName = getRandomString(20);
+ files.put(fileName, addFile(fileName));
+ }
+ ObjectCollection2 col2 = new ObjectCollectionFactory<>(Sha256Identifier::fromFile,
+ 1, 1)
+ .fromDirectory(new File(srcRoot));
+ manager.addObjectCollection(col2, new File(srcRoot));
+ manager.deleteObjectCollection(col, Collections.singleton(col2));
+ assertTrue(manager.contains(col2));
+ }
+
+ @Test
+ public void testDeleteSuper() throws IOException {
+ // create partial collection
+ ObjectCollection2 col = new ObjectCollectionFactory<>(Sha256Identifier::fromFile,
+ 1, 1)
+ .fromDirectory(new File(srcRoot));
+ IncrementalBackupStorageManager manager =
+ new IncrementalBackupStorageManager(new File(destRoot).toPath());
+ manager.addObjectCollection(col, new File(srcRoot));
+ assertTrue(manager.contains(col));
+ manager.deleteObjectCollection(col);
+ new ObjectCollectionIterator(col).forEachRemaining(
+ ele -> assertFalse(manager.contains(ele.getIdentifier())));
+
+ // expand
+ for (int i = 0; i < 50; i++) {
+ String fileName = getRandomString(20);
+ files.put(fileName, addFile(fileName));
+ }
+ ObjectCollection2 col2 = new ObjectCollectionFactory<>(Sha256Identifier::fromFile,
+ 1, 1)
+ .fromDirectory(new File(srcRoot));
+ manager.addObjectCollection(col2, new File(srcRoot));
+ manager.deleteObjectCollection(col2, Collections.singleton(col));
+ assertTrue(manager.contains(col));
+ }
+} \ No newline at end of file