Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Package up base db and atomic db test suites into re-usable classes
- Loading branch information
1 parent
d2ccc1e
commit 5c2bb36
Showing
10 changed files
with
298 additions
and
332 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
import pytest | ||
|
||
from eth_utils import ValidationError | ||
|
||
from eth.abc import AtomicDatabaseAPI | ||
|
||
|
||
class AtomicDatabaseBatchAPITestSuite: | ||
def test_atomic_batch_set_and_get(self, atomic_db: AtomicDatabaseAPI) -> None: | ||
with atomic_db.atomic_batch() as batch: | ||
batch.set(b'1', b'2') | ||
assert batch.get(b'1') == b'2' | ||
|
||
assert atomic_db.get(b'1') == b'2' | ||
|
||
def test_atomic_db_cannot_recursively_batch(self, atomic_db: AtomicDatabaseAPI) -> None: | ||
with atomic_db.atomic_batch() as batch: | ||
assert not hasattr(batch, 'atomic_batch') | ||
|
||
def test_atomic_db_with_set_and_delete_batch(self, atomic_db: AtomicDatabaseAPI) -> None: | ||
atomic_db[b'key-1'] = b'origin' | ||
|
||
with atomic_db.atomic_batch() as batch: | ||
batch.delete(b'key-1') | ||
|
||
assert b'key-1' not in batch | ||
with pytest.raises(KeyError): | ||
assert batch[b'key-1'] | ||
|
||
with pytest.raises(KeyError): | ||
atomic_db[b'key-1'] | ||
|
||
def test_atomic_db_unbatched_sets_are_immediate(self, atomic_db: AtomicDatabaseAPI) -> None: | ||
atomic_db[b'1'] = b'A' | ||
|
||
with atomic_db.atomic_batch() as batch: | ||
# Unbatched changes are immediate, and show up in batch reads | ||
atomic_db[b'1'] = b'B' | ||
assert batch[b'1'] == b'B' | ||
|
||
batch[b'1'] = b'C1' | ||
|
||
# It doesn't matter what changes happen underlying, all reads now | ||
# show the write applied to the batch db handle | ||
atomic_db[b'1'] = b'C2' | ||
assert batch[b'1'] == b'C1' | ||
|
||
# the batch write should overwrite any intermediate changes | ||
assert atomic_db[b'1'] == b'C1' | ||
|
||
def test_atomic_db_unbatched_deletes_are_immediate(self, atomic_db: AtomicDatabaseAPI) -> None: | ||
atomic_db[b'1'] = b'A' | ||
|
||
with atomic_db.atomic_batch() as batch: | ||
assert b'1' in batch | ||
|
||
# Unbatched changes are immediate, and show up in batch reads | ||
del atomic_db[b'1'] | ||
|
||
assert b'1' not in batch | ||
|
||
batch[b'1'] = b'C1' | ||
|
||
# It doesn't matter what changes happen underlying, all reads now | ||
# show the write applied to the batch db handle | ||
atomic_db[b'1'] = b'C2' | ||
assert batch[b'1'] == b'C1' | ||
|
||
# the batch write should overwrite any intermediate changes | ||
assert atomic_db[b'1'] == b'C1' | ||
|
||
def test_atomic_db_cannot_use_batch_after_context(self, atomic_db: AtomicDatabaseAPI) -> None: | ||
atomic_db[b'1'] = b'A' | ||
|
||
with atomic_db.atomic_batch() as batch: | ||
batch[b'1'] = b'B' | ||
|
||
# set | ||
with pytest.raises(ValidationError): | ||
batch[b'1'] = b'C' | ||
|
||
with pytest.raises(ValidationError): | ||
batch.set(b'1', b'C') | ||
|
||
# get | ||
with pytest.raises(ValidationError): | ||
batch[b'1'] | ||
|
||
with pytest.raises(ValidationError): | ||
batch.get(b'1') | ||
|
||
# exists | ||
with pytest.raises(ValidationError): | ||
b'1' in batch | ||
|
||
with pytest.raises(ValidationError): | ||
batch.exists(b'1') | ||
|
||
# delete | ||
with pytest.raises(ValidationError): | ||
del batch[b'1'] | ||
|
||
with pytest.raises(ValidationError): | ||
batch.delete(b'1') | ||
|
||
# none of the invalid changes above should change the original db | ||
assert atomic_db[b'1'] == b'B' | ||
|
||
def test_atomic_db_with_reverted_delete_batch(self, atomic_db: AtomicDatabaseAPI) -> None: | ||
class CustomException(Exception): | ||
pass | ||
|
||
atomic_db[b'key-1'] = b'origin' | ||
|
||
with pytest.raises(CustomException): | ||
with atomic_db.atomic_batch() as batch: | ||
batch.delete(b'key-1') | ||
|
||
assert b'key-1' not in batch | ||
with pytest.raises(KeyError): | ||
assert batch[b'key-1'] | ||
|
||
raise CustomException('pretend something went wrong') | ||
|
||
assert atomic_db[b'key-1'] == b'origin' | ||
|
||
def test_atomic_db_temporary_state_dropped_across_batches(self, | ||
atomic_db: AtomicDatabaseAPI) -> None: | ||
class CustomException(Exception): | ||
pass | ||
|
||
atomic_db[b'key-1'] = b'origin' | ||
|
||
with pytest.raises(CustomException): | ||
with atomic_db.atomic_batch() as batch: | ||
batch.delete(b'key-1') | ||
batch.set(b'key-2', b'val-2') | ||
raise CustomException('pretend something went wrong') | ||
|
||
with atomic_db.atomic_batch() as batch: | ||
assert batch[b'key-1'] == b'origin' | ||
assert b'key-2' not in batch | ||
|
||
def test_atomic_db_with_exception_batch(self, atomic_db: AtomicDatabaseAPI) -> None: | ||
atomic_db.set(b'key-1', b'value-1') | ||
|
||
try: | ||
with atomic_db.atomic_batch() as batch: | ||
batch.set(b'key-1', b'new-value-1') | ||
batch.set(b'key-2', b'value-2') | ||
raise Exception | ||
except Exception: | ||
pass | ||
|
||
assert atomic_db.get(b'key-1') == b'value-1' | ||
|
||
with pytest.raises(KeyError): | ||
atomic_db[b'key-2'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import pytest | ||
|
||
from eth.abc import DatabaseAPI | ||
|
||
|
||
class DatabaseAPITestSuite: | ||
def test_database_api_get(self, db: DatabaseAPI) -> None: | ||
db[b'key-1'] = b'value-1' | ||
assert db.get(b'key-1') == b'value-1' | ||
|
||
def test_database_api_item_getter(self, db: DatabaseAPI) -> None: | ||
db[b'key-1'] = b'value-1' | ||
assert db[b'key-1'] == b'value-1' | ||
|
||
def test_database_api_get_missing_key(self, db: DatabaseAPI) -> None: | ||
assert b'key-1' not in db | ||
assert db.get(b'key-1') is None | ||
|
||
def test_database_api_item_getter_missing_key(self, db: DatabaseAPI) -> None: | ||
assert b'key-1' not in db | ||
with pytest.raises(KeyError): | ||
db[b'key-1'] | ||
|
||
def test_database_api_set(self, db: DatabaseAPI) -> None: | ||
db[b'key-1'] = b'value-1' | ||
assert db[b'key-1'] == b'value-1' | ||
db[b'key-1'] = b'value-2' | ||
assert db[b'key-1'] == b'value-2' | ||
|
||
def test_database_api_item_setter(self, db: DatabaseAPI) -> None: | ||
db.set(b'key-1', b'value-1') | ||
assert db[b'key-1'] == b'value-1' | ||
db.set(b'key-1', b'value-2') | ||
assert db[b'key-1'] == b'value-2' | ||
|
||
def test_database_api_exists(self, db: DatabaseAPI) -> None: | ||
assert db.exists(b'key-1') is False | ||
|
||
db[b'key-1'] = b'value-1' | ||
|
||
assert db.exists(b'key-1') is True | ||
|
||
def test_database_api_contains_checking(self, db: DatabaseAPI) -> None: | ||
assert b'key-1' not in db | ||
|
||
db[b'key-1'] = b'value-1' | ||
|
||
assert b'key-1' in db | ||
|
||
def test_database_api_delete(self, db: DatabaseAPI) -> None: | ||
db[b'key-1'] = b'value-1' | ||
|
||
assert b'key-1' in db | ||
|
||
db.delete(b'key-1') | ||
|
||
assert not db.exists(b'key-1') | ||
assert b'key-1' not in db | ||
|
||
def test_database_api_item_delete(self, db: DatabaseAPI) -> None: | ||
db[b'key-1'] = b'value-1' | ||
|
||
assert b'key-1' in db | ||
|
||
del db[b'key-1'] | ||
|
||
assert b'key-1' not in db | ||
|
||
def test_database_api_delete_missing_key(self, db: DatabaseAPI) -> None: | ||
assert b'key-1' not in db | ||
db.delete(b'key-1') | ||
|
||
def test_database_api_item_delete_missing_key(self, db: DatabaseAPI) -> None: | ||
assert b'key-1' not in db | ||
with pytest.raises(KeyError): | ||
del db[b'key-1'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import pytest | ||
|
||
from eth.db.atomic import AtomicDB | ||
from eth.db.backends.level import LevelDB | ||
|
||
from eth.tools.db.base import DatabaseAPITestSuite | ||
from eth.tools.db.atomic import AtomicDatabaseBatchAPITestSuite | ||
|
||
|
||
@pytest.fixture(params=['atomic', 'level']) | ||
def atomic_db(request, tmpdir): | ||
if request.param == 'atomic': | ||
return AtomicDB() | ||
elif request.param == 'level': | ||
return LevelDB(db_path=tmpdir.mkdir("level_db_path")) | ||
else: | ||
raise ValueError("Unexpected database type: {}".format(request.param)) | ||
|
||
|
||
@pytest.fixture | ||
def db(atomic_db): | ||
return atomic_db | ||
|
||
|
||
class TestAtomicDatabaseBatchAPI(AtomicDatabaseBatchAPITestSuite): | ||
pass | ||
|
||
|
||
class TestAtomicDatabaseAPI(DatabaseAPITestSuite): | ||
pass |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.