retry_ut.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include "retry.h"
  2. #include <library/cpp/testing/unittest/registar.h>
  3. namespace {
  4. class TDoOnSecondOrThrow {
  5. public:
  6. ui32 operator()() {
  7. if (attempt++ != 1) {
  8. throw yexception();
  9. }
  10. return 42;
  11. }
  12. private:
  13. ui32 attempt = 0;
  14. };
  15. class TDoOnSecondOrFail {
  16. public:
  17. bool operator()() {
  18. return (attempt++ == 1);
  19. }
  20. private:
  21. ui32 attempt = 0;
  22. };
  23. }
  24. Y_UNIT_TEST_SUITE(Retry) {
  25. Y_UNIT_TEST(RetryOnExceptionSuccess) {
  26. UNIT_ASSERT_NO_EXCEPTION(DoWithRetry(TDoOnSecondOrThrow{}, TRetryOptions(1, TDuration::Zero())));
  27. }
  28. Y_UNIT_TEST(RetryOnExceptionSuccessWithOnFail) {
  29. ui32 value = 0;
  30. std::function<void(const yexception&)> cb = [&value](const yexception&){ value += 1; };
  31. UNIT_ASSERT_NO_EXCEPTION(DoWithRetry<ui32>(TDoOnSecondOrThrow{}, cb, TRetryOptions(1, TDuration::Zero()), true));
  32. UNIT_ASSERT_EQUAL(value, 1);
  33. }
  34. Y_UNIT_TEST(RetryOnExceptionFail) {
  35. UNIT_ASSERT_EXCEPTION(DoWithRetry(TDoOnSecondOrThrow{}, TRetryOptions(0, TDuration::Zero())), yexception);
  36. }
  37. Y_UNIT_TEST(RetryOnExceptionFailWithOnFail) {
  38. ui32 value = 0;
  39. std::function<void(const yexception&)> cb = [&value](const yexception&) { value += 1; };
  40. UNIT_ASSERT_EXCEPTION(DoWithRetry<ui32>(TDoOnSecondOrThrow{}, cb, TRetryOptions(0, TDuration::Zero()), true), yexception);
  41. UNIT_ASSERT_EQUAL(value, 1);
  42. }
  43. Y_UNIT_TEST(RetryOnExceptionSuccessWithValue) {
  44. std::function<ui32()> f = TDoOnSecondOrThrow{};
  45. UNIT_ASSERT(42 == *DoWithRetry<ui32>(f, TRetryOptions(1, TDuration::Zero()), false));
  46. }
  47. Y_UNIT_TEST(RetryOnExceptionSuccessWithValueWithOnFail) {
  48. ui32 value = 0;
  49. std::function<ui32()> f = TDoOnSecondOrThrow{};
  50. std::function<void(const yexception&)> cb = [&value](const yexception&){ value += 1; };
  51. UNIT_ASSERT(42 == *DoWithRetry<ui32>(f, cb, TRetryOptions(1, TDuration::Zero()), false));
  52. UNIT_ASSERT_EQUAL(value, 1);
  53. }
  54. Y_UNIT_TEST(RetryOnExceptionFailWithValue) {
  55. std::function<ui32()> f = TDoOnSecondOrThrow{};
  56. UNIT_ASSERT(!DoWithRetry<ui32>(f, TRetryOptions(0, TDuration::Zero()), false).Defined());
  57. }
  58. Y_UNIT_TEST(RetryOnExceptionFailWithValueWithOnFail) {
  59. ui32 value = 0;
  60. std::function<ui32()> f = TDoOnSecondOrThrow{};
  61. std::function<void(const yexception&)> cb = [&value](const yexception&){ value += 1; };
  62. UNIT_ASSERT(!DoWithRetry<ui32>(f, cb, TRetryOptions(0, TDuration::Zero()), false).Defined());
  63. UNIT_ASSERT_EQUAL(value, 1);
  64. }
  65. Y_UNIT_TEST(RetryOnExceptionSuccessWithValueAndRethrow) {
  66. std::function<ui32()> f = TDoOnSecondOrThrow{};
  67. UNIT_ASSERT(42 == *DoWithRetry<ui32>(f, TRetryOptions(1, TDuration::Zero()), true));
  68. }
  69. Y_UNIT_TEST(RetryOnExceptionSuccessWithValueAndRethrowWithOnFail) {
  70. ui32 value = 0;
  71. std::function<ui32()> f = TDoOnSecondOrThrow{};
  72. std::function<void(const yexception&)> cb = [&value](const yexception&){ value += 1; };
  73. UNIT_ASSERT(42 == *DoWithRetry<ui32>(f, cb, TRetryOptions(1, TDuration::Zero()), true));
  74. UNIT_ASSERT_EQUAL(value, 1);
  75. }
  76. Y_UNIT_TEST(RetryOnExceptionFailWithValueAndRethrow) {
  77. std::function<ui32()> f = TDoOnSecondOrThrow{};
  78. UNIT_ASSERT_EXCEPTION(DoWithRetry<ui32>(f, TRetryOptions(0, TDuration::Zero()), true), yexception);
  79. }
  80. Y_UNIT_TEST(RetryOnExceptionFailWithValueAndRethrowWithOnFail) {
  81. ui32 value = 0;
  82. std::function<ui32()> f = TDoOnSecondOrThrow{};
  83. std::function<void(const yexception&)> cb = [&value](const yexception&){ value += 1; };
  84. UNIT_ASSERT_EXCEPTION(42 == *DoWithRetry<ui32>(f, cb, TRetryOptions(0, TDuration::Zero()), true), yexception);
  85. UNIT_ASSERT_EQUAL(value, 1);
  86. }
  87. Y_UNIT_TEST(RetryOnRetCodeSuccess) {
  88. UNIT_ASSERT(true == DoWithRetryOnRetCode(TDoOnSecondOrFail{}, TRetryOptions(1, TDuration::Zero())));
  89. }
  90. Y_UNIT_TEST(RetryOnRetCodeFail) {
  91. UNIT_ASSERT(false == DoWithRetryOnRetCode(TDoOnSecondOrFail{}, TRetryOptions(0, TDuration::Zero())));
  92. }
  93. Y_UNIT_TEST(MakeRetryOptionsFromProto) {
  94. NRetry::TRetryOptionsPB protoOptions;
  95. protoOptions.SetMaxTries(1);
  96. protoOptions.SetInitialSleepMs(2);
  97. protoOptions.SetSleepIncrementMs(3);
  98. protoOptions.SetRandomDeltaMs(4);
  99. protoOptions.SetExponentalMultiplierMs(5);
  100. const TRetryOptions options = MakeRetryOptions(protoOptions);
  101. UNIT_ASSERT_EQUAL(options.RetryCount, 1);
  102. UNIT_ASSERT_EQUAL(options.SleepDuration, TDuration::MilliSeconds(2));
  103. UNIT_ASSERT_EQUAL(options.SleepIncrement, TDuration::MilliSeconds(3));
  104. UNIT_ASSERT_EQUAL(options.SleepRandomDelta, TDuration::MilliSeconds(4));
  105. UNIT_ASSERT_EQUAL(options.SleepExponentialMultiplier, TDuration::MilliSeconds(5));
  106. }
  107. }