dev_server_unittest.py revision 761341eafc11de617743ca8126a3b1a3b9f9c430
1#!/usr/bin/python 2# 3# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7"""Unit tests for client/common_lib/cros/dev_server.py.""" 8 9import httplib 10import logging 11import mox 12import StringIO 13import unittest 14import urllib2 15 16from autotest_lib.client.common_lib.cros import dev_server 17 18 19class DevServerTest(mox.MoxTestBase): 20 """Unit tests for dev_server.DevServer. 21 22 @var _HOST: fake dev server host address. 23 """ 24 25 _HOST = 'http://nothing' 26 _CRASH_HOST = 'http://nothing-crashed' 27 28 def setUp(self): 29 super(DevServerTest, self).setUp() 30 self.dev_server = dev_server.DevServer(self._HOST, self._CRASH_HOST) 31 32 33 def _returnHttpServerError(self): 34 self.mox.StubOutWithMock(urllib2, 'urlopen') 35 e500 = urllib2.HTTPError(url='', 36 code=httplib.INTERNAL_SERVER_ERROR, 37 msg='', 38 hdrs=None, 39 fp=StringIO.StringIO('Expected.')) 40 urllib2.urlopen(mox.IgnoreArg()).AndRaise(e500) 41 42 43 def _returnHttpForbidden(self): 44 self.mox.StubOutWithMock(urllib2, 'urlopen') 45 e403 = urllib2.HTTPError(url='', 46 code=httplib.FORBIDDEN, 47 msg='', 48 hdrs=None, 49 fp=StringIO.StringIO('Expected.')) 50 urllib2.urlopen(mox.IgnoreArg()).AndRaise(e403) 51 52 53 def testSuccessfulTriggerDownloadSync(self): 54 """Call the dev server's download method with synchronous=True.""" 55 name = 'fake/image' 56 self.mox.StubOutWithMock(urllib2, 'urlopen') 57 self.mox.StubOutWithMock(dev_server.DevServer, 'finish_download') 58 to_return = StringIO.StringIO('Success') 59 urllib2.urlopen(mox.And(mox.StrContains(self._HOST), 60 mox.StrContains(name))).AndReturn(to_return) 61 self.dev_server.finish_download(name) 62 63 # Synchronous case requires a call to finish download. 64 self.mox.ReplayAll() 65 self.dev_server.trigger_download(name, synchronous=True) 66 self.mox.VerifyAll() 67 68 69 def testSuccessfulTriggerDownloadASync(self): 70 """Call the dev server's download method with synchronous=False.""" 71 name = 'fake/image' 72 self.mox.StubOutWithMock(urllib2, 'urlopen') 73 self.mox.StubOutWithMock(dev_server.DevServer, 'finish_download') 74 to_return = StringIO.StringIO('Success') 75 urllib2.urlopen(mox.And(mox.StrContains(self._HOST), 76 mox.StrContains(name))).AndReturn(to_return) 77 78 self.mox.ReplayAll() 79 self.dev_server.trigger_download(name, synchronous=False) 80 self.mox.VerifyAll() 81 82 83 def testErrorTriggerDownload(self): 84 """Should call the dev server's download method, fail gracefully.""" 85 self._returnHttpForbidden() 86 self.mox.ReplayAll() 87 self.assertRaises(dev_server.DevServerException, 88 self.dev_server.trigger_download, 89 '') 90 91 92 def testForbiddenTriggerDownload(self): 93 """Should call the dev server's download method, get exception.""" 94 self._returnHttpForbidden() 95 self.mox.ReplayAll() 96 self.assertRaises(dev_server.DevServerException, 97 self.dev_server.trigger_download, 98 '') 99 100 101 def testSuccessfulFinishDownload(self): 102 """Should successfully call the dev server's finish download method.""" 103 name = 'fake/image' 104 self.mox.StubOutWithMock(urllib2, 'urlopen') 105 to_return = StringIO.StringIO('Success') 106 urllib2.urlopen(mox.And(mox.StrContains(self._HOST), 107 mox.StrContains(name))).AndReturn(to_return) 108 109 # Synchronous case requires a call to finish download. 110 self.mox.ReplayAll() 111 self.dev_server.finish_download(name) # Raises on failure. 112 self.mox.VerifyAll() 113 114 115 def testErrorTriggerDownload(self): 116 """Should call the dev server's finish download method, fail gracefully. 117 """ 118 self._returnHttpServerError() 119 self.mox.ReplayAll() 120 self.assertRaises(dev_server.DevServerException, 121 self.dev_server.finish_download, 122 '') 123 124 125 def testListControlFiles(self): 126 """Should successfully list control files from the dev server.""" 127 name = 'fake/build' 128 control_files = ['file/one', 'file/two'] 129 self.mox.StubOutWithMock(urllib2, 'urlopen') 130 to_return = StringIO.StringIO('\n'.join(control_files)) 131 urllib2.urlopen(mox.And(mox.StrContains(self._HOST), 132 mox.StrContains(name))).AndReturn(to_return) 133 self.mox.ReplayAll() 134 paths = self.dev_server.list_control_files(name) 135 self.assertEquals(len(paths), 2) 136 for f in control_files: 137 self.assertTrue(f in paths) 138 139 140 def testFailedListControlFiles(self): 141 """Should call the dev server's list-files method, get exception.""" 142 self._returnHttpServerError() 143 self.mox.ReplayAll() 144 self.assertRaises(dev_server.DevServerException, 145 self.dev_server.list_control_files, 146 '') 147 148 149 def testExplodingListControlFiles(self): 150 """Should call the dev server's list-files method, get exception.""" 151 self._returnHttpForbidden() 152 self.mox.ReplayAll() 153 self.assertRaises(dev_server.DevServerException, 154 self.dev_server.list_control_files, 155 '') 156 157 158 def testGetControlFile(self): 159 """Should successfully get a control file from the dev server.""" 160 name = 'fake/build' 161 file = 'file/one' 162 contents = 'Multi-line\nControl File Contents\n' 163 self.mox.StubOutWithMock(urllib2, 'urlopen') 164 to_return = StringIO.StringIO(contents) 165 urllib2.urlopen(mox.And(mox.StrContains(self._HOST), 166 mox.StrContains(name), 167 mox.StrContains(file))).AndReturn(to_return) 168 self.mox.ReplayAll() 169 self.assertEquals(self.dev_server.get_control_file(name, file), 170 contents) 171 172 173 def testErrorGetControlFile(self): 174 """Should try to get the contents of a control file, get exception.""" 175 self._returnHttpServerError() 176 self.mox.ReplayAll() 177 self.assertRaises(dev_server.DevServerException, 178 self.dev_server.get_control_file, 179 '', '') 180 181 182 def testForbiddenGetControlFile(self): 183 """Should try to get the contents of a control file, get exception.""" 184 self._returnHttpForbidden() 185 self.mox.ReplayAll() 186 self.assertRaises(dev_server.DevServerException, 187 self.dev_server.get_control_file, 188 '', '') 189 190 191 def testGetLatestBuild(self): 192 """Should successfully return a build for a given target.""" 193 target = 'x86-generic-release' 194 build_string = 'R18-1586.0.0-a1-b1514' 195 self.mox.StubOutWithMock(urllib2, 'urlopen') 196 to_return = StringIO.StringIO(build_string) 197 urllib2.urlopen(mox.And(mox.StrContains(self._HOST), 198 mox.StrContains(target))).AndReturn(to_return) 199 self.mox.ReplayAll() 200 build = self.dev_server.get_latest_build(target) 201 self.assertEquals(build_string, build) 202 203 204 def testThatWeCorrectlyReHashToTheSameDevserver(self): 205 """Ensure calls with same hashing_value go to the same devserver.""" 206 for index in range(10): 207 self.dev_server._dev_servers.append('http://nothing_%d' % index) 208 209 method_name = 'my_method' 210 hv1 = 'iliketacos' 211 hv2 = 'iliketacos' 212 hv3 = 'idontliketacos :(' 213 hv4 = 'idontliketacos :(' 214 215 call1 = self.dev_server._build_call(method_name, hashing_value=hv1) 216 call2 = self.dev_server._build_call(method_name, hashing_value=hv2, 217 some_arg='value') 218 call3 = self.dev_server._build_call(method_name, hashing_value=hv3) 219 call4 = self.dev_server._build_call(method_name, hashing_value=hv4, 220 some_arg='value') 221 222 self.assertTrue(call2.startswith(call1)) 223 self.assertTrue(call4.startswith(call3)) 224 225 226 def testGetLatestBuildWithManyDevservers(self): 227 """Should successfully return newest build with multiple devservers.""" 228 self.dev_server._dev_servers.append('http://nothing_2') 229 self.dev_server._dev_servers.append('http://nothing_3') 230 target = 'x86-generic-release' 231 build_string1 = 'R9-1586.0.0-a1-b1514' 232 build_string2 = 'R19-1586.0.0-a1-b3514' 233 build_string3 = 'R18-1486.0.0-a1-b2514' 234 self.mox.StubOutWithMock(urllib2, 'urlopen') 235 to_return1 = StringIO.StringIO(build_string1) 236 to_return2 = StringIO.StringIO(build_string2) 237 to_return3 = StringIO.StringIO(build_string3) 238 urllib2.urlopen(mox.And(mox.StrContains(self._HOST), 239 mox.StrContains(target))).AndReturn(to_return1) 240 urllib2.urlopen(mox.And(mox.StrContains(self._HOST), 241 mox.StrContains(target))).AndReturn(to_return2) 242 urllib2.urlopen(mox.And(mox.StrContains(self._HOST), 243 mox.StrContains(target))).AndReturn(to_return3) 244 245 self.mox.ReplayAll() 246 build = self.dev_server.get_latest_build(target) 247 self.assertEquals(build_string2, build) 248 249 250 def testCrashesAreSetToTheCrashServer(self): 251 """Should send symbolicate dump rpc calls to crash_server.""" 252 hv = 'iliketacos' 253 self.mox.ReplayAll() 254 call = self.dev_server._build_call('symbolicate_dump', hashing_value=hv) 255 self.assertTrue(call.startswith(self._CRASH_HOST)) 256