| Index: build/android/pylib/device/decorators_test.py
|
| diff --git a/build/android/pylib/device/decorators_test.py b/build/android/pylib/device/decorators_test.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..be36aa904fcd0b32a43145ca8c676e7e638688d8
|
| --- /dev/null
|
| +++ b/build/android/pylib/device/decorators_test.py
|
| @@ -0,0 +1,233 @@
|
| +# Copyright 2014 The Chromium Authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +
|
| +"""
|
| +Unit tests for decorators.py.
|
| +"""
|
| +
|
| +# pylint: disable=W0613
|
| +
|
| +import time
|
| +import traceback
|
| +import unittest
|
| +
|
| +from pylib.device import decorators
|
| +from pylib.device import device_errors
|
| +
|
| +_DEFAULT_TIMEOUT = 30
|
| +_DEFAULT_RETRIES = 3
|
| +
|
| +class DecoratorsTest(unittest.TestCase):
|
| + _decorated_function_called_count = 0
|
| +
|
| + def testFunctionDecoratorSetsTimeout(self):
|
| + """ Tests that the WithTimeoutAndRetries decorator sets |timeout|
|
| + appropriately.
|
| + """
|
| + @decorators.WithTimeoutAndRetriesDefaults(
|
| + _DEFAULT_TIMEOUT, _DEFAULT_RETRIES)
|
| + def alwaysReturnTimeoutVal(timeout=None, retries=None):
|
| + return timeout
|
| +
|
| + self.assertEquals(_DEFAULT_TIMEOUT, alwaysReturnTimeoutVal())
|
| + self.assertEquals(8, alwaysReturnTimeoutVal(timeout=8))
|
| +
|
| + def testFunctionDecoratorSetsRetries(self):
|
| + """ Tests that the WithTimeoutAndRetries decorator sets |retries|
|
| + appropriately.
|
| + """
|
| + @decorators.WithTimeoutAndRetriesDefaults(
|
| + _DEFAULT_TIMEOUT, _DEFAULT_RETRIES)
|
| + def alwaysReturnRetriesVal(timeout=None, retries=None):
|
| + return retries
|
| +
|
| + self.assertEquals(_DEFAULT_RETRIES, alwaysReturnRetriesVal())
|
| + self.assertEquals(1, alwaysReturnRetriesVal(retries=1))
|
| +
|
| + def testFunctionDecoratorDoesTimeouts(self):
|
| + """ Tests that the WithTimeoutAndRetries decorator handles the timeout
|
| + logic.
|
| + """
|
| + DecoratorsTest._decorated_function_called_count = 0
|
| + @decorators.WithTimeoutAndRetriesDefaults(
|
| + _DEFAULT_TIMEOUT, _DEFAULT_RETRIES)
|
| + def alwaysTimesOut(timeout=None, retries=None):
|
| + DecoratorsTest._decorated_function_called_count += 1
|
| + time.sleep(100 * timeout)
|
| +
|
| + start_time = time.time()
|
| + with self.assertRaises(device_errors.CommandTimeoutError):
|
| + alwaysTimesOut(timeout=1, retries=0)
|
| + elapsed_time = time.time() - start_time
|
| + self.assertTrue(elapsed_time >= 1)
|
| + self.assertEquals(1, DecoratorsTest._decorated_function_called_count)
|
| +
|
| + def testFunctionDecoratorDoesRetries(self):
|
| + """ Tests that the WithTimeoutAndRetries decorator handles the retries
|
| + logic.
|
| + """
|
| + DecoratorsTest._decorated_function_called_count = 0
|
| + @decorators.WithTimeoutAndRetriesDefaults(
|
| + _DEFAULT_TIMEOUT, _DEFAULT_RETRIES)
|
| + def alwaysRaisesCommandFailedError(timeout=None, retries=None):
|
| + DecoratorsTest._decorated_function_called_count += 1
|
| + raise device_errors.CommandFailedError(['testCommand'],
|
| + 'testCommand failed')
|
| +
|
| + with self.assertRaises(device_errors.CommandFailedError):
|
| + alwaysRaisesCommandFailedError(retries=10)
|
| + self.assertEquals(11, DecoratorsTest._decorated_function_called_count)
|
| +
|
| + def testFunctionDecoratorNoDefaults(self):
|
| + """ Tests that the WithTimeoutAndRetries decorator requires values for
|
| + timeout and retries when no defaults are supplied.
|
| + """
|
| + @decorators.WithTimeoutAndRetries
|
| + def requiresExplicitTimeoutAndRetries(timeout=None, retries=None):
|
| + return (timeout, retries)
|
| + with self.assertRaises(TypeError):
|
| + requiresExplicitTimeoutAndRetries()
|
| + with self.assertRaises(TypeError):
|
| + requiresExplicitTimeoutAndRetries(timeout=10)
|
| + with self.assertRaises(TypeError):
|
| + requiresExplicitTimeoutAndRetries(retries=0)
|
| + expected_timeout = 10
|
| + expected_retries = 1
|
| + actual_timeout, actual_retries = (
|
| + requiresExplicitTimeoutAndRetries(timeout=expected_timeout,
|
| + retries=expected_retries))
|
| + self.assertEquals(expected_timeout, actual_timeout)
|
| + self.assertEquals(expected_retries, actual_retries)
|
| +
|
| + class _MethodDecoratorTestObject(object):
|
| + """ An object suitable for testing the
|
| + WithTimeoutAndRetriesFromInstance method decorator.
|
| + """
|
| +
|
| + def __init__(self, test_case, default_timeout=_DEFAULT_TIMEOUT,
|
| + default_retries=_DEFAULT_RETRIES):
|
| + self._test_case = test_case
|
| + self.default_timeout = default_timeout
|
| + self.default_retries = default_retries
|
| + self.function_call_counters = {
|
| + 'alwaysRaisesCommandFailedError': 0,
|
| + 'alwaysTimesOut': 0,
|
| + 'requiresExplicitTimeoutAndRetries': 0,
|
| + }
|
| +
|
| + # pylint: disable=R0201
|
| +
|
| + @decorators.WithTimeoutAndRetriesFromInstance('default_timeout',
|
| + 'default_retries')
|
| + def alwaysReturnTimeoutVal(self, timeout=None, retries=None):
|
| + return timeout
|
| +
|
| + @decorators.WithTimeoutAndRetriesFromInstance('default_timeout',
|
| + 'default_retries')
|
| + def alwaysReturnRetriesVal(self, timeout=None, retries=None):
|
| + return retries
|
| +
|
| + # pylint: enable=R0201
|
| +
|
| + @decorators.WithTimeoutAndRetriesFromInstance('default_timeout',
|
| + 'default_retries')
|
| + def alwaysTimesOut(self, timeout=None, retries=None):
|
| + self.function_call_counters['alwaysTimesOut'] += 1
|
| + time.sleep(100 * timeout)
|
| + self._test_case.assertFalse(True, msg='Failed to time out?')
|
| +
|
| + @decorators.WithTimeoutAndRetriesFromInstance('default_timeout',
|
| + 'default_retries')
|
| + def alwaysRaisesCommandFailedError(self, timeout=None, retries=None):
|
| + self.function_call_counters['alwaysRaisesCommandFailedError'] += 1
|
| + raise device_errors.CommandFailedError(['testCommand'],
|
| + 'testCommand failed')
|
| +
|
| + @decorators.WithTimeoutAndRetries
|
| + def requiresExplicitTimeoutAndRetries(self, timeout=None, retries=None):
|
| + self.function_call_counters['requiresExplicitTimeoutAndRetries'] += 1
|
| + return (timeout, retries)
|
| +
|
| + def testMethodDecoratorSetsTimeout(self):
|
| + """ Tests that the WithTimeoutAndRetriesFromInstance decorator sets
|
| + |timeout| appropriately.
|
| + """
|
| + expected_default_timeout = 37
|
| + expected_custom_timeout = 38
|
| + test_obj = self._MethodDecoratorTestObject(
|
| + self, default_timeout=expected_default_timeout)
|
| + self.assertEquals(
|
| + expected_default_timeout, test_obj.alwaysReturnTimeoutVal())
|
| + self.assertEquals(
|
| + expected_custom_timeout,
|
| + test_obj.alwaysReturnTimeoutVal(timeout=expected_custom_timeout))
|
| +
|
| + def testMethodDecoratorSetsRetries(self):
|
| + """ Tests that the WithTimeoutAndRetriesFromInstance decorator sets
|
| + |retries| appropriately.
|
| + """
|
| + expected_default_retries = 5
|
| + expected_custom_retries = 6
|
| + test_obj = self._MethodDecoratorTestObject(
|
| + self, default_retries=expected_default_retries)
|
| + self.assertEquals(
|
| + expected_default_retries, test_obj.alwaysReturnRetriesVal())
|
| + self.assertEquals(
|
| + expected_custom_retries,
|
| + test_obj.alwaysReturnRetriesVal(retries=expected_custom_retries))
|
| +
|
| + def testMethodDecoratorDoesTimeout(self):
|
| + """ Tests that the WithTimeoutAndRetriesFromInstance decorator handles
|
| + the timeout logic.
|
| + """
|
| + test_obj = self._MethodDecoratorTestObject(self)
|
| + start_time = time.time()
|
| + with self.assertRaises(device_errors.CommandTimeoutError):
|
| + try:
|
| + test_obj.alwaysTimesOut(timeout=1, retries=0)
|
| + except:
|
| + traceback.print_exc()
|
| + raise
|
| + elapsed_time = time.time() - start_time
|
| + self.assertTrue(elapsed_time >= 1)
|
| + self.assertEquals(1, test_obj.function_call_counters['alwaysTimesOut'])
|
| +
|
| + def testMethodDecoratorDoesRetries(self):
|
| + """ Tests that the WithTimeoutAndRetriesFromInstance decorator handles
|
| + the retries logic.
|
| + """
|
| + test_obj = self._MethodDecoratorTestObject(self)
|
| + with self.assertRaises(device_errors.CommandFailedError):
|
| + try:
|
| + test_obj.alwaysRaisesCommandFailedError(retries=10)
|
| + except:
|
| + traceback.print_exc()
|
| + raise
|
| + self.assertEquals(
|
| + 11, test_obj.function_call_counters['alwaysRaisesCommandFailedError'])
|
| +
|
| + def testMethodDecoratorNoDefaults(self):
|
| + """ Tests that the WithTimeoutAndRetries decorator requires defaults
|
| + when applied to a method.
|
| + """
|
| + test_obj = self._MethodDecoratorTestObject(self)
|
| + with self.assertRaises(TypeError):
|
| + test_obj.requiresExplicitTimeoutAndRetries()
|
| + with self.assertRaises(TypeError):
|
| + test_obj.requiresExplicitTimeoutAndRetries(timeout=10)
|
| + with self.assertRaises(TypeError):
|
| + test_obj.requiresExplicitTimeoutAndRetries(retries=0)
|
| + expected_timeout = 10
|
| + expected_retries = 1
|
| + actual_timeout, actual_retries = (
|
| + test_obj.requiresExplicitTimeoutAndRetries(timeout=expected_timeout,
|
| + retries=expected_retries))
|
| + self.assertEquals(expected_timeout, actual_timeout)
|
| + self.assertEquals(expected_retries, actual_retries)
|
| +
|
| +
|
| +if __name__ == '__main__':
|
| + unittest.main()
|
| +
|
| +
|
|
|