blob: 03c9a765693d64243e9424d512863638bfddd197 [file] [log] [blame]
# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Module containing methods and classes to interact with a devserver instance.
"""
import os
import threading
import time
import cros_build_lib as cros_lib
# Wait up to 3 minutes for the dev server to start.
DEV_SERVER_TIMEOUT = 180
def GenerateUpdateId(target, src, key, for_vm):
"""Returns a simple representation id of target and src paths."""
update_id = target
if src: update_id = '->'.join([src, update_id])
if key: update_id = '+'.join([update_id, key])
if not for_vm: update_id = '+'.join([update_id, 'patched_kernel'])
return update_id
class DevServerException(Exception):
"""Thrown when the devserver fails to start up correctly."""
pass
class DevServerWrapper(threading.Thread):
"""A Simple wrapper around a dev server instance."""
def __init__(self, test_root):
self.proc = None
self.test_root = test_root
self._log_filename = os.path.join(test_root, 'dev_server.log')
threading.Thread.__init__(self)
def run(self):
# Kill previous running instance of devserver if it exists.
cros_lib.RunCommand(['sudo', 'pkill', '-f', 'devserver.py'], error_ok=True,
print_cmd=False)
cros_lib.RunCommand(['sudo',
'start_devserver',
'--archive_dir=./static',
'--production',
], enter_chroot=True, print_cmd=False,
log_to_file=self._log_filename,
cwd=cros_lib.GetCrosUtilsPath())
def Stop(self):
"""Kills the devserver instance."""
cros_lib.RunCommand(['sudo', 'pkill', '-f', 'devserver.py'], error_ok=True,
print_cmd=False)
def PrintLog(self):
"""Print devserver output."""
# Open in update mode in case the child process hasn't opened the file yet.
log = open(self._log_filename, 'w+')
print '--- Start output from %s ---' % self._log_filename
for line in log:
sys.stdout.write(line)
print '--- End output from %s ---' % self._log_filename
log.close()
def WaitUntilStarted(self):
"""Wait until the devserver has started."""
# Open in update mode in case the child process hasn't opened the file yet.
log = open(self._log_filename, 'w+')
pos = 0
for _ in range(DEV_SERVER_TIMEOUT * 2):
log.seek(pos)
for line in log:
# When the dev server has started, it will print a line stating
# 'Bus STARTED'. Wait for that line to appear.
if 'Bus STARTED' in line:
log.close()
return
# If we've read a complete line, and it doesn't contain the magic
# phrase, move on to the next line.
if line.endswith('\n'):
pos = log.tell()
# Looks like it hasn't started yet. Keep waiting...
time.sleep(0.5)
else:
log.close()
self.PrintLog()
raise DevServerException('Timeout waiting for the devserver to startup.')
@classmethod
def GetDevServerURL(cls, port, sub_dir):
"""Returns the dev server url for a given port and sub directory."""
ip_addr = cros_lib.GetIPAddress()
if not port: port = 8080
url = 'http://%(ip)s:%(port)s/%(dir)s' % {'ip': ip_addr,
'port': str(port),
'dir': sub_dir}
return url
@classmethod
def WipePayloadCache(cls):
"""Cleans up devserver cache of payloads."""
cros_lib.Info('Cleaning up previously generated payloads.')
cros_lib.RunCommandCaptureOutput(
['sudo', 'start_devserver', '--clear_cache', '--exit'],
enter_chroot=True, print_cmd=False, combine_stdout_stderr=True,
cwd=cros_lib.GetCrosUtilsPath())