1# Copyright 2014 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import unittest 6 7from telemetry.unittest import simple_mock 8from telemetry.core.backends.chrome import inspector_websocket 9from telemetry.core.backends.chrome import websocket 10 11 12class FakeSocket(object): 13 """ A fake socket that: 14 + Receives first package of data after 10 second in the first recv(). 15 + Receives second package of data after 10 second in the second recv(). 16 + Raises a websocket.WebSocketTimeoutException after 15 seconds in the 17 third recv(). 18 + Raises a websocket.WebSocketTimeoutException after 15 seconds in the 19 fourth recv(). 20 + Receives third package of data after 10 second in the fifth recv(). 21 + Receives last package of data (containing 'method') after 10 second 22 in the last recv(). 23 """ 24 def __init__(self, mock_timer): 25 self._mock_timer = mock_timer 26 self._recv_counter = 0 27 28 def recv(self): 29 self._recv_counter += 1 30 if self._recv_counter == 1: 31 self._mock_timer.SetTime(10) 32 return '["foo"]' 33 elif self._recv_counter == 2: 34 self._mock_timer.SetTime(20) 35 return '["bar"]' 36 elif self._recv_counter == 3: 37 self._mock_timer.SetTime(35) 38 raise websocket.WebSocketTimeoutException() 39 elif self._recv_counter == 4: 40 self._mock_timer.SetTime(50) 41 raise websocket.WebSocketTimeoutException() 42 elif self._recv_counter == 5: 43 self._mock_timer.SetTime(60) 44 return '["baz"]' 45 elif self._recv_counter == 6: 46 self._mock_timer.SetTime(70) 47 return '["method"]' 48 49 def settimeout(self, timeout): 50 pass 51 52 53def _ReraiseExceptionErrorHandler(_elapsed_time): 54 raise 55 56 57def _DoNothingExceptionErrorHandler(_elapsed_time): 58 pass 59 60 61class InspectorWebsocketUnittest(unittest.TestCase): 62 63 def setUp(self): 64 self._mock_timer = simple_mock.MockTimer(inspector_websocket) 65 66 def tearDown(self): 67 self._mock_timer.Restore() 68 69 def testDispatchNotificationUntilDoneTimedOutOne(self): 70 inspector = inspector_websocket.InspectorWebsocket( 71 notification_handler=lambda data: True, 72 error_handler=_ReraiseExceptionErrorHandler) 73 inspector._socket = FakeSocket(self._mock_timer) 74 # The third call to socket.recv() will take 15 seconds without any data 75 # received, hence the below call will raise a 76 # DispatchNotificationsUntilDoneTimeoutException. 77 with self.assertRaises( 78 inspector_websocket.DispatchNotificationsUntilDoneTimeoutException): 79 inspector.DispatchNotificationsUntilDone(12) 80 81 def testDispatchNotificationUntilDoneTimedOutTwo(self): 82 inspector = inspector_websocket.InspectorWebsocket( 83 notification_handler=lambda data: True, 84 error_handler=_DoNothingExceptionErrorHandler) 85 inspector._socket = FakeSocket(self._mock_timer) 86 # The third and forth calls to socket.recv() will take 30 seconds without 87 # any data received, hence the below call will raise a 88 # DispatchNotificationsUntilDoneTimeoutException. 89 with self.assertRaises( 90 inspector_websocket.DispatchNotificationsUntilDoneTimeoutException): 91 inspector.DispatchNotificationsUntilDone(29) 92 93 def testDispatchNotificationUntilDoneNotTimedOut(self): 94 inspector = inspector_websocket.InspectorWebsocket( 95 notification_handler=lambda data: True, 96 error_handler=_ReraiseExceptionErrorHandler) 97 inspector._socket = FakeSocket(self._mock_timer) 98 # Even though it takes 70 seconds to receive all the data, the call below 99 # will succeed since there are no interval which the previous data package 100 # received and the next failed data receiving attempt was greater than 101 # 30 seconds. 102 inspector.DispatchNotificationsUntilDone(31) 103