summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorKeuin <[email protected]>2021-01-21 01:50:08 +0800
committerKeuin <[email protected]>2021-01-21 01:50:08 +0800
commitac3b5e1476dedcefb723f19bd0fdd9a22fcb16e9 (patch)
tree75d0994f3f7aa37c3d240933f0f2d179d318e597 /src/test
parent82e3986045ac7eaca6aaa290fb2283fd6c6c901a (diff)
parent7a5297de3467b1069fdf5e4a1b2aaf510ca35663 (diff)
Merge remote-tracking branch 'origin/master'
# Conflicts: # src/main/java/com/keuin/kbackupfabric/operation/backup/PrimitiveBackupMethod.java
Diffstat (limited to 'src/test')
-rw-r--r--src/test/java/IncrementalBackupUtilTest.java16
-rw-r--r--src/test/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredIncrementalBackupMethodTest.java213
-rw-r--r--src/test/java/com/keuin/kbackupfabric/util/backup/incremental/ObjectCollectionFactoryTest.java80
-rw-r--r--src/test/java/com/keuin/kbackupfabric/util/backup/incremental/ObjectCollectionSerializerTest.java29
-rw-r--r--src/test/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/Sha256IdentifierTest.java25
-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.java50
7 files changed, 435 insertions, 16 deletions
diff --git a/src/test/java/IncrementalBackupUtilTest.java b/src/test/java/IncrementalBackupUtilTest.java
deleted file mode 100644
index b050a91..0000000
--- a/src/test/java/IncrementalBackupUtilTest.java
+++ /dev/null
@@ -1,16 +0,0 @@
-import com.keuin.kbackupfabric.operation.backup.IncrementalBackupUtil;
-
-import java.io.IOException;
-
-public class IncrementalBackupUtilTest {
-
- @org.junit.Test
- public void generateDirectoryJsonObject() {
- try {
- System.out.println(IncrementalBackupUtil.generateDirectoryJsonObject("D:\\1"));
- } catch (IOException exception) {
- exception.printStackTrace();
- }
-
- }
-} \ No newline at end of file
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
new file mode 100644
index 0000000..30f2d44
--- /dev/null
+++ b/src/test/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredIncrementalBackupMethodTest.java
@@ -0,0 +1,213 @@
+package com.keuin.kbackupfabric.operation.backup.method;
+
+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.*;
+import java.util.function.Function;
+
+import static org.apache.commons.io.FileUtils.forceDelete;
+import static org.junit.Assert.*;
+
+public class ConfiguredIncrementalBackupMethodTest {
+
+ private final String testTempPath = (new File("R:\\").isDirectory()) ? "R:\\" : ".\\testfile\\ConfiguredIncrementalBackupMethodTest";
+ private final String sourceDirectoryName = "source";
+ private final String destDirectoryName = "destination";
+ private final String indexFileName = "index";
+
+ private final double directoryFactor = 0.02;
+ 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 = 12;
+ for (int i = 0; i < a; ++i) {
+ performTest(Math.min(i + 1, 10));
+ System.out.println("Round " + i + " passed.");
+ }
+ }
+
+ private void performTest(int scale) throws IOException {
+
+ // init source and destination
+ final Path sourcePath = Paths.get(testTempPath, sourceDirectoryName);
+ final Path destPath = Paths.get(testTempPath, destDirectoryName);
+ if (new File(sourcePath.toString()).exists()) {
+ forceDelete(new File(sourcePath.toString()));
+ if (!new File(sourcePath.toString()).mkdirs())
+ fail();
+ }
+ if (new File(destPath.toString()).exists()) {
+ forceDelete(new File(destPath.toString()));
+ if (!new File(destPath.toString()).mkdirs())
+ fail();
+ }
+ if (new File(testTempPath, indexFileName).exists()) {
+ if (!new File(testTempPath, indexFileName).delete())
+ fail();
+ }
+
+ // initialize src
+ createRandomDirectoryTree(sourcePath.toString(), scale);
+
+ String hash1 = calcMD5HashForDir(sourcePath.toFile(), true);
+
+ // copy src to dest
+ ConfiguredIncrementalBackupMethod method = new ConfiguredIncrementalBackupMethod(
+ indexFileName,
+ sourcePath.toString(),
+ testTempPath,
+ destPath.toString()
+ );
+ method.backup();
+
+ // delete src
+ forceDelete(sourcePath.toFile());
+ assertFalse(sourcePath.toFile().isDirectory());
+
+ // restore src
+ 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);
+
+ if (!fake)
+ assertEquals(hash1, hash2);
+ else
+ assertNotEquals(hash1, hash2);
+ }
+
+ private void createRandomDirectoryTree(String path, int scale) throws IOException {
+ if (scale <= 0) {
+ if (Math.random() < 0.5)
+ if (!new File(path).mkdirs() && !new File(path).exists())
+ throw new IOException("Failed to create directory " + path);
+ return;
+ }
+ if (!new File(path).isDirectory() && !new File(path).mkdirs())
+ throw new IOException("Failed to create directory " + path);
+
+ int subFileCount = (int) Math.round(Math.random() * 10 * scale * fileFactor);
+ for (int i = 0; i < subFileCount; i++) {
+ String subFile = null;
+ while (subFile == null || new File(path, subFile).exists())
+ subFile = getRandomString((int) (Math.random() * 16 + 5));
+ createRandomFile(new File(path, subFile), maxRandomFileSizeBytes);
+ }
+
+
+ int subDirCount = (int) Math.round(Math.random() * 10 * scale * directoryFactor);
+ for (int i = 0; i < subDirCount; i++) {
+ String subDir = null;
+ while (subDir == null || new File(path, subDir).exists())
+ subDir = getRandomString((int) (Math.random() * 16 + 5));
+ createRandomDirectoryTree(new File(path, subDir).getAbsolutePath(), scaleDecayFunc.apply(scale));
+ }
+ }
+
+ private static void createRandomFile(File file, int maxSizeBytes) throws IOException {
+ if (!file.createNewFile())
+ throw new IOException("Failed to create file " + file.getAbsolutePath());
+ try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
+ int fileBytes = (int) (maxSizeBytes * Math.random() + 1);
+ Random random = new Random();
+ final int chunkSize = 1024 * 4;
+ byte[] randomChunk = new byte[chunkSize];
+ for (int i = 0; i < fileBytes / chunkSize; i++) {
+ random.nextBytes(randomChunk);
+ fileOutputStream.write(randomChunk);
+ }
+ if (fileBytes % chunkSize != 0) {
+ randomChunk = new byte[fileBytes % chunkSize];
+ random.nextBytes(randomChunk);
+ fileOutputStream.write(randomChunk);
+ }
+ }
+ }
+
+ 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();
+ }
+
+ public String calcMD5HashForDir(File dirToHash, boolean includeHiddenFiles) {
+
+ assert (dirToHash.isDirectory());
+ Vector<FileInputStream> fileStreams = new Vector<>();
+
+ System.out.println("Found files for hashing:");
+ collectInputStreams(dirToHash, fileStreams, includeHiddenFiles);
+
+ SequenceInputStream seqStream =
+ new SequenceInputStream(fileStreams.elements());
+
+ try {
+ String md5Hash = DigestUtils.md5Hex(seqStream);
+ seqStream.close();
+ return md5Hash;
+ } catch (IOException e) {
+ throw new RuntimeException("Error reading files to hash in "
+ + dirToHash.getAbsolutePath(), e);
+ }
+
+ }
+
+ private void collectInputStreams(File dir,
+ List<FileInputStream> foundStreams,
+ boolean includeHiddenFiles) {
+
+ File[] fileList = dir.listFiles();
+ Arrays.sort(fileList, // Need in reproducible order
+ new Comparator<File>() {
+ public int compare(File f1, File f2) {
+ return f1.getName().compareTo(f2.getName());
+ }
+ });
+
+ for (File f : fileList) {
+ if (!includeHiddenFiles && f.getName().startsWith(".")) {
+ // Skip it
+ } else if (f.isDirectory()) {
+ collectInputStreams(f, foundStreams, includeHiddenFiles);
+ } else {
+ try {
+ System.out.println("\t" + f.getAbsolutePath());
+ foundStreams.add(new FileInputStream(f));
+ } catch (FileNotFoundException e) {
+ throw new AssertionError(e.getMessage()
+ + ": file should never not be found!");
+ }
+ }
+ }
+
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000..3f722a4
--- /dev/null
+++ b/src/test/java/com/keuin/kbackupfabric/util/backup/incremental/ObjectCollectionFactoryTest.java
@@ -0,0 +1,80 @@
+package com.keuin.kbackupfabric.util.backup.incremental;
+
+import com.keuin.kbackupfabric.util.backup.incremental.identifier.Sha256Identifier;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+
+import static org.junit.Assert.*;
+
+public class ObjectCollectionFactoryTest {
+
+ private void validate(ObjectCollection collection, List<String> subCollections, Map<String, String> subElements) {
+ assertEquals(subCollections.size(), collection.getSubCollectionMap().size());
+ assertEquals(subElements.size(), collection.getElementSet().size());
+ for (Map.Entry<String, ObjectCollection> c : collection.getSubCollectionMap().entrySet()) {
+ assertEquals(c.getKey(), c.getValue().getName());
+ assertTrue(subCollections.contains(c.getKey()));
+ }
+ for (Map.Entry<String, ObjectElement> entry : collection.getElementMap().entrySet()) {
+// assertTrue(subElements.contains(e.getIdentification()));
+ assertEquals(subElements.get(entry.getKey()).toUpperCase(), entry.getValue().getIdentifier().getIdentification().toUpperCase());
+ }
+ }
+
+ @Test
+ public void fromDirectory() {
+ try {
+ ObjectCollectionFactory<Sha256Identifier> factory =
+ new ObjectCollectionFactory<>(Sha256Identifier.getFactory());
+ ObjectCollection collection =
+ factory.fromDirectory(new File("./testfile/ObjectCollectionFactoryTest"));
+
+ assertEquals("ObjectCollectionFactoryTest", collection.getName());
+ assertEquals(3, collection.getSubCollectionMap().size());
+ assertEquals(2, collection.getElementSet().size());
+
+ final Map<String, String> elements = new HashMap<>();
+
+ // check root dir
+ 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", "S2-E8620F35A5DB33B1257CC51245DDACDA8AF3E0D431A8A38473575E468BCBD0BD");
+ elements.put("b", "S2-19EE41585A674274891DE5A4B365DBAB9C49C576AB6F86CD515B683724D2DBBD");
+ validate(collection.getSubCollectionMap().get("1"), Arrays.asList("11", "12"), elements);
+ elements.clear();
+
+ // check `2`
+ validate(collection.getSubCollectionMap().get("2"), Collections.emptyList(), Collections.emptyMap());
+
+ // check `3`
+ validate(collection.getSubCollectionMap().get("3"), Collections.emptyList(), Collections.emptyMap());
+
+ // check `11`
+ validate(collection.getSubCollectionMap().get("1").getSubCollectionMap().get("11"), Collections.singletonList("111"), Collections.emptyMap());
+
+ // check `111`
+ elements.put("a", "S2-1EDBE882A757E1FAFCA77A9D3BE3FF5D2BB3E2037B238C865F1F957C431F43B4");
+ elements.put("b", "S2-30BA7CD8B4AD93A8B3826CD8D1518790924EEBB930EC04DF7DFB03A50B17D7BC");
+ validate(
+ collection.getSubCollectionMap().get("1").getSubCollectionMap().get("11").getSubCollectionMap().get("111"),
+ Collections.emptyList(),
+ elements
+ );
+ elements.clear();
+
+ // check `12`
+ validate(collection.getSubCollectionMap().get("1").getSubCollectionMap().get("12"), Collections.emptyList(), Collections.emptyMap());
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/test/java/com/keuin/kbackupfabric/util/backup/incremental/ObjectCollectionSerializerTest.java b/src/test/java/com/keuin/kbackupfabric/util/backup/incremental/ObjectCollectionSerializerTest.java
new file mode 100644
index 0000000..0edfe01
--- /dev/null
+++ b/src/test/java/com/keuin/kbackupfabric/util/backup/incremental/ObjectCollectionSerializerTest.java
@@ -0,0 +1,29 @@
+package com.keuin.kbackupfabric.util.backup.incremental;
+
+import com.keuin.kbackupfabric.util.backup.incremental.identifier.Sha256Identifier;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+
+import static org.junit.Assert.assertEquals;
+
+public class ObjectCollectionSerializerTest {
+ @Test
+ public void testSerializationConsistency() throws IOException {
+ ObjectCollectionFactory<Sha256Identifier> factory =
+ new ObjectCollectionFactory<>(Sha256Identifier.getFactory());
+ ObjectCollection collection =
+ factory.fromDirectory(new File("./testfile/ObjectCollectionFactoryTest"));
+ File file = new File("./testfile/serialized");
+ if (file.exists()) {
+ Files.delete(file.toPath());
+ }
+ ObjectCollectionSerializer.toFile(collection, file);
+ ObjectCollection collection2 = ObjectCollectionSerializer.fromFile(file);
+ Files.delete(file.toPath());
+ assertEquals(collection, collection2);
+ }
+
+} \ No newline at end of file
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
new file mode 100644
index 0000000..f799a95
--- /dev/null
+++ b/src/test/java/com/keuin/kbackupfabric/util/backup/incremental/identifier/Sha256IdentifierTest.java
@@ -0,0 +1,25 @@
+package com.keuin.kbackupfabric.util.backup.incremental.identifier;
+
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class Sha256IdentifierTest {
+
+ @Test
+ public void fromFile() {
+ try {
+ Sha256Identifier sha256 = Sha256Identifier.fromFile(new File("./testfile/Sha256IdentifierTest"));
+ String str = sha256.getIdentification().toUpperCase();
+ assertEquals("S2-315F5BDB76D078C43B8AC0064E4A0164612B1FCE77C869345BFC94C75894EDD3", str);
+ } catch (IOException e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+} \ No newline at end of file
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
new file mode 100644
index 0000000..abc19d5
--- /dev/null
+++ b/src/test/java/com/keuin/kbackupfabric/util/backup/name/PrimitiveBackupFileNameEncoderTest.java
@@ -0,0 +1,50 @@
+package com.keuin.kbackupfabric.util.backup.name;
+
+import org.junit.Test;
+
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+
+import static org.junit.Assert.*;
+
+public class PrimitiveBackupFileNameEncoderTest {
+
+ @Test
+ public void testConsistency() {
+ 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