diff --git a/Jenkinsfile b/Jenkinsfile
index e85efc8..bf047ac 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -7,9 +7,14 @@ pipeline {
}
stages {
+ stage('Test') {
+ steps {
+ sh 'mvn test'
+ }
+ }
stage('Build') {
steps {
- sh 'mvn -B -DskipTests clean package'
+ sh 'mvn clean package'
}
}
}
diff --git a/pom.xml b/pom.xml
index a0b0b52..2b96fe1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -150,6 +150,25 @@
1.3.0
compile
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ 5.5.2
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.5.2
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-params
+ 5.5.2
+ test
+
diff --git a/src/main/java/nsusbloader/COM/NET/NetworkSetupValidator.java b/src/main/java/nsusbloader/COM/NET/NetworkSetupValidator.java
index b46b418..009cd74 100644
--- a/src/main/java/nsusbloader/COM/NET/NetworkSetupValidator.java
+++ b/src/main/java/nsusbloader/COM/NET/NetworkSetupValidator.java
@@ -77,12 +77,21 @@ public class NetworkSetupValidator {
Arrays.sort(subFiles, Comparator.comparingInt(file -> Integer.parseInt(file.getName())));
for (int i = subFiles.length - 2; i > 0 ; i--){
- if (subFiles[i].length() < subFiles[i-1].length()) {
+ if (subFiles[i].length() != subFiles[i-1].length()) {
logPrinter.print("NET: Exclude split file: "+f.getName()+
"\n Chunk sizes of the split file are not the same, but has to be.", EMsgType.WARNING);
return true;
}
}
+
+ long firstFileLength = subFiles[0].length();
+ long lastFileLength = subFiles[subFiles.length-1].length();
+
+ if (lastFileLength > firstFileLength){
+ logPrinter.print("NET: Exclude split file: "+f.getName()+
+ "\n Chunk sizes of the split file are not the same, but has to be.", EMsgType.WARNING);
+ return true;
+ }
return false;
});
}
diff --git a/src/main/java/nsusbloader/COM/USB/TransferModule.java b/src/main/java/nsusbloader/COM/USB/TransferModule.java
index f7a734b..02dd059 100644
--- a/src/main/java/nsusbloader/COM/USB/TransferModule.java
+++ b/src/main/java/nsusbloader/COM/USB/TransferModule.java
@@ -41,32 +41,40 @@ public abstract class TransferModule {
this.task = task;
this.logPrinter = printer;
- // Validate split files to be sure that there is no crap
- //logPrinter.print("TransferModule: Validating split files ...", EMsgType.INFO); // NOTE: Used for debug
- Iterator> iterator = nspMap.entrySet().iterator();
- while (iterator.hasNext()){
- File f = iterator.next().getValue();
- if (f.isDirectory()){
- File[] subFiles = f.listFiles((file, name) -> name.matches("[0-9]{2}"));
- if (subFiles == null || subFiles.length == 0) {
- logPrinter.print("TransferModule: Removing empty folder: " + f.getName(), EMsgType.WARNING);
- iterator.remove();
- }
- else {
- Arrays.sort(subFiles, Comparator.comparingInt(file -> Integer.parseInt(file.getName())));
-
- for (int i = subFiles.length - 2; i > 0 ; i--){
- if (subFiles[i].length() < subFiles[i-1].length()) {
- logPrinter.print("TransferModule: Removing strange split file: "+f.getName()+
- "\n (Chunk sizes of the split file are not the same, but has to be.)", EMsgType.WARNING);
- iterator.remove();
- } // what
- } // a
- } // nice
- } // stairway
- } // here =)
- //logPrinter.print("TransferModule: Validation complete.", EMsgType.INFO); // NOTE: Used for debug
+ filterFiles();
}
+ void filterFiles(){
+ nspMap.values().removeIf(f -> {
+ if (f.isFile())
+ return false;
+ File[] subFiles = f.listFiles((file, name) -> name.matches("[0-9]{2}"));
+
+ if (subFiles == null || subFiles.length == 0) {
+ logPrinter.print("TransferModule: Exclude folder: " + f.getName(), EMsgType.WARNING);
+ return true;
+ }
+
+ Arrays.sort(subFiles, Comparator.comparingInt(file -> Integer.parseInt(file.getName())));
+
+ for (int i = subFiles.length - 2; i > 0 ; i--){
+ if (subFiles[i].length() != subFiles[i-1].length()) {
+ logPrinter.print("TransferModule: Exclude split file: "+f.getName()+
+ "\n Chunk sizes of the split file are not the same, but has to be.", EMsgType.WARNING);
+ return true;
+ }
+ }
+
+ long firstFileLength = subFiles[0].length();
+ long lastFileLength = subFiles[subFiles.length-1].length();
+
+ if (lastFileLength > firstFileLength){
+ logPrinter.print("TransferModule: Exclude split file: "+f.getName()+
+ "\n Chunk sizes of the split file are not the same, but has to be.", EMsgType.WARNING);
+ return true;
+ }
+ return false;
+ });
+ }
public EFileStatus getStatus(){ return status; }
}
diff --git a/src/main/java/nsusbloader/FilesHelper.java b/src/main/java/nsusbloader/FilesHelper.java
index 5267ada..7988a06 100644
--- a/src/main/java/nsusbloader/FilesHelper.java
+++ b/src/main/java/nsusbloader/FilesHelper.java
@@ -23,10 +23,10 @@ import java.nio.file.Path;
import java.nio.file.Paths;
public class FilesHelper {
- public static String getRealFolder(String path){
- Path splitMergePath = Paths.get(path);
- if (Files.notExists(splitMergePath) || Files.isRegularFile(splitMergePath))
+ public static String getRealFolder(String location){
+ Path locationAsPath = Paths.get(location);
+ if (Files.notExists(locationAsPath) || Files.isRegularFile(locationAsPath))
return System.getProperty("user.home");
- return path;
+ return location;
}
}
diff --git a/src/main/java/nsusbloader/RainbowHexDump.java b/src/main/java/nsusbloader/RainbowHexDump.java
index ebdd277..109957d 100644
--- a/src/main/java/nsusbloader/RainbowHexDump.java
+++ b/src/main/java/nsusbloader/RainbowHexDump.java
@@ -37,10 +37,10 @@ public class RainbowHexDump {
public static void hexDumpUTF8(byte[] byteArray){
System.out.print(ANSI_BLUE);
for (int i=0; i < byteArray.length; i++)
- System.out.print(String.format("%02d-", i%100));
+ System.out.printf("%02d-", i%100);
System.out.println(">"+ANSI_RED+byteArray.length+ANSI_RESET);
for (byte b: byteArray)
- System.out.print(String.format("%02x ", b));
+ System.out.printf("%02x ", b);
System.out.println();
System.out.print("\t\t\t"
+ new String(byteArray, StandardCharsets.UTF_8)
@@ -49,10 +49,10 @@ public class RainbowHexDump {
public static void hexDumpUTF8ForWin(byte[] byteArray){
for (int i=0; i < byteArray.length; i++)
- System.out.print(String.format("%02d-", i%100));
+ System.out.printf("%02d-", i%100);
System.out.println(">"+byteArray.length);
for (byte b: byteArray)
- System.out.print(String.format("%02x ", b));
+ System.out.printf("%02x ", b);
System.out.println();
System.out.print(new String(byteArray, StandardCharsets.UTF_8)
+ "\n");
@@ -61,10 +61,10 @@ public class RainbowHexDump {
public static void hexDumpUTF16LE(byte[] byteArray){
System.out.print(ANSI_BLUE);
for (int i=0; i < byteArray.length; i++)
- System.out.print(String.format("%02d-", i%100));
+ System.out.printf("%02d-", i%100);
System.out.println(">"+ANSI_RED+byteArray.length+ANSI_RESET);
for (byte b: byteArray)
- System.out.print(String.format("%02x ", b));
+ System.out.printf("%02x ", b);
System.out.print(new String(byteArray, StandardCharsets.UTF_16LE)
+ "\n");
}
diff --git a/src/test/java/nsusbloader/COM/USB/TransferModuleTest.java b/src/test/java/nsusbloader/COM/USB/TransferModuleTest.java
new file mode 100644
index 0000000..12acb65
--- /dev/null
+++ b/src/test/java/nsusbloader/COM/USB/TransferModuleTest.java
@@ -0,0 +1,227 @@
+package nsusbloader.COM.USB;
+
+import nsusbloader.ModelControllers.CancellableRunnable;
+import nsusbloader.ModelControllers.ILogPrinter;
+import nsusbloader.ModelControllers.LogPrinterCli;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import org.usb4java.DeviceHandle;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.LinkedHashMap;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class TransferModuleTest{
+
+ @TempDir
+ File testFilesLocation;
+
+ final String regularFileName1 = "file1.nsp";
+ final String regularFileName2 = "file2.nsz";
+ final String regularFileName3 = "file3.xci";
+ final String regularFileName4 = "file4.xcz";
+ final String splitFileName1 = "splitFile1.nsp";
+ final String splitFileName2 = "splitFile2.nsp";
+ final String splitFileName3 = "splitFile3.nsp";
+ final String splitFileName4 = "splitFile4.nsp";
+ final String splitFileName5 = "splitFile5.nsp";
+ final String splitFileName6 = "splitFile6.nsp";
+ final String splitFileName7 = "splitFile7.nsp";
+ final String splitFileName8 = "splitFile8.nsp";
+ final String splitFileName9 = "splitFile9.nsp";
+ final String splitFileName10 = "splitFile10.nsp";
+ final String splitFileName11 = "splitFile11.nsp";
+
+ TransferModuleImplementation transferModule;
+
+ @BeforeEach
+ void createFiles() throws Exception{
+ String parentTempDirectory = testFilesLocation.getAbsolutePath();
+
+ File regularFile1 = createFile(parentTempDirectory, regularFileName1);
+ File regularFile2 = createFile(parentTempDirectory, regularFileName2);
+ File regularFile3 = createFile(parentTempDirectory, regularFileName3);
+ File regularFile4 = createFile(parentTempDirectory, regularFileName4);
+ File splitFile1 = createSplitInvalidEmpty(parentTempDirectory, splitFileName1);
+ File splitFile2 = createSplitInvalidEmpty(parentTempDirectory, splitFileName2);
+ File splitFile3 = createSplitValid(parentTempDirectory, splitFileName3);
+ File splitFile4 = createSplitValid(parentTempDirectory, splitFileName4);
+ File splitFile5 = createSplitValidWithExtras(parentTempDirectory, splitFileName5);
+ File splitFile6 = createSplitInvalidVariant1(parentTempDirectory, splitFileName6);
+ File splitFile7 = createSplitInvalidVariant2(parentTempDirectory, splitFileName7);
+ File splitFile8 = createSplitInvalidVariant3(parentTempDirectory, splitFileName8);
+ File splitFile9 = createSplitInvalidVariant4(parentTempDirectory, splitFileName9);
+ File splitFile10 = createSplitInvalidVariant5(parentTempDirectory, splitFileName10);
+ File splitFile11 = createSplitValidSingleChunk(parentTempDirectory, splitFileName11);
+
+
+ LinkedHashMap filesMap = new LinkedHashMap<>();
+
+ filesMap.put(regularFileName1, regularFile1);
+ filesMap.put(regularFileName2, regularFile2);
+ filesMap.put(regularFileName3, regularFile3);
+ filesMap.put(regularFileName4, regularFile4);
+ filesMap.put(splitFileName1, splitFile1);
+ filesMap.put(splitFileName2, splitFile2);
+ filesMap.put(splitFileName3, splitFile3);
+ filesMap.put(splitFileName4, splitFile4);
+ filesMap.put(splitFileName5, splitFile5);
+ filesMap.put(splitFileName6, splitFile6);
+ filesMap.put(splitFileName7, splitFile7);
+ filesMap.put(splitFileName8, splitFile8);
+ filesMap.put(splitFileName9, splitFile9);
+ filesMap.put(splitFileName10, splitFile10);
+ filesMap.put(splitFileName11, splitFile11);
+
+ ILogPrinter printer = new LogPrinterCli();
+ this.transferModule = new TransferModuleImplementation((DeviceHandle)null, filesMap, (CancellableRunnable)null, printer);
+ }
+
+ File createFile(String parent, String name) throws Exception{
+ Path file = Paths.get(parent, name);
+ Files.createFile(file);
+ return new File(parent, name);
+ }
+
+ File createSplitInvalidEmpty(String parent, String name) throws Exception{
+ Path file = Paths.get(parent, name);
+ Files.createDirectory(file);
+ return new File(parent, name);
+ }
+
+ File createSplitValid(String parent, String name) throws Exception{
+ Path path = Paths.get(parent, name);
+ Files.createDirectory(path);
+ makeSplitFileEntryBigger(path, 0);
+ makeSplitFileEntryBigger(path, 1);
+ makeSplitFileEntryBigger(path, 2);
+ makeSplitFileEntryBigger(path, 3);
+ makeSplitFileEntrySmaller(path, 4);
+ return new File(parent, name);
+ }
+
+ File createSplitValidWithExtras(String parent, String name) throws Exception{
+ Path path = Paths.get(parent, name);
+ Files.createDirectory(path);
+ makeSplitFileEntrySmaller(path, 0);
+ makeSplitFileEntrySmaller(path, 1);
+ makeSplitFileEntrySmaller(path, 2);
+ makeSplitFileEntryWeired(path);
+ return new File(parent, name);
+ }
+
+ File createSplitInvalidVariant1(String parent, String name) throws Exception{
+ Path path = Paths.get(parent, name);
+ Files.createDirectory(path);
+ makeSplitFileEntrySmaller(path, 0);
+ makeSplitFileEntrySmaller(path, 1);
+ makeSplitFileEntryBigger(path, 2); //incorrect
+ makeSplitFileEntrySmaller(path, 3);
+ return new File(parent, name);
+ }
+ File createSplitInvalidVariant2(String parent, String name) throws Exception{
+ Path path = Paths.get(parent, name);
+ Files.createDirectory(path);
+ makeSplitFileEntryBigger(path, 0); //incorrect
+ makeSplitFileEntrySmaller(path, 1);
+ makeSplitFileEntrySmaller(path, 2);
+ makeSplitFileEntrySmaller(path, 3);
+ return new File(parent, name);
+ }
+ File createSplitInvalidVariant3(String parent, String name) throws Exception{
+ Path path = Paths.get(parent, name);
+ Files.createDirectory(path);
+ makeSplitFileEntrySmaller(path, 0);
+ makeSplitFileEntryBigger(path, 1); //incorrect
+ makeSplitFileEntrySmaller(path, 2);
+ makeSplitFileEntrySmaller(path, 3);
+ return new File(parent, name);
+ }
+ File createSplitInvalidVariant4(String parent, String name) throws Exception{
+ Path path = Paths.get(parent, name);
+ Files.createDirectory(path);
+ makeSplitFileEntrySmaller(path, 0); //incorrect
+ makeSplitFileEntryBigger(path, 1);
+ makeSplitFileEntryBigger(path, 2);
+ makeSplitFileEntryBigger(path, 3);
+ return new File(parent, name);
+ }
+ File createSplitInvalidVariant5(String parent, String name) throws Exception{
+ Path path = Paths.get(parent, name);
+ Files.createDirectory(path);
+ makeSplitFileEntrySmaller(path, 0);
+ makeSplitFileEntrySmaller(path, 1);
+ makeSplitFileEntrySmaller(path, 2);
+ makeSplitFileEntryBigger(path, 3); //incorrect: Could be only smaller
+ return new File(parent, name);
+ }
+
+ File createSplitValidSingleChunk(String parent, String name) throws Exception{
+ Path path = Paths.get(parent, name);
+ Files.createDirectory(path);
+ makeSplitFileEntryBigger(path, 0);
+ return new File(parent, name);
+ }
+
+ void makeSplitFileEntrySmaller(Path path, int entryNum) throws Exception{
+ try (FileWriter writer = new FileWriter(String.format("%s%s%02x", path.toString(), File.separator, entryNum))){
+ writer.write("test");
+ writer.flush();
+ }
+ }
+ void makeSplitFileEntryBigger(Path path, int entryNum) throws Exception{
+ try (FileWriter writer = new FileWriter(String.format("%s%s%02x", path.toString(), File.separator, entryNum))){
+ writer.write("test_");
+ writer.flush();
+ }
+ }
+ void makeSplitFileEntryWeired(Path path) throws Exception{
+ try (FileWriter writer = new FileWriter(String.format("%s%sNOT_A_VALID_FILE.nsp", path.toString(), File.separator))){
+ writer.write("literally anything");
+ writer.flush();
+ }
+ }
+
+ private static class TransferModuleImplementation extends TransferModule{
+ TransferModuleImplementation(DeviceHandle handler,
+ LinkedHashMap nspMap,
+ CancellableRunnable task,
+ ILogPrinter printer)
+ {
+ super(handler, nspMap, task, printer);
+ }
+
+ LinkedHashMap getFiles(){ return nspMap; }
+ }
+
+ @DisplayName("Test 'split-files' filter-validator")
+ @Test
+ void validateTransferModule() {
+ LinkedHashMap files = transferModule.getFiles();
+
+ assertTrue(files.containsKey(regularFileName1));
+ assertTrue(files.containsKey(regularFileName2));
+ assertTrue(files.containsKey(regularFileName3));
+ assertTrue(files.containsKey(regularFileName4));
+ assertFalse(files.containsKey(splitFileName1));
+ assertFalse(files.containsKey(splitFileName1));
+ assertFalse(files.containsKey(splitFileName2));
+ assertTrue(files.containsKey(splitFileName3));
+ assertTrue(files.containsKey(splitFileName4));
+ assertTrue(files.containsKey(splitFileName5));
+ assertFalse(files.containsKey(splitFileName6));
+ assertFalse(files.containsKey(splitFileName7));
+ assertFalse(files.containsKey(splitFileName8));
+ assertFalse(files.containsKey(splitFileName9));
+ assertFalse(files.containsKey(splitFileName10));
+ assertTrue(files.containsKey(splitFileName11));
+ }
+}
\ No newline at end of file