net_test_server.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. # Copyright 2018 The Chromium Authors. All rights reserved.
  2. # Use of this source code is governed by a BSD-style license that can be
  3. # found in the LICENSE file.
  4. import common
  5. import json
  6. import logging
  7. import os
  8. import re
  9. import socket
  10. import sys
  11. import subprocess
  12. import tempfile
  13. DIR_SOURCE_ROOT = os.path.abspath(
  14. os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
  15. sys.path.append(os.path.join(DIR_SOURCE_ROOT, 'build', 'util', 'lib', 'common'))
  16. import chrome_test_server_spawner
  17. # Implementation of chrome_test_server_spawner.PortForwarder that uses SSH's
  18. # remote port forwarding feature to forward ports.
  19. class SSHPortForwarder(chrome_test_server_spawner.PortForwarder):
  20. def __init__(self, target):
  21. self._target = target
  22. # Maps the host (server) port to the device port number.
  23. self._port_mapping = {}
  24. def Map(self, port_pairs):
  25. for p in port_pairs:
  26. _, host_port = p
  27. self._port_mapping[host_port] = \
  28. common.ConnectPortForwardingTask(self._target, host_port)
  29. def GetDevicePortForHostPort(self, host_port):
  30. return self._port_mapping[host_port]
  31. def Unmap(self, device_port):
  32. for host_port, entry in self._port_mapping.items():
  33. if entry == device_port:
  34. forwarding_args = [
  35. '-NT', '-O', 'cancel', '-R', '0:localhost:%d' % host_port]
  36. task = self._target.RunCommandPiped([],
  37. ssh_args=forwarding_args,
  38. stdout=open(os.devnull, 'w'),
  39. stderr=subprocess.PIPE)
  40. task.wait()
  41. if task.returncode != 0:
  42. raise Exception(
  43. 'Error %d when unmapping port %d' % (task.returncode,
  44. device_port))
  45. del self._port_mapping[host_port]
  46. return
  47. raise Exception('Unmap called for unknown port: %d' % device_port)
  48. def SetupTestServer(target, test_concurrency):
  49. """Provisions a forwarding test server and configures |target| to use it.
  50. Args:
  51. target: The target to which port forwarding to the test server will be
  52. established.
  53. test_concurrency: The number of parallel test jobs that will be run.
  54. Returns a tuple of a Popen object for the test server process and the local
  55. url to use on `target` to reach the test server."""
  56. logging.debug('Starting test server.')
  57. # The TestLauncher can launch more jobs than the limit specified with
  58. # --test-launcher-jobs so the max number of spawned test servers is set to
  59. # twice that limit here. See https://crbug.com/913156#c19.
  60. spawning_server = chrome_test_server_spawner.SpawningServer(
  61. 0, SSHPortForwarder(target), test_concurrency * 2)
  62. forwarded_port = common.ConnectPortForwardingTask(
  63. target, spawning_server.server_port)
  64. spawning_server.Start()
  65. logging.debug('Test server listening for connections (port=%d)' %
  66. spawning_server.server_port)
  67. logging.debug('Forwarded port is %d' % forwarded_port)
  68. return (spawning_server, 'http://localhost:%d' % forwarded_port)