Move dev_server_wrapper from crostestutils.lib to chromite.lib

Scripts such as cros flash can use dev_server_wrapper. crostestutils
already imports chromite.

BUG=None
TEST=None
CQ-DEPEND=CL:181048

Change-Id: Ide5890e69e0ec13ccce449a412ac0e782c340a79
Reviewed-on: https://chromium-review.googlesource.com/181049
Reviewed-by: Chris Sosa <sosa@chromium.org>
Commit-Queue: Yu-Ju Hong <yjhong@chromium.org>
Tested-by: Yu-Ju Hong <yjhong@chromium.org>
diff --git a/au_test_harness/au_worker.py b/au_test_harness/au_worker.py
index c1067d4..981cde5 100644
--- a/au_test_harness/au_worker.py
+++ b/au_test_harness/au_worker.py
@@ -13,8 +13,8 @@
 import os
 
 from chromite.lib import cros_build_lib
+from chromite.lib import dev_server_wrapper
 from crostestutils.au_test_harness import update_exception
-from crostestutils.lib import dev_server_wrapper
 
 
 class AUWorker(object):
diff --git a/au_test_harness/cros_au_test_harness.py b/au_test_harness/cros_au_test_harness.py
index 0745267..014884b 100755
--- a/au_test_harness/cros_au_test_harness.py
+++ b/au_test_harness/cros_au_test_harness.py
@@ -26,12 +26,12 @@
 sys.path.append(constants.SOURCE_ROOT)
 
 from chromite.lib import cros_build_lib
+from chromite.lib import dev_server_wrapper
 from chromite.lib import parallel
 from chromite.lib import sudo
 from chromite.lib import timeout_util
 from crostestutils.au_test_harness import au_test
 from crostestutils.au_test_harness import au_worker
-from crostestutils.lib import dev_server_wrapper
 from crostestutils.lib import test_helper
 
 # File location for update cache in given folder.
diff --git a/devmode-test/devinstall_test.py b/devmode-test/devinstall_test.py
index 82d32f8..d27707c 100755
--- a/devmode-test/devinstall_test.py
+++ b/devmode-test/devinstall_test.py
@@ -27,8 +27,8 @@
 sys.path.append(constants.CROS_PLATFORM_ROOT)
 
 from chromite.lib import cros_build_lib
+from chromite.lib import dev_server_wrapper
 from chromite.lib import remote_access
-from crostestutils.lib import dev_server_wrapper
 from crostestutils.lib import mount_helper
 from crostestutils.lib import test_helper
 
diff --git a/generate_test_payloads/cros_generate_test_payloads.py b/generate_test_payloads/cros_generate_test_payloads.py
index 538d76f..c46062a 100755
--- a/generate_test_payloads/cros_generate_test_payloads.py
+++ b/generate_test_payloads/cros_generate_test_payloads.py
@@ -33,6 +33,7 @@
 sys.path.append(constants.SOURCE_ROOT)
 
 from chromite.lib import cros_build_lib
+from chromite.lib import dev_server_wrapper
 from chromite.lib import git
 from chromite.lib import locking
 from chromite.lib import osutils
@@ -41,7 +42,6 @@
 from chromite.lib import timeout_util
 from crostestutils.au_test_harness import cros_au_test_harness
 from crostestutils.generate_test_payloads import payload_generation_exception
-from crostestutils.lib import dev_server_wrapper
 from crostestutils.lib import image_extractor
 from crostestutils.lib import public_key_manager
 from crostestutils.lib import test_helper
diff --git a/lib/dev_server_wrapper.py b/lib/dev_server_wrapper.py
deleted file mode 100644
index 5242e72..0000000
--- a/lib/dev_server_wrapper.py
+++ /dev/null
@@ -1,185 +0,0 @@
-# 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 logging
-import multiprocessing
-import os
-import re
-import sys
-import tempfile
-import time
-import urllib2
-
-import constants
-from chromite.lib import cros_build_lib
-
-# Wait up to 15 minutes for the dev server to start. It can take a while to
-# start when generating payloads in parallel.
-DEV_SERVER_TIMEOUT = 900
-CHECK_HEALTH_URL = 'http://127.0.0.1:8080/check_health'
-KILL_TIMEOUT = 10
-
-
-def GetIPAddress(device='eth0'):
-  """Returns the IP Address for a given device using ifconfig.
-
-  socket.gethostname() is insufficient for machines where the host files are
-  not set up "correctly."  Since some of our builders may have this issue,
-  this method gives you a generic way to get the address so you are reachable
-  either via a VM or remote machine on the same network.
-  """
-  result = cros_build_lib.RunCommandCaptureOutput(
-      ['/sbin/ifconfig', device], print_cmd=False)
-  match = re.search('.*inet addr:(\d+\.\d+\.\d+\.\d+).*', result.output)
-  if match:
-    return match.group(1)
-  cros_build_lib.Warning('Failed to find ip address in %r', result.output)
-  return None
-
-
-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."""
-
-
-class DevServerWrapper(multiprocessing.Process):
-  """A Simple wrapper around a dev server instance."""
-
-  def __init__(self, test_root=None):
-    super(DevServerWrapper, self).__init__()
-    self.test_root = test_root or DevServerWrapper.MkChrootTemp(is_dir=True)
-    self._log_filename = os.path.join(self.test_root, 'dev_server.log')
-    self._pid_file = DevServerWrapper.MkChrootTemp(is_dir=False)
-    self._pid = None
-
-  # Chroot helper methods. Since we call a script into the chroot with paths
-  # created outside the chroot, translation back and forth is needed. These
-  # methods all assume the default chroot dir.
-
-  @staticmethod
-  def MkChrootTemp(is_dir):
-    """Returns a temp(dir if is_dir, file otherwise) in the chroot."""
-    chroot_tmp = os.path.join(constants.SOURCE_ROOT, 'chroot', 'tmp')
-    if is_dir:
-      return tempfile.mkdtemp(prefix='devserver_wrapper', dir=chroot_tmp)
-    else:
-      return tempfile.NamedTemporaryFile(prefix='devserver_wrapper',
-                                         dir=chroot_tmp, delete=False).name
-
-  @staticmethod
-  def ToChrootPath(path):
-    """Converts the path outside the chroot to one that can be used inside."""
-    path = os.path.abspath(path)
-    if '/chroot/' not in path:
-      raise ValueError('Path %s is not a path that points inside the chroot' %
-                       path)
-
-    return '/' + path.partition('/chroot/')[2]
-
-  def _WaitUntilStarted(self):
-    """Wait until the devserver has started."""
-    current_time = time.time()
-    deadline = current_time + DEV_SERVER_TIMEOUT
-    while current_time <= deadline:
-      try:
-        if not self.is_alive():
-          raise DevServerException('Devserver crashed while starting')
-
-        urllib2.urlopen(CHECK_HEALTH_URL, timeout=0.05)
-        return
-      except IOError:
-        # urlopen errors will throw a subclass of IOError if we can't connect.
-        pass
-      finally:
-        # Let's not churn needlessly in this loop as the devserver starts up.
-        time.sleep(1)
-
-      current_time = time.time()
-    else:
-      self.terminate()
-      raise DevServerException('Devserver did not start')
-
-  def run(self):
-    """Kicks off devserver in a separate process and waits for it to finish."""
-    cmd = ['start_devserver',
-           '--pidfile', DevServerWrapper.ToChrootPath(self._pid_file),
-           '--logfile', DevServerWrapper.ToChrootPath(self._log_filename)]
-    return_obj = cros_build_lib.SudoRunCommand(
-        cmd, enter_chroot=True, debug_level=logging.DEBUG,
-        cwd=constants.SOURCE_ROOT, error_code_ok=True,
-        redirect_stdout=True, combine_stdout_stderr=True)
-    if return_obj.returncode != 0:
-      logging.error('Devserver terminated unexpectedly!')
-      logging.error(return_obj.output)
-
-  def Start(self):
-    """Starts a background devserver and waits for it to start.
-
-    Starts a background devserver and waits for it to start. Will only return
-    once devserver has started and running pid has been read.
-    """
-    self.start()
-    self._WaitUntilStarted()
-    # Pid file was passed into the chroot.
-    with open(self._pid_file, 'r') as f:
-      self._pid = f.read()
-
-  def Stop(self):
-    """Kills the devserver instance with SIGTERM and SIGKILL if SIGTERM fails"""
-    if not self._pid:
-      logging.error('No devserver running.')
-      return
-
-    logging.debug('Stopping devserver instance with pid %s', self._pid)
-    if self.is_alive():
-      cros_build_lib.SudoRunCommand(['kill', self._pid],
-                                    debug_level=logging.DEBUG)
-    else:
-      logging.error('Devserver not running!')
-      return
-
-    self.join(KILL_TIMEOUT)
-    if self.is_alive():
-      logging.warning('Devserver is unstoppable. Killing with SIGKILL')
-      cros_build_lib.SudoRunCommand(['kill', '-9', self._pid],
-                                    debug_level=logging.DEBUG)
-
-  def PrintLog(self):
-    """Print devserver output to stdout."""
-    print '--- Start output from %s ---' % self._log_filename
-    # Open in update mode in case the child process hasn't opened the file yet.
-    with open(self._log_filename) as log:
-      sys.stdout.writelines(log)
-
-    print '--- End output from %s ---' % self._log_filename
-
-  @classmethod
-  def GetDevServerURL(cls, port=None, sub_dir=None):
-    """Returns the dev server url for a given port and sub directory."""
-    if not port: port = 8080
-    url = 'http://%(ip)s:%(port)s' % {'ip': GetIPAddress(), 'port': str(port)}
-    if sub_dir:
-      url += '/' + sub_dir
-
-    return url
-
-  @classmethod
-  def WipePayloadCache(cls):
-    """Cleans up devserver cache of payloads."""
-    cros_build_lib.Info('Cleaning up previously generated payloads.')
-    cmd = ['start_devserver', '--clear_cache', '--exit']
-    cros_build_lib.SudoRunCommand(
-        cmd, enter_chroot=True, print_cmd=False, combine_stdout_stderr=True,
-        redirect_stdout=True, redirect_stderr=True, cwd=constants.SOURCE_ROOT)
diff --git a/lib/dev_server_wrapper_stress_test.py b/lib/dev_server_wrapper_stress_test.py
deleted file mode 100755
index b10b907..0000000
--- a/lib/dev_server_wrapper_stress_test.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/python
-
-# Copyright (c) 2013 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.
-
-"""Stress test for dev_server_wrapper.
-
-Test script runs a long time stressing the ability to start and stop the
-dev_server_wrapper. Even very rare hangs will cause significant build flake.
-"""
-
-import logging
-import sys
-
-import constants
-sys.path.append(constants.CROS_PLATFORM_ROOT)
-sys.path.append(constants.SOURCE_ROOT)
-
-from crostestutils.lib import dev_server_wrapper
-
-
-_ITERATIONS = 10000
-
-
-def main():
-  logging.getLogger().setLevel(logging.DEBUG)
-  for i in range(_ITERATIONS):
-    print 'Iteration {}'.format(i)
-    wrapper = dev_server_wrapper.DevServerWrapper()
-    print 'Starting'
-    wrapper.Start()
-    print 'Stopping'
-    wrapper.Stop()
-
-
-if __name__ == '__main__':
-  main()