#!/usr/bin/env vpython
# Copyright (c) 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import os
import shutil
import SocketServer
import subprocess
import sys
import tempfile
import threading
import time
import unittest


CONFIG_PRIVATE_DOT_PY_TEMPLATE = '''
PublicMaster = object()

class Master(object):
  server_url = ''
  repo_root = ''
  webkit_root_url = ''
  git_server_url = ''
  googlecode_url = '%%s'

  bot_password = 'banana'

  class SmokeTest(object):
    master_host = 'localhost'
    slave_port = %(slave_port)d
'''

BOOTSTRAPPER_PY_TEMPLATE = '''#!/usr/bin/env python
import sys, os

# Hack up sys.path to import our hacked config_private.py module.
sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))
import config_private
sys.path.pop(0)

# These envvars reflect values in config_private.py above.
os.environ['TESTING_MASTER'] = 'SmokeTest'
os.environ['TESTING_SLAVENAME'] = 'test-slave-name'

# We need to fake out __file__ because run_slave_py computes paths relative to
# itself. We need to "become" run_slave.py.
RUN_SLAVE_PY = %(run_slave_py)r
__file__ = RUN_SLAVE_PY

execfile(RUN_SLAVE_PY)
'''

class SlaveShouldSend(str):
  pass


class MasterSends(str):
  pass


# This is a twisted pb handshake between a buildbot slave called
# "test-slave-name" and a buildbot master, using the password "banana".
HANDSHAKE = [
    MasterSends('\x02\x80\x02\x82pb\x04\x82none'),
    SlaveShouldSend('\x02\x82pb\x02\x80\x13\x87\x06\x81\x07\x80\x1a\x87\x01'
                    '\x81\x04\x82root\x14\x87\x01\x81\x02\x80\x0b\x87\x0f'
                    '\x82test-slave-name\x01\x80\x05\x87'),
    MasterSends('\x02\x80\x13\x87\x06\x81\x03\x80\x1b\x87\x01\x81\x03\x80\x0b'
                '\x87\x10\x82?\r5[\xcc\x13\x8a\x15\x80\x983\x19i~D\xa0\x02\x80'
                '\x10\x87\x01\x81'),
    SlaveShouldSend('\x07\x80\x1a\x87\x02\x81\x01\x81\x07\x82respond\x01\x81'
                    '\x03\x80\x0b\x87\x10\x82\x0c\x17L\xc1\xc10\xf0\x08\x05'
                    '\x92\x9b\r\xae\x93O\xef\x02\x80\x10\x87\x01\x81\x01\x80'
                    '\x05\x87\x02\x80\x1d\x87\x01\x81'),
    MasterSends('\x07\x80\x1a\x87\x01\x81\x01\x81\x05\x82print\x01\x81\x02\x80'
                '\x0b\x87\x0d\x82test message!\x01\x80\x05\x87'),
]


class FakeBuildmasterRequestHandler(SocketServer.BaseRequestHandler):
  def handle(self):
    for data in HANDSHAKE:
      if isinstance(data, MasterSends):
        self.request.sendall(data)
      elif isinstance(data, SlaveShouldSend):
        self.server.data_received.append(self.request.recv(1024))

  def finish(self):
    # Give the slave process a chance to output the "test message!", and then
    # terminate it.
    time.sleep(0.5)
    self.server.slave_process.terminate()


class FakeBuildmasterServer(SocketServer.TCPServer):
  def __init__(self, *args, **kwargs):
    SocketServer.TCPServer.__init__(self, *args, **kwargs)
    self.data_received = []
    self.slave_process = None


class SlaveTest(unittest.TestCase):
  def setUp(self):
    os.environ['BUILDBOT_TEST_PASSWORD'] = 'banana'

    # Start a TCP server that pretends to be a buildmaster.
    self.server = FakeBuildmasterServer(
        ('localhost', 0), FakeBuildmasterRequestHandler)
    _, port = self.server.server_address
    self.server_thread = threading.Thread(target=self.server.serve_forever)
    self.server_thread.setDaemon(True)
    self.server_thread.start()

    # Write a config_private.py file in a temporary directory pointing to the
    # port we're listening on.  The slave process will import this file to
    # figure out what port it should connect to.
    self.temp_dir = tempfile.mkdtemp()
    with open(os.path.join(self.temp_dir, 'config_private.py'), 'w') as fh:
      fh.write(CONFIG_PRIVATE_DOT_PY_TEMPLATE % {'slave_port': port})

    # Get the path to run_slave.py.
    run_slave = os.path.abspath(
        os.path.join(os.path.dirname(__file__), '..', 'slave', 'run_slave.py'))

    self.boostrapper_py = os.path.join(self.temp_dir, 'test_bootstrapper.py')

    with open(self.boostrapper_py, 'w') as fh:
      fh.write(BOOTSTRAPPER_PY_TEMPLATE % {'run_slave_py': run_slave})
    os.chmod(self.boostrapper_py, 0777)

  def tearDown(self):
    shutil.rmtree(self.temp_dir)
    self.server.shutdown()
    os.environ.pop('BUILDBOT_TEST_PASSWORD', None)

  def test_slave_connects(self):
    # Start the slave.
    handle = subprocess.Popen([
        self.boostrapper_py,
        '--no-gclient-sync',
        '-y',
        'buildbot.tac',
        '--nodaemon',
    ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

    # The HTTP handler will kill the slave after it's finished the handshake.
    self.server.slave_process = handle

    # Kill the slave after 30 seconds if it doesn't connect at all.
    timer = threading.Timer(30, handle.kill)
    timer.start()
    try:
      output, _ = handle.communicate()
    finally:
      timer.cancel()

    self.assertEqual([x for x in HANDSHAKE if isinstance(x, SlaveShouldSend)],
                     self.server.data_received)
    self.assertIn('message from master: test message!', output)


if __name__ == '__main__':
  unittest.main()
