Skip to content

Commit b6b9b63

Browse files
committed
work on storage test coverage
1 parent f5a52f6 commit b6b9b63

File tree

2 files changed

+69
-6
lines changed

2 files changed

+69
-6
lines changed

zarr/storage.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -274,11 +274,9 @@ def init_group(store, overwrite=False, path=None):
274274
def ensure_bytes(s):
275275
if isinstance(s, binary_type):
276276
return s
277-
if hasattr(s, 'encode'):
278-
return s.encode()
279277
if hasattr(s, 'tobytes'):
280278
return s.tobytes()
281-
if PY2 and hasattr(s, 'tostring'):
279+
if PY2 and hasattr(s, 'tostring'): # pragma: no cover
282280
return s.tostring()
283281
return memoryview(s).tobytes()
284282

@@ -295,7 +293,7 @@ def _dict_store_keys(d, prefix='', cls=dict):
295293

296294
def buffersize(v):
297295
from array import array as _stdlib_array
298-
if PY2 and isinstance(v, _stdlib_array):
296+
if PY2 and isinstance(v, _stdlib_array): # pragma: no cover
299297
# special case array.array because does not support buffer
300298
# interface in PY2
301299
return v.buffer_info()[1] * v.itemsize
@@ -533,8 +531,13 @@ def __setitem__(self, key, value):
533531

534532
# ensure containing directory exists
535533
dir_path, file_name = os.path.split(file_path)
534+
if os.path.isfile(dir_path):
535+
raise KeyError(key)
536536
if not os.path.exists(dir_path):
537-
os.makedirs(dir_path)
537+
try:
538+
os.makedirs(dir_path)
539+
except NotADirectoryError:
540+
raise KeyError(key)
538541

539542
# write to temporary file
540543
with tempfile.NamedTemporaryFile(mode='wb', delete=False,

zarr/tests/test_storage.py

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,22 @@ def test_hierarchy(self):
146146
assert 'c/' not in store
147147
assert 'c/e' not in store
148148
assert 'c/e/' not in store
149+
assert 'c/d/x' not in store
150+
151+
# check __getitem__
152+
with assert_raises(KeyError):
153+
store['c']
154+
with assert_raises(KeyError):
155+
store['c/e']
156+
with assert_raises(KeyError):
157+
store['c/d/x']
149158

150159
# test listdir (optional)
151160
if hasattr(store, 'listdir'):
152161
eq({'a', 'b', 'c'}, set(store.listdir()))
153162
eq({'d', 'e'}, set(store.listdir('c')))
154163
eq({'f', 'g'}, set(store.listdir('c/e')))
164+
# TODO further listdir tests
155165

156166
# test getsize (optional)
157167
if hasattr(store, 'getsize'):
@@ -163,6 +173,7 @@ def test_hierarchy(self):
163173
eq(6, store.getsize('c/e'))
164174
eq(3, store.getsize('c/e/f'))
165175
eq(3, store.getsize('c/e/g'))
176+
# TODO further getsize tests
166177

167178
# test rmdir (optional)
168179
if hasattr(store, 'rmdir'):
@@ -339,7 +350,7 @@ def test_init_group_overwrite(self):
339350
order='F')
340351
)
341352

342-
# don't overwrite (default)
353+
# don't overwrite array (default)
343354
with assert_raises(ValueError):
344355
init_group(store)
345356

@@ -354,6 +365,10 @@ def test_init_group_overwrite(self):
354365
meta = decode_group_metadata(store[group_meta_key])
355366
eq(ZARR_FORMAT, meta['zarr_format'])
356367

368+
# don't overwrite group
369+
with assert_raises(ValueError):
370+
init_group(store)
371+
357372
def test_init_group_overwrite_path(self):
358373
# setup
359374
path = 'foo/bar'
@@ -398,11 +413,52 @@ def create_store(self):
398413
return dict()
399414

400415

416+
def setdel_hierarchy_checks(store):
417+
# these tests are for stores that are aware of hierarchy levels; this
418+
# behaviour is not stricly required by Zarr but these tests are included
419+
# to define behaviour of DictStore and DirectoryStore classes
420+
421+
# check __setitem__ and __delitem__ blocked by leaf
422+
423+
store['a/b'] = b'aaa'
424+
with assert_raises(KeyError):
425+
store['a/b/c'] = b'xxx'
426+
with assert_raises(KeyError):
427+
del store['a/b/c']
428+
429+
store['d'] = b'ddd'
430+
with assert_raises(KeyError):
431+
store['d/e/f'] = b'xxx'
432+
with assert_raises(KeyError):
433+
del store['d/e/f']
434+
435+
# test __setitem__ overwrite level
436+
store['x/y/z'] = b'xxx'
437+
store['x/y'] = b'yyy'
438+
eq(b'yyy', store['x/y'])
439+
assert 'x/y/z' not in store
440+
store['x'] = b'zzz'
441+
eq(b'zzz', store['x'])
442+
assert 'x/y' not in store
443+
444+
# test __delitem__ overwrite level
445+
store['r/s/t'] = b'xxx'
446+
del store['r/s']
447+
assert 'r/s/t' not in store
448+
store['r/s'] = b'xxx'
449+
del store['r']
450+
assert 'r/s' not in store
451+
452+
401453
class TestDictStore(StoreTests, unittest.TestCase):
402454

403455
def create_store(self):
404456
return DictStore()
405457

458+
def test_setdel(self):
459+
store = self.create_store()
460+
setdel_hierarchy_checks(store)
461+
406462

407463
def rmtree_if_exists(path, rmtree=shutil.rmtree, isdir=os.path.isdir):
408464
if isdir(path):
@@ -446,6 +502,10 @@ def test_pickle_ext(self):
446502
store2['xxx'] = b'yyy'
447503
eq(b'yyy', store['xxx'])
448504

505+
def test_setdel(self):
506+
store = self.create_store()
507+
setdel_hierarchy_checks(store)
508+
449509

450510
class TestZipStore(StoreTests, unittest.TestCase):
451511

0 commit comments

Comments
 (0)