44import com .amazonaws .auth .AnonymousAWSCredentials ;
55import com .amazonaws .services .s3 .AmazonS3ClientBuilder ;
66import com .fasterxml .jackson .databind .ObjectMapper ;
7+ import com .github .luben .zstd .Zstd ;
8+ import com .github .luben .zstd .ZstdCompressCtx ;
79import dev .zarr .zarrjava .store .FilesystemStore ;
810import dev .zarr .zarrjava .store .HttpStore ;
911import dev .zarr .zarrjava .store .S3Store ;
1012import dev .zarr .zarrjava .store .StoreHandle ;
1113import dev .zarr .zarrjava .utils .MultiArrayUtils ;
1214import dev .zarr .zarrjava .v3 .*;
15+ import dev .zarr .zarrjava .v3 .codec .CodecBuilder ;
1316import dev .zarr .zarrjava .v3 .codec .core .TransposeCodec ;
1417import org .junit .jupiter .api .Assertions ;
1518import org .junit .jupiter .api .BeforeAll ;
1619import org .junit .jupiter .api .Test ;
1720import org .junit .jupiter .params .ParameterizedTest ;
21+ import org .junit .jupiter .params .provider .CsvSource ;
1822import org .junit .jupiter .params .provider .ValueSource ;
23+ import ucar .ma2 .MAMath ;
1924
20- import java .io .BufferedReader ;
21- import java .io .File ;
22- import java .io .IOException ;
23- import java .io .InputStreamReader ;
25+ import java .io .*;
26+ import java .nio .ByteBuffer ;
2427import java .nio .file .Files ;
2528import java .nio .file .Path ;
2629import java .nio .file .Paths ;
@@ -35,8 +38,7 @@ public class ZarrTest {
3538
3639 final static Path TESTDATA = Paths .get ("testdata" );
3740 final static Path TESTOUTPUT = Paths .get ("testoutput" );
38- final static Path ZARRITA_WRITE_PATH = Paths .get ("src/test/java/dev/zarr/zarrjava/zarrita_write.py" );
39- final static Path ZARRITA_READ_PATH = Paths .get ("src/test/java/dev/zarr/zarrjava/zarrita_read.py" );
41+ final static Path PYTHON_TEST_PATH = Paths .get ("src/test/python-scripts/" );
4042
4143 public static String pythonPath () {
4244 if (System .getProperty ("os.name" ).startsWith ("Windows" )) {
@@ -60,7 +62,7 @@ public static void clearTestoutputFolder() throws IOException {
6062 public void testReadFromZarrita (String codec ) throws IOException , ZarrException , InterruptedException {
6163
6264 String command = pythonPath ();
63- ProcessBuilder pb = new ProcessBuilder (command , ZARRITA_WRITE_PATH .toString (), codec , TESTOUTPUT .toString ());
65+ ProcessBuilder pb = new ProcessBuilder (command , PYTHON_TEST_PATH . resolve ( "zarrita_write.py" ) .toString (), codec , TESTOUTPUT .toString ());
6466 Process process = pb .start ();
6567
6668 BufferedReader reader = new BufferedReader (new InputStreamReader (process .getInputStream ()));
@@ -91,10 +93,43 @@ public void testReadFromZarrita(String codec) throws IOException, ZarrException,
9193 Assertions .assertArrayEquals (expectedData , (int []) result .get1DJavaArray (ucar .ma2 .DataType .INT ));
9294 }
9395
96+ @ CsvSource ({"0,true" , "0,false" , "5, true" , "10, false" })
97+ @ ParameterizedTest
98+ public void testZstdLibrary (int clevel , boolean checksumFlag ) throws IOException , InterruptedException {
99+ //compress using ZstdCompressCtx
100+ int number = 123456 ;
101+ byte [] src = ByteBuffer .allocate (4 ).putInt (number ).array ();
102+ byte [] compressed ;
103+ try (ZstdCompressCtx ctx = new ZstdCompressCtx ()) {
104+ ctx .setLevel (clevel );
105+ ctx .setChecksum (checksumFlag );
106+ compressed = ctx .compress (src );
107+ }
108+ //decompress with Zstd.decompress
109+ long originalSize = Zstd .decompressedSize (compressed );
110+ byte [] decompressed = Zstd .decompress (compressed , (int ) originalSize );
111+ Assertions .assertEquals (number , ByteBuffer .wrap (decompressed ).getInt ());
112+
113+ //write compressed to file
114+ String compressedDataPath = TESTOUTPUT .resolve ("compressed" + clevel + checksumFlag + ".bin" ).toString ();
115+ try (FileOutputStream fos = new FileOutputStream (compressedDataPath )) {
116+ fos .write (compressed );
117+ }
118+
119+ //decompress in python
120+ Process process = new ProcessBuilder (
121+ pythonPath (),
122+ PYTHON_TEST_PATH .resolve ("zstd_decompress.py" ).toString (),
123+ compressedDataPath ,
124+ Integer .toString (number )
125+ ).start ();
126+ int exitCode = process .waitFor ();
127+ assert exitCode == 0 ;
128+ }
129+
94130 //TODO: add crc32c
95- //Disabled "zstd": known issue
96131 @ ParameterizedTest
97- @ ValueSource (strings = {"blosc" , "gzip" , "bytes" , "transpose" , "sharding_start" , "sharding_end" })
132+ @ ValueSource (strings = {"blosc" , "gzip" , "zstd" , " bytes" , "transpose" , "sharding_start" , "sharding_end" })
98133 public void testWriteToZarrita (String codec ) throws IOException , ZarrException , InterruptedException {
99134 StoreHandle storeHandle = new FilesystemStore (TESTOUTPUT ).resolve ("write_to_zarrita" , codec );
100135 ArrayMetadataBuilder builder = Array .metadataBuilder ()
@@ -105,10 +140,10 @@ public void testWriteToZarrita(String codec) throws IOException, ZarrException,
105140
106141 switch (codec ) {
107142 case "blosc" :
108- builder = builder .withCodecs (c -> c . withBlosc () );
143+ builder = builder .withCodecs (CodecBuilder :: withBlosc );
109144 break ;
110145 case "gzip" :
111- builder = builder .withCodecs (c -> c . withGzip () );
146+ builder = builder .withCodecs (CodecBuilder :: withGzip );
112147 break ;
113148 case "zstd" :
114149 builder = builder .withCodecs (c -> c .withZstd (0 ));
@@ -140,7 +175,7 @@ public void testWriteToZarrita(String codec) throws IOException, ZarrException,
140175
141176 String command = pythonPath ();
142177
143- ProcessBuilder pb = new ProcessBuilder (command , ZARRITA_READ_PATH .toString (), codec , TESTOUTPUT .toString ());
178+ ProcessBuilder pb = new ProcessBuilder (command , PYTHON_TEST_PATH . resolve ( "zarrita_read.py" ) .toString (), codec , TESTOUTPUT .toString ());
144179 Process process = pb .start ();
145180
146181 BufferedReader reader = new BufferedReader (new InputStreamReader (process .getInputStream ()));
@@ -161,7 +196,7 @@ public void testWriteToZarrita(String codec) throws IOException, ZarrException,
161196
162197 @ ParameterizedTest
163198 @ ValueSource (strings = {"blosc" , "gzip" , "zstd" , "bytes" , "transpose" , "sharding_start" , "sharding_end" })
164- public void testCodecsWriteRead (String codec ) throws IOException , ZarrException , InterruptedException {
199+ public void testCodecsWriteRead (String codec ) throws IOException , ZarrException {
165200 int [] testData = new int [16 * 16 * 16 ];
166201 Arrays .setAll (testData , p -> p );
167202
@@ -175,10 +210,10 @@ public void testCodecsWriteRead(String codec) throws IOException, ZarrException,
175210
176211 switch (codec ) {
177212 case "blosc" :
178- builder = builder .withCodecs (c -> c . withBlosc () );
213+ builder = builder .withCodecs (CodecBuilder :: withBlosc );
179214 break ;
180215 case "gzip" :
181- builder = builder .withCodecs (c -> c . withGzip () );
216+ builder = builder .withCodecs (CodecBuilder :: withGzip );
182217 break ;
183218 case "zstd" :
184219 builder = builder .withCodecs (c -> c .withZstd (0 ));
@@ -216,8 +251,31 @@ public void testCodecsWriteRead(String codec) throws IOException, ZarrException,
216251 Assertions .assertArrayEquals (testData , (int []) result .get1DJavaArray (ucar .ma2 .DataType .INT ));
217252 }
218253
254+ @ ParameterizedTest
255+ @ CsvSource ({"0,true" , "0,false" , "5, true" , "5, false" })
256+ public void testZstdCodecReadWrite (int clevel , boolean checksum ) throws ZarrException , IOException {
257+ int [] testData = new int [16 * 16 * 16 ];
258+ Arrays .setAll (testData , p -> p );
259+
260+ StoreHandle storeHandle = new FilesystemStore (TESTOUTPUT ).resolve ("testZstdCodecReadWrite" , "checksum_" + checksum , "clevel_" + clevel );
261+ ArrayMetadataBuilder builder = Array .metadataBuilder ()
262+ .withShape (16 , 16 , 16 )
263+ .withDataType (DataType .UINT32 )
264+ .withChunkShape (2 , 4 , 8 )
265+ .withFillValue (0 )
266+ .withCodecs (c -> c .withZstd (clevel , checksum ));
267+ Array writeArray = Array .create (storeHandle , builder .build ());
268+ writeArray .write (ucar .ma2 .Array .factory (ucar .ma2 .DataType .UINT , new int []{16 , 16 , 16 }, testData ));
269+
270+ Array readArray = Array .open (storeHandle );
271+ ucar .ma2 .Array result = readArray .read ();
272+
273+ Assertions .assertArrayEquals (testData , (int []) result .get1DJavaArray (ucar .ma2 .DataType .INT ));
274+
275+ }
276+
219277 @ Test
220- public void testCodecTranspose () throws IOException , ZarrException , InterruptedException {
278+ public void testTransposeCodec () throws ZarrException {
221279 ucar .ma2 .Array testData = ucar .ma2 .Array .factory (ucar .ma2 .DataType .UINT , new int []{2 , 3 , 3 }, new int []{
222280 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 });
223281 ucar .ma2 .Array testDataTransposed120 = ucar .ma2 .Array .factory (ucar .ma2 .DataType .UINT , new int []{3 , 3 , 2 }, new int []{
@@ -237,8 +295,8 @@ public void testCodecTranspose() throws IOException, ZarrException, InterruptedE
237295 transposeCodecWrongOrder2 .setCoreArrayMetadata (metadata );
238296 transposeCodecWrongOrder3 .setCoreArrayMetadata (metadata );
239297
240- assert ucar . ma2 . MAMath .equals (testDataTransposed120 , transposeCodec .encode (testData ));
241- assert ucar . ma2 . MAMath .equals (testData , transposeCodec .decode (testDataTransposed120 ));
298+ assert MAMath .equals (testDataTransposed120 , transposeCodec .encode (testData ));
299+ assert MAMath .equals (testData , transposeCodec .decode (testDataTransposed120 ));
242300 assertThrows (ZarrException .class , () -> transposeCodecWrongOrder1 .encode (testData ));
243301 assertThrows (ZarrException .class , () -> transposeCodecWrongOrder2 .encode (testData ));
244302 assertThrows (ZarrException .class , () -> transposeCodecWrongOrder3 .encode (testData ));
@@ -295,8 +353,8 @@ public void testV3ShardingReadCutout() throws IOException, ZarrException {
295353 Array array = Array .open (new FilesystemStore (TESTDATA ).resolve ("l4_sample" , "color" , "1" ));
296354
297355 ucar .ma2 .Array outArray = array .read (new long []{0 , 3073 , 3073 , 513 }, new int []{1 , 64 , 64 , 64 });
298- assertEquals (outArray .getSize (), 64 * 64 * 64 );
299- assertEquals (outArray .getByte (0 ), -98 );
356+ Assertions . assertEquals (outArray .getSize (), 64 * 64 * 64 );
357+ Assertions . assertEquals (outArray .getByte (0 ), -98 );
300358 }
301359
302360 @ Test
@@ -306,8 +364,8 @@ public void testV3Access() throws IOException, ZarrException {
306364 ucar .ma2 .Array outArray = readArray .access ().withOffset (0 , 3073 , 3073 , 513 )
307365 .withShape (1 , 64 , 64 , 64 )
308366 .read ();
309- assertEquals (outArray .getSize (), 64 * 64 * 64 );
310- assertEquals (outArray .getByte (0 ), -98 );
367+ Assertions . assertEquals (outArray .getSize (), 64 * 64 * 64 );
368+ Assertions . assertEquals (outArray .getByte (0 ), -98 );
311369
312370 Array writeArray = Array .create (
313371 new FilesystemStore (TESTOUTPUT ).resolve ("l4_sample_2" , "color" , "1" ),
@@ -375,15 +433,15 @@ public void testV3ArrayMetadataBuilder() throws ZarrException {
375433 .withChunkShape (1 , 1024 , 1024 , 1024 )
376434 .withFillValue (0 )
377435 .withCodecs (
378- c -> c .withSharding (new int []{1 , 32 , 32 , 32 }, c1 -> c1 . withBlosc () ))
436+ c -> c .withSharding (new int []{1 , 32 , 32 , 32 }, CodecBuilder :: withBlosc ))
379437 .build ();
380438 }
381439
382440 @ Test
383441 public void testV3FillValue () throws ZarrException {
384- assertEquals ((int ) ArrayMetadata .parseFillValue (0 , DataType .UINT32 ), 0 );
385- assertEquals ((int ) ArrayMetadata .parseFillValue ("0x00010203" , DataType .UINT32 ), 50462976 );
386- assertEquals ((byte ) ArrayMetadata .parseFillValue ("0b00000010" , DataType .UINT8 ), 2 );
442+ Assertions . assertEquals ((int ) ArrayMetadata .parseFillValue (0 , DataType .UINT32 ), 0 );
443+ Assertions . assertEquals ((int ) ArrayMetadata .parseFillValue ("0x00010203" , DataType .UINT32 ), 50462976 );
444+ Assertions . assertEquals ((byte ) ArrayMetadata .parseFillValue ("0b00000010" , DataType .UINT8 ), 2 );
387445 assert Double .isNaN ((double ) ArrayMetadata .parseFillValue ("NaN" , DataType .FLOAT64 ));
388446 assert Double .isInfinite ((double ) ArrayMetadata .parseFillValue ("-Infinity" , DataType .FLOAT64 ));
389447 }
@@ -401,18 +459,15 @@ public void testV3Group() throws IOException, ZarrException {
401459 );
402460 array .write (new long []{2 , 2 }, ucar .ma2 .Array .factory (ucar .ma2 .DataType .UBYTE , new int []{8 , 8 }));
403461
404- assertArrayEquals (
405- ((Array ) ((Group ) group .listAsArray ()[0 ]).listAsArray ()[0 ]).metadata .chunkShape (),
406- new int []{5 , 5 });
462+ Assertions .assertArrayEquals (((Array ) ((Group ) group .listAsArray ()[0 ]).listAsArray ()[0 ]).metadata .chunkShape (), new int []{5 , 5 });
407463 }
408464
409465 @ Test
410- public void testV2 () throws IOException , ZarrException {
466+ public void testV2 () throws IOException {
411467 FilesystemStore fsStore = new FilesystemStore ("" );
412468 HttpStore httpStore = new HttpStore ("https://static.webknossos.org/data" );
413469
414- System .out .println (
415- dev .zarr .zarrjava .v2 .Array .open (httpStore .resolve ("l4_sample" , "color" , "1" )));
470+ System .out .println (dev .zarr .zarrjava .v2 .Array .open (httpStore .resolve ("l4_sample" , "color" , "1" )));
416471 }
417472
418473
0 commit comments