RateLimitManager.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /* eslint-disable
  2. no-return-assign,
  3. no-unused-vars,
  4. */
  5. // TODO: This file was created by bulk-decaffeinate.
  6. // Fix any style issues and re-enable lint.
  7. /*
  8. * decaffeinate suggestions:
  9. * DS102: Remove unnecessary code created because of implicit returns
  10. * DS206: Consider reworking classes to avoid initClass
  11. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  12. */
  13. const sinon = require('sinon')
  14. const { expect } = require('chai')
  15. const modulePath = '../../../../app/js/RateLimitManager.js'
  16. const SandboxedModule = require('sandboxed-module')
  17. describe('RateLimitManager', function () {
  18. beforeEach(function () {
  19. let Timer
  20. this.RateLimitManager = SandboxedModule.require(modulePath, {
  21. requires: {
  22. '@overleaf/settings': (this.settings = {}),
  23. './Metrics': (this.Metrics = {
  24. Timer: (Timer = (function () {
  25. Timer = class Timer {
  26. static initClass() {
  27. this.prototype.done = sinon.stub()
  28. }
  29. }
  30. Timer.initClass()
  31. return Timer
  32. })()),
  33. gauge: sinon.stub(),
  34. }),
  35. },
  36. })
  37. this.callback = sinon.stub()
  38. return (this.RateLimiter = new this.RateLimitManager(1))
  39. })
  40. describe('for a single task', function () {
  41. beforeEach(function () {
  42. this.task = sinon.stub()
  43. return this.RateLimiter.run(this.task, this.callback)
  44. })
  45. it('should execute the task in the background', function () {
  46. return this.task.called.should.equal(true)
  47. })
  48. it('should call the callback', function () {
  49. return this.callback.called.should.equal(true)
  50. })
  51. return it('should finish with a worker count of one', function () {
  52. // because it's in the background
  53. return expect(this.RateLimiter.ActiveWorkerCount).to.equal(1)
  54. })
  55. })
  56. describe('for multiple tasks', function () {
  57. beforeEach(function (done) {
  58. this.task = sinon.stub()
  59. this.finalTask = sinon.stub()
  60. const task = cb => {
  61. this.task()
  62. return setTimeout(cb, 100)
  63. }
  64. const finalTask = cb => {
  65. this.finalTask()
  66. return setTimeout(cb, 100)
  67. }
  68. this.RateLimiter.run(task, this.callback)
  69. this.RateLimiter.run(task, this.callback)
  70. this.RateLimiter.run(task, this.callback)
  71. return this.RateLimiter.run(finalTask, err => {
  72. this.callback(err)
  73. return done()
  74. })
  75. })
  76. it('should execute the first three tasks', function () {
  77. return this.task.calledThrice.should.equal(true)
  78. })
  79. it('should execute the final task', function () {
  80. return this.finalTask.called.should.equal(true)
  81. })
  82. it('should call the callback', function () {
  83. return this.callback.called.should.equal(true)
  84. })
  85. return it('should finish with worker count of zero', function () {
  86. return expect(this.RateLimiter.ActiveWorkerCount).to.equal(0)
  87. })
  88. })
  89. return describe('for a mixture of long-running tasks', function () {
  90. beforeEach(function (done) {
  91. this.task = sinon.stub()
  92. this.finalTask = sinon.stub()
  93. const finalTask = cb => {
  94. this.finalTask()
  95. return setTimeout(cb, 100)
  96. }
  97. this.RateLimiter.run(this.task, this.callback)
  98. this.RateLimiter.run(this.task, this.callback)
  99. this.RateLimiter.run(this.task, this.callback)
  100. return this.RateLimiter.run(finalTask, err => {
  101. this.callback(err)
  102. return done()
  103. })
  104. })
  105. it('should execute the first three tasks', function () {
  106. return this.task.calledThrice.should.equal(true)
  107. })
  108. it('should execute the final task', function () {
  109. return this.finalTask.called.should.equal(true)
  110. })
  111. it('should call the callback', function () {
  112. return this.callback.called.should.equal(true)
  113. })
  114. return it('should finish with worker count of three', function () {
  115. return expect(this.RateLimiter.ActiveWorkerCount).to.equal(3)
  116. })
  117. })
  118. })