Skip to content

Commit b31eae3

Browse files
committed
Merge branch 'RM-3761_file_handling_windows' into 'master'
Rm 3761 file handling on Windows See merge request cdoc2/cdoc2-java-ref-impl!55
2 parents 15ae898 + f78a927 commit b31eae3

File tree

4 files changed

+143
-19
lines changed

4 files changed

+143
-19
lines changed

cdoc2-cli/src/test/java/cli/CDocCliTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import org.junit.jupiter.api.BeforeEach;
1616
import org.junit.jupiter.api.Disabled;
1717
import org.junit.jupiter.api.Test;
18+
import org.junit.jupiter.api.condition.DisabledOnOs;
19+
import org.junit.jupiter.api.condition.OS;
1820
import org.junit.jupiter.api.function.Executable;
1921
import org.junit.jupiter.api.io.TempDir;
2022
import org.opentest4j.AssertionFailedError;
@@ -124,6 +126,11 @@ void failToEncryptDocWhenSecretInPlainText() {
124126
);
125127
}
126128

129+
/**
130+
* Disable on Windows, because deleting the temp file by cdoc2 and junit concurrently fails
131+
* @throws Exception
132+
*/
133+
@DisabledOnOs(OS.WINDOWS)
127134
@Test
128135
void shouldFailToEncryptDocWithSecretButDecryptWithPassword() {
129136
encrypt(SECRET_OPTION);
@@ -133,6 +140,11 @@ void shouldFailToEncryptDocWithSecretButDecryptWithPassword() {
133140
);
134141
}
135142

143+
/**
144+
* Disable on Windows, because deleting the temp file by cdoc2 and junit concurrently fails
145+
* @throws Exception
146+
*/
147+
@DisabledOnOs(OS.WINDOWS)
136148
@Test
137149
void shouldFailToEncryptDocWithPasswordButDecryptWithSecret() {
138150
encrypt(PASSWORD_OPTION);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package ee.cyber.cdoc2;
2+
3+
import org.junit.jupiter.api.*;
4+
import org.slf4j.Logger;
5+
import org.slf4j.LoggerFactory;
6+
7+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
8+
public interface TestLifecycleLogger {
9+
10+
Logger logger = LoggerFactory.getLogger(TestLifecycleLogger.class.getName());
11+
12+
@BeforeAll
13+
default void beforeAllTests() {
14+
logger.info("Before all tests");
15+
}
16+
17+
@AfterAll
18+
default void afterAllTests() {
19+
logger.info("After all tests");
20+
}
21+
22+
@BeforeEach
23+
default void beforeEachTest(TestInfo testInfo) {
24+
logger.info("=== TEST START {} {} {}",
25+
testInfo.getTestClass(), testInfo.getTestMethod(), testInfo.getDisplayName());
26+
}
27+
28+
@AfterEach
29+
default void afterEachTest(TestInfo testInfo) {
30+
logger.info("=== TEST END {} {} {}", testInfo.getTestClass(), testInfo.getTestMethod());
31+
}
32+
33+
}

cdoc2-lib/src/test/java/ee/cyber/cdoc2/container/EnvelopeTest.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package ee.cyber.cdoc2.container;
22

3+
import ee.cyber.cdoc2.TestLifecycleLogger;
34
import ee.cyber.cdoc2.container.recipients.EccRecipient;
45
import ee.cyber.cdoc2.container.recipients.EccServerKeyRecipient;
56
import ee.cyber.cdoc2.container.recipients.Recipient;
@@ -53,11 +54,9 @@
5354

5455
import org.apache.commons.compress.archivers.ArchiveEntry;
5556
import org.apache.commons.io.input.CountingInputStream;
56-
import org.junit.jupiter.api.Assertions;
57-
import org.junit.jupiter.api.BeforeAll;
58-
import org.junit.jupiter.api.DisplayName;
59-
import org.junit.jupiter.api.Tag;
60-
import org.junit.jupiter.api.Test;
57+
import org.junit.jupiter.api.*;
58+
import org.junit.jupiter.api.condition.DisabledOnOs;
59+
import org.junit.jupiter.api.condition.OS;
6160
import org.junit.jupiter.api.extension.ExtendWith;
6261
import org.junit.jupiter.api.io.TempDir;
6362
import org.junit.jupiter.api.parallel.Isolated;
@@ -94,7 +93,7 @@
9493
// some tests can be run parallel, but this is untested
9594
@Isolated
9695
@ExtendWith(MockitoExtension.class)
97-
class EnvelopeTest {
96+
class EnvelopeTest implements TestLifecycleLogger {
9897
private static final Logger log = LoggerFactory.getLogger(EnvelopeTest.class);
9998

10099
private static KeyLabelParams bobKeyLabelParams;
@@ -573,6 +572,12 @@ void testRsaServerScenario(@TempDir Path tempDir) throws Exception {
573572
}
574573

575574

575+
/**
576+
* Disable on Windows, because deleting the temp file by cdoc2 and junit concurrently fails
577+
* @param tempDir
578+
* @throws Exception
579+
*/
580+
@DisabledOnOs(OS.WINDOWS)
576581
@Test
577582
@DisplayName("Check that already created files are removed, when mac check in ChaCha20Poly1305 fails")
578583
void testContainerWrongPoly1305Mac(@TempDir Path tempDir) throws Exception {
@@ -624,6 +629,12 @@ void testContainerWrongPoly1305Mac(@TempDir Path tempDir) throws Exception {
624629
assertTrue(Arrays.stream(outDir.toFile().listFiles()).toList().isEmpty());
625630
}
626631

632+
/**
633+
* This test fails under Windows because creating file with this invalid file name fails first
634+
* @param tempDir
635+
* @throws Exception
636+
*/
637+
@DisabledOnOs(OS.WINDOWS)
627638
@Test
628639
void testThatIncompleteCDocFilesAreRemoved(@TempDir Path tempDir) throws Exception {
629640
PublicKey publicKey = createPublicKey();

cdoc2-lib/src/test/java/ee/cyber/cdoc2/container/TarDeflateTest.java

Lines changed: 81 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
package ee.cyber.cdoc2.container;
22

33
import java.io.*;
4+
import java.nio.charset.UnmappableCharacterException;
45
import java.nio.file.*;
56
import java.util.*;
67
import java.util.stream.Collectors;
78
import java.util.stream.Stream;
89

910
import ee.cyber.cdoc2.CDocConfiguration;
11+
import ee.cyber.cdoc2.TestLifecycleLogger;
1012
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
1113
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
1214
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
1315
import org.apache.commons.compress.compressors.deflate.DeflateCompressorInputStream;
1416
import org.apache.commons.compress.compressors.deflate.DeflateCompressorOutputStream;
1517
import org.apache.commons.compress.compressors.deflate.DeflateParameters;
1618
import org.junit.jupiter.api.Test;
19+
import org.junit.jupiter.api.condition.DisabledOnOs;
20+
import org.junit.jupiter.api.condition.OS;
1721
import org.junit.jupiter.api.io.TempDir;
1822
import org.junit.jupiter.api.parallel.Isolated;
1923
import org.slf4j.Logger;
@@ -25,7 +29,7 @@
2529

2630
// test are executed sequentially without any other tests running at the same time
2731
@Isolated
28-
class TarDeflateTest {
32+
class TarDeflateTest implements TestLifecycleLogger {
2933
private static final Logger log = LoggerFactory.getLogger(TarDeflateTest.class);
3034

3135
private static final String TGZ_FILE_NAME = "archive.tgz";
@@ -128,6 +132,12 @@ void testArchiveData(@TempDir Path tempDir) throws IOException {
128132
}
129133
}
130134

135+
/**
136+
* Disable on Windows, because deleting the temp file by cdoc2 and junit concurrently fails
137+
* @param tempDir
138+
* @throws Exception
139+
*/
140+
@DisabledOnOs(OS.WINDOWS)
131141
@Test
132142
void testTarGzBomb(@TempDir Path tempDir) throws IOException {
133143
byte[] zeros = new byte[1024]; //1KB
@@ -174,6 +184,12 @@ void testTarGzBomb(@TempDir Path tempDir) throws IOException {
174184
log.debug("Got {} with message: {}", exception.getClass().getName(), exception.getMessage());
175185
}
176186

187+
/**
188+
* Disable on Windows, because deleting the temp file by cdoc2 and junit concurrently fails
189+
* @param tempDir
190+
* @throws Exception
191+
*/
192+
@DisabledOnOs(OS.WINDOWS)
177193
@Test
178194
void testCheckDiskSpaceAvailable(@TempDir Path tempDir) {
179195
//might cause other tests to fail, if tests executed parallel
@@ -202,14 +218,36 @@ void shouldValidateFileNameWhenCreatingTar(@TempDir Path tempDir) throws IOExcep
202218

203219
// should fail
204220
for (String fileName: INVALID_FILE_NAMES) {
205-
File file = createAndWriteToFile(tempDir, fileName, PAYLOAD);
221+
222+
File file;
223+
log.debug("test file name '{}'", fileName);
224+
try {
225+
//Windows is more restrictive on what file names can be created
226+
file = createAndWriteToFile(tempDir, fileName, PAYLOAD);
227+
} catch (InvalidPathException invalidPathException) {
228+
if (OS.WINDOWS.isCurrentOs()) {
229+
// do nothing
230+
log.debug("Filename '{}' not allowed under Windows", fileName);
231+
continue;
232+
}
233+
234+
throw invalidPathException;
235+
}
236+
237+
assertNotNull(file);
238+
206239
OutputStream os = new ByteArrayOutputStream();
207240
List<File> files = List.of(file);
241+
242+
// Under Windows file name 'abc/' transforms to 'abc' and is not invalid anymore.
243+
if (file.getName().equals("abc") && OS.WINDOWS.isCurrentOs()) continue;
244+
208245
assertThrows(
209-
InvalidPathException.class,
210-
() -> Tar.archiveFiles(os, files),
211-
"File with name '" + file + "' should not be allowed in created tar"
246+
InvalidPathException.class,
247+
() -> Tar.archiveFiles(os, files),
248+
"File with name '" + file + "' should not be allowed in created tar"
212249
);
250+
213251
}
214252

215253
// should pass
@@ -221,18 +259,37 @@ void shouldValidateFileNameWhenCreatingTar(@TempDir Path tempDir) throws IOExcep
221259
}
222260
}
223261

262+
/**
263+
* Disable on Windows, because deleting the temp file by cdoc2 and junit concurrently fails
264+
* @param tempDir
265+
* @throws Exception
266+
*/
267+
@DisabledOnOs(OS.WINDOWS)
224268
@Test
225269
void shouldValidateFileNameWhenExtractingTar(@TempDir Path tempDir) throws IOException {
226270
// should fail
227271
for (int i = 0; i < INVALID_FILE_NAMES.size(); i++) {
228272
String fileName = INVALID_FILE_NAMES.get(i);
229-
File file = createTar(tempDir, TGZ_FILE_NAME + '.' + i, fileName, PAYLOAD);
230273

231-
assertThrows(
232-
InvalidPathException.class,
233-
() -> new TarDeflate(new FileInputStream(file)).extractFilesToDir(List.of(fileName), tempDir),
234-
"File with name '" + fileName + "' should not be extracted from tar"
235-
);
274+
log.debug("Op system is '{}'", System.getProperty("os.name"));
275+
276+
try {
277+
File file = createTar(tempDir, TGZ_FILE_NAME + '.' + i, fileName, PAYLOAD);
278+
279+
assertThrows(
280+
InvalidPathException.class,
281+
() -> new TarDeflate(new FileInputStream(file)).extractFilesToDir(List.of(fileName), tempDir),
282+
"File with name '" + fileName + "' should not be extracted from tar"
283+
);
284+
285+
} catch (IOException e) {
286+
if (OS.WINDOWS.isCurrentOs()) {
287+
// do nothing
288+
log.debug("Filename '{}'not allowed under Windows", fileName);
289+
} else {
290+
throw e;
291+
}
292+
}
236293

237294
}
238295

@@ -299,8 +356,19 @@ void shouldSupportLongFileName() throws IOException {
299356

300357

301358
ByteArrayInputStream is = new ByteArrayInputStream(destTarZ.toByteArray());
302-
List<String> filesList = TarDeflate.listFiles(is);
303-
assertEquals(List.of(longFileName), filesList);
359+
360+
try {
361+
List<String> filesList = TarDeflate.listFiles(is);
362+
assertEquals(List.of(longFileName), filesList);
363+
364+
} catch (UnmappableCharacterException e) {
365+
if (OS.WINDOWS.isCurrentOs()) {
366+
// do nothing
367+
log.debug("Filename not allowed under Windows, exception {}", e.getMessage());
368+
} else {
369+
throw e;
370+
}
371+
}
304372
}
305373

306374
@Test

0 commit comments

Comments
 (0)