def test_load_snapshots(engine, atomic_mode): """Loading builds a snapshot for future atomic operations""" user = User(id=uuid.uuid4()) # In the case of missing data, load may not return fields # (or in the case of multi-view tables, non-mapped data) engine.client.batch_get_items.return_value = { "User": [{ "age": { "N": 5 }, "id": { "S": str(user.id) }, "extra_field": { "freeform data": "not parsed" } }] } engine.config["atomic"] = atomic_mode engine.load(user) # Cached snapshots are in dumped form expected_condition = ((User.age == { "N": "5" }) & (User.email.is_(None)) & (User.id == { "S": str(user.id) }) & (User.joined.is_(None)) & (User.name.is_(None))) actual_condition = bloop.tracking.get_snapshot(user) assert actual_condition == expected_condition
def test_load_objects(engine): user1 = User(id=uuid.uuid4()) user2 = User(id=uuid.uuid4()) expected = { "User": { "Keys": [{ "id": { "S": str(user1.id) } }, { "id": { "S": str(user2.id) } }], "ConsistentRead": False } } response = { "User": [{ "age": { "N": 5 }, "name": { "S": "foo" }, "id": { "S": str(user1.id) } }, { "age": { "N": 10 }, "name": { "S": "bar" }, "id": { "S": str(user2.id) } }] } def respond(input): assert bloop.util.ordered(input) == bloop.util.ordered(expected) return response engine.client.batch_get_items = respond engine.load((user1, user2)) assert user1.age == 5 assert user1.name == "foo" assert user2.age == 10 assert user2.name == "bar"
def test_load_missing_attrs(engine): """ When an instance of a Model is loaded into, existing attributes should be overwritten with new values, or if there is no new value, should be deleted """ obj = User(id=uuid.uuid4(), age=4, name="user") response = {"User": [{"age": {"N": 5}, "id": {"S": str(obj.id)}}]} engine.client.batch_get_items = lambda input: response engine.load(obj) assert obj.age == 5 assert obj.name is None
def test_missing_objects(User, engine): """ When objects aren't loaded, ObjectsNotFound is raised with a list of missing objects """ # Patch batch_get_items to return no results engine.client.batch_get_items = lambda *a, **kw: {} users = [User(id=uuid.uuid4()) for _ in range(3)] with pytest.raises(bloop.exceptions.NotModified) as excinfo: engine.load(users) assert set(excinfo.value.objects) == set(users)
def test_load_missing_key(engine, User, ComplexModel): """Trying to load objects with missing hash and range keys raises""" user = User(age=2) with pytest.raises(ValueError): engine.load(user) complex_models = [ ComplexModel(), ComplexModel(name="no range"), ComplexModel(date="no hash") ] for model in complex_models: with pytest.raises(ValueError): engine.load(model)
def test_load_missing_attrs(User, engine): """ When an instance of a Model is loaded into, existing attributes should be overwritten with new values, or if there is no new value, should be deleted """ obj = User(id=uuid.uuid4(), age=4, name="user") response = {"User": [{"age": {"N": 5}, "id": {"S": str(obj.id)}}]} engine.client.batch_get_items = lambda input: response engine.load(obj) assert obj.age == 5 assert obj.name is None
def test_load_missing_key(engine): """Trying to load objects with missing hash and range keys raises""" user = User(age=2) with pytest.raises(ValueError): engine.load(user) complex_models = [ ComplexModel(), ComplexModel(name="no range"), ComplexModel(date="no hash") ] for model in complex_models: with pytest.raises(ValueError): engine.load(model)
def test_missing_objects(engine): """ When objects aren't loaded, ObjectsNotFound is raised with a list of missing objects """ # Patch batch_get_items to return no results engine.client.batch_get_items = lambda *a, **kw: {} users = [User(id=uuid.uuid4()) for _ in range(3)] with pytest.raises(bloop.exceptions.NotModified) as excinfo: engine.load(users) assert set(excinfo.value.objects) == set(users)
def test_load_duplicate_objects(User, engine): """Duplicate objects are handled correctly when loading""" user = User(id=uuid.uuid4()) expected = {"User": {"Keys": [{"id": {"S": str(user.id)}}], "ConsistentRead": False}} response = {"User": [{"age": {"N": 5}, "name": {"S": "foo"}, "id": {"S": str(user.id)}}]} def respond(input): assert bloop.util.ordered(input) == bloop.util.ordered(expected) return response engine.client.batch_get_items = respond engine.load((user, user)) assert user.age == 5 assert user.name == "foo"
def test_load_object(User, engine): user_id = uuid.uuid4() expected = {"User": {"Keys": [{"id": {"S": str(user_id)}}], "ConsistentRead": True}} response = {"User": [{"age": {"N": 5}, "name": {"S": "foo"}, "id": {"S": str(user_id)}}]} def respond(input): assert input == expected return response engine.client.batch_get_items = respond user = User(id=user_id) engine.load(user, consistent=True) assert user.age == 5 assert user.name == "foo" assert user.id == user_id
def test_load_object(engine): user_id = uuid.uuid4() expected = { "User": { "Keys": [{ "id": { "S": str(user_id) } }], "ConsistentRead": True } } response = { "User": [{ "age": { "N": 5 }, "name": { "S": "foo" }, "id": { "S": str(user_id) } }] } def respond(input): assert input == expected return response engine.client.batch_get_items = respond user = User(id=user_id) engine.load(user, consistent=True) assert user.age == 5 assert user.name == "foo" assert user.id == user_id
def test_load_duplicate_objects(engine): """Duplicate objects are handled correctly when loading""" user = User(id=uuid.uuid4()) expected = { "User": { "Keys": [{ "id": { "S": str(user.id) } }], "ConsistentRead": False } } response = { "User": [{ "age": { "N": 5 }, "name": { "S": "foo" }, "id": { "S": str(user.id) } }] } def respond(input): assert bloop.util.ordered(input) == bloop.util.ordered(expected) return response engine.client.batch_get_items = respond engine.load((user, user)) assert user.age == 5 assert user.name == "foo"
def test_load_objects(User, engine): user1 = User(id=uuid.uuid4()) user2 = User(id=uuid.uuid4()) expected = {"User": {"Keys": [{"id": {"S": str(user1.id)}}, {"id": {"S": str(user2.id)}}], "ConsistentRead": False}} response = {"User": [{"age": {"N": 5}, "name": {"S": "foo"}, "id": {"S": str(user1.id)}}, {"age": {"N": 10}, "name": {"S": "bar"}, "id": {"S": str(user2.id)}}]} def respond(input): assert bloop.util.ordered(input) == bloop.util.ordered(expected) return response engine.client.batch_get_items = respond engine.load((user1, user2)) assert user1.age == 5 assert user1.name == "foo" assert user2.age == 10 assert user2.name == "bar"