def test_transient_write_error(self): initial_lines = [ "key 1=value 1", "key 2=value 2", "_SHA_CKSUM=ad4e8ffdd89dde809bf1ed700838b590b08a3826", ] b = MemoryBackend(lines=initial_lines) pd = persistent.PersistentDict(b) # Simulate transient error on storage. b.fail_write = True with pytest.raises(WriteError): pd["key 2"] = "new value 2" # Nothing should change. assert pd["key 1"] == "value 1" assert pd["key 2"] == "value 2" assert b.lines == initial_lines assert b.version == 0 # Restore storage, writing should work now. b.fail_write = False pd["key 2"] = "new value 2" # Both dict and storage should change. assert pd["key 1"] == "value 1" assert pd["key 2"] == "new value 2" assert b.lines == [ "key 1=value 1", "key 2=new value 2", "_SHA_CKSUM=3c313d2c72ab17086f75350f5cf71d9a42655419", ] assert b.version == 1
def test_persistent_dict_transient_read_error(self): initial_lines = [ "key 1=value 1", "key 2=value 2", "_SHA_CKSUM=ad4e8ffdd89dde809bf1ed700838b590b08a3826", ] w = MemoryWriter(lines=initial_lines) pd = persistent.PersistentDict(w) # Simulate transient error on storage. w.fail_read = True with pytest.raises(ReadError): pd["key 2"] = "new value 2" # Nothing should be written since the transaction was aborted. assert w.lines == initial_lines assert w.version == 0 # Restore storage, reading and writing should work now. w.fail_read = False pd["key 2"] = "new value 2" # Both dict and storage should change. assert pd["key 1"] == "value 1" assert pd["key 2"] == "new value 2" assert w.lines == [ "key 1=value 1", "key 2=new value 2", "_SHA_CKSUM=3c313d2c72ab17086f75350f5cf71d9a42655419", ] assert w.version == 1
def test_persistent_dict_get(): w = MemoryWriter() pd = persistent.PersistentDict(w) assert pd.get("key") is None pd["key"] = "value" assert pd.get("key") == "value"
def test_write_error(self): initial_lines = [ "key 1=value 1", "key 2=value 2", "_SHA_CKSUM=ad4e8ffdd89dde809bf1ed700838b590b08a3826", ] b = MemoryBackend(lines=initial_lines, fail_write=True) pd = persistent.PersistentDict(b) # All access to persistent dict should fail the transaction when trying # to modify storage, and rollback to previous state. with pytest.raises(WriteError): pd["key 1"] = "new value 1" assert pd["key 1"] == "value 1" assert pd["key 2"] == "value 2" with pytest.raises(WriteError): del pd["key 1"] assert pd["key 1"] == "value 1" assert pd["key 2"] == "value 2" assert b.lines == initial_lines assert b.version == 0
def test_persistent_dict_storage(): w = MemoryWriter() pd = persistent.PersistentDict(w) # Setting value flush dict to writer. pd["key 1"] = "value 1" assert w.lines == [ "key 1=value 1", "_SHA_CKSUM=fce57dc690209dc4109d993de9c11d72c8ffd4b6", ] assert w.version == 1 # Setting another value flush entire dict again. pd["key 2"] = "value 2" assert w.lines == [ "key 1=value 1", "key 2=value 2", "_SHA_CKSUM=ad4e8ffdd89dde809bf1ed700838b590b08a3826", ] assert w.version == 2 # Updating flush entire dict again. pd.update({"key 3": "value 3", "key 2": "new value 2"}) assert w.lines == [ "key 1=value 1", "key 2=new value 2", "key 3=value 3", "_SHA_CKSUM=96cff78771397697ce609321364aabc818299be8", ] assert w.version == 3
def test_get(self): b = MemoryBackend() pd = persistent.PersistentDict(b) assert pd.get("key") is None pd["key"] = "value" assert pd.get("key") == "value"
def test_contains(self): b = MemoryBackend() pd = persistent.PersistentDict(b) assert "key" not in pd pd["key"] = "value" assert "key" in pd
def test_invalidate(self): b = MemoryBackend([ "int_str=1", "str_str=2", "_SHA_CKSUM=fd58b7962408a4956bd694d617a1201306b363c2", ]) pd = persistent.PersistentDict(b) dv = persistent.DictValidator(pd, self.VALID_FIELDS) # Trigger reading from storage. assert dv["int_str"] == 1 # Storage contents changed from another host... b.lines = [ "int_str=1", "str_str=2", "func_func=3", "_SHA_CKSUM=5e5ad85614c502d9a2f44d0473b9384ac49eedff", ] # Return value read before. assert dv["str_str"] == "2" assert "func_func" not in dv # Invalidating the dict will cause the next get to read again from # storage. dv.invalidate() assert dv["int_str"] == 1 assert dv["str_str"] == "2" assert dv["func_func"] == "3"
def test_persistent_dict_invalidate(): w = MemoryWriter([ "key 1=value 1", "key 2=value 2", "_SHA_CKSUM=ad4e8ffdd89dde809bf1ed700838b590b08a3826", ]) pd = persistent.PersistentDict(w) # Trigger reading from storage. assert pd["key 1"] == "value 1" # Storage contents changed from another host... w.lines = [ "key 1=value 1", "key 2=new value 2", "key 3=value 3", "_SHA_CKSUM=96cff78771397697ce609321364aabc818299be8", ] # Return value read before. assert pd["key 2"] == "value 2" assert "key 3" not in pd # Invalidating the dict will cause the next get to read again from storage. pd.invalidate() assert pd["key 1"] == "value 1" assert pd["key 2"] == "new value 2" assert pd["key 3"] == "value 3"
def test_persistent_dict_contains(): w = MemoryWriter() pd = persistent.PersistentDict(w) assert "key" not in pd pd["key"] = "value" assert "key" in pd
def test_set(self): pd = persistent.PersistentDict(MemoryBackend()) dv = persistent.DictValidator(pd, self.VALID_FIELDS) dv["str_str"] = "value 1" # test item was created and underlying dict has same value assert pd["str_str"] == "value 1" assert dv["str_str"] == "value 1"
def test_contains(self): pd = persistent.PersistentDict(MemoryBackend()) dv = persistent.DictValidator(pd, self.VALID_FIELDS) dv["str_str"] = "value 1" # test contains operation assert "str_str" in dv assert "int_str" not in dv assert "not-exists" not in dv
def test_get_good_checksum(self): b = MemoryBackend([ "key 1=value 1", "key 2=value 2", "_SHA_CKSUM=ad4e8ffdd89dde809bf1ed700838b590b08a3826", ]) pd = persistent.PersistentDict(b) assert pd["key 1"] == "value 1" assert pd["key 2"] == "value 2"
def test_persistent_dict_get_good_checksum(): w = MemoryWriter([ "key 1=value 1", "key 2=value 2", "_SHA_CKSUM=ad4e8ffdd89dde809bf1ed700838b590b08a3826", ]) pd = persistent.PersistentDict(w) assert pd["key 1"] == "value 1" assert pd["key 2"] == "value 2"
def test_clear(self): pd = persistent.PersistentDict(MemoryBackend()) dv = persistent.DictValidator(pd, self.VALID_FIELDS) dv["int_str"] = 1 dv["str_str"] = "2" dv.clear() assert not pd assert not dv
def test_key_iteration(self): pd = persistent.PersistentDict(MemoryBackend()) dv = persistent.DictValidator(pd, self.VALID_FIELDS) dv["int_str"] = 1 dv["str_str"] = "2" dv["func_func"] = "3" expected = {"int_str", "str_str", "func_func"} assert set(dv.iterkeys()) == expected assert set(dv) == expected assert set(dv.keys()) == expected
def test_persistent_dict_len(): w = MemoryWriter() pd = persistent.PersistentDict(w) assert len(pd) == 0 pd["key 1"] = "value 1" assert len(pd) == 1 pd["key 2"] = "value 2" assert len(pd) == 2
def test_len(self): b = MemoryBackend() pd = persistent.PersistentDict(b) assert len(pd) == 0 pd["key 1"] = "value 1" assert len(pd) == 1 pd["key 2"] = "value 2" assert len(pd) == 2
def test_transaction_nested(self): b = MemoryBackend() pd = persistent.PersistentDict(b) # Transaction flushes lines to storage once. with pd.transaction(): pd["key 1"] = "value 1" with pd.transaction(): pd["key 2"] = "value 2" assert pd["key 1"] == "value 1" assert pd["key 2"] == "value 2" assert b.version == 1
def test_persistent_transaction(): w = MemoryWriter() pd = persistent.PersistentDict(w) # Transaction flushes lines to storage once. with pd.transaction(): pd["key 1"] = "value 1" pd["key 2"] = "value 2" assert pd["key 1"] == "value 1" assert pd["key 2"] == "value 2" assert w.version == 1
def test_persistent_dict_transaction_user_error(): w = MemoryWriter() pd = persistent.PersistentDict(w) # User error during the transaction should abort the entire transaction, # otherwise we may leave partial changes on storage. with pytest.raises(UserError): with pd.transaction(): pd["key 1"] = 1 raise UserError # Nothing should be written since the transaction was aborted. assert w.lines == []
def test_persistent_transaction(self): b = MemoryBackend() pd = persistent.PersistentDict(b) dv = persistent.DictValidator(pd, self.VALID_FIELDS) # Transaction flushes lines to storage once. with dv.transaction(): dv["str_str"] = "value 1" dv["func_func"] = "value 2" assert dv["str_str"] == "value 1" assert dv["func_func"] == "value 2" assert b.version == 1
def test_get_no_checksum(self): initial_lines = [ "key 1=value 1", "key 2=value 2", ] b = MemoryBackend(initial_lines) pd = persistent.PersistentDict(b) assert pd["key 1"] == "value 1" assert pd["key 2"] == "value 2" # Storage not modified by reading. assert b.lines == initial_lines
def test_persistent_dict_nested_transaction_write_error(): w = MemoryWriter(fail=True) pd = persistent.PersistentDict(w) # Write error will abort the entire transaction. with pytest.raises(WriterError): with pd.transaction(): pd["key 1"] = 1 with pd.transaction(): pd["key 2"] = 2 # Nothing should be written as we use failing writer. assert w.lines == []
def testFailedNestedTransaction(self): pd = persistentDict.PersistentDict(DummyFailWriter()) try: with pd.transaction(): with pd.transaction(): raise SpecialError("Take the Kama Sutra. How many people " "died from the Kama Sutra, as opposed " "to the Bible? Who wins?") # (C) Frank Zappa except RuntimeError: return self.fail("Exception was not thrown")
def test_persistent_dict_get_no_checksum(): initial_lines = [ "key 1=value 1", "key 2=value 2", ] w = MemoryWriter(initial_lines) pd = persistent.PersistentDict(w) assert pd["key 1"] == "value 1" assert pd["key 2"] == "value 2" # Storage not modified by reading. assert w.lines == initial_lines
def test_length(self): pd = persistent.PersistentDict(MemoryBackend()) dv = persistent.DictValidator(pd, self.VALID_FIELDS) assert len(dv) == 0 dv["str_str"] = "value 1" assert len(pd) == 1 assert len(dv) == 1 dv["func_func"] = "value 2" assert len(pd) == 2 assert len(dv) == 2
def test_copy_with_invalid_items(self): pd = persistent.PersistentDict(MemoryBackend()) dv = persistent.DictValidator(pd, self.VALID_FIELDS) dv_expected = {"int_str": 1, "str_str": "2", "func_func": "3"} dv.update(dv_expected) dv._dict["invalid_key"] = "invalid value" dv_expected.update({"invalid_key": "invalid value"}) dv_copy = dv.copy() # Expected behaviour is that even invalid items are still kept in the # dict. This is used e.g. in spbackends.py assert dv_copy == dv_expected
def test_persistent_dict_get_bad_checksum(): initial_lines = [ "key 1=value 1", "key 2=value 2", "_SHA_CKSUM=badchecksum", ] w = MemoryWriter(initial_lines) pd = persistent.PersistentDict(w) with pytest.raises(se.MetaDataSealIsBroken): pd["key 1"] # Storage not modified by reading. assert w.lines == initial_lines
def test_read(self): pd = persistent.PersistentDict(MemoryBackend()) dv = persistent.DictValidator(pd, self.VALID_FIELDS) dv["str_str"] = "value 1" # test item read assert dv.get("str_str") == "value 1" assert dv["str_str"] == "value 1" # test read item which doesn't exists assert dv.get("int_str") is None # test read item which is not allowed with pytest.raises(KeyError): dv.get("not-exists")