Skip to content

Commit 6061c3b

Browse files
committed
added storage hierarchy tests
1 parent 0bcb71f commit 6061c3b

File tree

2 files changed

+125
-13
lines changed

2 files changed

+125
-13
lines changed

zarr/storage.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,9 @@ def rmdir(self, prefix=None):
426426
c = c[k]
427427
# remove final key
428428
del c[keys[-1]]
429+
else:
430+
# clear out root
431+
self.root = self.cls()
429432

430433
def getsize(self, prefix=None):
431434
prefix = normalize_prefix(prefix)
@@ -573,7 +576,10 @@ def listdir(self, prefix=None):
573576
prefix = normalize_prefix(prefix)
574577
if prefix:
575578
path = os.path.join(path, prefix)
576-
return sorted(os.listdir(path))
579+
if os.path.isdir(path):
580+
return sorted(os.listdir(path))
581+
else:
582+
return []
577583

578584
def rmdir(self, prefix=None):
579585
path = self.path

zarr/tests/test_storage.py

Lines changed: 118 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
from nose.tools import assert_raises, eq_ as eq, assert_is_none
1515

1616

17-
from zarr.storage import DirectoryStore, DictStore, ZipStore, init_array
18-
from zarr.meta import decode_metadata
17+
from zarr.storage import DirectoryStore, DictStore, ZipStore, init_array, \
18+
listdir, rmdir
19+
from zarr.meta import decode_metadata, encode_metadata
1920
from zarr.compat import text_type
2021

2122

@@ -41,20 +42,83 @@ def test_init_array():
4142

4243
def test_init_array_overwrite():
4344

44-
store = dict(shape=(2000,), chunks=(200,))
45+
store = dict()
46+
store['meta'] = encode_metadata(dict(shape=(2000,),
47+
chunks=(200,),
48+
dtype=np.dtype('u1'),
49+
compression='zlib',
50+
compression_opts=1,
51+
fill_value=0,
52+
order='F'))
4553

4654
# overwrite
47-
init_array(store, shape=1000, chunks=100, overwrite=True)
55+
init_array(store, shape=1000, chunks=100, dtype='i4', overwrite=True)
4856
assert 'meta' in store
4957
meta = decode_metadata(store['meta'])
5058
eq((1000,), meta['shape'])
5159
eq((100,), meta['chunks'])
60+
eq(np.dtype('i4'), meta['dtype'])
5261

5362
# don't overwrite
5463
with assert_raises(ValueError):
5564
init_array(store, shape=1000, chunks=100, overwrite=False)
5665

5766

67+
def test_init_array_prefix():
68+
69+
store = dict()
70+
init_array(store, shape=1000, chunks=100, prefix='foo/bar')
71+
72+
# check metadata
73+
assert 'foo/bar/meta' in store
74+
meta = decode_metadata(store['foo/bar/meta'])
75+
eq((1000,), meta['shape'])
76+
eq((100,), meta['chunks'])
77+
eq(np.dtype(None), meta['dtype'])
78+
eq('blosc', meta['compression'])
79+
assert 'compression_opts' in meta
80+
assert_is_none(meta['fill_value'])
81+
82+
# check attributes
83+
assert 'foo/bar/attrs' in store
84+
eq(dict(), json.loads(text_type(store['foo/bar/attrs'], 'ascii')))
85+
86+
87+
def test_init_array_overwrite_prefix():
88+
89+
store = dict()
90+
meta = dict(shape=(2000,),
91+
chunks=(200,),
92+
dtype=np.dtype('u1'),
93+
compression='zlib',
94+
compression_opts=1,
95+
fill_value=0,
96+
order='F')
97+
store['meta'] = encode_metadata(meta)
98+
store['foo/bar/meta'] = encode_metadata(meta)
99+
100+
# overwrite
101+
init_array(store, shape=1000, chunks=100, dtype='i4', overwrite=True,
102+
prefix='foo/bar')
103+
assert 'meta' in store
104+
assert 'foo/bar/meta' in store
105+
# should have been overwritten
106+
meta = decode_metadata(store['foo/bar/meta'])
107+
eq((1000,), meta['shape'])
108+
eq((100,), meta['chunks'])
109+
eq(np.dtype('i4'), meta['dtype'])
110+
# should have been left untouched
111+
meta = decode_metadata(store['meta'])
112+
eq((2000,), meta['shape'])
113+
eq((200,), meta['chunks'])
114+
eq(np.dtype('u1'), meta['dtype'])
115+
116+
# don't overwrite
117+
with assert_raises(ValueError):
118+
init_array(store, shape=1000, chunks=100, overwrite=False,
119+
prefix='foo/bar')
120+
121+
58122
class StoreTests(object):
59123

60124
def create_store(self, **kwargs):
@@ -102,14 +166,16 @@ def test_iterators(self):
102166
eq(set(), set(store.values()))
103167
eq(set(), set(store.items()))
104168

105-
store['foo'] = b'bar'
106-
store['baz'] = b'quux'
169+
store['a'] = b'xxx'
170+
store['b'] = b'yyy'
171+
store['c/d'] = b'zzz'
107172

108-
eq(2, len(store))
109-
eq(set(['foo', 'baz']), set(store))
110-
eq(set(['foo', 'baz']), set(store.keys()))
111-
eq(set([b'bar', b'quux']), set(store.values()))
112-
eq(set([('foo', b'bar'), ('baz', b'quux')]), set(store.items()))
173+
eq(3, len(store))
174+
eq({'a', 'b', 'c/d'}, set(store))
175+
eq({'a', 'b', 'c/d'}, set(store.keys()))
176+
eq({b'xxx', b'yyy', b'zzz'}, set(store.values()))
177+
eq({('a', b'xxx'), ('b', b'yyy'), ('c/d', b'zzz')},
178+
set(store.items()))
113179

114180
def test_nbytes_stored(self):
115181
store = self.create_store()
@@ -134,6 +200,41 @@ def test_pickle(self):
134200
if not callable(v):
135201
eq(v, getattr(store2, k))
136202

203+
def test_listdir_rmdir(self):
204+
# setup
205+
store = self.create_store()
206+
store['a'] = b'aaa'
207+
store['b'] = b'bbb'
208+
store['c/d'] = b'ddd'
209+
store['c/e/f'] = b'fff'
210+
211+
# test listdir
212+
eq({'a', 'b', 'c'}, set(listdir(store)))
213+
eq({'d', 'e'}, set(listdir(store, 'c')))
214+
eq({'f'}, set(listdir(store, 'c/e')))
215+
assert 'a' in store
216+
assert 'b' in store
217+
assert 'c' not in store
218+
assert 'c/d' in store
219+
assert 'c/e' not in store
220+
assert 'c/e/f' in store
221+
222+
# test rmdir
223+
try:
224+
rmdir(store, 'c/e')
225+
assert 'c/d' in store
226+
assert 'c/e/f' not in store
227+
eq({'d'}, set(listdir(store, 'c')))
228+
rmdir(store, 'c')
229+
assert 'c/d' not in store
230+
eq({'a', 'b'}, set(listdir(store)))
231+
rmdir(store)
232+
assert 'a' not in store
233+
assert 'b' not in store
234+
eq([], listdir(store))
235+
except NotImplementedError:
236+
pass
237+
137238

138239
class TestGenericStore(StoreTests, unittest.TestCase):
139240

@@ -147,11 +248,16 @@ def create_store(self):
147248
return DictStore()
148249

149250

251+
def rmtree_if_exists(path, rmtree=shutil.rmtree, isdir=os.path.isdir):
252+
if isdir(path):
253+
rmtree(path)
254+
255+
150256
class TestDirectoryStore(StoreTests, unittest.TestCase):
151257

152258
def create_store(self):
153259
path = tempfile.mkdtemp()
154-
atexit.register(shutil.rmtree, path)
260+
atexit.register(rmtree_if_exists, path)
155261
store = DirectoryStore(path)
156262
return store
157263

0 commit comments

Comments
 (0)