You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
2.2 KiB
75 lines
2.2 KiB
# Copyright 2017 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.
|
|
from contextlib import contextmanager
|
|
|
|
import logging
|
|
import multiprocessing
|
|
import os
|
|
import shutil
|
|
import tempfile
|
|
import SocketServer
|
|
import SimpleHTTPServer
|
|
|
|
import common
|
|
from autotest_lib.client.bin import utils
|
|
from autotest_lib.client.common_lib import error
|
|
from autotest_lib.site_utils.lxc import constants
|
|
|
|
|
|
@contextmanager
|
|
def serve_locally(file_path):
|
|
"""Starts an http server on the localhost, to serve the given file.
|
|
|
|
Copies the given file to a temporary location, then starts a local http
|
|
server to serve that file. Intended for use with unit tests that require
|
|
some URL to download a file (see testInstallSsp as an example).
|
|
|
|
@param file_path: The path of the file to serve.
|
|
|
|
@return The URL at which the file will be served.
|
|
"""
|
|
p = None
|
|
try:
|
|
# Copy the target file into a tmpdir for serving.
|
|
tmpdir = tempfile.mkdtemp()
|
|
shutil.copy(file_path, tmpdir)
|
|
|
|
httpd = SocketServer.TCPServer(
|
|
('', 0), SimpleHTTPServer.SimpleHTTPRequestHandler)
|
|
port = httpd.socket.getsockname()[1]
|
|
|
|
# Start the http daemon in the tmpdir to serve the file.
|
|
def serve():
|
|
"""Serves the tmpdir."""
|
|
os.chdir(tmpdir)
|
|
httpd.serve_forever()
|
|
p = multiprocessing.Process(target=serve)
|
|
p.daemon = True
|
|
p.start()
|
|
|
|
utils.poll_for_condition(
|
|
condition=lambda: http_up(port),
|
|
timeout=constants.NETWORK_INIT_TIMEOUT,
|
|
sleep_interval=constants.NETWORK_INIT_CHECK_INTERVAL)
|
|
url = 'http://127.0.0.1:{port}/{filename}'.format(
|
|
port=port, filename=os.path.basename(file_path))
|
|
logging.debug('Serving %s as %s', file_path, url)
|
|
yield url
|
|
finally:
|
|
if p is not None:
|
|
p.terminate()
|
|
shutil.rmtree(tmpdir)
|
|
|
|
|
|
def http_up(port):
|
|
"""Checks for an http server on localhost:port.
|
|
|
|
@param port: The port to check.
|
|
"""
|
|
try:
|
|
utils.run('curl --head http://127.0.0.1:%d' % port)
|
|
return True
|
|
except error.CmdError:
|
|
return False
|