The code lives in maint/appengine/common, but should be run from the py25
or py27 subdirectories (which contain an app.yaml and a bunch of symlinks).
runtests.py is the entry point; cgi_runtests.py is used internally.
-dev_appserver.py doesn't work with virtualenv
-(http://code.google.com/p/googleappengine/issues/detail?id=4339) so these
-tests are not hooked into tox yet.
#!/usr/bin/env python
-import logging
+import sys
import unittest
# Most of our tests depend on IOLoop, which is not importable on app engine.
def all():
return unittest.defaultTestLoader.loadTestsFromNames(TEST_MODULES)
-if __name__ == '__main__':
+def main():
print "Content-Type: text/plain\r\n\r\n",
import_everything()
- import tornado.testing
try:
- tornado.testing.main()
+ unittest.main(defaultTest="all", argv=sys.argv)
except SystemExit, e:
if e.code == 0:
print "PASS"
else:
raise
+
+if __name__ == '__main__':
+ main()
+
#!/usr/bin/env python
+from __future__ import with_statement
+import contextlib
+import errno
import os
import random
import signal
+import socket
import subprocess
import sys
import time
# does dev_appserver.py ever live anywhere but /usr/local/bin?
proc = subprocess.Popen([sys.executable,
"/usr/local/bin/dev_appserver.py",
- os.path.dirname(__file__),
- "--port=%d" % port
+ os.path.dirname(os.path.abspath(__file__)),
+ "--port=%d" % port,
+ "--skip_sdk_update_check",
],
cwd=tornado_root)
- time.sleep(3)
+
try:
+ for i in xrange(50):
+ with contextlib.closing(socket.socket()) as sock:
+ err = sock.connect_ex(('localhost', port))
+ if err == 0:
+ break
+ elif err != errno.ECONNREFUSED:
+ raise Exception("Got unexpected socket error %d" % err)
+ time.sleep(0.1)
+ else:
+ raise Exception("Server didn't start listening")
+
resp = urllib2.urlopen("http://localhost:%d/" % port)
print resp.read()
finally:
- os.kill(proc.pid, signal.SIGTERM)
- proc.wait()
+ # dev_appserver sometimes ignores SIGTERM (especially on 2.5),
+ # so try a few times to kill it.
+ for sig in [signal.SIGTERM, signal.SIGTERM, signal.SIGKILL]:
+ os.kill(proc.pid, sig)
+ res = os.waitpid(proc.pid, os.WNOHANG)
+ if res != (0,0):
+ break
+ time.sleep(0.1)
+ else:
+ os.waitpid(proc.pid, 0)
--- /dev/null
+# Dummy setup file to make tox happy. In the appengine world things aren't
+# installed through setup.py
+import distutils.core
+distutils.core.setup()
--- /dev/null
+# App Engine tests require the SDK to be installed separately.
+# Version 1.6.1 or newer is required (older versions don't work when
+# python is run from a virtualenv)
+#
+# These are currently excluded from the main tox.ini because their
+# logs are spammy and they're a little flaky.
+[tox]
+envlist = py25-appengine, py27-appengine
+
+[testenv]
+changedir = {toxworkdir}
+
+[testenv:py25-appengine]
+basepython = python2.5
+commands = python {toxinidir}/py25/runtests.py {posargs:}
+
+[testenv:py27-appengine]
+basepython = python2.7
+commands = python {toxinidir}/py27/runtests.py {posargs:}