def test_handle_GET_internal_server_error(self): """ A GET request that causes an exception simply returns a 500 (Internal Server Error). """ test_key = hashlib.sha512().hexdigest() mockMessage = mock.MagicMock() mockMessage.method = 'GET' mockMessage.version = '1.1' mockMessage.path = ''.join(['/', test_key]) connector = HttpConnector(self.event_loop) def faux_get(*args, **kwargs): raise Exception('Bang!') connector.get = mock.MagicMock(side_effect=faux_get) node = Node(PUBLIC_KEY, PRIVATE_KEY, self.event_loop, connector, 1908) hrh = HttpRequestHandler(connector, node, debug=True) peer = '192.168.0.1' hrh.transport = mock.MagicMock() hrh.transport.get_extra_info = mock.MagicMock(side_effect=peer) hrh.writer = mock.MagicMock() with mock.patch.object(aiohttp, 'Response', return_value=mock.MagicMock()) as response: self.event_loop.run_until_complete(hrh.handle_request(mockMessage, None)) response.assert_called_once_with(hrh.writer, 500, http_version=mockMessage.version)
def test_handle_GET_request(self): """ A valid GET request casues a 200 reponse. """ test_key = hashlib.sha512().hexdigest() mockMessage = mock.MagicMock() mockMessage.method = 'GET' mockMessage.version = '1.1' mockMessage.path = ''.join(['/', test_key]) connector = HttpConnector(self.event_loop) def faux_get(*args, **kwargs): return { 'key': test_key, 'status': 'pending', } connector.get = mock.MagicMock(side_effect=faux_get) node = Node(PUBLIC_KEY, PRIVATE_KEY, self.event_loop, connector, 1908) hrh = HttpRequestHandler(connector, node, debug=True) peer = '192.168.0.1' hrh.transport = mock.MagicMock() hrh.transport.get_extra_info = mock.MagicMock(side_effect=peer) hrh.writer = mock.MagicMock() with mock.patch.object(aiohttp, 'Response', return_value=mock.MagicMock()) as response: self.event_loop.run_until_complete(hrh.handle_request(mockMessage, None)) response.assert_called_once_with(hrh.writer, 200, http_version=mockMessage.version)
def test_handle_GET_no_cache(self): """ Ensure that if the cache-control header in the request is set to no-cache then the lookup is foreced (i.e. don't use the local cache). """ test_key = hashlib.sha512().hexdigest() mockMessage = mock.MagicMock() mockMessage.method = 'GET' mockMessage.version = '1.1' mockMessage.path = ''.join(['/', test_key]) mockMessage.headers = {'Cache-Control': 'no-cache', } connector = HttpConnector(self.event_loop) def faux_get(*args, **kwargs): return { 'key': test_key, 'status': 'pending', } connector.get = mock.MagicMock(side_effect=faux_get) node = Node(PUBLIC_KEY, PRIVATE_KEY, self.event_loop, connector, 1908) hrh = HttpRequestHandler(connector, node, debug=True) peer = '192.168.0.1' hrh.transport = mock.MagicMock() hrh.transport.get_extra_info = mock.MagicMock(side_effect=peer) hrh.writer = mock.MagicMock() with mock.patch.object(aiohttp, 'Response', return_value=mock.MagicMock()) as response: self.event_loop.run_until_complete(hrh.handle_request(mockMessage, None)) response.assert_called_once_with(hrh.writer, 200, http_version=mockMessage.version) # The connector's get method was called with the forced flag set # to True. connector.get.assert_called_once_with(test_key, node, True)
def test_get_existing_lookup_failed(self): """ Getting an existing key that has resulted in an error returns a 'finished' status and an 'error' flag. """ connector = HttpConnector(self.event_loop) self.assertEqual({}, connector.lookups) handler = Node(PUBLIC_KEY, PRIVATE_KEY, self.event_loop, connector, 1908) faux_lookup = asyncio.Future() ex = Exception('Bang!') faux_lookup.set_exception(ex) test_key = hashlib.sha512().hexdigest() connector.lookups[test_key] = { 'last_access': 123.45, 'lookup': faux_lookup } result = connector.get(test_key, handler) self.assertIn(test_key, connector.lookups) self.assertTrue(connector.lookups[test_key]['last_access'] > 123.45) self.assertEqual(connector.lookups[test_key]['lookup'], faux_lookup) self.assertEqual(result['key'], test_key) self.assertEqual(result['status'], faux_lookup._state.lower()) self.assertEqual(result['error'], True) self.assertEqual(3, len(result))
def test_get_existing_lookup(self): """ Getting an existing key that has completed returns a 'finished' status and associated value. """ connector = HttpConnector(self.event_loop) self.assertEqual({}, connector.lookups) handler = Node(PUBLIC_KEY, PRIVATE_KEY, self.event_loop, connector, 1908) faux_lookup = asyncio.Future() faux_lookup.set_result('foo') test_key = hashlib.sha512().hexdigest() connector.lookups[test_key] = { 'last_access': 123.45, 'lookup': faux_lookup } result = connector.get(test_key, handler) self.assertIn(test_key, connector.lookups) # Check the last_access has been updated self.assertTrue(connector.lookups[test_key]['last_access'] > 123.45) self.assertEqual(connector.lookups[test_key]['lookup'], faux_lookup) self.assertEqual(result['key'], test_key) self.assertEqual(result['status'], faux_lookup._state.lower()) self.assertEqual(result['value'], 'foo') self.assertEqual(3, len(result))
def test_get_forced_refresh_no_existing_cached_value(self): """ Ensures that even if there's no cached value a new lookup is executed if the 'forced' flag is True. """ connector = HttpConnector(self.event_loop) self.assertEqual({}, connector.lookups) handler = Node(PUBLIC_KEY, PRIVATE_KEY, self.event_loop, connector, 1908) faux_lookup = asyncio.Future() handler.retrieve = mock.MagicMock(return_value=faux_lookup) test_key = hashlib.sha512().hexdigest() result = connector.get(test_key, handler, forced=True) handler.retrieve.assert_called_once_with(test_key) self.assertIn(test_key, connector.lookups) self.assertIsInstance(connector.lookups[test_key]['last_access'], float) self.assertEqual(connector.lookups[test_key]['lookup'], faux_lookup) self.assertEqual(result['key'], test_key) self.assertEqual(result['status'], faux_lookup._state.lower()) self.assertEqual(2, len(result))
def test_get_new_lookup(self): """ Getting an unknown key fires a new lookup that is initially produces a 'pending' status. """ connector = HttpConnector(self.event_loop) self.assertEqual({}, connector.lookups) handler = Node(PUBLIC_KEY, PRIVATE_KEY, self.event_loop, connector, 1908) faux_lookup = asyncio.Future() handler.retrieve = mock.MagicMock(return_value=faux_lookup) test_key = hashlib.sha512().hexdigest() result = connector.get(test_key, handler) handler.retrieve.assert_called_once_with(test_key) self.assertIn(test_key, connector.lookups) self.assertIsInstance(connector.lookups[test_key]['last_access'], float) self.assertEqual(connector.lookups[test_key]['lookup'], faux_lookup) self.assertEqual(result['key'], test_key) self.assertEqual(result['status'], faux_lookup._state.lower()) self.assertEqual(2, len(result))
def test_get_forced_refresh_existing_value(self): """ Ensures that an existing result is ignored and a new lookup is executed if the 'forced' flag is True. """ connector = HttpConnector(self.event_loop) self.assertEqual({}, connector.lookups) handler = Node(PUBLIC_KEY, PRIVATE_KEY, self.event_loop, connector, 1908) cached_lookup = asyncio.Future() cached_lookup.set_result('foo') test_key = hashlib.sha512().hexdigest() connector.lookups[test_key] = cached_lookup new_lookup = asyncio.Future() handler.retrieve = mock.MagicMock(return_value=new_lookup) result = connector.get(test_key, handler, forced=True) self.assertIn(test_key, connector.lookups) self.assertIsInstance(connector.lookups[test_key]['last_access'], float) self.assertEqual(connector.lookups[test_key]['lookup'], new_lookup) self.assertEqual(result['key'], test_key) self.assertEqual(result['status'], new_lookup._state.lower()) self.assertEqual(2, len(result))