@@ -49,6 +49,77 @@ function test_store_common(ds)
4949 @test ! Zarr. isemptysub (ds," bar/" )
5050end
5151
52+ """
53+ Function to test the interface of a read only AbstractStore. Every complete implementation should pass this test.
54+
55+ `converter` is a function that takes a Zarr.DictStore, and converts it to a read only store.
56+
57+ `closer` is a function that gets called to close the read only store.
58+ """
59+ function test_read_only_store_common (converter, closer= Returns (nothing ))
60+ ds = Zarr. DictStore ()
61+ rs = converter (ds)
62+ @test ! Zarr. is_zgroup (rs," " )
63+
64+ closer (rs)
65+ ds[" .zgroup" ]= rand (UInt8,50 )
66+ rs = converter (ds)
67+
68+ @test haskey (rs," .zgroup" )
69+
70+ @test Zarr. is_zgroup (rs," " )
71+ @test ! Zarr. is_zarray (rs," " )
72+
73+ @test isempty (Zarr. subdirs (rs," " ))
74+ @test sort (collect (Zarr. subkeys (rs," " )))== [" .zgroup" ]
75+
76+ # Create a subgroup
77+ @test ! Zarr. is_zarray (rs," bar" )
78+
79+ closer (rs)
80+ ds[" bar/.zarray" ] = rand (UInt8,50 )
81+ rs = converter (ds)
82+
83+ @test Zarr. is_zarray (rs," bar" )
84+ @test Zarr. subdirs (rs," " ) == [" bar" ]
85+ @test Zarr. subdirs (rs," bar" ) == String[]
86+ # Test getindex and setindex
87+ data = rand (UInt8,50 )
88+
89+ closer (rs)
90+ ds[" bar/0.0.0" ] = data
91+ rs = converter (ds)
92+
93+ @test rs[" bar/0.0.0" ]== data
94+ @test Zarr. storagesize (rs," bar" )== 50
95+ @test Zarr. isinitialized (rs," bar/0.0.0" )
96+ @test ! Zarr. isinitialized (rs," bar/0.0.1" )
97+
98+ closer (rs)
99+ Zarr. writeattrs (ds," bar" ,Dict (" a" => " b" ))
100+ rs = converter (ds)
101+
102+ @test Zarr. getattrs (rs," bar" )== Dict (" a" => " b" )
103+
104+ closer (rs)
105+ delete! (ds," bar/0.0.0" )
106+ rs = converter (ds)
107+
108+ @test ! Zarr. isinitialized (rs," bar" ,CartesianIndex ((0 ,0 ,0 )))
109+ @test ! Zarr. isinitialized (rs," bar/0.0.0" )
110+
111+ closer (rs)
112+ ds[" bar/0.0.0" ] = data
113+ rs = converter (ds)
114+
115+ # Add tests for empty storage
116+ @test Zarr. isemptysub (rs," ba" )
117+ @test Zarr. isemptysub (rs," ba/" )
118+ @test ! Zarr. isemptysub (rs," bar" )
119+ @test ! Zarr. isemptysub (rs," bar/" )
120+ closer (rs)
121+ end
122+
52123@testset " DirectoryStore" begin
53124 A = fill (1.0 , 30 , 20 )
54125 chunks = (5 ,10 )
145216 @test g2. attrs == Dict (" groupatt" => 5 )
146217 @test g2[" a1" ]. attrs == Dict (" arratt" => 2.5 )
147218 @test g2[" a1" ][:,:] == reshape (1 : 200 ,10 ,20 )
219+
220+ # The following test doesn't pass, but maybe should?
221+ # test_read_only_store_common() do ds
222+ # # This converts a DictStore to a read only ConsolidatedStore HTTPStore
223+ # @async HTTP.serve(ds,"",ip,port,server=server)
224+ # Zarr.ConsolidatedStore(Zarr.HTTPStore("http://$ip:$port"),"")
225+ # end
148226 close (server)
149227 # Test server that returns 403 instead of 404 for missing chunks
150228 server = Sockets. listen (0 )
159237 @test all (== (- 1 ),g3[" a" ][:,:])
160238 close (server)
161239end
240+
241+ @testset " Zip Storage" begin
242+ s = Zarr. DictStore ()
243+ g = zgroup (s, attrs = Dict (" groupatt" => 5 ))
244+ a = zcreate (Int,g," a1" ,10 ,20 ,chunks= (5 ,5 ),attrs= Dict (" arratt" => 2.5 ))
245+ a .= reshape (1 : 200 ,10 ,20 )
246+ io = IOBuffer ()
247+ Zarr. writezip (io, g)
248+ data = take! (io)
249+ ds = Zarr. ZipStore (data)
250+ @test sprint (show, ds) == " Read Only Zip Storage"
251+ g2 = zopen (ds)
252+ @test g2. attrs == Dict (" groupatt" => 5 )
253+ @test g2[" a1" ]. attrs == Dict (" arratt" => 2.5 )
254+ @test g2[" a1" ][:,:] == reshape (1 : 200 ,10 ,20 )
255+
256+ test_read_only_store_common () do ds
257+ # This converts a DictStore to a read only ZipStore
258+ io = IOBuffer ()
259+ Zarr. writezip (io, ds)
260+ Zarr. ZipStore (take! (io))
261+ end
262+ end
0 commit comments