1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez# Copyright 2014 The Chromium Authors. All rights reserved. 2645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez# Use of this source code is governed by a BSD-style license that can be 3645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez# found in the LICENSE file. 4645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 5645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez""" 6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezUnit tests for decorators.py. 7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez""" 8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 9645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez# pylint: disable=W0613 10645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezimport time 12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezimport traceback 13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezimport unittest 14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezfrom devil.android import decorators 16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezfrom devil.android import device_errors 17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezfrom devil.utils import reraiser_thread 18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez_DEFAULT_TIMEOUT = 30 20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez_DEFAULT_RETRIES = 3 21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass DecoratorsTest(unittest.TestCase): 24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez _decorated_function_called_count = 0 25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def testFunctionDecoratorDoesTimeouts(self): 27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Tests that the base decorator handles the timeout logic.""" 28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DecoratorsTest._decorated_function_called_count = 0 29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @decorators.WithTimeoutAndRetries 31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def alwaysTimesOut(timeout=None, retries=None): 32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DecoratorsTest._decorated_function_called_count += 1 33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez time.sleep(100) 34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez start_time = time.time() 36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez with self.assertRaises(device_errors.CommandTimeoutError): 37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez alwaysTimesOut(timeout=1, retries=0) 38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez elapsed_time = time.time() - start_time 39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertTrue(elapsed_time >= 1) 40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(1, DecoratorsTest._decorated_function_called_count) 41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def testFunctionDecoratorDoesRetries(self): 43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Tests that the base decorator handles the retries logic.""" 44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DecoratorsTest._decorated_function_called_count = 0 45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @decorators.WithTimeoutAndRetries 47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def alwaysRaisesCommandFailedError(timeout=None, retries=None): 48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DecoratorsTest._decorated_function_called_count += 1 49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez raise device_errors.CommandFailedError('testCommand failed') 50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez with self.assertRaises(device_errors.CommandFailedError): 52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez alwaysRaisesCommandFailedError(timeout=30, retries=10) 53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(11, DecoratorsTest._decorated_function_called_count) 54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def testFunctionDecoratorRequiresParams(self): 56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Tests that the base decorator requires timeout and retries params.""" 57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @decorators.WithTimeoutAndRetries 58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def requiresExplicitTimeoutAndRetries(timeout=None, retries=None): 59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return (timeout, retries) 60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez with self.assertRaises(KeyError): 62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez requiresExplicitTimeoutAndRetries() 63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez with self.assertRaises(KeyError): 64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez requiresExplicitTimeoutAndRetries(timeout=10) 65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez with self.assertRaises(KeyError): 66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez requiresExplicitTimeoutAndRetries(retries=0) 67645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez expected_timeout = 10 68645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez expected_retries = 1 69645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez (actual_timeout, actual_retries) = ( 70645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez requiresExplicitTimeoutAndRetries(timeout=expected_timeout, 71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez retries=expected_retries)) 72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(expected_timeout, actual_timeout) 73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(expected_retries, actual_retries) 74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def testFunctionDecoratorTranslatesReraiserExceptions(self): 76645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Tests that the explicit decorator translates reraiser exceptions.""" 77645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @decorators.WithTimeoutAndRetries 78645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def alwaysRaisesProvidedException(exception, timeout=None, retries=None): 79645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez raise exception 80645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 81645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez exception_desc = 'Reraiser thread timeout error' 82645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez with self.assertRaises(device_errors.CommandTimeoutError) as e: 83645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez alwaysRaisesProvidedException( 84645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez reraiser_thread.TimeoutError(exception_desc), 85645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez timeout=10, retries=1) 86645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(exception_desc, str(e.exception)) 87645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 88645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def testConditionalRetriesDecoratorRetries(self): 89645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def do_not_retry_no_adb_error(exc): 90645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return not isinstance(exc, device_errors.NoAdbError) 91645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 92645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez actual_tries = [0] 93645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 94645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @decorators.WithTimeoutAndConditionalRetries(do_not_retry_no_adb_error) 95645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def alwaysRaisesCommandFailedError(timeout=None, retries=None): 96645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez actual_tries[0] += 1 97645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez raise device_errors.CommandFailedError('Command failed :(') 98645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 99645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez with self.assertRaises(device_errors.CommandFailedError): 100645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez alwaysRaisesCommandFailedError(timeout=10, retries=10) 101645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(11, actual_tries[0]) 102645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 103645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def testConditionalRetriesDecoratorDoesntRetry(self): 104645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def do_not_retry_no_adb_error(exc): 105645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return not isinstance(exc, device_errors.NoAdbError) 106645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 107645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez actual_tries = [0] 108645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 109645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @decorators.WithTimeoutAndConditionalRetries(do_not_retry_no_adb_error) 110645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def alwaysRaisesNoAdbError(timeout=None, retries=None): 111645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez actual_tries[0] += 1 112645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez raise device_errors.NoAdbError() 113645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 114645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez with self.assertRaises(device_errors.NoAdbError): 115645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez alwaysRaisesNoAdbError(timeout=10, retries=10) 116645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(1, actual_tries[0]) 117645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 118645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def testDefaultsFunctionDecoratorDoesTimeouts(self): 119645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Tests that the defaults decorator handles timeout logic.""" 120645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DecoratorsTest._decorated_function_called_count = 0 121645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 122645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @decorators.WithTimeoutAndRetriesDefaults(1, 0) 123645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def alwaysTimesOut(timeout=None, retries=None): 124645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DecoratorsTest._decorated_function_called_count += 1 125645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez time.sleep(100) 126645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 127645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez start_time = time.time() 128645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez with self.assertRaises(device_errors.CommandTimeoutError): 129645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez alwaysTimesOut() 130645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez elapsed_time = time.time() - start_time 131645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertTrue(elapsed_time >= 1) 132645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(1, DecoratorsTest._decorated_function_called_count) 133645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 134645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DecoratorsTest._decorated_function_called_count = 0 135645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez with self.assertRaises(device_errors.CommandTimeoutError): 136645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez alwaysTimesOut(timeout=2) 137645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez elapsed_time = time.time() - start_time 138645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertTrue(elapsed_time >= 2) 139645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(1, DecoratorsTest._decorated_function_called_count) 140645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 141645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def testDefaultsFunctionDecoratorDoesRetries(self): 142645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Tests that the defaults decorator handles retries logic.""" 143645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DecoratorsTest._decorated_function_called_count = 0 144645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 145645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @decorators.WithTimeoutAndRetriesDefaults(30, 10) 146645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def alwaysRaisesCommandFailedError(timeout=None, retries=None): 147645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DecoratorsTest._decorated_function_called_count += 1 148645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez raise device_errors.CommandFailedError('testCommand failed') 149645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 150645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez with self.assertRaises(device_errors.CommandFailedError): 151645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez alwaysRaisesCommandFailedError() 152645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(11, DecoratorsTest._decorated_function_called_count) 153645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 154645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DecoratorsTest._decorated_function_called_count = 0 155645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez with self.assertRaises(device_errors.CommandFailedError): 156645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez alwaysRaisesCommandFailedError(retries=5) 157645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(6, DecoratorsTest._decorated_function_called_count) 158645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 159645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def testDefaultsFunctionDecoratorPassesValues(self): 160645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Tests that the defaults decorator passes timeout and retries kwargs.""" 161645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @decorators.WithTimeoutAndRetriesDefaults(30, 10) 162645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def alwaysReturnsTimeouts(timeout=None, retries=None): 163645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return timeout 164645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 165645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(30, alwaysReturnsTimeouts()) 166645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(120, alwaysReturnsTimeouts(timeout=120)) 167645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 168645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @decorators.WithTimeoutAndRetriesDefaults(30, 10) 169645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def alwaysReturnsRetries(timeout=None, retries=None): 170645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return retries 171645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 172645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(10, alwaysReturnsRetries()) 173645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(1, alwaysReturnsRetries(retries=1)) 174645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 175645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def testDefaultsFunctionDecoratorTranslatesReraiserExceptions(self): 176645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Tests that the explicit decorator translates reraiser exceptions.""" 177645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @decorators.WithTimeoutAndRetriesDefaults(30, 10) 178645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def alwaysRaisesProvidedException(exception, timeout=None, retries=None): 179645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez raise exception 180645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 181645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez exception_desc = 'Reraiser thread timeout error' 182645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez with self.assertRaises(device_errors.CommandTimeoutError) as e: 183645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez alwaysRaisesProvidedException( 184645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez reraiser_thread.TimeoutError(exception_desc)) 185645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(exception_desc, str(e.exception)) 186645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 187645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def testExplicitFunctionDecoratorDoesTimeouts(self): 188645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Tests that the explicit decorator handles timeout logic.""" 189645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DecoratorsTest._decorated_function_called_count = 0 190645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 191645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @decorators.WithExplicitTimeoutAndRetries(1, 0) 192645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def alwaysTimesOut(): 193645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DecoratorsTest._decorated_function_called_count += 1 194645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez time.sleep(100) 195645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 196645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez start_time = time.time() 197645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez with self.assertRaises(device_errors.CommandTimeoutError): 198645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez alwaysTimesOut() 199645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez elapsed_time = time.time() - start_time 200645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertTrue(elapsed_time >= 1) 201645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(1, DecoratorsTest._decorated_function_called_count) 202645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 203645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def testExplicitFunctionDecoratorDoesRetries(self): 204645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Tests that the explicit decorator handles retries logic.""" 205645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DecoratorsTest._decorated_function_called_count = 0 206645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 207645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @decorators.WithExplicitTimeoutAndRetries(30, 10) 208645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def alwaysRaisesCommandFailedError(): 209645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DecoratorsTest._decorated_function_called_count += 1 210645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez raise device_errors.CommandFailedError('testCommand failed') 211645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 212645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez with self.assertRaises(device_errors.CommandFailedError): 213645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez alwaysRaisesCommandFailedError() 214645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(11, DecoratorsTest._decorated_function_called_count) 215645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 216645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def testExplicitDecoratorTranslatesReraiserExceptions(self): 217645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Tests that the explicit decorator translates reraiser exceptions.""" 218645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @decorators.WithExplicitTimeoutAndRetries(30, 10) 219645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def alwaysRaisesProvidedException(exception): 220645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez raise exception 221645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 222645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez exception_desc = 'Reraiser thread timeout error' 223645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez with self.assertRaises(device_errors.CommandTimeoutError) as e: 224645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez alwaysRaisesProvidedException( 225645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez reraiser_thread.TimeoutError(exception_desc)) 226645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(exception_desc, str(e.exception)) 227645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 228645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez class _MethodDecoratorTestObject(object): 229645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """An object suitable for testing the method decorator.""" 230645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 231645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def __init__(self, test_case, default_timeout=_DEFAULT_TIMEOUT, 232645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez default_retries=_DEFAULT_RETRIES): 233645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self._test_case = test_case 234645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.default_timeout = default_timeout 235645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.default_retries = default_retries 236645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.function_call_counters = { 237645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 'alwaysRaisesCommandFailedError': 0, 238645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 'alwaysTimesOut': 0, 239645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 'requiresExplicitTimeoutAndRetries': 0, 240645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } 241645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 242645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @decorators.WithTimeoutAndRetriesFromInstance( 243645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 'default_timeout', 'default_retries') 244645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def alwaysTimesOut(self, timeout=None, retries=None): 245645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.function_call_counters['alwaysTimesOut'] += 1 246645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez time.sleep(100) 247645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self._test_case.assertFalse(True, msg='Failed to time out?') 248645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 249645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @decorators.WithTimeoutAndRetriesFromInstance( 250645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 'default_timeout', 'default_retries') 251645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def alwaysRaisesCommandFailedError(self, timeout=None, retries=None): 252645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.function_call_counters['alwaysRaisesCommandFailedError'] += 1 253645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez raise device_errors.CommandFailedError('testCommand failed') 254645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 255645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez # pylint: disable=no-self-use 256645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 257645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @decorators.WithTimeoutAndRetriesFromInstance( 258645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 'default_timeout', 'default_retries') 259645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def alwaysReturnsTimeout(self, timeout=None, retries=None): 260645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return timeout 261645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 262645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @decorators.WithTimeoutAndRetriesFromInstance( 263645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 'default_timeout', 'default_retries', min_default_timeout=100) 264645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def alwaysReturnsTimeoutWithMin(self, timeout=None, retries=None): 265645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return timeout 266645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 267645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @decorators.WithTimeoutAndRetriesFromInstance( 268645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 'default_timeout', 'default_retries') 269645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def alwaysReturnsRetries(self, timeout=None, retries=None): 270645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return retries 271645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 272645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @decorators.WithTimeoutAndRetriesFromInstance( 273645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 'default_timeout', 'default_retries') 274645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def alwaysRaisesProvidedException(self, exception, timeout=None, 275645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez retries=None): 276645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez raise exception 277645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 278645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez # pylint: enable=no-self-use 279645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 280645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def testMethodDecoratorDoesTimeout(self): 281645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Tests that the method decorator handles timeout logic.""" 282645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez test_obj = self._MethodDecoratorTestObject(self) 283645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez start_time = time.time() 284645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez with self.assertRaises(device_errors.CommandTimeoutError): 285645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez try: 286645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez test_obj.alwaysTimesOut(timeout=1, retries=0) 287645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez except: 288645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez traceback.print_exc() 289645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez raise 290645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez elapsed_time = time.time() - start_time 291645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertTrue(elapsed_time >= 1) 292645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(1, test_obj.function_call_counters['alwaysTimesOut']) 293645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 294645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def testMethodDecoratorDoesRetries(self): 295645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Tests that the method decorator handles retries logic.""" 296645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez test_obj = self._MethodDecoratorTestObject(self) 297645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez with self.assertRaises(device_errors.CommandFailedError): 298645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez try: 299645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez test_obj.alwaysRaisesCommandFailedError(retries=10) 300645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez except: 301645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez traceback.print_exc() 302645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez raise 303645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals( 304645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 11, test_obj.function_call_counters['alwaysRaisesCommandFailedError']) 305645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 306645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def testMethodDecoratorPassesValues(self): 307645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Tests that the method decorator passes timeout and retries kwargs.""" 308645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez test_obj = self._MethodDecoratorTestObject( 309645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self, default_timeout=42, default_retries=31) 310645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(42, test_obj.alwaysReturnsTimeout()) 311645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(41, test_obj.alwaysReturnsTimeout(timeout=41)) 312645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(31, test_obj.alwaysReturnsRetries()) 313645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(32, test_obj.alwaysReturnsRetries(retries=32)) 314645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 315645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def testMethodDecoratorUsesMiniumumTimeout(self): 316645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez test_obj = self._MethodDecoratorTestObject( 317645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self, default_timeout=42, default_retries=31) 318645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(100, test_obj.alwaysReturnsTimeoutWithMin()) 319645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(41, test_obj.alwaysReturnsTimeoutWithMin(timeout=41)) 320645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 321645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def testMethodDecoratorTranslatesReraiserExceptions(self): 322645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez test_obj = self._MethodDecoratorTestObject(self) 323645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 324645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez exception_desc = 'Reraiser thread timeout error' 325645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez with self.assertRaises(device_errors.CommandTimeoutError) as e: 326645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez test_obj.alwaysRaisesProvidedException( 327645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez reraiser_thread.TimeoutError(exception_desc)) 328645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.assertEquals(exception_desc, str(e.exception)) 329645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 330645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezif __name__ == '__main__': 331645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez unittest.main(verbosity=2) 332645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 333