示例#1
0
    def testRetryRetryExceptionExcluded(self, mockTime, mockSleep):
        """ Test that retry is not triggered if raised exeception is not in
    retryExceptions """

        time_test_utils.configureTimeAndSleepMocks(mockTime, mockSleep)

        class TestExceptionA(Exception):
            pass

        class TestExceptionB(Exception):
            pass

        _retry = error_handling.retry(timeoutSec=1,
                                      initialRetryDelaySec=1,
                                      maxRetryDelaySec=10,
                                      retryExceptions=(TestExceptionA, ))

        @_retry
        def testFunction():
            raise TestExceptionB("Test exception")

        with self.assertRaises(TestExceptionB):
            testFunction()

        self.assertEqual(mockSleep.call_count, 0)
    def testWaitForFlusherAndGarbageCollectWithFlusherNotFound(self, getAllCustomMetricsMock, timeMock, sleepMock):

        time_test_utils.configureTimeAndSleepMocks(timeMock, sleepMock)

        flusherMetricName = delete_companies._DATA_PATH_FLUSHER_METRIC_PREFIX + "1"

        # Patch getAllCustomMetrics to return all negatives and positives
        getAllCustomMetricsMock.return_value = [{"name": "XIGNITE.FOOBAR.CLOSINGPRICE"}]

        # Execute and validate
        with self.assertRaises(delete_companies.FlusherMetricNotFound):
            delete_companies._waitForFlusherAndGarbageCollect(
                engineServer="host", engineApiKey="apikey", flusherMetricName=flusherMetricName
            )
  def testNoRetryIfCallSucceeds(self, mockTime, mockSleep):
    """If the initial call succeeds, test that no retries are performed."""

    time_test_utils.configureTimeAndSleepMocks(mockTime, mockSleep)

    _retry = error_handling.retry(
      timeoutSec=30, initialRetryDelaySec=2,
      maxRetryDelaySec=10)

    testFunction = Mock(__name__="testFunction", autospec=True)

    _retry(testFunction)()

    testFunction.assert_called_once_with()
示例#4
0
    def testNoRetryIfCallSucceeds(self, mockTime, mockSleep):
        """If the initial call succeeds, test that no retries are performed."""

        time_test_utils.configureTimeAndSleepMocks(mockTime, mockSleep)

        _retry = error_handling.retry(timeoutSec=30,
                                      initialRetryDelaySec=2,
                                      maxRetryDelaySec=10)

        testFunction = Mock(__name__="testFunction", autospec=True)

        _retry(testFunction)()

        testFunction.assert_called_once_with()
  def testReturnsExpectedWithExpectedArgs(self, mockTime, mockSleep):
    """Test that docorated function receives only expected args and
    that it returns the expected value on success."""

    time_test_utils.configureTimeAndSleepMocks(mockTime, mockSleep)

    _retry = error_handling.retry(
      timeoutSec=30, initialRetryDelaySec=2,
      maxRetryDelaySec=10)

    testFunction = Mock(return_value=321,
                        __name__="testFunction", autospec=True)

    returnValue = _retry(testFunction)(1, 2, a=3, b=4)

    self.assertEqual(returnValue, 321)
    testFunction.assert_called_once_with(1, 2, a=3, b=4)
示例#6
0
    def _runTransientErrorRetryTest(self, numErrors):

        with patch("time.sleep", autospec=True) as sleepMock, \
             patch("time.time", autospec=True) as timeMock:

            time_test_utils.configureTimeAndSleepMocks(timeMock, sleepMock)

            for errorCode in _ALL_RETRIABLE_ERROR_CODES:
                clientSideEffects = [
                    sqlalchemy.exc.OperationalError(
                        orig=MySQLdb.OperationalError(errorCode),
                        statement="err",
                        params=None)
                ] * numErrors + [DEFAULT]

                serverSideEffects = [
                    sqlalchemy.exc.InternalError(
                        orig=MySQLdb.InternalError(errorCode),
                        statement="err",
                        params=None)
                ] * numErrors + [DEFAULT]

                if 3000 > errorCode >= 2000:
                    # The error is client side. Return one operationalError, then pass
                    with patch.object(Engine,
                                      "execute",
                                      spec_set=Engine.execute,
                                      side_effect=clientSideEffects) \
                        as mockExecute:
                        retryOnTransientErrors(mockExecute)(Mock())
                        self.assertEqual(mockExecute.call_count, numErrors + 1)

                elif errorCode >= 1000:
                    # The error is server side. Return one internalError, then pass
                    with patch.object(Engine,
                                      "execute",
                                      spec_set=Engine.execute,
                                      side_effect=serverSideEffects) \
                        as mockExecute:
                        retryOnTransientErrors(mockExecute)(Mock())
                        self.assertEqual(mockExecute.call_count, numErrors + 1)

                else:
                    self.fail("Error code is neither client nor server: %s" %
                              errorCode)
  def testRetryRetryExceptionIncluded(self, mockTime, mockSleep):
    """Test that retry is triggered if raised exception is in
    retryExceptions."""

    time_test_utils.configureTimeAndSleepMocks(mockTime, mockSleep)

    _retry = error_handling.retry(
      timeoutSec=1, initialRetryDelaySec=1,
      maxRetryDelaySec=10, retryExceptions=(TestParentException,))

    @_retry
    def testFunction():
      raise TestChildException("Test exception")

    with self.assertRaises(TestChildException):
      testFunction()

    self.assertEqual(mockSleep.call_count, 1)
示例#8
0
    def testReturnsExpectedWithExpectedArgs(self, mockTime, mockSleep):
        """Test that docorated function receives only expected args and
    that it returns the expected value on success."""

        time_test_utils.configureTimeAndSleepMocks(mockTime, mockSleep)

        _retry = error_handling.retry(timeoutSec=30,
                                      initialRetryDelaySec=2,
                                      maxRetryDelaySec=10)

        testFunction = Mock(return_value=321,
                            __name__="testFunction",
                            autospec=True)

        returnValue = _retry(testFunction)(1, 2, a=3, b=4)

        self.assertEqual(returnValue, 321)
        testFunction.assert_called_once_with(1, 2, a=3, b=4)
  def testRetryWaitsInitialRetryDelaySec(self, mockTime, mockSleep):
    """Test that delay times are correct."""

    time_test_utils.configureTimeAndSleepMocks(mockTime, mockSleep)

    _retry = error_handling.retry(
      timeoutSec=30, initialRetryDelaySec=2,
      maxRetryDelaySec=10)

    testFunction = Mock(side_effect=TestParentException("Test exception"),
                        __name__="testFunction", autospec=True)

    with self.assertRaises(TestParentException):
      _retry(testFunction)()

    self.assertEqual(mockSleep.mock_calls, [call(2), call(4), call(8),
                                            call(10), call(10)])

    self.assertEqual(testFunction.call_count, 6)
  def testRetryNoTimeForRetries(self, mockTime, mockSleep):
    """Test that when timeoutSec == 0, function is executed exactly once
    with no retries, and raises an exception on failure.
    """

    time_test_utils.configureTimeAndSleepMocks(mockTime, mockSleep)

    _retry = error_handling.retry(
      timeoutSec=0, initialRetryDelaySec=0.2,
      maxRetryDelaySec=10)

    testFunction = Mock(side_effect=TestParentException("Test exception"),
                        __name__="testFunction", autospec=True)

    with self.assertRaises(TestParentException):
      _retry(testFunction)()

    self.assertFalse(mockSleep.called)
    testFunction.assert_called_once_with()
示例#11
0
  def testConfigureTimeAndSleepMocks(self):

    timeMock = Mock(spec_set=time.time)
    sleepMock = Mock(spec_set=time.sleep)

    time_test_utils.configureTimeAndSleepMocks(timeMock, sleepMock)

    originalTime = timeMock()

    # Try with floating point
    sleepMock(10.5)

    now = timeMock()

    self.assertEqual(now, originalTime + 10.5)

    # Try with whole number
    sleepMock(5)
    self.assertEqual(timeMock(), originalTime + 10.5 + 5)
示例#12
0
    def testRetryRetryExceptionIncluded(self, mockTime, mockSleep):
        """Test that retry is triggered if raised exception is in
    retryExceptions."""

        time_test_utils.configureTimeAndSleepMocks(mockTime, mockSleep)

        _retry = error_handling.retry(timeoutSec=1,
                                      initialRetryDelaySec=1,
                                      maxRetryDelaySec=10,
                                      retryExceptions=(TestParentException, ))

        @_retry
        def testFunction():
            raise TestChildException("Test exception")

        with self.assertRaises(TestChildException):
            testFunction()

        self.assertEqual(mockSleep.call_count, 1)
示例#13
0
    def testRetryRetryFilter(self, mockTime, mockSleep):
        """Test that if retryFilter is specified and exception is in
    retryExceptions, retries iff retryFilter returns true."""

        time_test_utils.configureTimeAndSleepMocks(mockTime, mockSleep)

        # Test with retryFilter returning True

        _retryTrueFilter = error_handling.retry(
            timeoutSec=1,
            initialRetryDelaySec=1,
            maxRetryDelaySec=10,
            retryExceptions=(TestParentException, ),
            retryFilter=lambda _1, _2, _3: True)

        @_retryTrueFilter
        def testFunctionTrue():
            raise TestChildException("Test exception")

        with self.assertRaises(TestChildException):
            testFunctionTrue()

        self.assertEqual(mockSleep.call_count, 1)

        # Test with retryFilter returning False

        mockSleep.reset_mock()

        _retryFalseFilter = error_handling.retry(
            timeoutSec=1,
            initialRetryDelaySec=1,
            maxRetryDelaySec=10,
            retryExceptions=(TestParentException, ),
            retryFilter=lambda _1, _2, _3: False)

        @_retryFalseFilter
        def testFunctionFalse():
            raise TestChildException("Test exception")

        with self.assertRaises(TestChildException):
            testFunctionFalse()

        self.assertEqual(mockSleep.call_count, 0)
  def _runTransientErrorRetryTest(self, numErrors):

    with patch("time.sleep", autospec=True) as sleepMock, \
         patch("time.time", autospec=True) as timeMock:

      time_test_utils.configureTimeAndSleepMocks(timeMock, sleepMock)

      for errorCode in _ALL_RETRIABLE_ERROR_CODES:
        clientSideEffects = [
          sqlalchemy.exc.OperationalError(
            orig=MySQLdb.OperationalError(errorCode),
            statement="err", params=None)
        ] * numErrors + [DEFAULT]

        serverSideEffects = [
          sqlalchemy.exc.InternalError(
            orig=MySQLdb.InternalError(errorCode),
            statement="err", params=None)
        ] * numErrors + [DEFAULT]

        if 3000 > errorCode >= 2000:
          # The error is client side. Return one operationalError, then pass
          with patch.object(Engine,
                            "execute",
                            spec_set=Engine.execute,
                            side_effect=clientSideEffects) \
              as mockExecute:
            retryOnTransientErrors(mockExecute)(Mock())
            self.assertEqual(mockExecute.call_count, numErrors + 1)

        elif errorCode >= 1000:
          # The error is server side. Return one internalError, then pass
          with patch.object(Engine,
                            "execute",
                            spec_set=Engine.execute,
                            side_effect=serverSideEffects) \
              as mockExecute:
            retryOnTransientErrors(mockExecute)(Mock())
            self.assertEqual(mockExecute.call_count, numErrors + 1)

        else:
          self.fail("Error code is neither client nor server: %s" % errorCode)
示例#15
0
    def testWaitForFlusherAndGarbageCollectWithFlusherNotFound(
            self, getAllCustomMetricsMock, timeMock, sleepMock):

        time_test_utils.configureTimeAndSleepMocks(timeMock, sleepMock)

        flusherMetricName = (
            delete_companies._DATA_PATH_FLUSHER_METRIC_PREFIX + "1")

        # Patch getAllCustomMetrics to return all negatives and positives
        getAllCustomMetricsMock.return_value = [{
            "name":
            "XIGNITE.FOOBAR.CLOSINGPRICE"
        }]

        # Execute and validate
        with self.assertRaises(delete_companies.FlusherMetricNotFound):
            delete_companies._waitForFlusherAndGarbageCollect(
                engineServer="host",
                engineApiKey="apikey",
                flusherMetricName=flusherMetricName)
示例#16
0
    def testRetryNoTimeForRetries(self, mockTime, mockSleep):
        """Test that when timeoutSec == 0, function is executed exactly once
    with no retries, and raises an exception on failure.
    """

        time_test_utils.configureTimeAndSleepMocks(mockTime, mockSleep)

        _retry = error_handling.retry(timeoutSec=0,
                                      initialRetryDelaySec=0.2,
                                      maxRetryDelaySec=10)

        testFunction = Mock(side_effect=TestParentException("Test exception"),
                            __name__="testFunction",
                            autospec=True)

        with self.assertRaises(TestParentException):
            _retry(testFunction)()

        self.assertFalse(mockSleep.called)
        testFunction.assert_called_once_with()
示例#17
0
    def testFailsFirstSucceedsLater(self, mockTime, mockSleep):
        """If initial attempts fail but subsequent attempt succeeds, ensure that
    expected number of retries is performed and expected value is returned."""

        time_test_utils.configureTimeAndSleepMocks(mockTime, mockSleep)

        _retry = error_handling.retry(timeoutSec=30,
                                      initialRetryDelaySec=2,
                                      maxRetryDelaySec=10)

        testFunction = Mock(side_effect=[
            TestParentException("Test exception 1"),
            TestParentException("Test exception 2"), 321
        ],
                            __name__="testFunction",
                            autospec=True)

        returnValue = _retry(testFunction)()

        self.assertEqual(returnValue, 321)
        self.assertEqual(testFunction.call_count, 3)
示例#18
0
    def testRetryWaitsInitialRetryDelaySec(self, mockTime, mockSleep):
        """Test that delay times are correct."""

        time_test_utils.configureTimeAndSleepMocks(mockTime, mockSleep)

        _retry = error_handling.retry(timeoutSec=30,
                                      initialRetryDelaySec=2,
                                      maxRetryDelaySec=10)

        testFunction = Mock(side_effect=TestParentException("Test exception"),
                            __name__="testFunction",
                            autospec=True)

        with self.assertRaises(TestParentException):
            _retry(testFunction)()

        self.assertEqual(
            mockSleep.mock_calls,
            [call(2), call(4), call(8),
             call(10), call(10)])

        self.assertEqual(testFunction.call_count, 6)
  def testRetryRetryFilter(self, mockTime, mockSleep):
    """Test that if retryFilter is specified and exception is in
    retryExceptions, retries iff retryFilter returns true."""

    time_test_utils.configureTimeAndSleepMocks(mockTime, mockSleep)

    # Test with retryFilter returning True

    _retryTrueFilter = error_handling.retry(
      timeoutSec=1, initialRetryDelaySec=1,
      maxRetryDelaySec=10, retryExceptions=(TestParentException,),
      retryFilter=lambda _1, _2, _3: True)

    @_retryTrueFilter
    def testFunctionTrue():
      raise TestChildException("Test exception")

    with self.assertRaises(TestChildException):
      testFunctionTrue()

    self.assertEqual(mockSleep.call_count, 1)

    # Test with retryFilter returning False

    mockSleep.reset_mock()

    _retryFalseFilter = error_handling.retry(
      timeoutSec=1, initialRetryDelaySec=1,
      maxRetryDelaySec=10, retryExceptions=(TestParentException,),
      retryFilter=lambda _1, _2, _3: False)

    @_retryFalseFilter
    def testFunctionFalse():
      raise TestChildException("Test exception")

    with self.assertRaises(TestChildException):
      testFunctionFalse()

    self.assertEqual(mockSleep.call_count, 0)
  def testFailsFirstSucceedsLater(self, mockTime, mockSleep):
    """If initial attempts fail but subsequent attempt succeeds, ensure that
    expected number of retries is performed and expected value is returned."""

    time_test_utils.configureTimeAndSleepMocks(mockTime, mockSleep)

    _retry = error_handling.retry(
      timeoutSec=30, initialRetryDelaySec=2,
      maxRetryDelaySec=10)

    testFunction = Mock(
      side_effect=[
        TestParentException("Test exception 1"),
        TestParentException("Test exception 2"),
        321
      ],
      __name__="testFunction", autospec=True)

    returnValue = _retry(testFunction)()

    self.assertEqual(returnValue, 321)
    self.assertEqual(testFunction.call_count, 3)
  def testRetryRetryExceptionExcluded(self, mockTime, mockSleep):
    """ Test that retry is not triggered if raised exeception is not in
    retryExceptions """

    time_test_utils.configureTimeAndSleepMocks(mockTime, mockSleep)

    class TestExceptionA(Exception):
      pass

    class TestExceptionB(Exception):
      pass

    _retry = error_handling.retry(
      timeoutSec=1, initialRetryDelaySec=1,
      maxRetryDelaySec=10, retryExceptions=(TestExceptionA,))

    @_retry
    def testFunction():
      raise TestExceptionB("Test exception")

    with self.assertRaises(TestExceptionB):
      testFunction()

    self.assertEqual(mockSleep.call_count, 0)