diff --git a/pom.xml b/pom.xml index e14cd3d..b36cfe0 100644 --- a/pom.xml +++ b/pom.xml @@ -138,7 +138,7 @@ 1.1.1 - 3.1.3 + 3.2.0 1.0.2 diff --git a/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrCompressor.java b/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrCompressor.java index 2ee83e2..815a9df 100644 --- a/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrCompressor.java +++ b/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrCompressor.java @@ -35,6 +35,8 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import com.google.gson.JsonNull; +import com.google.gson.JsonSerializer; import org.janelia.saalfeldlab.n5.Bzip2Compression; import org.janelia.saalfeldlab.n5.Compression; import org.janelia.saalfeldlab.n5.GzipCompression; @@ -265,12 +267,12 @@ public Bzip2Compression getCompression() { } } - public static class Raw extends RawCompression implements ZarrCompressor { - + class Raw implements ZarrCompressor { + public Raw() {} @Override public RawCompression getCompression() { - return this; + return new RawCompression(); } } @@ -294,4 +296,6 @@ public ZarrCompressor deserialize(final JsonElement json, final Type typeOfT, fi return context.deserialize(json, compressorClass); } } + + JsonSerializer rawNullAdapter = (src, typeOfSrc, context) -> JsonNull.INSTANCE; } diff --git a/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrKeyValueReader.java b/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrKeyValueReader.java index 3a1dfde..e35dec3 100644 --- a/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrKeyValueReader.java +++ b/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrKeyValueReader.java @@ -149,6 +149,21 @@ public ZarrKeyValueReader( final boolean cacheMeta) throws N5Exception { + this(checkVersion, keyValueAccess, basePath, gsonBuilder, mapN5DatasetAttributes, mergeAttributes, cacheMeta, true); + } + + protected ZarrKeyValueReader( + final boolean checkVersion, + final KeyValueAccess keyValueAccess, + final String basePath, + final GsonBuilder gsonBuilder, + final boolean mapN5DatasetAttributes, + final boolean mergeAttributes, + final boolean cacheMeta, + final boolean checkRootExists + ) { + + this.keyValueAccess = keyValueAccess; this.gson = registerGson(gsonBuilder); this.cacheMeta = cacheMeta; @@ -169,6 +184,10 @@ public ZarrKeyValueReader( cache = newCache(); else cache = null; + + if( checkRootExists && !exists("/")) + throw new N5Exception.N5IOException("No container exists at " + basePath ); + } /** @@ -837,6 +856,7 @@ protected static GsonBuilder addTypeAdapters(final GsonBuilder gsonBuilder) { gsonBuilder.registerTypeAdapter(DataType.class, new DataType.JsonAdapter()); gsonBuilder.registerTypeAdapter(ZarrCompressor.class, ZarrCompressor.jsonAdapter); + gsonBuilder.registerTypeAdapter(ZarrCompressor.Raw.class, ZarrCompressor.rawNullAdapter); gsonBuilder.registerTypeHierarchyAdapter(Compression.class, CompressionAdapter.getJsonAdapter()); gsonBuilder.registerTypeAdapter(Compression.class, CompressionAdapter.getJsonAdapter()); gsonBuilder.registerTypeAdapter(ZArrayAttributes.class, ZArrayAttributes.jsonAdapter); diff --git a/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrKeyValueWriter.java b/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrKeyValueWriter.java index e681210..78721f2 100644 --- a/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrKeyValueWriter.java +++ b/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrKeyValueWriter.java @@ -120,7 +120,8 @@ public ZarrKeyValueWriter( gsonBuilder, mapN5DatasetAttributes, mergeAttributes, - cacheAttributes); + cacheAttributes, + false); this.dimensionSeparator = dimensionSeparator; Version version = null; if (exists("/")) { diff --git a/src/test/java/org/janelia/saalfeldlab/n5/zarr/N5ZarrTest.java b/src/test/java/org/janelia/saalfeldlab/n5/zarr/N5ZarrTest.java index 4a4bdf8..3381927 100644 --- a/src/test/java/org/janelia/saalfeldlab/n5/zarr/N5ZarrTest.java +++ b/src/test/java/org/janelia/saalfeldlab/n5/zarr/N5ZarrTest.java @@ -28,41 +28,39 @@ */ package org.janelia.saalfeldlab.n5.zarr; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertThrows; -import static org.junit.Assert.assertTrue; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.URISyntaxException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonNull; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import com.google.gson.reflect.TypeToken; +import net.imglib2.RandomAccess; +import net.imglib2.RandomAccessibleInterval; +import net.imglib2.type.numeric.IntegerType; +import net.imglib2.type.numeric.RealType; +import net.imglib2.type.numeric.integer.LongType; +import net.imglib2.type.numeric.integer.UnsignedByteType; +import net.imglib2.type.numeric.integer.UnsignedIntType; +import net.imglib2.type.numeric.integer.UnsignedLongType; +import net.imglib2.type.numeric.real.DoubleType; +import net.imglib2.type.numeric.real.FloatType; +import net.imglib2.view.Views; import org.janelia.saalfeldlab.n5.AbstractN5Test; import org.janelia.saalfeldlab.n5.Bzip2Compression; import org.janelia.saalfeldlab.n5.Compression; import org.janelia.saalfeldlab.n5.DataBlock; import org.janelia.saalfeldlab.n5.DataType; import org.janelia.saalfeldlab.n5.DatasetAttributes; +import org.janelia.saalfeldlab.n5.FileSystemKeyValueAccess; import org.janelia.saalfeldlab.n5.GzipCompression; +import org.janelia.saalfeldlab.n5.KeyValueAccess; +import org.janelia.saalfeldlab.n5.LockedChannel; import org.janelia.saalfeldlab.n5.N5Exception; +import org.janelia.saalfeldlab.n5.N5Exception.N5ClassCastException; import org.janelia.saalfeldlab.n5.N5Reader; import org.janelia.saalfeldlab.n5.N5Reader.Version; import org.janelia.saalfeldlab.n5.N5Writer; import org.janelia.saalfeldlab.n5.RawCompression; -import org.janelia.saalfeldlab.n5.N5Exception.N5ClassCastException; import org.janelia.saalfeldlab.n5.StringDataBlock; import org.janelia.saalfeldlab.n5.blosc.BloscCompression; import org.janelia.saalfeldlab.n5.imglib2.N5Utils; @@ -74,24 +72,26 @@ import org.junit.Ignore; import org.junit.Test; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonElement; -import com.google.gson.JsonNull; -import com.google.gson.JsonObject; -import com.google.gson.JsonPrimitive; -import com.google.gson.reflect.TypeToken; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URISyntaxException; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; -import net.imglib2.RandomAccess; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.type.numeric.IntegerType; -import net.imglib2.type.numeric.RealType; -import net.imglib2.type.numeric.integer.LongType; -import net.imglib2.type.numeric.integer.UnsignedByteType; -import net.imglib2.type.numeric.integer.UnsignedIntType; -import net.imglib2.type.numeric.integer.UnsignedLongType; -import net.imglib2.type.numeric.real.DoubleType; -import net.imglib2.type.numeric.real.FloatType; -import net.imglib2.view.Views; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; /** * @author Stephan Saalfeld <saalfelds@janelia.hhmi.org> @@ -100,65 +100,69 @@ public class N5ZarrTest extends AbstractN5Test { static private final String testZarrDatasetName = "/test/data"; + public static KeyValueAccess createKeyValueAccess() { + return new FileSystemKeyValueAccess(FileSystems.getDefault()); + } + @Override protected String tempN5Location() { try { - return Files.createTempDirectory("n5-zarr-test").toUri().toString(); + return Files.createTempDirectory("n5-zarr-test").toUri().getPath(); } catch (IOException e) { throw new RuntimeException(e); } } - protected static String tmpPathName(final String prefix) { + @Override + protected N5Writer createN5Writer() { - try { - final File tmpFile = Files.createTempDirectory(prefix).toFile(); - tmpFile.deleteOnExit(); - return tmpFile.getCanonicalPath(); - } catch (final Exception e) { - throw new RuntimeException(e); - } + final String testDirPath = tempN5Location(); + return new ZarrKeyValueWriter(createKeyValueAccess(), testDirPath, new GsonBuilder(), true, true, ".",false); } @Override - protected N5ZarrWriter createN5Writer() throws IOException { + protected N5Writer createN5Writer(final String location, final GsonBuilder gsonBuilder) throws IOException { - final String testDirPath = tmpPathName("n5-zarr-test-"); - return new N5ZarrWriter(testDirPath, new GsonBuilder(), ".", true, false) { + return createTempN5Writer(location, gsonBuilder, ".", true); + } - @Override public void close() { + protected N5Writer createTempN5Writer(final String location, final String dimensionSeparator) throws IOException { - assertTrue(remove()); - super.close(); - } - }; + return createTempN5Writer(location, new GsonBuilder(), dimensionSeparator, true); } - @Override - protected N5ZarrWriter createN5Writer(final String location, final GsonBuilder gsonBuilder) throws IOException { - return createN5Writer(location, gsonBuilder, ".", true); + protected N5Writer createTempN5Writer(final String location, final String dimensionSeparator, final boolean cacheAttributes) throws IOException { + + return createTempN5Writer(location, new GsonBuilder(), dimensionSeparator,true, cacheAttributes); } - protected N5ZarrWriter createN5Writer(final String location, final String dimensionSeparator) throws IOException { + protected N5Writer createTempN5Writer( + final String location, + final GsonBuilder gsonBuilder, + final String dimensionSeparator, + final boolean mapN5DatasetAttributes) throws IOException { - return createN5Writer(location, new GsonBuilder(), dimensionSeparator, true); + return createTempN5Writer(location, new GsonBuilder(), dimensionSeparator, mapN5DatasetAttributes, false); } - protected N5ZarrWriter createN5Writer( + protected N5Writer createTempN5Writer( final String location, final GsonBuilder gsonBuilder, final String dimensionSeparator, - final boolean mapN5DatasetAttributes) throws IOException { + final boolean mapN5DatasetAttributes, + final boolean cacheAttributes) { - return new N5ZarrWriter(location, gsonBuilder, dimensionSeparator, mapN5DatasetAttributes, false); + final ZarrKeyValueWriter tempWriter = new ZarrKeyValueWriter(createKeyValueAccess(), location, gsonBuilder, mapN5DatasetAttributes, true, dimensionSeparator, cacheAttributes); + tempWriters.add(tempWriter); + return tempWriter; } @Override protected N5Reader createN5Reader(final String location, final GsonBuilder gson) throws IOException { - return new N5ZarrReader(location, gson); + return new ZarrKeyValueReader(createKeyValueAccess(), location, gson, true, true, false); } @Override @@ -180,10 +184,10 @@ protected Compression[] getCompressions() { @Override @Test - public void testCreateDataset() throws IOException { + public void testCreateDataset() { final DatasetAttributes info; - try (N5Writer n5 = createN5Writer()) { + try (N5Writer n5 = createTempN5Writer()) { n5.createDataset(datasetName, dimensions, blockSize, DataType.UINT64, getCompressions()[0]); assertTrue("Dataset does not exist", n5.exists(datasetName)); @@ -201,41 +205,35 @@ public void testCreateNestedDataset() throws IOException { final String datasetName = "/test/nested/data"; - final String testDirPath = tmpPathName("n5-zarr-test-"); - final N5ZarrWriter n5Nested = createN5Writer(testDirPath, "/"); + final String testDirPath = tempN5Location(); + final ZarrKeyValueWriter n5Nested = (ZarrKeyValueWriter) createTempN5Writer(testDirPath, "/"); n5Nested.createDataset(datasetName, dimensions, blockSize, DataType.UINT64, getCompressions()[0]); assertEquals("/", n5Nested.getZArrayAttributes(datasetName).getDimensionSeparator()); // TODO test that parents of nested dataset are groups - - n5Nested.remove(datasetName); - n5Nested.remove(); - n5Nested.close(); } @Test - public void testCreateDatasetNameEmpty() throws IOException, URISyntaxException { + public void testCreateDatasetNameEmpty() { - final String testDirPath = tmpPathName("n5-zarr-test-"); - final N5Writer n5 = createN5Writer(testDirPath); + final String testDirPath = tempN5Location(); + final N5Writer n5 = createTempN5Writer(testDirPath); n5.createDataset("", dimensions, blockSize, DataType.UINT64, getCompressions()[0]); - n5.remove(); - n5.close(); } @Test - public void testCreateDatasetNameSlash() throws IOException { + public void testCreateDatasetNameSlash() { - try (final N5Writer n5 = createN5Writer()) { + try (final N5Writer n5 = createTempN5Writer()) { n5.createDataset("", dimensions, blockSize, DataType.UINT64, getCompressions()[0]); } } @Test - public void testGetDatasetAttributesNull() throws IOException { + public void testGetDatasetAttributesNull() { - try (final N5Writer n5 = createN5Writer()) { + try (final N5Writer n5 = createTempN5Writer()) { final DatasetAttributes attributes = n5.getDatasetAttributes(""); assertNull(attributes); } @@ -257,23 +255,23 @@ public void testPadCrop() { @Override @Test - public void testVersion() throws NumberFormatException, IOException { + public void testVersion() throws NumberFormatException, IOException, URISyntaxException { - try (final N5Writer writer = createN5Writer()) { + try (final N5Writer writer = createTempN5Writer()) { - final N5ZarrWriter zarr = (N5ZarrWriter)writer; + final ZarrKeyValueWriter zarr = (ZarrKeyValueWriter)writer; final Version n5Version = writer.getVersion(); assertEquals(n5Version, N5ZarrReader.VERSION); final JsonObject bumpVersion = new JsonObject(); - bumpVersion.add(ZarrKeyValueReader.ZARR_FORMAT_KEY, new JsonPrimitive(N5ZarrReader.VERSION.getMajor() + 1)); + bumpVersion.add(N5ZarrReader.ZARR_FORMAT_KEY, new JsonPrimitive(N5ZarrReader.VERSION.getMajor() + 1)); zarr.writeZGroup("", bumpVersion); final Version version = writer.getVersion(); assertFalse(N5ZarrReader.VERSION.isCompatible(version)); // check that writer creation fails for incompatible version - assertThrows(N5Exception.N5IOException.class, () -> createN5Writer(writer.getURI().toString())); + assertThrows(N5Exception.N5IOException.class, () -> createTempN5Writer(writer.getURI().toString())); // final Version compatibleVersion = new Version(N5ZarrReader.VERSION.getMajor(), N5ZarrReader.VERSION.getMinor(), N5Reader.VERSION.getPatch()); // writer.setAttribute("/", ZarrUtils.ZARR_FORMAT_KEY, compatibleVersion.toString()); @@ -284,10 +282,8 @@ public void testVersion() throws NumberFormatException, IOException { @Override public void testReaderCreation() throws IOException, URISyntaxException { - final File tmpFile = Files.createTempDirectory("reader-create-test-").toFile(); - tmpFile.delete(); - final String canonicalPath = tmpFile.getCanonicalPath(); - try (N5Writer writer = createN5Writer(canonicalPath)) { + final String canonicalPath = tempN5Location(); + try (N5Writer writer = createTempN5Writer(canonicalPath)) { final N5Reader n5r = createN5Reader(canonicalPath); assertNotNull(n5r); @@ -320,13 +316,13 @@ public void testReaderCreation() throws IOException, URISyntaxException { @Override @Test - public void testExists() throws IOException { + 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, getCompressions()[0]); assertTrue(n5.exists(datasetName2)); @@ -346,12 +342,12 @@ public void testExists() throws IOException { @Override @Test - public void testListAttributes() throws IOException { + public void testListAttributes() { final String groupName2 = groupName + "-2"; final String datasetName2 = datasetName + "-2"; - try (N5Writer n5 = createN5Writer()) { + try (N5Writer n5 = createTempN5Writer()) { n5.createDataset(datasetName2, dimensions, blockSize, DataType.UINT64, getCompressions()[0]); n5.setAttribute(datasetName2, "attr1", new double[]{1, 2, 3}); @@ -398,16 +394,16 @@ public void testWriteReadSerializableBlock() { } @Test - public void testWriteReadStringBlock() { + @Override + public void testWriteReadStringBlock() { DataType dataType = DataType.STRING; int[] blockSize = new int[]{3, 2, 1}; String[] stringBlock = new String[]{"", "a", "bc", "de", "fgh", ":-รพ"}; Compression[] compressions = this.getCompressions(); for (Compression compression : compressions) { - System.out.println("Testing " + compression.getType() + " " + dataType); - try (final N5Writer n5 = createN5Writer()) { + try (final N5Writer n5 = createTempN5Writer()) { n5.createDataset("/test/group/dataset", dimensions, blockSize, dataType, compression); DatasetAttributes attributes = n5.getDatasetAttributes("/test/group/dataset"); StringDataBlock dataBlock = new ZarrStringDataBlock(blockSize, new long[]{0L, 0L, 0L}, stringBlock); @@ -415,12 +411,8 @@ public void testWriteReadStringBlock() { DataBlock loadedDataBlock = n5.readBlock("/test/group/dataset", attributes, 0L, 0L, 0L); assertArrayEquals(stringBlock, (String[])loadedDataBlock.getData()); assertTrue(n5.remove("/test/group/dataset")); - } catch (IOException e) { - e.printStackTrace(); - Assert.fail("Block cannot be written."); } } - } private boolean runPythonTest(final String script, final String containerPath) throws InterruptedException { @@ -467,7 +459,7 @@ private static > void assertIsSequence( @Test public void testReadZarrPython() throws IOException, InterruptedException { - final String testZarrDirPath = tmpPathName("n5-zarr-test-"); + final String testZarrDirPath = tempN5Location(); /* create test data with python */ if (!runPythonTest("zarr-test.py", testZarrDirPath)) { @@ -475,8 +467,8 @@ public void testReadZarrPython() throws IOException, InterruptedException { return; } - final N5ZarrWriter n5Zarr = createN5Writer(testZarrDirPath, "."); - final N5ZarrWriter n5ZarrWithoutMapping = createN5Writer(testZarrDirPath, new GsonBuilder(), ".", false); + final ZarrKeyValueWriter n5Zarr = (ZarrKeyValueWriter)createTempN5Writer(testZarrDirPath, "."); + final ZarrKeyValueWriter n5ZarrWithoutMapping = (ZarrKeyValueWriter)createTempN5Writer(testZarrDirPath, new GsonBuilder(), ".", false); /* groups */ assertTrue(n5Zarr.exists(testZarrDatasetName) && !n5Zarr.datasetExists(testZarrDatasetName)); @@ -658,17 +650,12 @@ public void testReadZarrPython() throws IOException, InterruptedException { strAttributes = n5Zarr.getDatasetAttributes(datasetName); loadedDataBlock = n5Zarr.readBlock(datasetName, strAttributes, 1L, 0L); assertArrayEquals(expected, ((String[])loadedDataBlock.getData())); - - /* remove the container */ - n5Zarr.remove(); - n5Zarr.close(); - n5ZarrWithoutMapping.close(); } @Test public void testReadZarrNestedPython() throws IOException, InterruptedException { - final String testZarrNestedDirPath = tmpPathName("zarr-test-nested-"); + final String testZarrNestedDirPath = tempN5Location(); /* create test data with python */ if (!runPythonTest("zarr-nested-test.py", testZarrNestedDirPath)) { @@ -676,7 +663,7 @@ public void testReadZarrNestedPython() throws IOException, InterruptedException return; } - final N5ZarrWriter n5Zarr = new N5ZarrWriter(testZarrNestedDirPath, ".", true); + final ZarrKeyValueWriter n5Zarr = (ZarrKeyValueWriter) createTempN5Writer(testZarrNestedDirPath, ".", true); /* groups */ assertTrue(n5Zarr.exists(testZarrDatasetName) && !n5Zarr.datasetExists(testZarrDatasetName)); @@ -690,40 +677,33 @@ public void testReadZarrNestedPython() throws IOException, InterruptedException final UnsignedByteType refUnsignedByte = new UnsignedByteType(); assertIsSequence(N5Utils.open(n5Zarr, testZarrDatasetName + "/3x2_c_u1"), refUnsignedByte); - - /* remove the container */ - n5Zarr.remove(); - n5Zarr.close(); } @Test - public void testRawCompressorNullInZarray() throws IOException, ParseException { + public void testRawCompressorNullInZarray() throws IOException, ParseException, URISyntaxException { - final String testZarrDirPath = tmpPathName("n5-zarr-test-"); - final N5ZarrWriter n5 = new N5ZarrWriter(testZarrDirPath); + final ZarrKeyValueWriter n5 = (ZarrKeyValueWriter) createTempN5Writer(); n5.createDataset( testZarrDatasetName, new long[]{1, 2, 3}, new int[]{1, 2, 3}, DataType.UINT16, new RawCompression()); + final String zarrayLocation = n5.keyValueAccess.compose(n5.uri, testZarrDatasetName, ".zarray"); + final LockedChannel zarrayChannel = n5.keyValueAccess.lockForReading(zarrayLocation); final JSONParser jsonParser = new JSONParser(); - final File zArrayFile = Paths.get(testZarrDirPath, testZarrDatasetName, ".zarray").toFile(); - try (FileReader freader = new FileReader(zArrayFile)) { - final JSONObject zarray = (JSONObject)jsonParser.parse(freader); + try (Reader reader = zarrayChannel.newReader()) { + final JSONObject zarray = (JSONObject)jsonParser.parse(reader); final JSONObject compressor = (JSONObject)zarray.get("compressor"); assertNull(compressor); - } finally { - n5.remove(); - n5.close(); } } @Test @Override - public void testAttributes() throws IOException { + public void testAttributes() { - try (final N5Writer n5 = createN5Writer()) { + try (final N5Writer n5 = createTempN5Writer()) { n5.createGroup(groupName); n5.setAttribute(groupName, "key1", "value1"); @@ -757,7 +737,6 @@ public void testAttributes() throws IOException { }.getType())); - // test the case where the resulting file becomes shorter n5.setAttribute(groupName, "key1", 1); n5.setAttribute(groupName, "key2", 2); @@ -791,10 +770,10 @@ public void testAttributes() throws IOException { } @Test - public void testAttributeMapping() throws IOException { + public void testAttributeMapping() { // attribute mapping on by default - try (final N5Writer n5 = createN5Writer()) { + try (final N5Writer n5 = createTempN5Writer()) { n5.createDataset(datasetName, dimensions, blockSize, DataType.UINT64, getCompressions()[0]); @@ -861,12 +840,12 @@ public void testAttributeMapping() throws IOException { @Test @Override @Ignore - public void testNullAttributes() throws IOException { + public void testNullAttributes() { // serializeNulls must be on for Zarr to be able to write datasets with raw compression /* 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); @@ -903,8 +882,6 @@ public void testNullAttributes() throws 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(); } } diff --git a/src/test/java/org/janelia/saalfeldlab/n5/zarr/ZarrCachedFSTest.java b/src/test/java/org/janelia/saalfeldlab/n5/zarr/ZarrCachedFSTest.java index 4bd0bb5..d0743da 100644 --- a/src/test/java/org/janelia/saalfeldlab/n5/zarr/ZarrCachedFSTest.java +++ b/src/test/java/org/janelia/saalfeldlab/n5/zarr/ZarrCachedFSTest.java @@ -11,7 +11,6 @@ import java.net.URISyntaxException; import java.nio.file.FileSystems; import java.nio.file.Files; -import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; @@ -21,6 +20,7 @@ import org.janelia.saalfeldlab.n5.N5Exception; import org.janelia.saalfeldlab.n5.N5Reader; import org.janelia.saalfeldlab.n5.N5CachedFSTest.TrackingStorage; +import org.janelia.saalfeldlab.n5.N5Writer; import org.junit.Assert; import org.junit.Test; @@ -30,36 +30,37 @@ public class ZarrCachedFSTest extends N5ZarrTest { @Override - protected N5ZarrWriter createN5Writer() throws IOException { + protected String tempN5Location() { - final String testDirPath = tmpPathName("zarr-cached-test-"); - return new N5ZarrWriter(testDirPath, new GsonBuilder(), ".", true, true) { - @Override public void close() { + try { + return Files.createTempDirectory("n5-zarr-cached-test").toUri().getPath(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + protected N5ZarrWriter createN5Writer() { - assertTrue(remove()); - super.close(); - } - }; + final String testDirPath = tempN5Location(); + return new N5ZarrWriter(testDirPath, new GsonBuilder(), ".", true, true); } - protected N5ZarrWriter createN5Writer(final boolean cacheAttributes) throws IOException { + protected N5Writer createTempN5Writer(final boolean cacheAttributes) throws IOException { - if( cacheAttributes ) - return createN5Writer(tempN5PathName(), new GsonBuilder(), ".", true); - else - return super.createN5Writer(tempN5PathName(), new GsonBuilder(), ".", true); + return createTempN5Writer(tempN5PathName(), new GsonBuilder(), ".", true, cacheAttributes); } @Override protected N5ZarrWriter createN5Writer(final String location, final GsonBuilder gsonBuilder) throws IOException { - return createN5Writer(location, gsonBuilder, ".", true); + return createTempN5Writer(location, gsonBuilder, ".", true); } @Override - protected N5ZarrWriter createN5Writer(final String location, final String dimensionSeparator) throws IOException { + protected N5ZarrWriter createTempN5Writer(final String location, final String dimensionSeparator) throws IOException { - return createN5Writer(location, new GsonBuilder(), dimensionSeparator, true); + return createTempN5Writer(location, new GsonBuilder(), dimensionSeparator, true); } @Override @@ -69,7 +70,7 @@ protected N5Reader createN5Reader(final String location, final GsonBuilder gson) } @Override - protected N5ZarrWriter createN5Writer( + protected N5ZarrWriter createTempN5Writer( final String location, final GsonBuilder gsonBuilder, final String dimensionSeparator, @@ -91,7 +92,7 @@ protected static String tempN5PathName() { @Test public void cachedRootDatasetTest() throws IOException { - final String testDirPath = tmpPathName("zarr-cached-test-"); + final String testDirPath = tempN5Location(); try (ZarrKeyValueWriter writer = (ZarrKeyValueWriter) createN5Writer( testDirPath, new GsonBuilder() )) { writer.createDataset("/", dimensions, blockSize, DataType.UINT8, getCompressions()[0]); assertTrue( writer.exists("/")); @@ -103,12 +104,12 @@ public void cachedRootDatasetTest() throws IOException { } @Test - public void cacheTest() throws IOException { + public void cacheTest() throws IOException, URISyntaxException { /* Test the cache by setting many attributes, then manually deleting the underlying file. * The only possible way for the test to succeed is if it never again attempts to read the file, and relies on the cache. */ final String cachedGroup = "cachedGroup"; - try (ZarrKeyValueWriter zarr = (ZarrKeyValueWriter) createN5Writer()) { + try (ZarrKeyValueWriter zarr = (ZarrKeyValueWriter) createTempN5Writer()) { zarr.createGroup(cachedGroup); final String attributesPath = new File(zarr.getURI()).toPath() .resolve(cachedGroup) @@ -124,7 +125,7 @@ public void cacheTest() throws IOException { runTests(zarr, tests); } - try (final ZarrKeyValueWriter zarr = (ZarrKeyValueWriter) createN5Writer(false)) { + try (final ZarrKeyValueWriter zarr = (ZarrKeyValueWriter) createTempN5Writer(false)) { zarr.createGroup(cachedGroup); final String attributesPath = new File(zarr.getURI()).toPath() @@ -157,7 +158,7 @@ public void cacheBehaviorTest() throws IOException, URISyntaxException { } } - public static void zarrCacheBehaviorHelper(final TrackingStorage n5) throws IOException, URISyntaxException { + public static void zarrCacheBehaviorHelper(final TrackingStorage n5) { // non existant group final String groupA = "groupA"; @@ -398,7 +399,7 @@ public static class ZarrTrackingStorage extends ZarrKeyValueWriter implements Tr public int writeAttrCallCount = 0; public ZarrTrackingStorage(final KeyValueAccess keyValueAccess, final String basePath, - final GsonBuilder gsonBuilder, final boolean cacheAttributes) throws IOException { + final GsonBuilder gsonBuilder, final boolean cacheAttributes) { super(keyValueAccess, basePath, gsonBuilder, true, true, ".", cacheAttributes); }