From 02f461f0c51ddb50388edc227e8ec436156094a1 Mon Sep 17 00:00:00 2001 From: Hyunseok Seo Date: Fri, 14 Jun 2024 09:49:10 +0900 Subject: [PATCH] GH-42101: [Java] Create File for Output Validation in FileRoundtrip (#42115) ### Rationale for this change Enhance the logic to ensure that the output directory and file are created if they do not exist. While the input directory and file are mandatory, the output directory and file might not exist. ### What changes are included in this PR? - [x] Create file if output directory or file does not exist. - [x] Add unit tests - Test with different directories to validate creation of non-existent directory - Test for non-existent input file ### Are these changes tested? Yes. Additional unit tests have been added. ### Are there any user-facing changes? Maybe. Yes. * GitHub Issue: #42101 Authored-by: Hyunseok Seo Signed-off-by: David Li --- .../org/apache/arrow/tools/FileRoundtrip.java | 16 +++++++-- .../apache/arrow/tools/TestFileRoundtrip.java | 35 +++++++++++++++++++ 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/java/tools/src/main/java/org/apache/arrow/tools/FileRoundtrip.java b/java/tools/src/main/java/org/apache/arrow/tools/FileRoundtrip.java index 70e13c518b580..45205bab54655 100644 --- a/java/tools/src/main/java/org/apache/arrow/tools/FileRoundtrip.java +++ b/java/tools/src/main/java/org/apache/arrow/tools/FileRoundtrip.java @@ -52,13 +52,23 @@ public static void main(String[] args) { System.exit(new FileRoundtrip(System.err).run(args)); } - private File validateFile(String type, String fileName) { + private File validateFile(String type, String fileName) throws IOException { if (fileName == null) { throw new IllegalArgumentException("missing " + type + " file parameter"); } File f = new File(fileName); - if (!f.exists() || f.isDirectory()) { - throw new IllegalArgumentException(type + " file not found: " + f.getAbsolutePath()); + if (type.equals("input")) { + if (!f.exists() || f.isDirectory()) { + throw new IllegalArgumentException(type + " file not found: " + f.getAbsolutePath()); + } + } else if (type.equals("output")) { + File parentDir = f.getParentFile(); + if (parentDir != null && !parentDir.exists()) { + if (!parentDir.mkdirs()) { + throw new IOException( + "Failed to create parent directory: " + parentDir.getAbsolutePath()); + } + } } return f; } diff --git a/java/tools/src/test/java/org/apache/arrow/tools/TestFileRoundtrip.java b/java/tools/src/test/java/org/apache/arrow/tools/TestFileRoundtrip.java index 69b0b4807972d..a98fefeea7bed 100644 --- a/java/tools/src/test/java/org/apache/arrow/tools/TestFileRoundtrip.java +++ b/java/tools/src/test/java/org/apache/arrow/tools/TestFileRoundtrip.java @@ -19,10 +19,12 @@ import static org.apache.arrow.tools.ArrowFileTestFixtures.validateOutput; import static org.apache.arrow.tools.ArrowFileTestFixtures.writeInput; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; import java.io.File; import org.apache.arrow.memory.BufferAllocator; import org.apache.arrow.memory.RootAllocator; +import org.apache.arrow.vector.ipc.InvalidArrowFileException; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -32,6 +34,7 @@ public class TestFileRoundtrip { @Rule public TemporaryFolder testFolder = new TemporaryFolder(); + @Rule public TemporaryFolder testAnotherFolder = new TemporaryFolder(); private BufferAllocator allocator; @@ -58,4 +61,36 @@ public void test() throws Exception { validateOutput(testOutFile, allocator); } + + @Test + public void testDiffFolder() throws Exception { + File testInFile = testFolder.newFile("testIn.arrow"); + File testOutFile = testAnotherFolder.newFile("testOut.arrow"); + + writeInput(testInFile, allocator); + + String[] args = {"-i", testInFile.getAbsolutePath(), "-o", testOutFile.getAbsolutePath()}; + int result = new FileRoundtrip(System.err).run(args); + assertEquals(0, result); + + validateOutput(testOutFile, allocator); + } + + @Test + public void testNotPreparedInput() throws Exception { + File testInFile = testFolder.newFile("testIn.arrow"); + File testOutFile = testFolder.newFile("testOut.arrow"); + + String[] args = {"-i", testInFile.getAbsolutePath(), "-o", testOutFile.getAbsolutePath()}; + + // In JUnit 5, since the file itself is not created, the exception and message will be + // different. + Exception exception = + assertThrows( + InvalidArrowFileException.class, + () -> { + new FileRoundtrip(System.err).run(args); + }); + assertEquals("file too small: 0", exception.getMessage()); + } }