Skip to content

Commit

Permalink
add tests for sync/notsync, and make tests faster by generally not sy…
Browse files Browse the repository at this point in the history
…ncing
  • Loading branch information
JJ11teen committed May 16, 2021
1 parent b807ada commit 9e2ca86
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 40 deletions.
29 changes: 16 additions & 13 deletions tests/tests/2_singlecloudmapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@


class SingleCloudMappingTests:
def test_initialising_mapping(self, storage_provider: StorageProvider):
cm = CloudMapping(storageprovider=storage_provider)
def test_initialising_without_sync(self, storage_provider: StorageProvider):
CloudMapping(storageprovider=storage_provider, sync_initially=False)

def test_initialising_with_sync(self, storage_provider: StorageProvider):
CloudMapping(storageprovider=storage_provider, sync_initially=True)

def test_repr(self, storage_provider: StorageProvider):
cm = CloudMapping(storageprovider=storage_provider)
cm = CloudMapping(storageprovider=storage_provider, sync_initially=False)

_repr = str(cm)

Expand All @@ -25,7 +28,7 @@ def test_repr(self, storage_provider: StorageProvider):
assert "BucketName=" in _repr

def test_non_byte_values_error(self, storage_provider: StorageProvider, test_id: str):
cm = CloudMapping(storageprovider=storage_provider)
cm = CloudMapping(storageprovider=storage_provider, sync_initially=False)
key = test_id + "non-bytes-error"

with pytest.raises(ValueError, match="must be bytes like"):
Expand All @@ -40,7 +43,7 @@ def test_non_byte_values_error(self, storage_provider: StorageProvider, test_id:
cm[key] = {"or": "something more", "elaborate": True}

def test_no_key_errors(self, storage_provider: StorageProvider, test_id: str):
cm = CloudMapping(storageprovider=storage_provider)
cm = CloudMapping(storageprovider=storage_provider, sync_initially=False)
key = test_id + "/no-key-errors-test"

with pytest.raises(KeyError):
Expand All @@ -50,7 +53,7 @@ def test_no_key_errors(self, storage_provider: StorageProvider, test_id: str):
assert key not in cm

def test_basic_setting_and_getting(self, storage_provider: StorageProvider, test_id: str):
cm = CloudMapping(storageprovider=storage_provider)
cm = CloudMapping(storageprovider=storage_provider, sync_initially=False)

cm[test_id + "-key-A"] = b"100"
cm[test_id + "-key-a"] = b"uncapitalised"
Expand All @@ -61,7 +64,7 @@ def test_basic_setting_and_getting(self, storage_provider: StorageProvider, test
assert cm[test_id + "-key-3"] == b"three"

def test_complex_keys(self, storage_provider: StorageProvider, test_id: str):
cm = CloudMapping(storageprovider=storage_provider)
cm = CloudMapping(storageprovider=storage_provider, sync_initially=False)

cm[test_id + "/here/are/some/sub/dirs"] = b"0"
cm[test_id + "/howaboutsome ˆøœ¨åß∆∫ı˜ unusual !@#$%^* characters"] = b"1"
Expand All @@ -70,7 +73,7 @@ def test_complex_keys(self, storage_provider: StorageProvider, test_id: str):
assert cm[test_id + "/howaboutsome ˆøœ¨åß∆∫ı˜ unusual !@#$%^* characters"] == b"1"

def test_deleting_keys(self, storage_provider: StorageProvider, test_id: str):
cm = CloudMapping(storageprovider=storage_provider)
cm = CloudMapping(storageprovider=storage_provider, sync_initially=False)
key = test_id + "/delete-test"

cm[key] = b"0"
Expand All @@ -79,7 +82,7 @@ def test_deleting_keys(self, storage_provider: StorageProvider, test_id: str):
cm[key]

def test_contains(self, storage_provider: StorageProvider, test_id: str):
cm = CloudMapping(storageprovider=storage_provider)
cm = CloudMapping(storageprovider=storage_provider, sync_initially=False)
key = test_id + "/contains-test"

assert key not in cm
Expand All @@ -88,16 +91,16 @@ def test_contains(self, storage_provider: StorageProvider, test_id: str):
assert key in cm

def test_length(self, storage_provider: StorageProvider, test_id: str):
cm = CloudMapping(storageprovider=storage_provider)
cm = CloudMapping(storageprovider=storage_provider, sync_initially=False)
key_1 = test_id + "/length-test/1"
key_2 = test_id + "/length-test/2"
key_3 = test_id + "/length-test/3"

starting_length = len(cm)
assert len(cm) == 0

cm[key_1] = b"a"
cm[key_2] = b"b"
assert len(cm) == starting_length + 2
assert len(cm) == 2

cm[key_3] = b"c"
assert len(cm) == starting_length + 3
assert len(cm) == 3
91 changes: 64 additions & 27 deletions tests/tests/3_multiplecloudmapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,34 @@

class ConcurrentCloudMappingTests:
def test_no_ownership_error(self, storage_provider: StorageProvider, test_id: str):
sess_1 = CloudMapping(storageprovider=storage_provider)
sess_2 = CloudMapping(storageprovider=storage_provider)
sess_1 = CloudMapping(storageprovider=storage_provider, sync_initially=False)
sess_2 = CloudMapping(storageprovider=storage_provider, sync_initially=False)
key = test_id + "/concurrent/no-ownership-test"

# Session 1 takes ownership of key:
sess_1[key] = b"session_1"
# Session 2 is hasn't seen the key before, so KeySyncError when setting:
# Session 2 doesn't know the key exists, so KeyError on get and delete, and KeySyncError on set:
with pytest.raises(KeyError):
sess_2[key]
with pytest.raises(KeySyncError):
sess_2[key] = b"session_2"
with pytest.raises(KeyError):
del sess_2[key]

# Session 3 is created after the key is created
sess_3 = CloudMapping(storageprovider=storage_provider)
# Session 1 updates the key:
sess_1[key] = b"session_1"
# Session 3 is knows the key exists, so KeySyncError on get, set and delete:
with pytest.raises(KeySyncError):
sess_3[key]
with pytest.raises(KeySyncError):
sess_3[key] = b"session_2"
with pytest.raises(KeySyncError):
del sess_3[key]

def test_manual_change_error(self, storage_provider: StorageProvider, test_id: str):
cm = CloudMapping(storageprovider=storage_provider)
cm = CloudMapping(storageprovider=storage_provider, sync_initially=False)
key = test_id + "/concurrent/manual-change-test"

# Session 1 takes ownership of key:
Expand All @@ -34,34 +50,55 @@ def test_manual_change_error(self, storage_provider: StorageProvider, test_id: s
del cm[key]

def test_resync_all(self, storage_provider: StorageProvider, test_id: str):
sess_1 = CloudMapping(storageprovider=storage_provider)
sess_2 = CloudMapping(storageprovider=storage_provider)
key = test_id + "/concurrent/resync-all-test"
sess_1 = CloudMapping(storageprovider=storage_provider, sync_initially=False)
key_1 = test_id + "/concurrent/resync-all-test-1"
key_2 = test_id + "/concurrent/resync-all-test-2"
key_3 = test_id + "/concurrent/resync-all-test-3"

# Session 1 takes ownership of key
sess_1[key] = b"session_1"
# The blob is changed by some manual means:
storage_provider.upload_data(key, sess_1.etags[key], b"other")
# If sessions syncs all keys, they can now both read:
# Session 1 takes ownership of keys
sess_1[key_1] = b"session_1"
sess_1[key_2] = b"session_1"
sess_1[key_3] = b"session_1"
# Session 1 only knows of these 3 keys:
assert len(sess_1) == 3
# Key 1 is changed by some manual means:
storage_provider.upload_data(key_1, sess_1.etags[key_1], b"other")
# Session 2 is created after the data changed:
sess_2 = CloudMapping(storageprovider=storage_provider)
# Session 2 knows of all the keys in the cloud:
assert len(sess_2) >= 3
# Session 2 can read the keys
sess_2[key_1]
sess_2[key_2]
sess_2[key_3]
# If Session 1 syncs all keys, it can now read them again:
sess_1.sync_with_cloud()
sess_2.sync_with_cloud()
sess_1[key]
sess_2[key]
sess_1[key_1]
sess_1[key_2]
sess_1[key_3]

def test_resync_specific(self, storage_provider: StorageProvider, test_id: str):
sess_1 = CloudMapping(storageprovider=storage_provider)
sess_2 = CloudMapping(storageprovider=storage_provider)
key = test_id + "/concurrent/resync-specific-test"
sess_1 = CloudMapping(storageprovider=storage_provider, sync_initially=False)
sess_2 = CloudMapping(storageprovider=storage_provider, sync_initially=False)
key_1 = test_id + "/concurrent/resync-specific-test-1"
key_2 = test_id + "/concurrent/resync-specific-test-2"
key_3 = test_id + "/concurrent/resync-specific-test-3"

# Session 1 takes ownership of key
sess_1[key] = b"session_1"
# The blob is changed by some manual means:
storage_provider.upload_data(key, sess_1.etags[key], b"other")
# If sessions syncs all keys, they can now both read:
sess_1.sync_with_cloud(key)
sess_2.sync_with_cloud(key)
sess_1[key]
sess_2[key]
# Session 1 takes ownership of keys
sess_1[key_1] = b"session_1"
sess_1[key_2] = b"session_1"
sess_1[key_3] = b"session_1"
# Only session 1 knows of these 3 keys:
assert len(sess_1) == 3
assert len(sess_2) == 0
# Key 1 is changed by some manual means:
storage_provider.upload_data(key_1, sess_1.etags[key_1], b"other")
# Session 2 syncs key 1 only:
sess_2.sync_with_cloud(key_1)
# Session 2 can now read key 1
sess_2[key_1]
# Session 2 only knows this one key
assert len(sess_2) == 1

def test_resync_pass_ownership(self, storage_provider: StorageProvider, test_id: str):
sess_1 = CloudMapping(storageprovider=storage_provider)
Expand Down

0 comments on commit 9e2ca86

Please sign in to comment.