2048
2043
LayerProcessController.postTestInvariants()
2051
class BaseWindmillLayer(AppServerLayer):
2052
"""Layer for Windmill tests.
2054
This layer shouldn't be used directly. A subclass needs to be
2055
created specifying which base URL to use (e.g.
2056
http://bugs.launchpad.dev:8085/).
2061
shell_objects = None
2067
if cls.base_url is None:
2068
# Only do the setup if we're in a subclass that defines
2069
# base_url. With no base_url, we can't create the config
2070
# file windmill needs.
2073
cls._fixStandardInputFileno()
2074
cls._configureWindmillLogging()
2075
cls._configureWindmillStartup()
2077
# Tell windmill to start its browser and server. Our testrunner will
2078
# keep going, passing commands to the server for execution.
2079
cls.shell_objects = start_windmill()
2081
# Patch the config to provide the port number and not use https.
2083
(('vhost.%s' % sitename,
2084
'rooturl: %s/' % cls.appserver_root_url(sitename))
2085
for sitename in ['mainsite', 'answers', 'blueprints', 'bugs',
2086
'code', 'testopenid', 'translations']))
2088
config.push('windmillsettings', "\n[%s]\n%s\n" % site)
2094
if cls.shell_objects is not None:
2095
windmill_teardown(cls.shell_objects)
2096
if cls.config_file is not None:
2097
# Close the file so that it gets deleted.
2098
cls.config_file.close()
2099
config.reloadConfig()
2101
# XXX: deryck 2011-01-28 bug=709438
2102
# Windmill mucks about with the default timeout and this is
2103
# a fix until the library itself can be cleaned up.
2104
socket.setdefaulttimeout(None)
2109
# Left-over threads should be harmless, since they should all
2110
# belong to Windmill, which will be cleaned up on layer
2112
BaseLayer.disable_thread_check = True
2113
socket.setdefaulttimeout(120)
2117
def testTearDown(cls):
2118
# To play nice with Windmill layers, we need to reset
2119
# the socket timeout default in this method, too.
2120
socket.setdefaulttimeout(None)
2123
def _fixStandardInputFileno(cls):
2124
"""Patch the STDIN fileno so Windmill doesn't break."""
2125
# If we're running in a bin/test sub-process, sys.stdin is
2126
# replaced by FakeInputContinueGenerator, which doesn't have a
2127
# fileno method. When Windmill starts Firefox,
2128
# sys.stdin.fileno() is called, so we add such a method here, to
2129
# prevent it from breaking. By returning None, we should ensure
2130
# that it doesn't try to use the return value for anything.
2131
if not safe_hasattr(sys.stdin, 'fileno'):
2132
assert isinstance(sys.stdin, FakeInputContinueGenerator), (
2133
"sys.stdin (%r) doesn't have a fileno method." % sys.stdin)
2134
sys.stdin.fileno = lambda: None
2137
def _configureWindmillLogging(cls):
2138
"""Override the default windmill log handling."""
2139
if not config.windmill.debug_log:
2142
# Add a new log handler to capture all of the windmill testrunner
2143
# output. This overrides windmill's own log handling, which we do not
2144
# have direct access to.
2145
# We'll overwrite the previous log contents to keep the disk usage
2146
# low, and because the contents are only meant as an in-situ debugging
2148
filehandler = logging.FileHandler(config.windmill.debug_log, mode='w')
2149
filehandler.setLevel(logging.NOTSET)
2150
filehandler.setFormatter(
2152
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"))
2153
logging.getLogger('windmill').addHandler(filehandler)
2155
# Make sure that everything sent to the windmill logger is captured.
2156
# This works because windmill configures the root logger for its
2157
# purposes, and we are pre-empting that by inserting a new logger one
2158
# level higher in the logger chain.
2159
logging.getLogger('windmill').setLevel(logging.NOTSET)
2162
def _configureWindmillStartup(cls):
2163
"""Pass our startup parameters to the windmill server."""
2164
# Windmill needs a config file on disk to load its settings from.
2165
# There is no way to directly pass settings to the windmill test
2166
# driver from out here.
2167
config_text = dedent("""\
2168
START_FIREFOX = True
2170
CONSOLE_LOG_LEVEL = %d
2171
""" % (cls.base_url, logging.NOTSET))
2172
cls.config_file = tempfile.NamedTemporaryFile(suffix='.py')
2173
cls.config_file.write(config_text)
2174
# Flush the file so that windmill can read it.
2175
cls.config_file.flush()
2176
os.environ['WINDMILL_CONFIG_FILE'] = cls.config_file.name
2179
2046
class YUITestLayer(FunctionalLayer):
2180
2047
"""The base class for all YUITests cases."""