12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#!/usr/bin/env python
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved.
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# found in the LICENSE file.
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import os
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import Queue
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import sys
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import subprocess
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import threading
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import unittest
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import urllib2
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PARENT_DIR = os.path.dirname(SCRIPT_DIR)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)sys.path.append(PARENT_DIR)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import httpd
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class HTTPDTest(unittest.TestCase):
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def setUp(self):
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    self.server = httpd.LocalHTTPServer('.', 0)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def tearDown(self):
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.server.Shutdown()
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def testQuit(self):
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    urllib2.urlopen(self.server.GetURL('?quit=1'))
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.server.process.join(10)  # Wait 10 seconds for the process to finish.
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.assertFalse(self.server.process.is_alive())
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class RunTest(unittest.TestCase):
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def setUp(self):
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.process = None
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def tearDown(self):
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if self.process and self.process.returncode is None:
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self.process.kill()
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  @staticmethod
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def _SubprocessThread(process, queue):
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stdout, stderr = process.communicate()
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    queue.put((process.returncode, stdout, stderr))
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def _Run(self, args=None, timeout=None):
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    args = args or []
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    run_py = os.path.join(PARENT_DIR, 'run.py')
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cmd = [sys.executable, run_py]
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cmd.extend(args)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.process = subprocess.Popen(cmd, stdout=subprocess.PIPE,
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    stderr=subprocess.PIPE)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    queue = Queue.Queue()
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    thread = threading.Thread(target=RunTest._SubprocessThread,
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              args=(self.process, queue))
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    thread.daemon = True
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    thread.start()
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    thread.join(timeout)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if not thread.is_alive():
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      returncode, stdout, stderr = queue.get(False)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return returncode, stdout, stderr
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return -1, None, None
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def _GetChromeMockArgs(self, page, http_request_type, sleep,
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         expect_to_be_killed=True):
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    args = []
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if page:
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      args.extend(['-P', page])
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    args.append('--')
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    args.extend([sys.executable, os.path.join(SCRIPT_DIR, 'chrome_mock.py')])
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if http_request_type:
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      args.append('--' + http_request_type)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if sleep:
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      args.extend(['--sleep', str(sleep)])
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if expect_to_be_killed:
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      args.append('--expect-to-be-killed')
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return args
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def testQuit(self):
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    args = self._GetChromeMockArgs('?quit=1', 'get', sleep=10)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    _, stdout, _ = self._Run(args, timeout=20)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.assertTrue('Starting' in stdout)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.assertTrue('Expected to be killed' not in stdout)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def testSubprocessDies(self):
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    args = self._GetChromeMockArgs(page=None, http_request_type=None, sleep=0,
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   expect_to_be_killed=False)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    returncode, stdout, _ = self._Run(args, timeout=10)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.assertNotEqual(-1, returncode)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.assertTrue('Starting' in stdout)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)if __name__ == '__main__':
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unittest.main()
98