1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)# Copyright 2014 The Chromium Authors. All rights reserved. 2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)# found in the LICENSE file. 4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)""" 6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)Unit tests for decorators.py. 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)""" 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)# pylint: disable=W0613 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)import os 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)import sys 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)import time 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)import traceback 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)import unittest 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)from pylib import constants 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)from pylib.device import decorators 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)from pylib.device import device_errors 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)from pylib.utils import reraiser_thread 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)# TODO(jbudorick) Remove once the DeviceUtils implementations are no longer 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)# backed by AndroidCommands / android_testrunner. 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)sys.path.append(os.path.join(constants.DIR_SOURCE_ROOT, 'third_party', 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'android_testrunner')) 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)import errors as old_errors 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)_DEFAULT_TIMEOUT = 30 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)_DEFAULT_RETRIES = 3 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class DecoratorsTest(unittest.TestCase): 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) _decorated_function_called_count = 0 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def testFunctionDecoratorDoesTimeouts(self): 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) """Tests that the base decorator handles the timeout logic.""" 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DecoratorsTest._decorated_function_called_count = 0 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @decorators.WithTimeoutAndRetries 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def alwaysTimesOut(timeout=None, retries=None): 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DecoratorsTest._decorated_function_called_count += 1 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) time.sleep(100) 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) start_time = time.time() 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.CommandTimeoutError): 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) alwaysTimesOut(timeout=1, retries=0) 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) elapsed_time = time.time() - start_time 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertTrue(elapsed_time >= 1) 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(1, DecoratorsTest._decorated_function_called_count) 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def testFunctionDecoratorDoesRetries(self): 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) """Tests that the base decorator handles the retries logic.""" 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DecoratorsTest._decorated_function_called_count = 0 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @decorators.WithTimeoutAndRetries 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def alwaysRaisesCommandFailedError(timeout=None, retries=None): 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DecoratorsTest._decorated_function_called_count += 1 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch raise device_errors.CommandFailedError('testCommand failed') 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.CommandFailedError): 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) alwaysRaisesCommandFailedError(timeout=30, retries=10) 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(11, DecoratorsTest._decorated_function_called_count) 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def testFunctionDecoratorRequiresParams(self): 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) """Tests that the base decorator requires timeout and retries params.""" 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @decorators.WithTimeoutAndRetries 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def requiresExplicitTimeoutAndRetries(timeout=None, retries=None): 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return (timeout, retries) 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(KeyError): 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) requiresExplicitTimeoutAndRetries() 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(KeyError): 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) requiresExplicitTimeoutAndRetries(timeout=10) 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(KeyError): 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) requiresExplicitTimeoutAndRetries(retries=0) 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) expected_timeout = 10 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) expected_retries = 1 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (actual_timeout, actual_retries) = ( 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) requiresExplicitTimeoutAndRetries(timeout=expected_timeout, 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) retries=expected_retries)) 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(expected_timeout, actual_timeout) 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(expected_retries, actual_retries) 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def testFunctionDecoratorTranslatesOldExceptions(self): 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) """Tests that the explicit decorator translates old exceptions.""" 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @decorators.WithTimeoutAndRetries 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def alwaysRaisesProvidedException(exception, timeout=None, retries=None): 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) raise exception 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) exception_desc = 'Old response timeout error' 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.CommandTimeoutError) as e: 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) alwaysRaisesProvidedException( 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) old_errors.WaitForResponseTimedOutError(exception_desc), 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) timeout=10, retries=1) 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(exception_desc, str(e.exception)) 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) exception_desc = 'Old device error' 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.DeviceUnreachableError) as e: 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) alwaysRaisesProvidedException( 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) old_errors.DeviceUnresponsiveError(exception_desc), 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) timeout=10, retries=1) 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(exception_desc, str(e.exception)) 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def testFunctionDecoratorTranslatesReraiserExceptions(self): 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) """Tests that the explicit decorator translates reraiser exceptions.""" 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @decorators.WithTimeoutAndRetries 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def alwaysRaisesProvidedException(exception, timeout=None, retries=None): 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) raise exception 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) exception_desc = 'Reraiser thread timeout error' 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.CommandTimeoutError) as e: 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) alwaysRaisesProvidedException( 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reraiser_thread.TimeoutError(exception_desc), 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) timeout=10, retries=1) 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(exception_desc, str(e.exception)) 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def testDefaultsFunctionDecoratorDoesTimeouts(self): 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) """Tests that the defaults decorator handles timeout logic.""" 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DecoratorsTest._decorated_function_called_count = 0 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @decorators.WithTimeoutAndRetriesDefaults(1, 0) 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def alwaysTimesOut(timeout=None, retries=None): 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DecoratorsTest._decorated_function_called_count += 1 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) time.sleep(100) 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) start_time = time.time() 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.CommandTimeoutError): 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) alwaysTimesOut() 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) elapsed_time = time.time() - start_time 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertTrue(elapsed_time >= 1) 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(1, DecoratorsTest._decorated_function_called_count) 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DecoratorsTest._decorated_function_called_count = 0 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.CommandTimeoutError): 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) alwaysTimesOut(timeout=2) 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) elapsed_time = time.time() - start_time 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertTrue(elapsed_time >= 2) 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(1, DecoratorsTest._decorated_function_called_count) 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def testDefaultsFunctionDecoratorDoesRetries(self): 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) """Tests that the defaults decorator handles retries logic.""" 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DecoratorsTest._decorated_function_called_count = 0 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @decorators.WithTimeoutAndRetriesDefaults(30, 10) 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def alwaysRaisesCommandFailedError(timeout=None, retries=None): 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DecoratorsTest._decorated_function_called_count += 1 142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch raise device_errors.CommandFailedError('testCommand failed') 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.CommandFailedError): 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) alwaysRaisesCommandFailedError() 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(11, DecoratorsTest._decorated_function_called_count) 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DecoratorsTest._decorated_function_called_count = 0 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.CommandFailedError): 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) alwaysRaisesCommandFailedError(retries=5) 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(6, DecoratorsTest._decorated_function_called_count) 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def testDefaultsFunctionDecoratorPassesValues(self): 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) """Tests that the defaults decorator passes timeout and retries kwargs.""" 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @decorators.WithTimeoutAndRetriesDefaults(30, 10) 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def alwaysReturnsTimeouts(timeout=None, retries=None): 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return timeout 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(30, alwaysReturnsTimeouts()) 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(120, alwaysReturnsTimeouts(timeout=120)) 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @decorators.WithTimeoutAndRetriesDefaults(30, 10) 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def alwaysReturnsRetries(timeout=None, retries=None): 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return retries 165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(10, alwaysReturnsRetries()) 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(1, alwaysReturnsRetries(retries=1)) 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def testDefaultsFunctionDecoratorTranslatesOldExceptions(self): 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) """Tests that the explicit decorator translates old exceptions.""" 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @decorators.WithTimeoutAndRetriesDefaults(30, 10) 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def alwaysRaisesProvidedException(exception, timeout=None, retries=None): 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) raise exception 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) exception_desc = 'Old response timeout error' 176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.CommandTimeoutError) as e: 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) alwaysRaisesProvidedException( 178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) old_errors.WaitForResponseTimedOutError(exception_desc)) 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(exception_desc, str(e.exception)) 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) exception_desc = 'Old device error' 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.DeviceUnreachableError) as e: 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) alwaysRaisesProvidedException( 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) old_errors.DeviceUnresponsiveError(exception_desc)) 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(exception_desc, str(e.exception)) 186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def testDefaultsFunctionDecoratorTranslatesReraiserExceptions(self): 188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) """Tests that the explicit decorator translates reraiser exceptions.""" 189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @decorators.WithTimeoutAndRetriesDefaults(30, 10) 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def alwaysRaisesProvidedException(exception, timeout=None, retries=None): 191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) raise exception 192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) exception_desc = 'Reraiser thread timeout error' 194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.CommandTimeoutError) as e: 195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) alwaysRaisesProvidedException( 196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reraiser_thread.TimeoutError(exception_desc)) 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(exception_desc, str(e.exception)) 198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def testExplicitFunctionDecoratorDoesTimeouts(self): 200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) """Tests that the explicit decorator handles timeout logic.""" 201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DecoratorsTest._decorated_function_called_count = 0 202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @decorators.WithExplicitTimeoutAndRetries(1, 0) 203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def alwaysTimesOut(): 204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DecoratorsTest._decorated_function_called_count += 1 205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) time.sleep(100) 206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) start_time = time.time() 208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.CommandTimeoutError): 209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) alwaysTimesOut() 210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) elapsed_time = time.time() - start_time 211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertTrue(elapsed_time >= 1) 212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(1, DecoratorsTest._decorated_function_called_count) 213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def testExplicitFunctionDecoratorDoesRetries(self): 215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) """Tests that the explicit decorator handles retries logic.""" 216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DecoratorsTest._decorated_function_called_count = 0 217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @decorators.WithExplicitTimeoutAndRetries(30, 10) 218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def alwaysRaisesCommandFailedError(): 219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DecoratorsTest._decorated_function_called_count += 1 220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch raise device_errors.CommandFailedError('testCommand failed') 221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.CommandFailedError): 223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) alwaysRaisesCommandFailedError() 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(11, DecoratorsTest._decorated_function_called_count) 225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def testExplicitDecoratorTranslatesOldExceptions(self): 227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) """Tests that the explicit decorator translates old exceptions.""" 228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @decorators.WithExplicitTimeoutAndRetries(30, 10) 229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def alwaysRaisesProvidedException(exception): 230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) raise exception 231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) exception_desc = 'Old response timeout error' 233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.CommandTimeoutError) as e: 234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) alwaysRaisesProvidedException( 235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) old_errors.WaitForResponseTimedOutError(exception_desc)) 236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(exception_desc, str(e.exception)) 237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) exception_desc = 'Old device error' 239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.DeviceUnreachableError) as e: 240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) alwaysRaisesProvidedException( 241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) old_errors.DeviceUnresponsiveError(exception_desc)) 242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(exception_desc, str(e.exception)) 243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def testExplicitDecoratorTranslatesReraiserExceptions(self): 245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) """Tests that the explicit decorator translates reraiser exceptions.""" 246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @decorators.WithExplicitTimeoutAndRetries(30, 10) 247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def alwaysRaisesProvidedException(exception): 248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) raise exception 249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) exception_desc = 'Reraiser thread timeout error' 251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.CommandTimeoutError) as e: 252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) alwaysRaisesProvidedException( 253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reraiser_thread.TimeoutError(exception_desc)) 254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(exception_desc, str(e.exception)) 255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) class _MethodDecoratorTestObject(object): 257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) """An object suitable for testing the method decorator.""" 258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def __init__(self, test_case, default_timeout=_DEFAULT_TIMEOUT, 260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) default_retries=_DEFAULT_RETRIES): 261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self._test_case = test_case 262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.default_timeout = default_timeout 263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.default_retries = default_retries 264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.function_call_counters = { 265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'alwaysRaisesCommandFailedError': 0, 266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'alwaysTimesOut': 0, 267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'requiresExplicitTimeoutAndRetries': 0, 268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @decorators.WithTimeoutAndRetriesFromInstance( 271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'default_timeout', 'default_retries') 272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def alwaysTimesOut(self, timeout=None, retries=None): 273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.function_call_counters['alwaysTimesOut'] += 1 274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) time.sleep(100) 275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self._test_case.assertFalse(True, msg='Failed to time out?') 276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @decorators.WithTimeoutAndRetriesFromInstance( 278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'default_timeout', 'default_retries') 279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def alwaysRaisesCommandFailedError(self, timeout=None, retries=None): 280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.function_call_counters['alwaysRaisesCommandFailedError'] += 1 281116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch raise device_errors.CommandFailedError('testCommand failed') 282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) # pylint: disable=R0201 284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @decorators.WithTimeoutAndRetriesFromInstance( 286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'default_timeout', 'default_retries') 287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def alwaysReturnsTimeout(self, timeout=None, retries=None): 288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return timeout 289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @decorators.WithTimeoutAndRetriesFromInstance( 291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'default_timeout', 'default_retries') 292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def alwaysReturnsRetries(self, timeout=None, retries=None): 293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return retries 294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @decorators.WithTimeoutAndRetriesFromInstance( 296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'default_timeout', 'default_retries') 297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def alwaysRaisesProvidedException(self, exception, timeout=None, 298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) retries=None): 299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) raise exception 300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) # pylint: enable=R0201 302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def testMethodDecoratorDoesTimeout(self): 305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) """Tests that the method decorator handles timeout logic.""" 306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) test_obj = self._MethodDecoratorTestObject(self) 307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) start_time = time.time() 308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.CommandTimeoutError): 309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) try: 310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) test_obj.alwaysTimesOut(timeout=1, retries=0) 311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) except: 312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) traceback.print_exc() 313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) raise 314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) elapsed_time = time.time() - start_time 315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertTrue(elapsed_time >= 1) 316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(1, test_obj.function_call_counters['alwaysTimesOut']) 317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def testMethodDecoratorDoesRetries(self): 319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) """Tests that the method decorator handles retries logic.""" 320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) test_obj = self._MethodDecoratorTestObject(self) 321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.CommandFailedError): 322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) try: 323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) test_obj.alwaysRaisesCommandFailedError(retries=10) 324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) except: 325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) traceback.print_exc() 326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) raise 327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals( 328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 11, test_obj.function_call_counters['alwaysRaisesCommandFailedError']) 329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def testMethodDecoratorPassesValues(self): 331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) """Tests that the method decorator passes timeout and retries kwargs.""" 332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) test_obj = self._MethodDecoratorTestObject( 333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self, default_timeout=42, default_retries=31) 334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(42, test_obj.alwaysReturnsTimeout()) 335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(41, test_obj.alwaysReturnsTimeout(timeout=41)) 336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(31, test_obj.alwaysReturnsRetries()) 337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(32, test_obj.alwaysReturnsRetries(retries=32)) 338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def testMethodDecoratorTranslatesOldExceptions(self): 340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) test_obj = self._MethodDecoratorTestObject(self) 341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) exception_desc = 'Old response timeout error' 343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.CommandTimeoutError) as e: 344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) test_obj.alwaysRaisesProvidedException( 345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) old_errors.WaitForResponseTimedOutError(exception_desc)) 346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(exception_desc, str(e.exception)) 347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) exception_desc = 'Old device error' 349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.DeviceUnreachableError) as e: 350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) test_obj.alwaysRaisesProvidedException( 351cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) old_errors.DeviceUnresponsiveError(exception_desc)) 352cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(exception_desc, str(e.exception)) 353cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 354cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) def testMethodDecoratorTranslatesReraiserExceptions(self): 355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) test_obj = self._MethodDecoratorTestObject(self) 356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) exception_desc = 'Reraiser thread timeout error' 358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) with self.assertRaises(device_errors.CommandTimeoutError) as e: 359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) test_obj.alwaysRaisesProvidedException( 360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reraiser_thread.TimeoutError(exception_desc)) 361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.assertEquals(exception_desc, str(e.exception)) 362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)if __name__ == '__main__': 364cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) unittest.main(verbosity=2) 365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 366