def test_it(runstate): runstate.eventloop = mock.Mock(spec=("add_idle", "run")) future1 = _api.lookup(_mock_key("foo")) future2 = _api.lookup(_mock_key("foo")) future3 = _api.lookup(_mock_key("bar")) batch = runstate.batches[_api._LookupBatch][()] assert batch.todo["foo"] == [future1, future2] assert batch.todo["bar"] == [future3] assert runstate.eventloop.add_idle.call_count == 1
def test_lookup(runstate): runstate.eventloop = mock.Mock(spec=("add_idle", "run")) future1 = _api.lookup(_mock_key("foo")) future2 = _api.lookup(_mock_key("foo")) future3 = _api.lookup(_mock_key("bar")) batch = runstate.batches[_api._BATCH_LOOKUP] assert batch["foo"] == [future1, future2] assert batch["bar"] == [future3] runstate.eventloop.add_idle.assert_called_once_with( _api._perform_batch_lookup)
def test_it(context): eventloop = mock.Mock(spec=("add_idle", "run")) with context.new(eventloop=eventloop) as context: future1 = _api.lookup(_mock_key("foo")) future2 = _api.lookup(_mock_key("foo")) future3 = _api.lookup(_mock_key("bar")) batch = context.batches[_api._LookupBatch][()] assert batch.todo["foo"] == [future1, future2] assert batch.todo["bar"] == [future3] assert context.eventloop.add_idle.call_count == 1
def test_it_with_options(runstate): runstate.eventloop = mock.Mock(spec=("add_idle", "run")) future1 = _api.lookup(_mock_key("foo")) future2 = _api.lookup(_mock_key("foo"), read_consistency=_api.EVENTUAL) future3 = _api.lookup(_mock_key("bar")) batches = runstate.batches[_api._LookupBatch] batch1 = batches[()] assert batch1.todo["foo"] == [future1] assert batch1.todo["bar"] == [future3] batch2 = batches[(("read_consistency", _api.EVENTUAL),)] assert batch2.todo == {"foo": [future2]} add_idle = runstate.eventloop.add_idle assert add_idle.call_count == 2
def test_it_with_options(context): eventloop = mock.Mock(spec=("add_idle", "run")) with context.new(eventloop=eventloop).use() as context: future1 = _api.lookup(_mock_key("foo"), _options.ReadOptions()) future2 = _api.lookup( _mock_key("foo"), _options.ReadOptions(read_consistency=_api.EVENTUAL), ) future3 = _api.lookup(_mock_key("bar"), _options.ReadOptions()) batches = context.batches[_api._LookupBatch] batch1 = batches[()] assert batch1.todo["foo"] == [future1] assert batch1.todo["bar"] == [future3] batch2 = batches[(("read_consistency", _api.EVENTUAL), )] assert batch2.todo == {"foo": [future2]} add_idle = context.eventloop.add_idle assert add_idle.call_count == 2
def test_idle_callback(runstate): runstate.eventloop = mock.Mock(spec=("add_idle", "run")) future = _api.lookup(_mock_key("foo")) batches = runstate.batches[_api._LookupBatch] batch = batches[()] assert batch.todo["foo"] == [future] idle = runstate.eventloop.add_idle.call_args[0][0] batch.idle_callback = mock.Mock() idle() batch.idle_callback.assert_called_once_with() assert () not in batches
def test_idle_callback(context): eventloop = mock.Mock(spec=("add_idle", "run")) with context.new(eventloop=eventloop) as context: future = _api.lookup(_mock_key("foo")) batches = context.batches[_api._LookupBatch] batch = batches[()] assert batch.todo["foo"] == [future] idle = context.eventloop.add_idle.call_args[0][0] batch.idle_callback = mock.Mock() idle() batch.idle_callback.assert_called_once_with() assert () not in batches
def test_cache_miss_no_datastore(_LookupBatch, global_cache): class SomeKind(model.Model): pass key = key_module.Key("SomeKind", 1) cache_key = _cache.global_cache_key(key._key) batch = _LookupBatch.return_value batch.add.side_effect = Exception("Shouldn't use Datastore") future = _api.lookup(key._key, _options.ReadOptions(use_datastore=False)) assert future.result() is _api._NOT_FOUND assert global_cache.get([cache_key]) == [None]
def test_cache_not_found(_LookupBatch, global_cache): class SomeKind(model.Model): pass key = key_module.Key("SomeKind", 1) cache_key = _cache.global_cache_key(key._key) batch = _LookupBatch.return_value batch.add.return_value = future_result(_api._NOT_FOUND) future = _api.lookup(key._key, _options.ReadOptions()) assert future.result() is _api._NOT_FOUND assert global_cache.get([cache_key]) == [_cache._LOCKED]
def test_it(context): eventloop = mock.Mock(spec=("add_idle", "run")) with context.new(eventloop=eventloop).use() as context: _api.lookup(_mock_key("foo"), _options.ReadOptions()) _api.lookup(_mock_key("foo"), _options.ReadOptions()) _api.lookup(_mock_key("bar"), _options.ReadOptions()) batch = context.batches[_api._LookupBatch][()] assert len(batch.todo["foo"]) == 2 assert len(batch.todo["bar"]) == 1 assert context.eventloop.add_idle.call_count == 1
def test_cache_hit(_LookupBatch, global_cache): class SomeKind(model.Model): pass key = key_module.Key("SomeKind", 1) cache_key = _cache.global_cache_key(key._key) entity = SomeKind(key=key) entity_pb = model._entity_to_protobuf(entity) cache_value = entity_pb.SerializeToString() global_cache.set({cache_key: cache_value}) batch = _LookupBatch.return_value batch.add.side_effect = Exception("Shouldn't get called.") future = _api.lookup(key._key, _options.ReadOptions()) assert future.result() == entity_pb
def get_async(self, **options): """Asynchronously get the entity for this key. The result for the returned future will either be the retrieved :class:`.Model` or :data:`None` if there is no such entity. Args: options (Dict[str, Any]): The options for the request. For example, ``{"read_consistency": EVENTUAL}``. Returns: :class:`~google.cloud.ndb.tasklets.Future` """ from google.cloud.ndb import model # avoid circular import entity_pb = yield _datastore_api.lookup(self._key, **options) if entity_pb is not _datastore_api._NOT_FOUND: return model._entity_from_protobuf(entity_pb)
def test_cache_miss(_LookupBatch, global_cache): class SomeKind(model.Model): pass key = key_module.Key("SomeKind", 1) cache_key = _cache.global_cache_key(key._key) entity = SomeKind(key=key) entity_pb = model._entity_to_protobuf(entity) cache_value = entity_pb.SerializeToString() batch = _LookupBatch.return_value batch.add.return_value = future_result(entity_pb) future = _api.lookup(key._key, _options.ReadOptions()) assert future.result() == entity_pb assert global_cache.get([cache_key]) == [cache_value]
def test_cache_locked(_LookupBatch, global_cache): class SomeKind(model.Model): pass key = key_module.Key("SomeKind", 1) cache_key = _cache.global_cache_key(key._key) entity = SomeKind(key=key) entity_pb = model._entity_to_protobuf(entity) global_cache.set({cache_key: _cache._LOCKED}) batch = _LookupBatch.return_value batch.add.return_value = future_result(entity_pb) future = _api.lookup(key._key, _options.ReadOptions()) assert future.result() == entity_pb assert global_cache.get([cache_key]) == [_cache._LOCKED]
def test_it_with_transaction(context): eventloop = mock.Mock(spec=("add_idle", "run")) new_context = context.new(eventloop=eventloop, transaction=b"tx123") with new_context.use(): new_context._use_global_cache = mock.Mock( side_effect=Exception("Shouldn't call _use_global_cache")) _api.lookup(_mock_key("foo"), _options.ReadOptions()) _api.lookup(_mock_key("foo"), _options.ReadOptions()) _api.lookup(_mock_key("bar"), _options.ReadOptions()) batch = new_context.batches[_api._LookupBatch][()] assert len(batch.todo["foo"]) == 2 assert len(batch.todo["bar"]) == 1 assert new_context.eventloop.add_idle.call_count == 1
def test_it_no_global_cache_or_datastore(in_context): with pytest.raises(TypeError): _api.lookup( _mock_key("foo"), _options.ReadOptions(use_datastore=False) ).result()
def test_it_with_bad_option(runstate): with pytest.raises(NotImplementedError): _api.lookup(_mock_key("foo"), foo="bar")