Experiments getting google-cloud-python
working on
Google App Engine (Python).
I used an old trick to actually run unit tests by collection them directly form imported unit test modules.
I wanted to gather all unit test modules the same way
we do for datastore
doctests (via pkgutil.iter_modules
).
But it turns out this only works for the imported modules.
Getting this to work on prod and dev took a number of workarounds:
- Using a custom Python 2.7
virtualenv
with the same (very old) versions provided as libraries in App Engine (set up viaenv-requirements.txt
). - Had to patch the constructor for
google.appengine.tools.devappserver2.python.runtime.stubs.FakeFile
, it does not match the builtinfile
. - Patch builtin
open
so that it can handle opening/dev/null
. This is becausedill
(a dependency ofgoogle-gax
) usesopen
to alias the builtinfile
type (it's not so easy on Python 3). We will be droppingdill
in the future (it is a more extreme version ofpickle
, it's not a great design choice to use object serialization).
- Patch
_pyio.open
so that it can handle opening/dev/null
.
- Having a meticulously pinned
requirements.txt
to set up vendoredlib/
(this is not agrpc
/google-cloud-language
workaround, it's standard). - Removing
grpc
andgrpcio-1.4.0.dist-info
from vendoredlib/
so that we don't conflict with the environment. - Adding a fake
grpcio-1.0.0.dist-info
to vendoredlib/
so that the distribution info is available. (It is needed for unit tests.) - Had to "place" stubs
appengine_config.py
for standard library modules:subprocess
(needed by ??),_multiprocessing
(needed by ??) andctypes
(needed bysetuptools
, if not stubbed, the dev server won't even start). - Had to clear existing imports from
sys.modules
inappengine_config.py
so that our vendored packages could take precedence. This is true forsix
,setuptools
,pkg_resources
(fromsetuptools
) andgoogle.protobuf
.
There are still some frustrating issues:
- The libraries in prod over-ride any vendored in equivalent (see e.g.
google.protobuf
in/info
). This does not occur in dev. grpc
does not come with adist-info
directory.- Had to make sure to run
python2.7 $(which dev_appserver.py)
rather than justdev_appservery.py
on a system where the barepython
is not 2.7 (though this is in violation of PEP 394, so I deserve it). - Had to HTML-escape a hyphen in my
app.yaml
config (i.e.cleanD;env/
instead ofclean-env/
). This actually blocks thedevappserver
from even starting.