test-retry-operation.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. var common = require('../common');
  2. var assert = common.assert;
  3. var fake = common.fake.create();
  4. var retry = require(common.dir.lib + '/retry');
  5. (function testReset() {
  6. var error = new Error('some error');
  7. var operation = retry.operation([1, 2, 3]);
  8. var attempts = 0;
  9. var finalCallback = fake.callback('finalCallback');
  10. fake.expectAnytime(finalCallback);
  11. var expectedFinishes = 1;
  12. var finishes = 0;
  13. var fn = function() {
  14. operation.attempt(function(currentAttempt) {
  15. attempts++;
  16. assert.equal(currentAttempt, attempts);
  17. if (operation.retry(error)) {
  18. return;
  19. }
  20. finishes++
  21. assert.equal(expectedFinishes, finishes);
  22. assert.strictEqual(attempts, 4);
  23. assert.strictEqual(operation.attempts(), attempts);
  24. assert.strictEqual(operation.mainError(), error);
  25. if (finishes < 2) {
  26. attempts = 0;
  27. expectedFinishes++;
  28. operation.reset();
  29. fn()
  30. } else {
  31. finalCallback();
  32. }
  33. });
  34. };
  35. fn();
  36. })();
  37. (function testErrors() {
  38. var operation = retry.operation();
  39. var error = new Error('some error');
  40. var error2 = new Error('some other error');
  41. operation._errors.push(error);
  42. operation._errors.push(error2);
  43. assert.deepEqual(operation.errors(), [error, error2]);
  44. })();
  45. (function testMainErrorReturnsMostFrequentError() {
  46. var operation = retry.operation();
  47. var error = new Error('some error');
  48. var error2 = new Error('some other error');
  49. operation._errors.push(error);
  50. operation._errors.push(error2);
  51. operation._errors.push(error);
  52. assert.strictEqual(operation.mainError(), error);
  53. })();
  54. (function testMainErrorReturnsLastErrorOnEqualCount() {
  55. var operation = retry.operation();
  56. var error = new Error('some error');
  57. var error2 = new Error('some other error');
  58. operation._errors.push(error);
  59. operation._errors.push(error2);
  60. assert.strictEqual(operation.mainError(), error2);
  61. })();
  62. (function testAttempt() {
  63. var operation = retry.operation();
  64. var fn = new Function();
  65. var timeoutOpts = {
  66. timeout: 1,
  67. cb: function() {}
  68. };
  69. operation.attempt(fn, timeoutOpts);
  70. assert.strictEqual(fn, operation._fn);
  71. assert.strictEqual(timeoutOpts.timeout, operation._operationTimeout);
  72. assert.strictEqual(timeoutOpts.cb, operation._operationTimeoutCb);
  73. })();
  74. (function testRetry() {
  75. var error = new Error('some error');
  76. var operation = retry.operation([1, 2, 3]);
  77. var attempts = 0;
  78. var finalCallback = fake.callback('finalCallback');
  79. fake.expectAnytime(finalCallback);
  80. var fn = function() {
  81. operation.attempt(function(currentAttempt) {
  82. attempts++;
  83. assert.equal(currentAttempt, attempts);
  84. if (operation.retry(error)) {
  85. return;
  86. }
  87. assert.strictEqual(attempts, 4);
  88. assert.strictEqual(operation.attempts(), attempts);
  89. assert.strictEqual(operation.mainError(), error);
  90. finalCallback();
  91. });
  92. };
  93. fn();
  94. })();
  95. (function testRetryForever() {
  96. var error = new Error('some error');
  97. var operation = retry.operation({ retries: 3, forever: true });
  98. var attempts = 0;
  99. var finalCallback = fake.callback('finalCallback');
  100. fake.expectAnytime(finalCallback);
  101. var fn = function() {
  102. operation.attempt(function(currentAttempt) {
  103. attempts++;
  104. assert.equal(currentAttempt, attempts);
  105. if (attempts !== 6 && operation.retry(error)) {
  106. return;
  107. }
  108. assert.strictEqual(attempts, 6);
  109. assert.strictEqual(operation.attempts(), attempts);
  110. assert.strictEqual(operation.mainError(), error);
  111. finalCallback();
  112. });
  113. };
  114. fn();
  115. })();
  116. (function testRetryForeverNoRetries() {
  117. var error = new Error('some error');
  118. var delay = 50
  119. var operation = retry.operation({
  120. retries: null,
  121. forever: true,
  122. minTimeout: delay,
  123. maxTimeout: delay
  124. });
  125. var attempts = 0;
  126. var startTime = new Date().getTime();
  127. var finalCallback = fake.callback('finalCallback');
  128. fake.expectAnytime(finalCallback);
  129. var fn = function() {
  130. operation.attempt(function(currentAttempt) {
  131. attempts++;
  132. assert.equal(currentAttempt, attempts);
  133. if (attempts !== 4 && operation.retry(error)) {
  134. return;
  135. }
  136. var endTime = new Date().getTime();
  137. var minTime = startTime + (delay * 3);
  138. var maxTime = minTime + 20 // add a little headroom for code execution time
  139. assert(endTime >= minTime)
  140. assert(endTime < maxTime)
  141. assert.strictEqual(attempts, 4);
  142. assert.strictEqual(operation.attempts(), attempts);
  143. assert.strictEqual(operation.mainError(), error);
  144. finalCallback();
  145. });
  146. };
  147. fn();
  148. })();
  149. (function testStop() {
  150. var error = new Error('some error');
  151. var operation = retry.operation([1, 2, 3]);
  152. var attempts = 0;
  153. var finalCallback = fake.callback('finalCallback');
  154. fake.expectAnytime(finalCallback);
  155. var fn = function() {
  156. operation.attempt(function(currentAttempt) {
  157. attempts++;
  158. assert.equal(currentAttempt, attempts);
  159. if (attempts === 2) {
  160. operation.stop();
  161. assert.strictEqual(attempts, 2);
  162. assert.strictEqual(operation.attempts(), attempts);
  163. assert.strictEqual(operation.mainError(), error);
  164. finalCallback();
  165. }
  166. if (operation.retry(error)) {
  167. return;
  168. }
  169. });
  170. };
  171. fn();
  172. })();
  173. (function testMaxRetryTime() {
  174. var error = new Error('some error');
  175. var maxRetryTime = 30;
  176. var operation = retry.operation({
  177. minTimeout: 1,
  178. maxRetryTime: maxRetryTime
  179. });
  180. var attempts = 0;
  181. var finalCallback = fake.callback('finalCallback');
  182. fake.expectAnytime(finalCallback);
  183. var longAsyncFunction = function (wait, callback){
  184. setTimeout(callback, wait);
  185. };
  186. var fn = function() {
  187. var startTime = new Date().getTime();
  188. operation.attempt(function(currentAttempt) {
  189. attempts++;
  190. assert.equal(currentAttempt, attempts);
  191. if (attempts !== 2) {
  192. if (operation.retry(error)) {
  193. return;
  194. }
  195. } else {
  196. var curTime = new Date().getTime();
  197. longAsyncFunction(maxRetryTime - (curTime - startTime - 1), function(){
  198. if (operation.retry(error)) {
  199. assert.fail('timeout should be occurred');
  200. return;
  201. }
  202. assert.strictEqual(operation.mainError(), error);
  203. finalCallback();
  204. });
  205. }
  206. });
  207. };
  208. fn();
  209. })();