From 04316049c397eff37ed99483f8c07790ca55131a Mon Sep 17 00:00:00 2001 From: Caleb Hulbert Date: Fri, 23 Feb 2024 15:24:16 -0500 Subject: [PATCH 1/6] feat: add protected N5KeyValueReader constructor to optionally check if the root exist. Used for writer construction --- .../java/org/janelia/saalfeldlab/n5/N5KeyValueReader.java | 8 ++++++-- .../java/org/janelia/saalfeldlab/n5/N5KeyValueWriter.java | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/janelia/saalfeldlab/n5/N5KeyValueReader.java b/src/main/java/org/janelia/saalfeldlab/n5/N5KeyValueReader.java index 690724d3..29e43ce6 100644 --- a/src/main/java/org/janelia/saalfeldlab/n5/N5KeyValueReader.java +++ b/src/main/java/org/janelia/saalfeldlab/n5/N5KeyValueReader.java @@ -83,7 +83,7 @@ public N5KeyValueReader( final boolean cacheMeta) throws N5Exception { - this(true, keyValueAccess, basePath, gsonBuilder, cacheMeta); + this(true, keyValueAccess, basePath, gsonBuilder, cacheMeta, true); } /** @@ -116,7 +116,8 @@ protected N5KeyValueReader( final KeyValueAccess keyValueAccess, final String basePath, final GsonBuilder gsonBuilder, - final boolean cacheMeta) + final boolean cacheMeta, + final boolean checkExists) throws N5Exception { this.keyValueAccess = keyValueAccess; @@ -138,6 +139,9 @@ protected N5KeyValueReader( throw new N5Exception.N5IOException( "Incompatible version " + version + " (this is " + VERSION + ")."); } + + if (checkExists && !exists("/")) + throw new N5Exception.N5IOException("No container exists at " + basePath); } @Override diff --git a/src/main/java/org/janelia/saalfeldlab/n5/N5KeyValueWriter.java b/src/main/java/org/janelia/saalfeldlab/n5/N5KeyValueWriter.java index 88dfd6c4..37b9ae99 100644 --- a/src/main/java/org/janelia/saalfeldlab/n5/N5KeyValueWriter.java +++ b/src/main/java/org/janelia/saalfeldlab/n5/N5KeyValueWriter.java @@ -68,7 +68,7 @@ public N5KeyValueWriter( final boolean cacheAttributes) throws N5Exception { - super(false, keyValueAccess, basePath, gsonBuilder, cacheAttributes); + super(false, keyValueAccess, basePath, gsonBuilder, cacheAttributes, false); Version version = null; try { From 2c808826a9ee6d852a8f10faa75e2b0f59d34b95 Mon Sep 17 00:00:00 2001 From: Caleb Hulbert Date: Fri, 23 Feb 2024 15:25:19 -0500 Subject: [PATCH 2/6] fix(test): don't depend on default `createN5Writer` if specfic `GsonBuilder()` options are wanted (even default ones). --- .../java/org/janelia/saalfeldlab/n5/AbstractN5Test.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java b/src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java index db3b9a07..278bec43 100644 --- a/src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java +++ b/src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java @@ -643,7 +643,7 @@ public void testNullAttributes() throws IOException, URISyntaxException { } /* without serializeNulls*/ - try (N5Writer writer = createN5Writer()) { + try (N5Writer writer = createN5Writer(tempN5Location(), new GsonBuilder())) { writer.createGroup(groupName); writer.setAttribute(groupName, "nullValue", null); @@ -802,9 +802,8 @@ public void testRemoveAttributes() throws IOException, URISyntaxException { @Test public void testRemoveContainer() throws IOException, URISyntaxException { - String location; - try (final N5Writer n5 = createN5Writer(tempN5Location())) { - location = n5.getURI().toString(); + final String location = tempN5Location(); + try (final N5Writer n5 = createN5Writer(location)) { try (N5Reader n5Reader = createN5Reader(location)) { assertNotNull(n5Reader); } From 017ee15a75bf8428b4b9eeaaa82e5a514aded055 Mon Sep 17 00:00:00 2001 From: Caleb Hulbert Date: Wed, 28 Feb 2024 14:48:50 -0500 Subject: [PATCH 3/6] feat(test): provide tracking for temporary n5Writers for removal @After --- .../saalfeldlab/n5/AbstractN5Test.java | 219 ++++++++++-------- .../org/janelia/saalfeldlab/n5/N5FSTest.java | 16 +- 2 files changed, 131 insertions(+), 104 deletions(-) diff --git a/src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java b/src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java index 278bec43..e4b1c1c7 100644 --- a/src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java +++ b/src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java @@ -34,6 +34,7 @@ import com.google.gson.reflect.TypeToken; import org.janelia.saalfeldlab.n5.N5Exception.N5ClassCastException; import org.janelia.saalfeldlab.n5.N5Reader.Version; +import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -44,6 +45,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Random; @@ -58,7 +60,6 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; /** * Abstract base class for testing N5 functionality. @@ -85,6 +86,47 @@ public abstract class AbstractN5Test { static protected float[] floatBlock; static protected double[] doubleBlock; + protected final HashSet tempWriters = new HashSet<>(); + + protected final N5Writer createTempN5Writer() { + + try { + return createTempN5Writer(tempN5Location()); + } catch (URISyntaxException | IOException e) { + throw new RuntimeException(e); + } + } + + protected final N5Writer createTempN5Writer(String location) { + + return createTempN5Writer(location, new GsonBuilder()); + } + + protected final N5Writer createTempN5Writer(String location, GsonBuilder gson) { + + final N5Writer tempWriter; + try { + tempWriter = createN5Writer(location, gson); + } catch (IOException | URISyntaxException e) { + throw new RuntimeException(e); + } + tempWriters.add(tempWriter); + return tempWriter; + } + + @After + public void removeTempWriters() { + synchronized (tempWriters) { + for (N5Writer writer : tempWriters) { + try { + writer.remove(); + } catch (Exception e) { + } + } + tempWriters.clear(); + } + } + protected abstract String tempN5Location() throws URISyntaxException, IOException; protected N5Writer createN5Writer() throws IOException, URISyntaxException { @@ -140,9 +182,9 @@ public void setUpOnce() { } @Test - public void testCreateGroup() throws IOException, URISyntaxException { + public void testCreateGroup() { - try (N5Writer n5 = createN5Writer()) { + try (N5Writer n5 = createTempN5Writer()) { n5.createGroup(groupName); final Path groupPath = Paths.get(groupName); String subGroup = ""; @@ -154,9 +196,9 @@ public void testCreateGroup() throws IOException, URISyntaxException { } @Test - public void testSetAttributeDoesntCreateGroup() throws IOException, URISyntaxException { + public void testSetAttributeDoesntCreateGroup() { - try (final N5Writer writer = createN5Writer()) { + try (final N5Writer writer = createTempN5Writer()) { final String testGroup = "/group/should/not/exit"; assertFalse(writer.exists(testGroup)); assertThrows(N5Exception.N5IOException.class, () -> writer.setAttribute(testGroup, "test", "test")); @@ -165,10 +207,10 @@ public void testSetAttributeDoesntCreateGroup() throws IOException, URISyntaxExc } @Test - public void testCreateDataset() throws IOException, URISyntaxException { + public void testCreateDataset() { final DatasetAttributes info; - try (N5Writer writer = createN5Writer()) { + try (N5Writer writer = createTempN5Writer()) { writer.createDataset(datasetName, dimensions, blockSize, DataType.UINT64, new RawCompression()); assertTrue("Dataset does not exist", writer.exists(datasetName)); @@ -182,13 +224,13 @@ public void testCreateDataset() throws IOException, URISyntaxException { } @Test - public void testWriteReadByteBlock() throws URISyntaxException { + public void testWriteReadByteBlock() { for (final Compression compression : getCompressions()) { for (final DataType dataType : new DataType[]{ DataType.UINT8, DataType.INT8}) { - try (final N5Writer n5 = createN5Writer()) { + try (final N5Writer n5 = createTempN5Writer()) { n5.createDataset(datasetName, dimensions, blockSize, dataType, compression); final DatasetAttributes attributes = n5.getDatasetAttributes(datasetName); final ByteArrayDataBlock dataBlock = new ByteArrayDataBlock(blockSize, new long[]{0, 0, 0}, byteBlock); @@ -198,16 +240,13 @@ public void testWriteReadByteBlock() throws URISyntaxException { assertArrayEquals(byteBlock, (byte[])loadedDataBlock.getData()); assertTrue(n5.remove(datasetName)); - } catch (final IOException e) { - e.printStackTrace(); - fail("Block cannot be written."); } } } } @Test - public void testWriteReadStringBlock() throws URISyntaxException { + public void testWriteReadStringBlock() { // test dataset; all characters are valid UTF8 but may have different numbers of bytes! final DataType dataType = DataType.STRING; @@ -215,9 +254,7 @@ public void testWriteReadStringBlock() throws URISyntaxException { final String[] stringBlock = new String[]{"", "a", "bc", "de", "fgh", ":-รพ"}; for (final Compression compression : getCompressions()) { - - System.out.println("Testing " + compression.getType() + " " + dataType); - try (final N5Writer n5 = createN5Writer()) { + try (final N5Writer n5 = createTempN5Writer()) { n5.createDataset(datasetName, dimensions, blockSize, dataType, compression); final DatasetAttributes attributes = n5.getDatasetAttributes(datasetName); final StringDataBlock dataBlock = new StringDataBlock(blockSize, new long[]{0L, 0L, 0L}, stringBlock); @@ -229,22 +266,19 @@ public void testWriteReadStringBlock() throws URISyntaxException { assertTrue(n5.remove(datasetName)); - } catch (final IOException e) { - e.printStackTrace(); - fail("Block cannot be written."); } } } @Test - public void testWriteReadShortBlock() throws URISyntaxException { + public void testWriteReadShortBlock() { for (final Compression compression : getCompressions()) { for (final DataType dataType : new DataType[]{ DataType.UINT16, DataType.INT16}) { - try (final N5Writer n5 = createN5Writer()) { + try (final N5Writer n5 = createTempN5Writer()) { n5.createDataset(datasetName, dimensions, blockSize, dataType, compression); final DatasetAttributes attributes = n5.getDatasetAttributes(datasetName); final ShortArrayDataBlock dataBlock = new ShortArrayDataBlock(blockSize, new long[]{0, 0, 0}, shortBlock); @@ -256,23 +290,20 @@ public void testWriteReadShortBlock() throws URISyntaxException { assertTrue(n5.remove(datasetName)); - } catch (final IOException e) { - e.printStackTrace(); - fail("Block cannot be written."); } } } } @Test - public void testWriteReadIntBlock() throws URISyntaxException { + public void testWriteReadIntBlock() { for (final Compression compression : getCompressions()) { for (final DataType dataType : new DataType[]{ DataType.UINT32, DataType.INT32}) { - try (final N5Writer n5 = createN5Writer()) { + try (final N5Writer n5 = createTempN5Writer()) { n5.createDataset(datasetName, dimensions, blockSize, dataType, compression); final DatasetAttributes attributes = n5.getDatasetAttributes(datasetName); final IntArrayDataBlock dataBlock = new IntArrayDataBlock(blockSize, new long[]{0, 0, 0}, intBlock); @@ -284,23 +315,20 @@ public void testWriteReadIntBlock() throws URISyntaxException { assertTrue(n5.remove(datasetName)); - } catch (final IOException e) { - e.printStackTrace(); - fail("Block cannot be written."); } } } } @Test - public void testWriteReadLongBlock() throws URISyntaxException { + public void testWriteReadLongBlock() { for (final Compression compression : getCompressions()) { for (final DataType dataType : new DataType[]{ DataType.UINT64, DataType.INT64}) { - try (final N5Writer n5 = createN5Writer()) { + try (final N5Writer n5 = createTempN5Writer()) { n5.createDataset(datasetName, dimensions, blockSize, dataType, compression); final DatasetAttributes attributes = n5.getDatasetAttributes(datasetName); final LongArrayDataBlock dataBlock = new LongArrayDataBlock(blockSize, new long[]{0, 0, 0}, longBlock); @@ -312,19 +340,16 @@ public void testWriteReadLongBlock() throws URISyntaxException { assertTrue(n5.remove(datasetName)); - } catch (final IOException e) { - e.printStackTrace(); - fail("Block cannot be written."); } } } } @Test - public void testWriteReadFloatBlock() throws URISyntaxException { + public void testWriteReadFloatBlock() { for (final Compression compression : getCompressions()) { - try (final N5Writer n5 = createN5Writer()) { + try (final N5Writer n5 = createTempN5Writer()) { n5.createDataset(datasetName, dimensions, blockSize, DataType.FLOAT32, compression); final DatasetAttributes attributes = n5.getDatasetAttributes(datasetName); final FloatArrayDataBlock dataBlock = new FloatArrayDataBlock(blockSize, new long[]{0, 0, 0}, floatBlock); @@ -336,18 +361,15 @@ public void testWriteReadFloatBlock() throws URISyntaxException { assertTrue(n5.remove(datasetName)); - } catch (final IOException e) { - e.printStackTrace(); - fail("Block cannot be written."); } } } @Test - public void testWriteReadDoubleBlock() throws URISyntaxException { + public void testWriteReadDoubleBlock() { for (final Compression compression : getCompressions()) { - try (final N5Writer n5 = createN5Writer()) { + try (final N5Writer n5 = createTempN5Writer()) { n5.createDataset(datasetName, dimensions, blockSize, DataType.FLOAT64, compression); final DatasetAttributes attributes = n5.getDatasetAttributes(datasetName); final DoubleArrayDataBlock dataBlock = new DoubleArrayDataBlock(blockSize, new long[]{0, 0, 0}, doubleBlock); @@ -359,15 +381,12 @@ public void testWriteReadDoubleBlock() throws URISyntaxException { assertTrue(n5.remove(datasetName)); - } catch (final IOException e) { - e.printStackTrace(); - fail("Block cannot be written."); } } } @Test - public void testMode1WriteReadByteBlock() throws URISyntaxException { + public void testMode1WriteReadByteBlock() { final int[] differentBlockSize = new int[]{5, 10, 15}; @@ -376,7 +395,7 @@ public void testMode1WriteReadByteBlock() throws URISyntaxException { DataType.UINT8, DataType.INT8}) { - try (final N5Writer n5 = createN5Writer()) { + try (final N5Writer n5 = createTempN5Writer()) { n5.createDataset(datasetName, dimensions, differentBlockSize, dataType, compression); final DatasetAttributes attributes = n5.getDatasetAttributes(datasetName); final ByteArrayDataBlock dataBlock = new ByteArrayDataBlock(differentBlockSize, new long[]{0, 0, 0}, byteBlock); @@ -388,21 +407,18 @@ public void testMode1WriteReadByteBlock() throws URISyntaxException { assertTrue(n5.remove(datasetName)); - } catch (final IOException e) { - e.printStackTrace(); - fail("Block cannot be written."); } } } } @Test - public void testWriteReadSerializableBlock() throws ClassNotFoundException, URISyntaxException { + public void testWriteReadSerializableBlock() throws ClassNotFoundException { for (final Compression compression : getCompressions()) { final DataType dataType = DataType.OBJECT; - try (final N5Writer n5 = createN5Writer()) { + try (final N5Writer n5 = createTempN5Writer()) { n5.createDataset(datasetName, dimensions, blockSize, dataType, compression); final DatasetAttributes attributes = n5.getDatasetAttributes(datasetName); @@ -420,17 +436,14 @@ public void testWriteReadSerializableBlock() throws ClassNotFoundException, URIS assertTrue(n5.remove(datasetName)); - } catch (final IOException e) { - e.printStackTrace(); - fail("Block cannot be written."); } } } @Test - public void testOverwriteBlock() throws URISyntaxException { + public void testOverwriteBlock() { - try (final N5Writer n5 = createN5Writer()) { + try (final N5Writer n5 = createTempN5Writer()) { n5.createDataset(datasetName, dimensions, blockSize, DataType.INT32, new GzipCompression()); final DatasetAttributes attributes = n5.getDatasetAttributes(datasetName); @@ -447,16 +460,13 @@ public void testOverwriteBlock() throws URISyntaxException { assertTrue(n5.remove(datasetName)); - } catch (final IOException e) { - e.printStackTrace(); - fail("Block cannot be written."); } } @Test - public void testAttributeParsingPrimitive() throws IOException, URISyntaxException { + public void testAttributeParsingPrimitive() { - try (final N5Writer n5 = createN5Writer()) { + try (final N5Writer n5 = createTempN5Writer()) { n5.createGroup(groupName); @@ -530,9 +540,9 @@ public void testAttributeParsingPrimitive() throws IOException, URISyntaxExcepti } @Test - public void testAttributes() throws IOException, URISyntaxException { + public void testAttributes() { - try (final N5Writer n5 = createN5Writer()) { + try (final N5Writer n5 = createTempN5Writer()) { assertNull(n5.getAttribute(groupName, "test", String.class)); assertEquals(0, n5.listAttributes(groupName).size()); n5.createGroup(groupName); @@ -598,10 +608,10 @@ public void testAttributes() throws IOException, URISyntaxException { @Test - public void testNullAttributes() throws IOException, URISyntaxException { + public void testNullAttributes() throws URISyntaxException, IOException { /* serializeNulls*/ - try (N5Writer writer = createN5Writer(tempN5Location(), new GsonBuilder().serializeNulls())) { + try (N5Writer writer = createTempN5Writer(tempN5Location(), new GsonBuilder().serializeNulls())) { writer.createGroup(groupName); writer.setAttribute(groupName, "nullValue", null); @@ -643,7 +653,7 @@ public void testNullAttributes() throws IOException, URISyntaxException { } /* without serializeNulls*/ - try (N5Writer writer = createN5Writer(tempN5Location(), new GsonBuilder())) { + try (N5Writer writer = createTempN5Writer(tempN5Location(), new GsonBuilder())) { writer.createGroup(groupName); writer.setAttribute(groupName, "nullValue", null); @@ -687,7 +697,7 @@ public void testNullAttributes() throws IOException, URISyntaxException { @Test public void testRemoveAttributes() throws IOException, URISyntaxException { - try (N5Writer writer = createN5Writer(tempN5Location(), new GsonBuilder().serializeNulls())) { + try (N5Writer writer = createTempN5Writer(tempN5Location(), new GsonBuilder().serializeNulls())) { writer.setAttribute("", "a/b/c", 100); assertEquals((Integer)100, writer.getAttribute("", "a/b/c", Integer.class)); @@ -803,7 +813,7 @@ public void testRemoveAttributes() throws IOException, URISyntaxException { public void testRemoveContainer() throws IOException, URISyntaxException { final String location = tempN5Location(); - try (final N5Writer n5 = createN5Writer(location)) { + try (final N5Writer n5 = createTempN5Writer(location)) { try (N5Reader n5Reader = createN5Reader(location)) { assertNotNull(n5Reader); } @@ -816,7 +826,7 @@ public void testRemoveContainer() throws IOException, URISyntaxException { @Test public void testUri() throws IOException, URISyntaxException { - try (final N5Writer writer = createN5Writer()) { + try (final N5Writer writer = createTempN5Writer()) { try (final N5Reader reader = createN5Reader(writer.getURI().toString())) { assertEquals(writer.getURI(), reader.getURI()); } @@ -824,9 +834,9 @@ public void testUri() throws IOException, URISyntaxException { } @Test - public void testRemoveGroup() throws IOException, URISyntaxException { + public void testRemoveGroup() { - try (final N5Writer n5 = createN5Writer()) { + try (final N5Writer n5 = createTempN5Writer()) { n5.createDataset(datasetName, dimensions, blockSize, DataType.UINT64, new RawCompression()); n5.remove(groupName); assertFalse("Group still exists", n5.exists(groupName)); @@ -835,9 +845,9 @@ public void testRemoveGroup() throws IOException, URISyntaxException { } @Test - public void testList() throws URISyntaxException { + public void testList() { - try (final N5Writer listN5 = createN5Writer()) { + try (final N5Writer listN5 = createTempN5Writer()) { listN5.createGroup(groupName); for (final String subGroup : subGroupNames) listN5.createGroup(groupName + "/" + subGroup); @@ -856,15 +866,13 @@ public void testList() throws URISyntaxException { listN5.list("this-group-does-not-exist"); }); - } catch (final IOException e) { - fail(e.getMessage()); } } @Test - public void testDeepList() throws IOException, URISyntaxException, ExecutionException, InterruptedException { + public void testDeepList() throws ExecutionException, InterruptedException { - try (final N5Writer n5 = createN5Writer()) { + try (final N5Writer n5 = createTempN5Writer()) { n5.createGroup(groupName); for (final String subGroup : subGroupNames) @@ -979,12 +987,12 @@ public void testDeepList() throws IOException, URISyntaxException, ExecutionExce } @Test - public void testExists() throws IOException, URISyntaxException { + public void testExists() { final String groupName2 = groupName + "-2"; final String datasetName2 = datasetName + "-2"; final String notExists = groupName + "-notexists"; - try (N5Writer n5 = createN5Writer()) { + try (N5Writer n5 = createTempN5Writer()) { n5.createDataset(datasetName2, dimensions, blockSize, DataType.UINT64, new RawCompression()); assertTrue(n5.exists(datasetName2)); assertTrue(n5.datasetExists(datasetName2)); @@ -1000,9 +1008,9 @@ public void testExists() throws IOException, URISyntaxException { } @Test - public void testListAttributes() throws IOException, URISyntaxException { + public void testListAttributes() { - try (N5Writer n5 = createN5Writer()) { + try (N5Writer n5 = createTempN5Writer()) { final String groupName2 = groupName + "-2"; final String datasetName2 = datasetName + "-2"; n5.createDataset(datasetName2, dimensions, blockSize, DataType.UINT64, new RawCompression()); @@ -1051,7 +1059,7 @@ public void testListAttributes() throws IOException, URISyntaxException { @Test public void testVersion() throws NumberFormatException, IOException, URISyntaxException { - try (final N5Writer writer = createN5Writer()) { + try (final N5Writer writer = createTempN5Writer()) { final Version n5Version = writer.getVersion(); @@ -1064,7 +1072,7 @@ public void testVersion() throws NumberFormatException, IOException, URISyntaxEx assertThrows(N5Exception.N5IOException.class, () -> { final String containerPath = writer.getURI().toString(); - final N5Writer newWriter = createN5Writer(containerPath); + final N5Writer newWriter = createTempN5Writer(containerPath); newWriter.remove(); newWriter.close(); }); @@ -1079,7 +1087,7 @@ public void testVersion() throws NumberFormatException, IOException, URISyntaxEx public void testReaderCreation() throws IOException, URISyntaxException { final String location; - try (N5Writer writer = createN5Writer()) { + try (N5Writer writer = createTempN5Writer()) { location = writer.getURI().toString(); try (N5Reader n5r = createN5Reader(location)) { @@ -1120,9 +1128,9 @@ public void testReaderCreation() throws IOException, URISyntaxException { } @Test - public void testDelete() throws IOException, URISyntaxException { + public void testDelete() { - try (N5Writer n5 = createN5Writer()) { + try (N5Writer n5 = createTempN5Writer()) { final String datasetName = AbstractN5Test.datasetName + "-test-delete"; n5.createDataset(datasetName, dimensions, blockSize, DataType.UINT8, new RawCompression()); final DatasetAttributes attributes = n5.getDatasetAttributes(datasetName); @@ -1175,7 +1183,7 @@ public TestData(final String groupPath, final String key, final T attributeValue } } - protected static void addAndTest(final N5Writer writer, final ArrayList> existingTests, final TestData testData) throws IOException { + protected static void addAndTest(final N5Writer writer, final ArrayList> existingTests, final TestData testData) { /* test a new value on existing path */ writer.setAttribute(testData.groupPath, testData.attributePath, testData.attributeValue); assertEquals(testData.attributeValue, writer.getAttribute(testData.groupPath, testData.attributePath, testData.attributeClass)); @@ -1205,9 +1213,9 @@ protected static void runTests(final N5Writer writer, final ArrayList(groupName, "[0]", "array_root")); for (final TestData testData : tests) { - try (final N5Writer writer = createN5Writer()) { + try (final N5Writer writer = createTempN5Writer()) { writer.createGroup(testData.groupPath); writer.setAttribute(testData.groupPath, testData.attributePath, testData.attributeValue); assertEquals(testData.attributeValue, writer.getAttribute(testData.groupPath, testData.attributePath, testData.attributeClass)); @@ -1450,7 +1458,7 @@ private String jsonKeyVal(final String key, final String val) { tests.add(new TestData<>(groupName, "/", "replace_empty_root")); tests.add(new TestData<>(groupName, "[0]", "array_root")); - try (final N5Writer writer = createN5Writer()) { + try (final N5Writer writer = createTempN5Writer()) { writer.createGroup(groupName); for (final TestData testData : tests) { writer.setAttribute(testData.groupPath, testData.attributePath, testData.attributeValue); @@ -1467,7 +1475,7 @@ private String jsonKeyVal(final String key, final String val) { final TestData rootAsArray = new TestData<>(groupName, "/", 300); tests.add(rootAsPrimitive); tests.add(rootAsArray); - try (final N5Writer writer = createN5Writer()) { + try (final N5Writer writer = createTempN5Writer()) { writer.createGroup(groupName); for (final TestData test : tests) { /* Set the root as Object*/ @@ -1484,4 +1492,23 @@ private String jsonKeyVal(final String key, final String val) { } } } + + @Test + public void testWriterSeparation() { + + try (N5Writer writer1 = createTempN5Writer()) { + try (N5Writer writer2 = createTempN5Writer()) { + + assertTrue(writer1.exists("/")); + assertTrue(writer2.exists("/")); + + assertTrue(writer1.remove()); + assertTrue(writer2.exists("/")); + assertFalse(writer1.exists("/")); + + assertTrue(writer2.remove()); + assertFalse(writer2.exists("/")); + } + } + } } diff --git a/src/test/java/org/janelia/saalfeldlab/n5/N5FSTest.java b/src/test/java/org/janelia/saalfeldlab/n5/N5FSTest.java index 7ba57bff..8206ebaf 100644 --- a/src/test/java/org/janelia/saalfeldlab/n5/N5FSTest.java +++ b/src/test/java/org/janelia/saalfeldlab/n5/N5FSTest.java @@ -78,13 +78,13 @@ protected String tempN5Location() throws URISyntaxException { @Override protected N5Writer createN5Writer() throws IOException, URISyntaxException { - return new N5FSWriter(tempN5Location(), new GsonBuilder()) { - @Override public void close() { - - super.close(); - remove(); - } - }; + return new N5FSWriter(tempN5Location(), new GsonBuilder()); // { +// @Override public void close() { +// +// super.close(); +// remove(); +// } +// }; } @Override @@ -126,7 +126,7 @@ public void customObjectTest() throws IOException, URISyntaxException { "doubles4", new double[]{5.10, 4.8, 3.7}); - try (N5Writer n5 = createN5Writer()) { + try (N5Writer n5 = createTempN5Writer()) { n5.createGroup(testGroup); addAndTest(n5, existingTests, new TestData<>(testGroup, "/doubles[1]", doubles1)); addAndTest(n5, existingTests, new TestData<>(testGroup, "/doubles[2]", doubles2)); From 50421a07b914e9a3bd4008e9f6136cc9170a7260 Mon Sep 17 00:00:00 2001 From: Caleb Hulbert Date: Wed, 28 Feb 2024 17:07:11 -0500 Subject: [PATCH 4/6] fix(test): explicitly remove writer for this test --- .../java/org/janelia/saalfeldlab/n5/AbstractN5Test.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java b/src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java index e4b1c1c7..8d9ba69d 100644 --- a/src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java +++ b/src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java @@ -40,6 +40,7 @@ import java.io.IOException; import java.net.URISyntaxException; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; @@ -1087,7 +1088,9 @@ public void testVersion() throws NumberFormatException, IOException, URISyntaxEx public void testReaderCreation() throws IOException, URISyntaxException { final String location; - try (N5Writer writer = createTempN5Writer()) { + N5Writer removeMe = null; + try (N5Writer writer = createN5Writer()) { + removeMe = writer; location = writer.getURI().toString(); try (N5Reader n5r = createN5Reader(location)) { @@ -1117,7 +1120,10 @@ public void testReaderCreation() throws IOException, URISyntaxException { /*Only try with resource to ensure `close()` is called.*/ } }); + } finally { + removeMe.remove(); } + // non-existent location should fail assertThrows("Non-existent location throws error", N5Exception.N5IOException.class, () -> { From 07e53883916a2c768160211b6b7a87d1a3a32311 Mon Sep 17 00:00:00 2001 From: Caleb Hulbert Date: Thu, 29 Feb 2024 10:00:56 -0500 Subject: [PATCH 5/6] feat(test): update some previously removed tests chore: code cleanup --- .../org/janelia/saalfeldlab/n5/N5FSTest.java | 54 ++++++------------- 1 file changed, 15 insertions(+), 39 deletions(-) diff --git a/src/test/java/org/janelia/saalfeldlab/n5/N5FSTest.java b/src/test/java/org/janelia/saalfeldlab/n5/N5FSTest.java index 8206ebaf..bd1e43aa 100644 --- a/src/test/java/org/janelia/saalfeldlab/n5/N5FSTest.java +++ b/src/test/java/org/janelia/saalfeldlab/n5/N5FSTest.java @@ -56,7 +56,7 @@ */ public class N5FSTest extends AbstractN5Test { - private static FileSystemKeyValueAccess access = new FileSystemKeyValueAccess(FileSystems.getDefault()); + private static final FileSystemKeyValueAccess access = new FileSystemKeyValueAccess(FileSystems.getDefault()); private static String tempN5PathName() { @@ -78,13 +78,7 @@ protected String tempN5Location() throws URISyntaxException { @Override protected N5Writer createN5Writer() throws IOException, URISyntaxException { - return new N5FSWriter(tempN5Location(), new GsonBuilder()); // { -// @Override public void close() { -// -// super.close(); -// remove(); -// } -// }; + return new N5FSWriter(tempN5Location(), new GsonBuilder()); } @Override @@ -104,7 +98,7 @@ protected N5Reader createN5Reader( } @Test - public void customObjectTest() throws IOException, URISyntaxException { + public void customObjectTest() { final String testGroup = "test"; final ArrayList> existingTests = new ArrayList<>(); @@ -138,7 +132,7 @@ public void customObjectTest() throws IOException, URISyntaxException { } } -// @Test + @Test public void testReadLock() throws IOException { final Path path = Paths.get(tempN5PathName(), "lock"); @@ -171,7 +165,7 @@ public void testReadLock() throws IOException { exec.shutdownNow(); } -// @Test + @Test public void testWriteLock() throws IOException { final Path path = Paths.get(tempN5PathName(), "lock"); @@ -203,7 +197,7 @@ public void testWriteLock() throws IOException { } @Test - public void testLockReleaseByReader() throws IOException { + public void testLockReleaseByReader() throws IOException, ExecutionException, InterruptedException, TimeoutException { System.out.println("Testing lock release by Reader."); @@ -218,26 +212,16 @@ public void testLockReleaseByReader() throws IOException { return null; }); - try { - future.get(3, TimeUnit.SECONDS); - } catch (final TimeoutException e) { - fail("... lock not released!"); - future.cancel(true); - } catch (final InterruptedException | ExecutionException e) { - future.cancel(true); - System.out.println("... test interrupted!"); - } finally { - lock.close(); - Files.delete(path); - } + future.get(3, TimeUnit.SECONDS); + future.cancel(true); + lock.close(); + Files.delete(path); exec.shutdownNow(); } @Test - public void testLockReleaseByInputStream() throws IOException { - - System.out.println("Testing lock release by InputStream."); + public void testLockReleaseByInputStream() throws IOException, ExecutionException, InterruptedException, TimeoutException { final Path path = Paths.get(tempN5PathName(), "lock"); final LockedChannel lock = access.lockForWriting(path); @@ -250,18 +234,10 @@ public void testLockReleaseByInputStream() throws IOException { return null; }); - try { - future.get(3, TimeUnit.SECONDS); - } catch (final TimeoutException e) { - fail("... lock not released!"); - future.cancel(true); - } catch (final InterruptedException | ExecutionException e) { - future.cancel(true); - System.out.println("... test interrupted!"); - } finally { - lock.close(); - Files.delete(path); - } + future.get(3, TimeUnit.SECONDS); + future.cancel(true); + lock.close(); + Files.delete(path); exec.shutdownNow(); } From 003c0ffdc4118863df728f25302479b1f5b34a39 Mon Sep 17 00:00:00 2001 From: Caleb Hulbert Date: Fri, 1 Mar 2024 15:05:16 -0500 Subject: [PATCH 6/6] fix(test): no need to `remove()` when `createTempN5Writer()` --- .../janelia/saalfeldlab/n5/AbstractN5Test.java | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java b/src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java index 8d9ba69d..8fdd5281 100644 --- a/src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java +++ b/src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java @@ -40,7 +40,6 @@ import java.io.IOException; import java.net.URISyntaxException; -import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; @@ -649,8 +648,6 @@ public void testNullAttributes() throws URISyntaxException, IOException { writer.setAttribute(groupName, "existingValue", null); assertThrows(N5ClassCastException.class, () -> writer.getAttribute(groupName, "existingValue", Integer.class)); assertEquals(JsonNull.INSTANCE, writer.getAttribute(groupName, "existingValue", JsonElement.class)); - - writer.remove(); } /* without serializeNulls*/ @@ -805,8 +802,6 @@ public void testRemoveAttributes() throws IOException, URISyntaxException { writer.setAttribute("foo", "a", 100); writer.removeAttribute("foo", "a"); assertNull(writer.getAttribute("foo", "a", Integer.class)); - - writer.remove(); } } @@ -863,9 +858,7 @@ public void testList() { assertArrayEquals(new String[]{"test"}, listN5.list("/")); // calling list on a non-existant group throws an exception - assertThrows(N5Exception.class, () -> { - listN5.list("this-group-does-not-exist"); - }); + assertThrows(N5Exception.class, () -> listN5.list("this-group-does-not-exist")); } } @@ -1071,12 +1064,7 @@ public void testVersion() throws NumberFormatException, IOException, URISyntaxEx final Version version = writer.getVersion(); assertFalse(N5Reader.VERSION.isCompatible(version)); - assertThrows(N5Exception.N5IOException.class, () -> { - final String containerPath = writer.getURI().toString(); - final N5Writer newWriter = createTempN5Writer(containerPath); - newWriter.remove(); - newWriter.close(); - }); + assertThrows(N5Exception.N5IOException.class, () -> createTempN5Writer(writer.getURI().toString())); final Version compatibleVersion = new Version(N5Reader.VERSION.getMajor(), N5Reader.VERSION.getMinor(), N5Reader.VERSION.getPatch()); writer.setAttribute("/", N5Reader.VERSION_KEY, compatibleVersion.toString()); @@ -1173,7 +1161,7 @@ protected boolean testDeleteIsBlockDeleted(final DataBlock dataBlock) { return dataBlock == null; } - public class TestData { + public static class TestData { public String groupPath; public String attributePath;