summaryrefslogtreecommitdiff
path: root/src/test/java/com/keuin/kbackupfabric/backup/incremental/manager
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/java/com/keuin/kbackupfabric/backup/incremental/manager')
-rw-r--r--src/test/java/com/keuin/kbackupfabric/backup/incremental/manager/IncrementalBackupStorageManagerTest.java201
1 files changed, 201 insertions, 0 deletions
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