Skip to content

Commit 8d7a7d6

Browse files
kushalbakshiclaude
andcommitted
test: add unit tests for StorageAdapter plugin system
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent eaa0090 commit 8d7a7d6

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed

tests/unit/test_storage_adapter.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
"""Tests for the StorageAdapter plugin system."""
2+
3+
import pytest
4+
5+
from datajoint.errors import DataJointError
6+
from datajoint.storage_adapter import (
7+
StorageAdapter,
8+
_adapter_registry,
9+
_COMMON_STORE_KEYS,
10+
get_storage_adapter,
11+
)
12+
13+
14+
class _DummyAdapter(StorageAdapter):
15+
"""Test adapter for registry tests."""
16+
17+
protocol = "dummy"
18+
required_keys = ("protocol", "endpoint")
19+
allowed_keys = ("protocol", "endpoint", "token")
20+
21+
def create_filesystem(self, spec):
22+
return None # Not testing actual filesystem creation
23+
24+
25+
class TestStorageAdapterRegistry:
26+
def setup_method(self):
27+
_adapter_registry["dummy"] = _DummyAdapter()
28+
29+
def teardown_method(self):
30+
_adapter_registry.pop("dummy", None)
31+
32+
def test_get_registered_adapter(self):
33+
adapter = get_storage_adapter("dummy")
34+
assert adapter is not None
35+
assert adapter.protocol == "dummy"
36+
37+
def test_get_unknown_adapter_returns_none(self):
38+
adapter = get_storage_adapter("nonexistent_protocol_xyz")
39+
assert adapter is None
40+
41+
def test_adapter_protocol_attribute(self):
42+
adapter = get_storage_adapter("dummy")
43+
assert isinstance(adapter.protocol, str)
44+
assert adapter.protocol == "dummy"
45+
46+
47+
class TestStorageAdapterValidation:
48+
def setup_method(self):
49+
self.adapter = _DummyAdapter()
50+
51+
def test_valid_spec_passes(self):
52+
spec = {"protocol": "dummy", "endpoint": "https://example.com"}
53+
self.adapter.validate_spec(spec)
54+
55+
def test_missing_required_key_raises(self):
56+
spec = {"protocol": "dummy"}
57+
with pytest.raises(DataJointError, match="missing.*endpoint"):
58+
self.adapter.validate_spec(spec)
59+
60+
def test_invalid_key_raises(self):
61+
spec = {"protocol": "dummy", "endpoint": "https://example.com", "bogus": "val"}
62+
with pytest.raises(DataJointError, match="Invalid.*bogus"):
63+
self.adapter.validate_spec(spec)
64+
65+
def test_common_store_keys_always_allowed(self):
66+
spec = {
67+
"protocol": "dummy",
68+
"endpoint": "https://example.com",
69+
"hash_prefix": "_hash",
70+
"subfolding": None,
71+
"schema_prefix": "_schema",
72+
}
73+
self.adapter.validate_spec(spec)
74+
75+
def test_common_store_keys_content(self):
76+
assert "hash_prefix" in _COMMON_STORE_KEYS
77+
assert "schema_prefix" in _COMMON_STORE_KEYS
78+
assert "subfolding" in _COMMON_STORE_KEYS
79+
assert "protocol" in _COMMON_STORE_KEYS
80+
assert "location" in _COMMON_STORE_KEYS
81+
82+
83+
class TestStorageAdapterFullPath:
84+
def setup_method(self):
85+
self.adapter = _DummyAdapter()
86+
87+
def test_full_path_with_location(self):
88+
spec = {"location": "data/blobs"}
89+
assert self.adapter.full_path(spec, "schema/ab/cd/hash") == "data/blobs/schema/ab/cd/hash"
90+
91+
def test_full_path_empty_location(self):
92+
spec = {"location": ""}
93+
assert self.adapter.full_path(spec, "schema/ab/cd/hash") == "schema/ab/cd/hash"
94+
95+
def test_full_path_no_location_key(self):
96+
spec = {}
97+
assert self.adapter.full_path(spec, "schema/ab/cd/hash") == "schema/ab/cd/hash"
98+
99+
100+
class TestStorageAdapterGetUrl:
101+
def setup_method(self):
102+
self.adapter = _DummyAdapter()
103+
104+
def test_default_url_format(self):
105+
assert self.adapter.get_url({}, "data/file.dat") == "dummy://data/file.dat"

0 commit comments

Comments
 (0)