summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/keuin/kbackupfabric/KBCommands.java4
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/BytesUtil.java17
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/backup/BackupFilesystemUtil.java4
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/FileIdentifierProvider.java7
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/Sha256Identifier.java20
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/SingleHashIdentifier.java16
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/StorageObjectLoader.java25
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/backup/incremental/manager/IncrementalBackupStorageManager.java52
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/backup/name/BackupFileNameEncoder.java8
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/backup/name/IncrementalBackupFileNameEncoder.java2
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/backup/name/PrimitiveBackupFileNameEncoder.java2
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/backup/provider/AvailableBackupProvider.java8
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/backup/provider/IncrementalBackupInformation.java13
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/backup/provider/PrimitiveBackupInformation.java14
-rw-r--r--src/test/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredIncrementalBackupMethodTest.java34
-rw-r--r--src/test/java/com/keuin/kbackupfabric/util/backup/incremental/ObjectCollectionFactoryTest.java14
-rw-r--r--src/test/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/Sha256IdentifierTest.java2
-rw-r--r--src/test/java/com/keuin/kbackupfabric/util/backup/name/IncrementalBackupFileNameEncoderTest.java38
-rw-r--r--src/test/java/com/keuin/kbackupfabric/util/backup/name/PrimitiveBackupFileNameEncoderTest.java33
19 files changed, 281 insertions, 32 deletions
diff --git a/src/main/java/com/keuin/kbackupfabric/KBCommands.java b/src/main/java/com/keuin/kbackupfabric/KBCommands.java
index 847fe7c..98f6369 100644
--- a/src/main/java/com/keuin/kbackupfabric/KBCommands.java
+++ b/src/main/java/com/keuin/kbackupfabric/KBCommands.java
@@ -84,7 +84,9 @@ public final class KBCommands {
public static int list(CommandContext<ServerCommandSource> context) {
MinecraftServer server = context.getSource().getMinecraftServer();
File[] files = getBackupSaveDirectory(server).listFiles(
- (dir, name) -> dir.isDirectory() && name.toLowerCase().endsWith(".zip") && name.toLowerCase().startsWith(getBackupFileNamePrefix())
+ (dir, name) -> dir.isDirectory() &&
+ (name.toLowerCase().endsWith(".zip") && name.toLowerCase().startsWith(getBackupFileNamePrefix())
+ || name.toLowerCase().endsWith(".kbi"))
);
synchronized (backupFileNameList) {
diff --git a/src/main/java/com/keuin/kbackupfabric/util/BytesUtil.java b/src/main/java/com/keuin/kbackupfabric/util/BytesUtil.java
index 6ded7b8..c33c028 100644
--- a/src/main/java/com/keuin/kbackupfabric/util/BytesUtil.java
+++ b/src/main/java/com/keuin/kbackupfabric/util/BytesUtil.java
@@ -4,6 +4,7 @@ import java.nio.charset.StandardCharsets;
public class BytesUtil {
private static final byte[] HEX_ARRAY = "0123456789ABCDEF".getBytes(StandardCharsets.US_ASCII);
+
public static String bytesToHex(byte[] bytes) {
byte[] hexChars = new byte[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
@@ -11,6 +12,20 @@ public class BytesUtil {
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
- return new String(hexChars, StandardCharsets.UTF_8);
+ return new String(hexChars, StandardCharsets.UTF_8).toUpperCase();
+ }
+
+ public static byte[] hexToBytes(String s) {
+ int len = s.length();
+ if (len % 2 != 0)
+ throw new IllegalArgumentException("Invalid hex string.");
+ byte[] b = new byte[len / 2];
+ int index, v;
+ for (int i = 0; i < b.length; i++) {
+ index = i * 2;
+ v = Integer.parseInt(s.substring(index, index + 2), 16);
+ b[i] = (byte) v;
+ }
+ return b;
}
}
diff --git a/src/main/java/com/keuin/kbackupfabric/util/backup/BackupFilesystemUtil.java b/src/main/java/com/keuin/kbackupfabric/util/backup/BackupFilesystemUtil.java
index 837b638..7106ad2 100644
--- a/src/main/java/com/keuin/kbackupfabric/util/backup/BackupFilesystemUtil.java
+++ b/src/main/java/com/keuin/kbackupfabric/util/backup/BackupFilesystemUtil.java
@@ -23,10 +23,6 @@ public final class BackupFilesystemUtil {
return backupFileNamePrefix;
}
- @Deprecated
- public static String getBackupFileName(String backupName) {
- return backupFileNamePrefix + backupName + ".zip";
- }
// @Deprecated
// public static String getBackupName(String backupFileName) {
diff --git a/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/FileIdentifierProvider.java b/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/FileIdentifierProvider.java
index 9a03371..3fbe284 100644
--- a/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/FileIdentifierProvider.java
+++ b/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/FileIdentifierProvider.java
@@ -4,5 +4,12 @@ import java.io.File;
import java.io.IOException;
public interface FileIdentifierProvider<T extends ObjectIdentifier> {
+ /**
+ * Generate file identifier from a random file. The file is not necessarily in the object base.
+ *
+ * @param file the file.
+ * @return the file identifier.
+ * @throws IOException when an I/O error occurs.
+ */
T fromFile(File file) throws IOException;
}
diff --git a/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/Sha256Identifier.java b/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/Sha256Identifier.java
index cbf1bb9..c1c87e1 100644
--- a/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/Sha256Identifier.java
+++ b/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/Sha256Identifier.java
@@ -1,5 +1,7 @@
package com.keuin.kbackupfabric.util.backup.incremental.identifier;
+import com.keuin.kbackupfabric.util.BytesUtil;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@@ -16,20 +18,34 @@ public class Sha256Identifier extends SingleHashIdentifier {
private static final int SHA256_LENGTH = 32;
private static final Sha256Identifier DUMMY = new Sha256Identifier(new byte[SHA256_LENGTH]); // only for using its hash method
private static final FileIdentifierProvider<Sha256Identifier> factory = Sha256Identifier::fromFile;
+ private static final String marker = "S2";
public static Sha256Identifier fromFile(File file) throws IOException {
- if (!Objects.requireNonNull(file).isFile()) {
+ if (!file.isFile()) {
throw new IllegalArgumentException("file is not a file");
}
return new Sha256Identifier(DUMMY.hash(file));
}
+ /**
+ * Load sha-256 from a named file. Only used in StorageObjectLoader.
+ *
+ * @param fileName the file name.
+ * @return identifier.
+ */
+ static Sha256Identifier fromFileName(String fileName) {
+ if (!fileName.matches(marker + "-[0-9A-Fa-f]{32}"))
+ return null;
+ String hexString = fileName.substring(marker.length() + 1);
+ return new Sha256Identifier(BytesUtil.hexToBytes(hexString));
+ }
+
public static FileIdentifierProvider<Sha256Identifier> getFactory() {
return factory;
}
protected Sha256Identifier(byte[] hash) {
- super(hash);
+ super(hash, marker);
Objects.requireNonNull(hash);
if (hash.length != SHA256_LENGTH) {
throw new IllegalStateException(String.format("SHA256 must be %d bytes", SHA256_LENGTH));
diff --git a/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/SingleHashIdentifier.java b/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/SingleHashIdentifier.java
index 3b96f79..0f62f2b 100644
--- a/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/SingleHashIdentifier.java
+++ b/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/SingleHashIdentifier.java
@@ -5,6 +5,7 @@ import com.keuin.kbackupfabric.util.BytesUtil;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
+import java.util.Objects;
/**
* A simple identifier based on a single hash function.
@@ -13,9 +14,13 @@ import java.util.Arrays;
public abstract class SingleHashIdentifier implements ObjectIdentifier {
private final byte[] hash;
+ private final String type;
- protected SingleHashIdentifier(byte[] hash) {
+ protected SingleHashIdentifier(byte[] hash, String type) {
+ Objects.requireNonNull(hash);
+ Objects.requireNonNull(type);
this.hash = Arrays.copyOf(hash, hash.length);
+ this.type = type;
}
/**
@@ -28,7 +33,7 @@ public abstract class SingleHashIdentifier implements ObjectIdentifier {
@Override
public String getIdentification() {
- return BytesUtil.bytesToHex(hash);
+ return type + "-" + BytesUtil.bytesToHex(hash);
}
@Override
@@ -38,4 +43,11 @@ public abstract class SingleHashIdentifier implements ObjectIdentifier {
}
return Arrays.equals(hash, ((SingleHashIdentifier) obj).hash);
}
+
+ @Override
+ public int hashCode() {
+ int result = Objects.hash(type);
+ result = 31 * result + Arrays.hashCode(hash);
+ return result;
+ }
}
diff --git a/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/StorageObjectLoader.java b/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/StorageObjectLoader.java
new file mode 100644
index 0000000..96bc295
--- /dev/null
+++ b/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/StorageObjectLoader.java
@@ -0,0 +1,25 @@
+package com.keuin.kbackupfabric.util.backup.incremental.identifier;
+
+import java.io.File;
+import java.util.Objects;
+
+public class StorageObjectLoader {
+ /**
+ * Get identifier from storage file.
+ *
+ * @param file storage file.
+ * @return identifier. If failed, return null.
+ */
+ public static ObjectIdentifier asIdentifier(File file) {
+ Objects.requireNonNull(file);
+ String fileName = file.getName();
+ ObjectIdentifier identifier;
+
+ identifier = Sha256Identifier.fromFileName(fileName);
+ if (identifier != null)
+ return identifier;
+
+ // Add more identifiers.
+ return null;
+ }
+}
diff --git a/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/manager/IncrementalBackupStorageManager.java b/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/manager/IncrementalBackupStorageManager.java
index 6c359c6..6fd339b 100644
--- a/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/manager/IncrementalBackupStorageManager.java
+++ b/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/manager/IncrementalBackupStorageManager.java
@@ -3,6 +3,8 @@ package com.keuin.kbackupfabric.util.backup.incremental.manager;
import com.keuin.kbackupfabric.util.PrintUtil;
import com.keuin.kbackupfabric.util.backup.incremental.ObjectCollection;
import com.keuin.kbackupfabric.util.backup.incremental.ObjectElement;
+import com.keuin.kbackupfabric.util.backup.incremental.identifier.ObjectIdentifier;
+import com.keuin.kbackupfabric.util.backup.incremental.identifier.StorageObjectLoader;
import java.io.File;
import java.io.FileNotFoundException;
@@ -10,14 +12,15 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
import static org.apache.commons.io.FileUtils.forceDelete;
public class IncrementalBackupStorageManager {
private final Path backupStorageBase;
+ private final Map<ObjectIdentifier, File> map = new HashMap<>();
+ private boolean loaded = false;
public IncrementalBackupStorageManager(Path backupStorageBase) {
this.backupStorageBase = backupStorageBase;
@@ -127,8 +130,31 @@ public class IncrementalBackupStorageManager {
return copyCount;
}
+ public int cleanUnusedObjects(Iterable<ObjectCollection> collectionIterable) {
+ // construct object list in memory
+ Set<String> objects = new HashSet<>();
+// backupStorageBase
+
+ for (ObjectCollection collection : collectionIterable) {
+ for (ObjectElement ele : collection.getElementMap().values()) {
+
+ }
+ }
+ throw new RuntimeException("not impl");
+ }
+
+ /**
+ * Check all objects, return unused ones.
+ *
+ * @return the unused ones.
+ */
+ private Map<ObjectIdentifier, File> markUnusedObjects() {
+ throw new RuntimeException("not impl");
+ }
+
/**
* Check if the backup base contains given element.
+ *
* @param objectElement the element.
* @return true or false.
*/
@@ -137,4 +163,26 @@ public class IncrementalBackupStorageManager {
return (new File(backupStorageBase.toFile(), objectElement.getIdentifier().getIdentification())).exists();
}
+ private void lazyLoadStorage() throws IOException {
+ if (!loaded) {
+ loadStorage();
+ loaded = true;
+ }
+ }
+
+ private synchronized void loadStorage() throws IOException {
+ map.clear();
+ Files.walk(backupStorageBase, 1).forEach(path -> {
+ File file = path.toFile();
+ ObjectIdentifier identifier = StorageObjectLoader.asIdentifier(file);
+ if (identifier == null) {
+ map.clear();
+ throw new IllegalStateException(String.format(
+ "Bad storage object %s: cannot recognize identifier.", file.getName()
+ ));
+ }
+ map.put(identifier, file);
+ });
+ }
+
}
diff --git a/src/main/java/com/keuin/kbackupfabric/util/backup/name/BackupFileNameEncoder.java b/src/main/java/com/keuin/kbackupfabric/util/backup/name/BackupFileNameEncoder.java
index 972403b..8ebc7ff 100644
--- a/src/main/java/com/keuin/kbackupfabric/util/backup/name/BackupFileNameEncoder.java
+++ b/src/main/java/com/keuin/kbackupfabric/util/backup/name/BackupFileNameEncoder.java
@@ -18,13 +18,19 @@ public interface BackupFileNameEncoder {
/**
* Extract custom and backup time from backup file name.
+ *
* @param fileName the backup file name.
* @return the information. If the given file name is invalid, return null.
*/
BackupBasicInformation decode(String fileName);
+ default boolean isValidFileName(String fileName) {
+ return decode(fileName) != null;
+ }
+
/**
* Check if the given string is a valid custom backup name.
+ *
* @param customName the custom backup name.
* @return if the name is valid.
*/
@@ -45,7 +51,7 @@ public interface BackupFileNameEncoder {
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm.ss");
- BackupBasicInformation(String customName, LocalDateTime time) {
+ protected BackupBasicInformation(String customName, LocalDateTime time) {
this.customName = customName;
this.time = time;
}
diff --git a/src/main/java/com/keuin/kbackupfabric/util/backup/name/IncrementalBackupFileNameEncoder.java b/src/main/java/com/keuin/kbackupfabric/util/backup/name/IncrementalBackupFileNameEncoder.java
index 3c35201..926f47c 100644
--- a/src/main/java/com/keuin/kbackupfabric/util/backup/name/IncrementalBackupFileNameEncoder.java
+++ b/src/main/java/com/keuin/kbackupfabric/util/backup/name/IncrementalBackupFileNameEncoder.java
@@ -24,7 +24,7 @@ public class IncrementalBackupFileNameEncoder implements BackupFileNameEncoder {
@Override
public BackupFileNameEncoder.BackupBasicInformation decode(String fileName) {
Pattern pattern = Pattern.compile(
- backupFileNamePrefix + "-" + "([0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}-[0-9]{2}-[0-9]{2})_(.+)\\.kbi"
+ "^" + backupFileNamePrefix + "-" + "([0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}-[0-9]{2}-[0-9]{2})_(.+)\\.kbi" + "$"
);
Matcher matcher = pattern.matcher(fileName);
if (matcher.find()) {
diff --git a/src/main/java/com/keuin/kbackupfabric/util/backup/name/PrimitiveBackupFileNameEncoder.java b/src/main/java/com/keuin/kbackupfabric/util/backup/name/PrimitiveBackupFileNameEncoder.java
index bcba114..ef15ae7 100644
--- a/src/main/java/com/keuin/kbackupfabric/util/backup/name/PrimitiveBackupFileNameEncoder.java
+++ b/src/main/java/com/keuin/kbackupfabric/util/backup/name/PrimitiveBackupFileNameEncoder.java
@@ -20,7 +20,7 @@ public class PrimitiveBackupFileNameEncoder implements BackupFileNameEncoder {
@Override
public BackupBasicInformation decode(String fileName) {
Pattern pattern = Pattern.compile(
- backupFileNamePrefix + "-" + "([0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}-[0-9]{2}-[0-9]{2})_(.+)\\.zip"
+ "^" + backupFileNamePrefix + "-" + "([0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}-[0-9]{2}-[0-9]{2})_(.+)\\.zip" + "$"
);
Matcher matcher = pattern.matcher(fileName);
if (matcher.find()) {
diff --git a/src/main/java/com/keuin/kbackupfabric/util/backup/provider/AvailableBackupProvider.java b/src/main/java/com/keuin/kbackupfabric/util/backup/provider/AvailableBackupProvider.java
new file mode 100644
index 0000000..caa0e84
--- /dev/null
+++ b/src/main/java/com/keuin/kbackupfabric/util/backup/provider/AvailableBackupProvider.java
@@ -0,0 +1,8 @@
+package com.keuin.kbackupfabric.util.backup.provider;
+
+/**
+ * List all backup in disk. Provide their basic information as soon as possible.
+ */
+public class AvailableBackupProvider {
+ // TODO: remove obsolete impl. in command user interface. Use this instead.
+}
diff --git a/src/main/java/com/keuin/kbackupfabric/util/backup/provider/IncrementalBackupInformation.java b/src/main/java/com/keuin/kbackupfabric/util/backup/provider/IncrementalBackupInformation.java
new file mode 100644
index 0000000..861d210
--- /dev/null
+++ b/src/main/java/com/keuin/kbackupfabric/util/backup/provider/IncrementalBackupInformation.java
@@ -0,0 +1,13 @@
+package com.keuin.kbackupfabric.util.backup.provider;
+
+import com.keuin.kbackupfabric.util.backup.name.BackupFileNameEncoder;
+
+import java.time.LocalDateTime;
+
+public class IncrementalBackupInformation extends BackupFileNameEncoder.BackupBasicInformation {
+ // TODO: show total size for incremental backup
+
+ public IncrementalBackupInformation(String customName, LocalDateTime time) {
+ super(customName, time);
+ }
+}
diff --git a/src/main/java/com/keuin/kbackupfabric/util/backup/provider/PrimitiveBackupInformation.java b/src/main/java/com/keuin/kbackupfabric/util/backup/provider/PrimitiveBackupInformation.java
new file mode 100644
index 0000000..d3d2db8
--- /dev/null
+++ b/src/main/java/com/keuin/kbackupfabric/util/backup/provider/PrimitiveBackupInformation.java
@@ -0,0 +1,14 @@
+package com.keuin.kbackupfabric.util.backup.provider;
+
+import com.keuin.kbackupfabric.util.backup.name.BackupFileNameEncoder;
+
+import java.time.LocalDateTime;
+
+public class PrimitiveBackupInformation extends BackupFileNameEncoder.BackupBasicInformation {
+ public final long sizeBytes;
+
+ public PrimitiveBackupInformation(String customName, LocalDateTime time, long sizeBytes) {
+ super(customName, time);
+ this.sizeBytes = sizeBytes;
+ }
+}
diff --git a/src/test/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredIncrementalBackupMethodTest.java b/src/test/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredIncrementalBackupMethodTest.java
index 7e4f267..58e1711 100644
--- a/src/test/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredIncrementalBackupMethodTest.java
+++ b/src/test/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredIncrementalBackupMethodTest.java
@@ -4,6 +4,7 @@ import org.apache.commons.codec.digest.DigestUtils;
import org.junit.Test;
import java.io.*;
+import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
@@ -19,14 +20,14 @@ public class ConfiguredIncrementalBackupMethodTest {
private final String destDirectoryName = "destination";
private final String indexFileName = "index";
- private final double directoryFactor = 0.4;
- private final double fileFactor = 0.1;
- private final int maxRandomFileSizeBytes = 1024 * 1024;
+ private final double directoryFactor = 0.03;
+ private final double fileFactor = 0.05;
+ private final int maxRandomFileSizeBytes = 1024 * 1024 * 16;
private final Function<Integer, Integer> scaleDecayFunc = (x) -> x - 1;
@Test
public void iterationTest() throws IOException {
- int a = 100;
+ int a = 12;
for (int i = 0; i < a; ++i) {
performTest(Math.min(i + 1, 10));
System.out.println("Round " + i + " passed.");
@@ -75,9 +76,28 @@ public class ConfiguredIncrementalBackupMethodTest {
if (!method.restore())
fail();
+ boolean fake = scale % 2 != 0;
+
+ int[] success = new int[1];
+ if (fake) {
+ Files.walk(sourcePath).filter(path -> path.toFile().isFile()).limit(3).forEach(path -> {
+ if (!path.toFile().delete())
+ fail();
+ success[0]++;
+ });
+ if (success[0] == 0)
+ fake = false;
+ }
+
+ if (fake)
+ System.out.println("Fake: deleted " + success[0] + " file(s).");
+
String hash2 = calcMD5HashForDir(sourcePath.toFile(), true);
- assertEquals(hash1, hash2);
+ if (!fake)
+ assertEquals(hash1, hash2);
+ else
+ assertNotEquals(hash1, hash2);
}
private void createRandomDirectoryTree(String path, int scale) throws IOException {
@@ -94,7 +114,7 @@ public class ConfiguredIncrementalBackupMethodTest {
for (int i = 0; i < subFileCount; i++) {
String subFile = null;
while (subFile == null || new File(path, subFile).exists())
- subFile = getRandomString((int) (Math.random() * 16 + 1));
+ subFile = getRandomString((int) (Math.random() * 16 + 5));
createRandomFile(new File(path, subFile), maxRandomFileSizeBytes);
}
@@ -103,7 +123,7 @@ public class ConfiguredIncrementalBackupMethodTest {
for (int i = 0; i < subDirCount; i++) {
String subDir = null;
while (subDir == null || new File(path, subDir).exists())
- subDir = getRandomString((int) (Math.random() * 16 + 1));
+ subDir = getRandomString((int) (Math.random() * 16 + 5));
createRandomDirectoryTree(new File(path, subDir).getAbsolutePath(), scaleDecayFunc.apply(scale));
}
}
diff --git a/src/test/java/com/keuin/kbackupfabric/util/backup/incremental/ObjectCollectionFactoryTest.java b/src/test/java/com/keuin/kbackupfabric/util/backup/incremental/ObjectCollectionFactoryTest.java
index b7e0aad..3f722a4 100644
--- a/src/test/java/com/keuin/kbackupfabric/util/backup/incremental/ObjectCollectionFactoryTest.java
+++ b/src/test/java/com/keuin/kbackupfabric/util/backup/incremental/ObjectCollectionFactoryTest.java
@@ -20,7 +20,7 @@ public class ObjectCollectionFactoryTest {
}
for (Map.Entry<String, ObjectElement> entry : collection.getElementMap().entrySet()) {
// assertTrue(subElements.contains(e.getIdentification()));
- assertEquals(subElements.get(entry.getKey()), entry.getValue().getIdentifier().getIdentification());
+ assertEquals(subElements.get(entry.getKey()).toUpperCase(), entry.getValue().getIdentifier().getIdentification().toUpperCase());
}
}
@@ -39,14 +39,14 @@ public class ObjectCollectionFactoryTest {
final Map<String, String> elements = new HashMap<>();
// check root dir
- elements.put("a", "261CA0D59FEE8FD169802BB8030A07CF23E5C1593FA81A16C6D0A8CF27DAA2ED");
- elements.put("b", "B3FED75012C4969DC63A50EBC4E745FF77E4A06E0B04720EF71EF033032EBAF7");
+ elements.put("a", "S2-261CA0D59FEE8FD169802BB8030A07CF23E5C1593FA81A16C6D0A8CF27DAA2ED");
+ elements.put("b", "S2-B3FED75012C4969DC63A50EBC4E745FF77E4A06E0B04720EF71EF033032EBAF7");
validate(collection, Arrays.asList("1", "2", "3"), elements);
elements.clear();
// check `1`
- elements.put("a", "E8620F35A5DB33B1257CC51245DDACDA8AF3E0D431A8A38473575E468BCBD0BD");
- elements.put("b", "19EE41585A674274891DE5A4B365DBAB9C49C576AB6F86CD515B683724D2DBBD");
+ elements.put("a", "S2-E8620F35A5DB33B1257CC51245DDACDA8AF3E0D431A8A38473575E468BCBD0BD");
+ elements.put("b", "S2-19EE41585A674274891DE5A4B365DBAB9C49C576AB6F86CD515B683724D2DBBD");
validate(collection.getSubCollectionMap().get("1"), Arrays.asList("11", "12"), elements);
elements.clear();
@@ -60,8 +60,8 @@ public class ObjectCollectionFactoryTest {
validate(collection.getSubCollectionMap().get("1").getSubCollectionMap().get("11"), Collections.singletonList("111"), Collections.emptyMap());
// check `111`
- elements.put("a", "1EDBE882A757E1FAFCA77A9D3BE3FF5D2BB3E2037B238C865F1F957C431F43B4");
- elements.put("b", "30BA7CD8B4AD93A8B3826CD8D1518790924EEBB930EC04DF7DFB03A50B17D7BC");
+ elements.put("a", "S2-1EDBE882A757E1FAFCA77A9D3BE3FF5D2BB3E2037B238C865F1F957C431F43B4");
+ elements.put("b", "S2-30BA7CD8B4AD93A8B3826CD8D1518790924EEBB930EC04DF7DFB03A50B17D7BC");
validate(
collection.getSubCollectionMap().get("1").getSubCollectionMap().get("11").getSubCollectionMap().get("111"),
Collections.emptyList(),
diff --git a/src/test/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/Sha256IdentifierTest.java b/src/test/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/Sha256IdentifierTest.java
index 53e92e2..f799a95 100644
--- a/src/test/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/Sha256IdentifierTest.java
+++ b/src/test/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/Sha256IdentifierTest.java
@@ -15,7 +15,7 @@ public class Sha256IdentifierTest {
try {
Sha256Identifier sha256 = Sha256Identifier.fromFile(new File("./testfile/Sha256IdentifierTest"));
String str = sha256.getIdentification().toUpperCase();
- assertEquals("315F5BDB76D078C43B8AC0064E4A0164612B1FCE77C869345BFC94C75894EDD3", str);
+ assertEquals("S2-315F5BDB76D078C43B8AC0064E4A0164612B1FCE77C869345BFC94C75894EDD3", str);
} catch (IOException e) {
e.printStackTrace();
fail();
diff --git a/src/test/java/com/keuin/kbackupfabric/util/backup/name/IncrementalBackupFileNameEncoderTest.java b/src/test/java/com/keuin/kbackupfabric/util/backup/name/IncrementalBackupFileNameEncoderTest.java
new file mode 100644
index 0000000..e5fedd7
--- /dev/null
+++ b/src/test/java/com/keuin/kbackupfabric/util/backup/name/IncrementalBackupFileNameEncoderTest.java
@@ -0,0 +1,38 @@
+package com.keuin.kbackupfabric.util.backup.name;
+
+import org.junit.Test;
+
+import java.time.LocalDateTime;
+
+import static org.junit.Assert.*;
+
+public class IncrementalBackupFileNameEncoderTest {
+ @Test
+ public void testEncode() {
+ LocalDateTime time = LocalDateTime.of(1, 1, 1, 1, 1, 1);
+ String customName = "name";
+ IncrementalBackupFileNameEncoder encoder = new IncrementalBackupFileNameEncoder();
+ assertEquals("incremental-0001-01-01_01-01-01_name.kbi", encoder.encode(customName, time));
+ }
+
+ @Test
+ public void testDecode() {
+ LocalDateTime time = LocalDateTime.of(1, 1, 1, 1, 1, 1);
+ String customName = "name";
+ IncrementalBackupFileNameEncoder encoder = new IncrementalBackupFileNameEncoder();
+ BackupFileNameEncoder.BackupBasicInformation information = encoder.decode("incremental-0001-01-01_01-01-01_name.kbi");
+ assertEquals(time, information.time);
+ assertEquals(customName, information.customName);
+ }
+
+ @Test
+ public void isValid() {
+ IncrementalBackupFileNameEncoder encoder = new IncrementalBackupFileNameEncoder();
+ assertTrue(encoder.isValidFileName("incremental-0001-01-01_01-01-01_name.kbi"));
+ assertTrue(encoder.isValidFileName("incremental-0001-01-01_01-01-01_0001-01-01_01-01-01_name.kbi"));
+ assertFalse(encoder.isValidFileName("incremental-0001-01-01_01-01-01incremental-0001-01-01_01-01-01_name.kbi"));
+ assertFalse(encoder.isValidFileName("incremental-0001-01-01_01-01-01_name"));
+ assertFalse(encoder.isValidFileName("incremental-0001-01-01_01-01-01_name.zip"));
+ assertFalse(encoder.isValidFileName("somefile"));
+ }
+} \ No newline at end of file
diff --git a/src/test/java/com/keuin/kbackupfabric/util/backup/name/PrimitiveBackupFileNameEncoderTest.java b/src/test/java/com/keuin/kbackupfabric/util/backup/name/PrimitiveBackupFileNameEncoderTest.java
index 4823575..abc19d5 100644
--- a/src/test/java/com/keuin/kbackupfabric/util/backup/name/PrimitiveBackupFileNameEncoderTest.java
+++ b/src/test/java/com/keuin/kbackupfabric/util/backup/name/PrimitiveBackupFileNameEncoderTest.java
@@ -5,17 +5,46 @@ import org.junit.Test;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.*;
public class PrimitiveBackupFileNameEncoderTest {
@Test
public void testConsistency() {
- LocalDateTime time = LocalDateTime.ofEpochSecond(System.currentTimeMillis()/1000, 0, ZoneOffset.UTC);
+ LocalDateTime time = LocalDateTime.ofEpochSecond(System.currentTimeMillis() / 1000, 0, ZoneOffset.UTC);
String name = "Test Na_me";
PrimitiveBackupFileNameEncoder encoder = new PrimitiveBackupFileNameEncoder();
BackupFileNameEncoder.BackupBasicInformation information = encoder.decode(encoder.encode(name, time));
assertEquals(time, information.time);
assertEquals(name, information.customName);
}
+
+ @Test
+ public void testEncode() {
+ LocalDateTime time = LocalDateTime.of(1, 1, 1, 1, 1, 1);
+ String customName = "name";
+ PrimitiveBackupFileNameEncoder encoder = new PrimitiveBackupFileNameEncoder();
+ assertEquals("kbackup-0001-01-01_01-01-01_name.zip", encoder.encode(customName, time));
+ }
+
+ @Test
+ public void testDecode() {
+ LocalDateTime time = LocalDateTime.of(1, 1, 1, 1, 1, 1);
+ String customName = "name";
+ PrimitiveBackupFileNameEncoder encoder = new PrimitiveBackupFileNameEncoder();
+ BackupFileNameEncoder.BackupBasicInformation information = encoder.decode("kbackup-0001-01-01_01-01-01_name.zip");
+ assertEquals(time, information.time);
+ assertEquals(customName, information.customName);
+ }
+
+ @Test
+ public void isValid() {
+ PrimitiveBackupFileNameEncoder encoder = new PrimitiveBackupFileNameEncoder();
+ assertTrue(encoder.isValidFileName("kbackup-0001-01-01_01-01-01_name.zip"));
+ assertTrue(encoder.isValidFileName("kbackup-0001-01-01_01-01-01_0001-01-01_01-01-01_name.zip"));
+ assertFalse(encoder.isValidFileName("kbackup-0001-01-01_01-01-01kbackup-0001-01-01_01-01-01_name.zip"));
+ assertFalse(encoder.isValidFileName("kbackup-0001-01-01_01-01-01_name"));
+ assertFalse(encoder.isValidFileName("kbackup-0001-01-01_01-01-01_name.kbi"));
+ assertFalse(encoder.isValidFileName("somefile"));
+ }
} \ No newline at end of file