Skip to content

Commit d3f7986

Browse files
committed
tests: add blacklist functionality for unsupported ELN files in tests
1 parent 62b1b0c commit d3f7986

3 files changed

Lines changed: 72 additions & 49 deletions

File tree

src/main/java/edu/kit/datamanager/ro_crate/reader/ZipStreamStrategy.java

Lines changed: 35 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -85,53 +85,49 @@ public boolean isExtracted() {
8585
*
8686
* @param stream The input stream.
8787
*/
88-
private void readCrate(InputStream stream) {
89-
try {
90-
File folder = temporaryFolder.toFile();
91-
// ensure the directory is clean
92-
if (folder.exists()) {
93-
if (folder.isDirectory()) {
94-
FileUtils.cleanDirectory(folder);
95-
} else if (folder.isFile()) {
96-
FileUtils.delete(folder);
97-
}
98-
} else {
99-
FileUtils.forceMkdir(folder);
88+
private void readCrate(InputStream stream) throws IOException {
89+
File folder = temporaryFolder.toFile();
90+
// ensure the directory is clean
91+
if (folder.exists()) {
92+
if (folder.isDirectory()) {
93+
FileUtils.cleanDirectory(folder);
94+
} else if (folder.isFile()) {
95+
FileUtils.delete(folder);
10096
}
97+
} else {
98+
FileUtils.forceMkdir(folder);
99+
}
101100

102-
LocalFileHeader localFileHeader;
103-
int readLen;
104-
byte[] readBuffer = new byte[4096];
101+
LocalFileHeader localFileHeader;
102+
int readLen;
103+
byte[] readBuffer = new byte[4096];
105104

106-
try (ZipInputStream zipInputStream = new ZipInputStream(stream)) {
107-
while ((localFileHeader = zipInputStream.getNextEntry()) != null) {
108-
String fileName = localFileHeader.getFileName();
109-
File extractedFile = new File(folder, fileName).getCanonicalFile();
110-
if (!extractedFile.toPath().startsWith(folder.getCanonicalPath())) {
111-
throw new IOException("Entry is outside of target directory: " + fileName);
112-
}
113-
if (localFileHeader.isDirectory()) {
114-
FileUtils.forceMkdir(extractedFile);
115-
continue;
116-
}
117-
FileUtils.forceMkdir(extractedFile.getParentFile());
118-
try (OutputStream outputStream = new FileOutputStream(extractedFile)) {
119-
while ((readLen = zipInputStream.read(readBuffer)) != -1) {
120-
outputStream.write(readBuffer, 0, readLen);
121-
}
105+
try (ZipInputStream zipInputStream = new ZipInputStream(stream)) {
106+
while ((localFileHeader = zipInputStream.getNextEntry()) != null) {
107+
String fileName = localFileHeader.getFileName();
108+
File extractedFile = new File(folder, fileName).getCanonicalFile();
109+
if (!extractedFile.toPath().startsWith(folder.getCanonicalPath())) {
110+
throw new IOException("Entry is outside of target directory: " + fileName);
111+
}
112+
if (localFileHeader.isDirectory()) {
113+
FileUtils.forceMkdir(extractedFile);
114+
continue;
115+
}
116+
FileUtils.forceMkdir(extractedFile.getParentFile());
117+
try (OutputStream outputStream = new FileOutputStream(extractedFile)) {
118+
while ((readLen = zipInputStream.read(readBuffer)) != -1) {
119+
outputStream.write(readBuffer, 0, readLen);
122120
}
123121
}
124122
}
125-
this.isExtracted = true;
126-
// register deletion on exit
127-
FileUtils.forceDeleteOnExit(folder);
128-
} catch (IOException ex) {
129-
logger.error("Failed to read crate from input stream.", ex);
130123
}
124+
this.isExtracted = true;
125+
// register deletion on exit
126+
FileUtils.forceDeleteOnExit(folder);
131127
}
132128

133129
@Override
134-
public ObjectNode readMetadataJson(InputStream stream) {
130+
public ObjectNode readMetadataJson(InputStream stream) throws IOException {
135131
if (!isExtracted) {
136132
this.readCrate(stream);
137133
}
@@ -152,17 +148,11 @@ public ObjectNode readMetadataJson(InputStream stream) {
152148
.orElseThrow(() -> new IllegalStateException("No %s found in zip file".formatted(JsonDescriptor.ID)));
153149
jsonMetadata = firstSubdir.toPath().resolve(JsonDescriptor.ID).toFile();
154150
}
155-
156-
try {
157-
return objectMapper.readTree(jsonMetadata).deepCopy();
158-
} catch (IOException e) {
159-
logger.error("Failed to deserialize crate metadata.", e);
160-
return null;
161-
}
151+
return objectMapper.readTree(jsonMetadata).deepCopy();
162152
}
163153

164154
@Override
165-
public File readContent(InputStream stream) {
155+
public File readContent(InputStream stream) throws IOException {
166156
if (!isExtracted) {
167157
this.readCrate(stream);
168158
}

src/test/java/edu/kit/datamanager/ro_crate/reader/ElnFileFormatTest.java

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@ public interface ElnFileFormatTest<
1919
>
2020
extends TestableReaderStrategy<SOURCE_T, READER_STRATEGY>
2121
{
22+
/**
23+
* Some readers may not be able to read a subset of eln files,
24+
* e.g. because a zip file may not be readable in streaming mode.
25+
* <p>
26+
* An implementation test may use this methode to provide a subset of the
27+
* test cases where an IOException is expected.
28+
*
29+
* @param input the input to test for presence in the blacklist
30+
* @return true if the input is in the blacklist, false otherwise
31+
*/
32+
default boolean isInBlacklist(String input) {
33+
return false;
34+
}
35+
2236
/**
2337
* ELN Crates are zip files not fully compatible with the Ro-Crate standard
2438
* in the sense that they must contain a single subfolder in the zip file
@@ -46,9 +60,14 @@ default void testReadElnCrates(String urlStr, @TempDir Path tmp) throws IOExcept
4660
FileUtils.copyURLToFile(url, elnFile.toFile(), 10000, 10000);
4761
assertTrue(elnFile.toFile().exists());
4862

49-
// Read the crate from the downloaded file
50-
Crate read = this.readCrate(elnFile);
51-
assertNotNull(read);
52-
assertFalse(read.getAllDataEntities().isEmpty());
63+
if (!isInBlacklist(urlStr)) {
64+
// Read the crate from the downloaded file
65+
Crate read = this.readCrate(elnFile);
66+
assertNotNull(read);
67+
assertFalse(read.getAllDataEntities().isEmpty());
68+
} else {
69+
// If the file is in the blacklist, we expect an IOException
70+
assertThrows(IOException.class, () -> this.readCrate(elnFile));
71+
}
5372
}
5473
}

src/test/java/edu/kit/datamanager/ro_crate/reader/ZipStreamReaderTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import java.io.*;
77
import java.nio.file.Path;
8+
import java.util.Set;
89

910
import static org.junit.jupiter.api.Assertions.*;
1011

@@ -13,6 +14,19 @@ class ZipStreamReaderTest implements
1314
CommonReaderTest<InputStream, ZipStreamStrategy>,
1415
ElnFileFormatTest<InputStream, ZipStreamStrategy>
1516
{
17+
/**
18+
* At the point of writing this test,
19+
* these files are in a zip format which cannot be read in streaming mode
20+
*/
21+
@Override
22+
public boolean isInBlacklist(String input) {
23+
return Set.of(
24+
"https://github.com/TheELNConsortium/TheELNFileFormat/raw/refs/heads/master/examples/kadi4mat/records-example.eln",
25+
"https://github.com/TheELNConsortium/TheELNFileFormat/raw/refs/heads/master/examples/kadi4mat/collections-example.eln"
26+
)
27+
.contains(input);
28+
}
29+
1630
@Override
1731
public void saveCrate(Crate crate, Path target) throws IOException {
1832
Writers.newZipStreamWriter().save(crate, new FileOutputStream(target.toFile()));

0 commit comments

Comments
 (0)