DockerLockManagerTests.coffee 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. SandboxedModule = require('sandboxed-module')
  2. sinon = require('sinon')
  3. require('chai').should()
  4. require "coffee-script"
  5. modulePath = require('path').join __dirname, '../../../app/coffee/DockerLockManager'
  6. describe "LockManager", ->
  7. beforeEach ->
  8. @LockManager = SandboxedModule.require modulePath, requires:
  9. "settings-sharelatex": @Settings =
  10. clsi: docker: {}
  11. "logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub() }
  12. describe "runWithLock", ->
  13. describe "with a single lock", ->
  14. beforeEach (done) ->
  15. @callback = sinon.stub()
  16. @LockManager.runWithLock "lock-one", (releaseLock) ->
  17. setTimeout () ->
  18. releaseLock(null, "hello", "world")
  19. , 100
  20. , (err, args...) =>
  21. @callback(err,args...)
  22. done()
  23. it "should call the callback", ->
  24. @callback.calledWith(null,"hello","world").should.equal true
  25. describe "with two locks", ->
  26. beforeEach (done) ->
  27. @callback1 = sinon.stub()
  28. @callback2 = sinon.stub()
  29. @LockManager.runWithLock "lock-one", (releaseLock) ->
  30. setTimeout () ->
  31. releaseLock(null, "hello", "world","one")
  32. , 100
  33. , (err, args...) =>
  34. @callback1(err,args...)
  35. @LockManager.runWithLock "lock-two", (releaseLock) ->
  36. setTimeout () ->
  37. releaseLock(null, "hello", "world","two")
  38. , 200
  39. , (err, args...) =>
  40. @callback2(err,args...)
  41. done()
  42. it "should call the first callback", ->
  43. @callback1.calledWith(null,"hello","world","one").should.equal true
  44. it "should call the second callback", ->
  45. @callback2.calledWith(null,"hello","world","two").should.equal true
  46. describe "with lock contention", ->
  47. describe "where the first lock is released quickly", ->
  48. beforeEach (done) ->
  49. @LockManager.MAX_LOCK_WAIT_TIME = 1000
  50. @LockManager.LOCK_TEST_INTERVAL = 100
  51. @callback1 = sinon.stub()
  52. @callback2 = sinon.stub()
  53. @LockManager.runWithLock "lock", (releaseLock) ->
  54. setTimeout () ->
  55. releaseLock(null, "hello", "world","one")
  56. , 100
  57. , (err, args...) =>
  58. @callback1(err,args...)
  59. @LockManager.runWithLock "lock", (releaseLock) ->
  60. setTimeout () ->
  61. releaseLock(null, "hello", "world","two")
  62. , 200
  63. , (err, args...) =>
  64. @callback2(err,args...)
  65. done()
  66. it "should call the first callback", ->
  67. @callback1.calledWith(null,"hello","world","one").should.equal true
  68. it "should call the second callback", ->
  69. @callback2.calledWith(null,"hello","world","two").should.equal true
  70. describe "where the first lock is held longer than the waiting time", ->
  71. beforeEach (done) ->
  72. @LockManager.MAX_LOCK_HOLD_TIME = 10000
  73. @LockManager.MAX_LOCK_WAIT_TIME = 1000
  74. @LockManager.LOCK_TEST_INTERVAL = 100
  75. @callback1 = sinon.stub()
  76. @callback2 = sinon.stub()
  77. doneOne = doneTwo = false
  78. finish = (key) ->
  79. doneOne = true if key is 1
  80. doneTwo = true if key is 2
  81. done() if doneOne and doneTwo
  82. @LockManager.runWithLock "lock", (releaseLock) ->
  83. setTimeout () ->
  84. releaseLock(null, "hello", "world","one")
  85. , 1100
  86. , (err, args...) =>
  87. @callback1(err,args...)
  88. finish(1)
  89. @LockManager.runWithLock "lock", (releaseLock) ->
  90. setTimeout () ->
  91. releaseLock(null, "hello", "world","two")
  92. , 100
  93. , (err, args...) =>
  94. @callback2(err,args...)
  95. finish(2)
  96. it "should call the first callback", ->
  97. @callback1.calledWith(null,"hello","world","one").should.equal true
  98. it "should call the second callback with an error", ->
  99. error = sinon.match.instanceOf Error
  100. @callback2.calledWith(error).should.equal true
  101. describe "where the first lock is held longer than the max holding time", ->
  102. beforeEach (done) ->
  103. @LockManager.MAX_LOCK_HOLD_TIME = 1000
  104. @LockManager.MAX_LOCK_WAIT_TIME = 2000
  105. @LockManager.LOCK_TEST_INTERVAL = 100
  106. @callback1 = sinon.stub()
  107. @callback2 = sinon.stub()
  108. doneOne = doneTwo = false
  109. finish = (key) ->
  110. doneOne = true if key is 1
  111. doneTwo = true if key is 2
  112. done() if doneOne and doneTwo
  113. @LockManager.runWithLock "lock", (releaseLock) ->
  114. setTimeout () ->
  115. releaseLock(null, "hello", "world","one")
  116. , 1500
  117. , (err, args...) =>
  118. @callback1(err,args...)
  119. finish(1)
  120. @LockManager.runWithLock "lock", (releaseLock) ->
  121. setTimeout () ->
  122. releaseLock(null, "hello", "world","two")
  123. , 100
  124. , (err, args...) =>
  125. @callback2(err,args...)
  126. finish(2)
  127. it "should call the first callback", ->
  128. @callback1.calledWith(null,"hello","world","one").should.equal true
  129. it "should call the second callback", ->
  130. @callback2.calledWith(null,"hello","world","two").should.equal true