Skip to content

Commit

Permalink
Tests of ocfl.layout
Browse files Browse the repository at this point in the history
  • Loading branch information
zimeon committed Oct 14, 2024
1 parent da0c17c commit 575a118
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[
"This is not a JSON object",
"(it is an array, which is not legal for extension config.json)"
]
23 changes: 17 additions & 6 deletions ocfl/layout.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
"""Handle different storage layouts.
OCFL Storage roots require a deterministic mapping from the object identifiers
to the path within the storage root. This layout must be consistent across all
objects in the storage root. It often includes two components:
OCFL Storage Roots require a deterministic mapping from the object identifiers
to the path within the storage root. (It is not required that one can deduce the
object id from the path, as is the case with a hashed layout for example). The
layout must be consistent across all objects in the storage root. It often
includes two components:
1) A mapping from the identifier to a set of directory names to create a path
where objects are somewhatevenly distributed and will not end up with too many
Expand All @@ -12,7 +14,7 @@
2) A final directory name that may be a more complete representation of the
object id, by typically with at least some cleaning for safety. Some layouts
use just the remainder of a hash however. Obviously algorithms but avoid
use just the remainder of a hash however. Obviously algorithms must avoid
collision in this part within a given path.
See: https://ocfl.io/1.1/spec/#root-hierarchies
Expand Down Expand Up @@ -98,13 +100,19 @@ def read_layout_params(self, root_fs=None, params_required=False):
root_fs: the storage root fs object
params_required: if True then throw exception for params file not present
Returns None
Returns None, sets instance data in accord with the configuration using
the methods in self.PARAMS to parse for each key.
Raises LayoutException if the config can't be read or if required by
params_required but not present.
"""
config = None
print("Reading extension config file %s" % (self.config_file))
if root_fs.exists(self.config_file):
try:
with root_fs.open(self.config_file) as fh:
config = json.load(fh)
print("#### " + str(config))
except Exception as e:
raise LayoutException("Storage root extension config file %s exists but can't be read/parsed (%s)" % (self.config_file, str(e)))
if not isinstance(config, dict):
Expand All @@ -122,7 +130,7 @@ def check_and_set_layout_params(self, config, require_extension_name=True):
require_extension_name: boolean, True by default. If set False then
the extensionName paramater is not required
For each parameter that is recognizedm, the appropriate check and set
For each parameter that is recognized, the appropriate check and set
method in self.PARAMS is called. The methods set instance attributes.
"""
# Check the extensionName if required and/or specified
Expand All @@ -139,6 +147,9 @@ def write_layout_params(self, root_fs=None):
"""Write the config.json file with layout parameters if need for this layout.
Does nothing if there is no config.json content defined for this layout.
Raises a LayoutException if there is an error trying to write the config.json
file, including if one already exists.
"""
config = self.config
if config is None:
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ fs_s3fs >= 1.1.1
pairtree >= 0.8.1
# Required for extras
requests >= 2.20.0
mock >= 5.1.0
3 changes: 3 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ def run(self):
'fs_s3fs>=1.1.1',
'pairtree>=0.8.1'
],
tests_require=[
'mock>=5.1'
],
test_suite="tests",
cmdclass={
'coverage': Coverage
Expand Down
12 changes: 9 additions & 3 deletions tests/test_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def test_encodea_and_decode(self):
self.assertEqual(layout.decode('http%3a%2f%2Fa.b.c'), 'http://a.b.c')
self.assertRaises(LayoutException, layout.identifier_to_path, 'id')

def text_read_layout_params(self):
def test_read_layout_params(self):
"""Test read_layout_params."""
root_fs = open_fs("extra_fixtures/extension_configs")
layout = Layout()
Expand All @@ -54,14 +54,20 @@ def text_read_layout_params(self):
def parse_param(value):
layout.param = value
layout.PARAMS = {"param": parse_param}
layout.read_layout_params(root_fs=root_fs)
layout.read_layout_params(root_fs=root_fs, params_required=True)
self.assertEqual(layout.param, "yay!")
# No config file but none required
# Idoesn't do anything, nothing to check)
layout.NAME = "no_config"
layout.read_layout_params(root_fs=root_fs, params_required=False)
# Error cases
# No config file
layout.NAME = "no_config"
self.assertRaises(LayoutException, layout.read_layout_params, root_fs=root_fs)
self.assertRaises(LayoutException, layout.read_layout_params, root_fs=root_fs, params_required=True)
layout.NAME = "not_json"
self.assertRaises(LayoutException, layout.read_layout_params, root_fs=root_fs)
layout.NAME = "not_json_object"
self.assertRaises(LayoutException, layout.read_layout_params, root_fs=root_fs)

def test_check_and_set_layout_params(self):
"""Test check_and_set_layout_params."""
Expand Down

0 comments on commit 575a118

Please sign in to comment.