64
66
from zope.security.simplepolicies import PermissiveSecurityPolicy
65
67
from zope.server.logger.pythonlogger import PythonLogger
69
from canonical import pidfile
67
70
from canonical.config import config
68
71
from canonical.database.sqlbase import ZopelessTransactionManager
69
72
from canonical.launchpad.interfaces import IMailBox, IOpenLaunchBag
75
78
GoogleServiceTestSetup)
76
79
from canonical.launchpad.webapp.servers import (
77
80
LaunchpadAccessLogger, register_launchpad_request_publication_factories)
81
from canonical.lazr.config import ImplicitTypeSchema
78
82
from canonical.lazr.timeout import (
79
83
get_default_timeout_function, set_default_timeout_function)
80
84
from canonical.lp import initZopeless
141
def wait_children(seconds=120):
142
"""Wait for all children to exit.
144
:param seconds: Maximum number of seconds to wait. If None, wait
147
now = datetime.datetime.now
151
until = now() + datetime.timedelta(seconds=seconds)
154
os.waitpid(-1, os.WNOHANG)
155
except OSError, error:
156
if error.errno != errno.ECHILD:
159
if until is not None and now() > until:
215
237
os.chdir(BaseLayer.original_working_directory)
217
239
BaseLayer.original_working_directory = None
221
241
del canonical.launchpad.mail.stub.test_emails[:]
223
242
BaseLayer.test_name = None
225
243
BaseLayer.check()
227
245
# Check for tests that leave live threads around early.
228
246
# A live thread may be the cause of other failures, such as
229
247
# uncollectable garbage.
231
thread for thread in threading.enumerate()
232
if thread not in BaseLayer._threads and thread.isAlive()]
249
thread for thread in threading.enumerate()
250
if thread not in BaseLayer._threads and thread.isAlive()
234
254
BaseLayer.flagTestIsolationFailure(
235
"Test left new live threads: %s" % repr(new_threads))
255
"Test left new live threads: %s" % repr(new_threads))
236
256
del BaseLayer._threads
238
258
# Objects with __del__ methods cannot participate in refence cycles.
258
278
if FunctionalLayer.isSetUp and ZopelessLayer.isSetUp:
259
279
raise LayerInvariantError(
260
"Both Zopefull and Zopeless CA environments setup"
280
"Both Zopefull and Zopeless CA environments setup")
263
282
# Detect a test that causes the component architecture to be loaded.
264
283
# This breaks test isolation, as it cannot be torn down.
265
if (is_ca_available() and not FunctionalLayer.isSetUp
266
and not ZopelessLayer.isSetUp):
284
if (is_ca_available()
285
and not FunctionalLayer.isSetUp
286
and not ZopelessLayer.isSetUp):
267
287
raise LayerIsolationError(
268
288
"Component architecture should not be loaded by tests. "
269
289
"This should only be loaded by the Layer."
274
294
# but it is better for the tear down to be explicit.
275
295
if ZopelessTransactionManager._installed is not None:
276
296
raise LayerIsolationError(
277
"Zopeless environment was setup and not torn down."
297
"Zopeless environment was setup and not torn down.")
280
299
# Detect a test that forgot to reset the default socket timeout.
281
300
# This safety belt is cheap and protects us from very nasty
1126
1145
class TwistedLaunchpadZopelessLayer(TwistedLayer, LaunchpadZopelessLayer):
1127
1146
"""A layer for cleaning up the Twisted thread pool."""
1149
class AppServerLayer(LaunchpadLayer):
1150
"""Environment for starting and stopping the app server."""
1152
services = ('librarian', 'restricted-librarian')
1153
LPCONFIG = 'testrunner-appserver'
1158
cls.stopAllServices()
1159
# Get the child process's pid file.
1160
path = os.path.join(config.root, 'configs', cls.LPCONFIG,
1161
'launchpad-lazr.conf')
1162
schema = ImplicitTypeSchema(config.schema.filename)
1163
child_config = schema.load(path)
1164
# lazr.config doesn't set this attribute.
1165
child_config.instance_name = cls.LPCONFIG
1166
pid = pidfile.get_pid('launchpad', child_config)
1168
# Don't worry if the process no longer exists.
1170
os.kill(pid, signal.SIGTERM)
1171
except OSError, error:
1172
if error.errno != errno.ESRCH:
1174
pidfile.remove_pidfile('launchpad', child_config)
1178
os.execlp('make', 'make', '-i' '-s', 'LPCONFIG=%s' % cls.LPCONFIG,
1179
'run_all_quickly_and_quietly')
1180
# Should never get here...
1182
# The parent. Wait until the app server is responsive, but not
1183
# forever. Make sure the test database is set up.
1184
from canonical.launchpad.ftests.harness import LaunchpadTestSetup
1185
LaunchpadTestSetup().setUp()
1186
until = time.time() + 60
1187
while time.time() < until:
1189
connection = urlopen('http://launchpad.dev:8085')
1191
except IOError, (error_message, error):
1192
if error.args[0] != errno.ECONNREFUSED:
1199
cls.stopAllServices()
1204
# Force the database to reset.
1205
from canonical.launchpad.ftests.harness import LaunchpadTestSetup
1206
LaunchpadTestSetup().tearDown()
1207
cls.stopAllServices()
1208
# Ensure that there are no child processes still running.
1210
os.waitpid(-1, os.WNOHANG)
1211
except OSError, error:
1212
if error.errno != errno.ECHILD:
1215
cls.stopAllServices()
1216
raise LayerIsolationError('Child processes have leaked through.')
1225
def testTearDown(cls):
1226
DatabaseLayer.force_dirty_database()
1230
def stopAllServices(cls):
1231
os.system('make -i -s LPCONFIG=%s stop_quickly_and_quietly'