Gilad Arnold | 7de05f7 | 2014-02-14 21:14:20 | [diff] [blame] | 1 | #!/usr/bin/python |
| 2 | # |
| 3 | # Copyright (c) 2014 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 cherrypy_ext.""" |
| 8 | |
| 9 | import cherrypy |
| 10 | import tempfile |
| 11 | import unittest |
| 12 | |
| 13 | import mox |
| 14 | |
| 15 | import cherrypy_ext |
| 16 | |
| 17 | |
| 18 | class CherrypyExtTest(mox.MoxTestBase): |
| 19 | """Tests for the cherrypy_ext module.""" |
| 20 | |
| 21 | def testPortFile(self): |
| 22 | """Check that PortFile correctly reports a bound port.""" |
| 23 | with tempfile.NamedTemporaryFile(delete=False) as f: |
| 24 | portfile = f.name |
| 25 | bus = self.mox.CreateMock(cherrypy.engine) |
| 26 | self.mox.StubOutWithMock(bus, 'log') |
| 27 | bus.log(mox.IsA(str)).MultipleTimes() |
| 28 | |
| 29 | cherrypy.server = self.mox.CreateMock(object) |
| 30 | cherrypy.server.httpserver = self.mox.CreateMock(object) |
| 31 | cherrypy.server.httpserver.socket = self.mox.CreateMock(object) |
| 32 | cherrypy.server.httpserver.socket.getsockname = None |
| 33 | self.mox.StubOutWithMock(cherrypy.server.httpserver.socket, 'getsockname') |
| 34 | cherrypy.server.httpserver.socket.getsockname().AndReturn(None) |
| 35 | cherrypy.server.httpserver.socket.getsockname().AndReturn(('', 55555)) |
| 36 | |
| 37 | self.mox.ReplayAll() |
| 38 | |
| 39 | plugin = cherrypy_ext.PortFile(bus, portfile) |
| 40 | plugin.start() # Signal server start; no socket binding yet. |
| 41 | with open(portfile) as f: |
| 42 | self.assertEqual('', f.read()) |
| 43 | plugin.log('foo', 1) # Emit a log signal; socket "bound" at this point. |
| 44 | with open(portfile) as f: |
| 45 | self.assertEqual('55555', f.read()) |
| 46 | |
| 47 | self.mox.VerifyAll() |
| 48 | |
| 49 | def testZeroPortPatcherSuccess(self): |
| 50 | """Make sure that ZeroPatcher successfully patches CherryPy. |
| 51 | |
| 52 | This merely ensures that the patcher applies cleanly to the CherryPy |
| 53 | version available to the test environment, giving us some assurance that |
| 54 | it's still compatible with the range of versions that we might be using it |
| 55 | with. The actual testing of the arbitrary port binding feature is covered |
| 56 | by integration tests. |
| 57 | """ |
| 58 | self.assertIsNone(cherrypy_ext.ZeroPortPatcher.DoPatch(cherrypy)) |
| 59 | |
| 60 | def testZeroPortPatcherFailure(self): |
| 61 | """Make sure that ZeroPatcher fails with an incompatible CherryPy. |
| 62 | |
| 63 | This ensures that the patcher fails when applied to a CherryPy version that |
| 64 | does not have the desired properties. |
| 65 | """ |
| 66 | module = cherrypy.process.servers |
| 67 | func_name = 'wait_for_free_port' |
| 68 | orig_func = getattr(module, func_name, None) |
| 69 | self.assertTrue(orig_func) |
| 70 | delattr(module, func_name) |
| 71 | self.assertRaises(AttributeError, cherrypy_ext.ZeroPortPatcher.DoPatch, |
| 72 | cherrypy) |
| 73 | setattr(module, func_name, orig_func) |
| 74 | |
| 75 | |
| 76 | if __name__ == '__main__': |
| 77 | unittest.main() |