1 # Copyright (C) 2011 Google Inc. All rights reserved. 2 # 3 # Redistribution and use in source and binary forms, with or without 4 # modification, are permitted provided that the following conditions are 5 # met: 6 # 7 # * Redistributions of source code must retain the above copyright 8 # notice, this list of conditions and the following disclaimer. 9 # * Redistributions in binary form must reproduce the above 10 # copyright notice, this list of conditions and the following disclaimer 11 # in the documentation and/or other materials provided with the 12 # distribution. 13 # * Neither the name of Google Inc. nor the names of its 14 # contributors may be used to endorse or promote products derived from 15 # this software without specific prior written permission. 16 # 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 import json 30 import sys 31 import webkitpy.thirdparty.unittest2 as unittest 32 33 from webkitpy.common.system.outputcapture import OutputCapture 34 from webkitpy.layout_tests.models.test_configuration import * 35 from webkitpy.layout_tests.port import builders 36 from webkitpy.thirdparty.mock import Mock 37 from webkitpy.tool.mocktool import MockTool 38 from webkitpy.common.system.executive_mock import MockExecutive 39 from webkitpy.common.host_mock import MockHost 40 from webkitpy.tool.servers.gardeningserver import * 41 42 43 class TestPortFactory(object): 44 # FIXME: Why is this a class method? 45 @classmethod 46 def create(cls): 47 host = MockHost() 48 return host.port_factory.get("test-win-xp") 49 50 @classmethod 51 def path_to_generic_test_expectations_file(cls): 52 return cls.create().path_to_generic_test_expectations_file() 53 54 55 class MockServer(object): 56 def __init__(self): 57 self.tool = MockTool() 58 self.tool.executive = MockExecutive(should_log=True) 59 self.tool.filesystem.files[TestPortFactory.path_to_generic_test_expectations_file()] = "" 60 61 62 # The real GardeningHTTPRequestHandler has a constructor that's too hard to 63 # call in a unit test, so we create a subclass that's easier to constrcut. 64 class TestGardeningHTTPRequestHandler(GardeningHTTPRequestHandler): 65 def __init__(self, server): 66 self.server = server 67 self.body = None 68 69 def _expectations_updater(self): 70 return GardeningExpectationsUpdater(self.server.tool, TestPortFactory.create()) 71 72 def read_entity_body(self): 73 return self.body if self.body else '' 74 75 def _serve_text(self, text): 76 print "== Begin Response ==" 77 print text 78 print "== End Response ==" 79 80 def _serve_json(self, json_object): 81 print "== Begin JSON Response ==" 82 print json.dumps(json_object) 83 print "== End JSON Response ==" 84 85 def _serve_xml(self, xml): 86 print "== Begin XML Response ==" 87 print xml 88 print "== End XML Response ==" 89 90 class GardeningServerTest(unittest.TestCase): 91 def _post_to_path(self, path, body=None, expected_stderr=None, expected_stdout=None, server=None): 92 handler = TestGardeningHTTPRequestHandler(server or MockServer()) 93 handler.path = path 94 handler.body = body 95 OutputCapture().assert_outputs(self, handler.do_POST, expected_stderr=expected_stderr, expected_stdout=expected_stdout) 96 97 def test_svnlog(self): 98 expected_stderr = '' 99 expected_stdout = '== Begin XML Response ==\nMOCK output of child process\n== End XML Response ==\n' 100 self._post_to_path('/svnlog', expected_stderr=expected_stderr, expected_stdout=expected_stdout) 101 102 def test_lastroll(self): 103 expected_stderr = 'MOCK run_command: [\'svn\', \'cat\', \'http://src.chromium.org/chrome/trunk/src/DEPS\'], cwd=None, input=None\n' 104 expected_stdout = '== Begin Response ==\n1\n== End Response ==\n' 105 server = MockServer() 106 107 self.output = [' "webkit_revision": "3",', 'lol'] 108 109 def run_command(args, cwd=None, input=None, **kwargs): 110 print >> sys.stderr, "MOCK run_command: %s, cwd=%s, input=%s" % (args, cwd, input) 111 return self.output.pop(0) 112 113 server.tool.executive.run_command = run_command 114 self._post_to_path('/lastroll', expected_stderr=expected_stderr, expected_stdout='== Begin Response ==\n3\n== End Response ==\n', server=server) 115 self._post_to_path('/lastroll', expected_stderr=expected_stderr, expected_stdout='== Begin Response ==\n0\n== End Response ==\n', server=server) 116 117 def disabled_test_rollout(self): 118 expected_stderr = "MOCK run_command: ['echo', 'rollout', '--force-clean', '--non-interactive', '2314', 'MOCK rollout reason'], cwd=/mock-checkout\n" 119 expected_stdout = "== Begin Response ==\nsuccess\n== End Response ==\n" 120 self._post_to_path("/rollout?revision=2314&reason=MOCK+rollout+reason", expected_stderr=expected_stderr, expected_stdout=expected_stdout) 121 122 def disabled_test_rebaselineall(self): 123 expected_stderr = "MOCK run_command: ['echo', 'rebaseline-json'], cwd=/mock-checkout, input={\"user-scripts/another-test.html\":{\"%s\": [%s]}}\n" 124 expected_stdout = "== Begin Response ==\nsuccess\n== End Response ==\n" 125 server = MockServer() 126 127 self.output = ['{"add": [], "delete": []}', ''] 128 129 def run_command(args, cwd=None, input=None, **kwargs): 130 print >> sys.stderr, "MOCK run_command: %s, cwd=%s, input=%s" % (args, cwd, input) 131 return self.output.pop(0) 132 133 server.tool.executive.run_command = run_command 134 self._post_to_path("/rebaselineall", body='{"user-scripts/another-test.html":{"MOCK builder": ["txt","png"]}}', expected_stderr=expected_stderr % ('MOCK builder', '"txt","png"'), expected_stdout=expected_stdout, server=server) 135 136 self._post_to_path("/rebaselineall", body='{"user-scripts/another-test.html":{"MOCK builder (Debug)": ["txt","png"]}}', expected_stderr=expected_stderr % ('MOCK builder (Debug)', '"txt","png"'), expected_stdout=expected_stdout) 137