Expected Behavior
The tests should have passed.
From our own investigation, the issue is not related to the datastore stub in general, but when we test a flask view in which there is interaction with the datastore service.
The issue appears when we use:
- GAE 2nd gen
- Python 3
- Flask
- appengine-python-standard
- pytest
Actual Behavior
../../../miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/datastore/datastore_stub_util.py:469: AssertionError
-------------------------------------------------------------------------------------------------------------- Captured log call --------------------------------------------------------------------------------------------------------------
WARNING root:tasklets.py:482 suspended generator _put_tasklet(context.py:382) raised AssertionError()
WARNING root:tasklets.py:482 suspended generator put(context.py:850) raised AssertionError()
ERROR root:middlewares.py:155 Traceback (most recent call last):
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/runtime/middlewares.py", line 140, in ErrorLoggingMiddleware
return app(wsgi_env, start_response)
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/runtime/middlewares.py", line 82, in
lambda app: lambda wsgi_env, start_resp: f(app, wsgi_env, start_resp),
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/runtime/middlewares.py", line 378, in BackgroundAndShutdownMiddleware
return app(wsgi_env, start_response)
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/runtime/middlewares.py", line 82, in
lambda app: lambda wsgi_env, start_resp: f(app, wsgi_env, start_resp),
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/runtime/middlewares.py", line 405, in SetNamespaceFromHeader
return app(wsgi_env, start_response)
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/flask/app.py", line 2080, in wsgi_app
response = self.handle_exception(e)
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/flask/app.py", line 2077, in wsgi_app
response = self.full_dispatch_request()
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/flask/app.py", line 1525, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/flask/app.py", line 1523, in full_dispatch_request
rv = self.dispatch_request()
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/flask/app.py", line 1509, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/my_home_dir/Downloads/migrate-python2-appengine-master/mod1b-flask/main.py", line 39, in root
store_visit(request.remote_addr, request.user_agent)
File "/my_home_dir/Downloads/migrate-python2-appengine-master/mod1b-flask/main.py", line 30, in store_visit
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/ext/ndb/model.py", line 3538, in _put
return self._put_async(**ctx_options).get_result()
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/ext/ndb/tasklets.py", line 397, in get_result
self.check_success()
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/ext/ndb/tasklets.py", line 394, in check_success
six.reraise(self._exception.class, self._exception, self._traceback)
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/six.py", line 719, in reraise
raise value
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/ext/ndb/tasklets.py", line 441, in _help_tasklet_along
value = gen.throw(exc.class, exc, tb)
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/ext/ndb/context.py", line 850, in put
key = yield self._put_batcher.add(entity, options)
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/ext/ndb/tasklets.py", line 441, in _help_tasklet_along
value = gen.throw(exc.class, exc, tb)
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/ext/ndb/context.py", line 382, in _put_tasklet
keys = yield self._conn.async_put(options, datastore_entities)
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/ext/ndb/tasklets.py", line 527, in _on_rpc_completion
result = rpc.get_result()
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/api/apiproxy_stub_map.py", line 648, in get_result
return self.__get_result_hook(self)
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/datastore/datastore_rpc.py", line 1875, in __put_hook
self.check_rpc_success(rpc)
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/datastore/datastore_rpc.py", line 1365, in check_rpc_success
rpc.check_success()
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/api/apiproxy_stub_map.py", line 614, in check_success
self.__rpc.CheckSuccess()
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/api/apiproxy_rpc.py", line 149, in CheckSuccess
raise self.exception
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/api/apiproxy_rpc.py", line 212, in _CaptureTrace
f()
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/api/apiproxy_rpc.py", line 207, in _SendRequest
self.stub.MakeSyncCall(self.package, self.call, self.request, self.response)
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/api/datastore_file_stub.py", line 593, in MakeSyncCall
super(DatastoreFileStub, self).MakeSyncCall(service,
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/api/apiproxy_stub.py", line 143, in MakeSyncCall
method(request, response)
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/datastore/datastore_stub_util.py", line 3344, in _Dynamic_Put
results = self._datastore.Put(req.entity, res.cost, transaction,
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/datastore/datastore_stub_util.py", line 2772, in Put
CheckEntity(trusted, calling_app, raw_entity)
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/datastore/datastore_stub_util.py", line 522, in CheckEntity
CheckReference(request_trusted, request_app_id, entity.key, False)
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/datastore/datastore_stub_util.py", line 494, in CheckReference
CheckAppId(request_trusted, request_app_id, key.app)
File "/my_home_dir/miniconda3/envs/testndb/lib/python3.9/site-packages/google/appengine/datastore/datastore_stub_util.py", line 469, in CheckAppId
assert app_id
AssertionError
=========================================================================================================== short test summary info ===========================================================================================================
FAILED main_test.py::test_index - AssertionError
============================================================================================================== 1 failed in 0.78s ==============================================================================================================
Steps to Reproduce the Problem
- Clone https://github.com/googlecodelabs/migrate-python2-appengine
- Go to mod1b-flask
- python3 -m venv env
- source env/bin/activate
- pip install -r requirements.txt
- pip install pytest
- Create new file test_main.py with the following content:
import pytest
import requests
import main
@pytest.fixture
def testbed():
from google.appengine.ext import testbed
from google.appengine.datastore import datastore_stub_util
testbed = testbed.Testbed()
testbed.activate()
testbed.init_datastore_v3_stub(
consistency_policy=datastore_stub_util.PseudoRandomHRConsistencyPolicy(probability=1)
)
testbed.init_memcache_stub()
testbed.init_app_identity_stub()
yield testbed
testbed.deactivate()
@pytest.fixture
def client():
main.app.testing = True
client = main.app.test_client()
reset_datastore() # clean up before every test
yield client
def reset_datastore():
# clean up/delete the database (reset Datastore)
response = requests.post("http://localhost:8081/reset")
assert response.status_code == 200
def test_index(testbed, client):
r = client.get('/')
assert r.status_code == 200
- gcloud beta emulators datastore start --project=test-project --host-port localhost:8081 --no-store-on-disk
- pytest . -p no:warnings
Specifications
The latest versions of the gcloud sdk and respective libraries are installed.
The packages installed in the virtualenv are presented below:
appengine-python-standard 1.0.0
attrs 21.4.0
cachetools 5.2.0
certifi 2022.6.15
charset-normalizer 2.1.0
click 8.1.3
Flask 2.1.2
frozendict 2.3.2
google-auth 2.9.0
idna 3.3
importlib-metadata 4.12.0
itsdangerous 2.1.2
Jinja2 3.1.2
MarkupSafe 2.1.1
mock 4.0.3
Pillow 9.2.0
pip 22.0.4
protobuf 4.21.2
pyasn1 0.4.8
pyasn1-modules 0.2.8
pytz 2022.1
requests 2.28.1
rsa 4.8
ruamel.yaml 0.17.21
ruamel.yaml.clib 0.2.6
setuptools 58.1.0
six 1.16.0
urllib3 1.26.10
Werkzeug 2.1.2
zipp 3.8.0