LatexRunnerTests.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  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. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  11. */
  12. const SandboxedModule = require('sandboxed-module')
  13. const sinon = require('sinon')
  14. const { expect } = require('chai')
  15. const modulePath = require('path').join(
  16. __dirname,
  17. '../../../app/js/LatexRunner'
  18. )
  19. const Path = require('path')
  20. describe('LatexRunner', function () {
  21. beforeEach(function () {
  22. let Timer
  23. this.LatexRunner = SandboxedModule.require(modulePath, {
  24. requires: {
  25. '@overleaf/settings': (this.Settings = {
  26. docker: {
  27. socketPath: '/var/run/docker.sock',
  28. },
  29. }),
  30. './Metrics': {
  31. Timer: (Timer = class Timer {
  32. done() {}
  33. }),
  34. },
  35. './CommandRunner': (this.CommandRunner = {}),
  36. fs: (this.fs = {
  37. writeFile: sinon.stub().callsArg(2),
  38. }),
  39. },
  40. })
  41. this.directory = '/local/compile/directory'
  42. this.mainFile = 'main-file.tex'
  43. this.compiler = 'pdflatex'
  44. this.image = 'example.com/image'
  45. this.compileGroup = 'compile-group'
  46. this.callback = sinon.stub()
  47. this.project_id = 'project-id-123'
  48. return (this.env = { foo: '123' })
  49. })
  50. return describe('runLatex', function () {
  51. beforeEach(function () {
  52. return (this.CommandRunner.run = sinon.stub().callsArgWith(7, null, {
  53. stdout: 'this is stdout',
  54. stderr: 'this is stderr',
  55. }))
  56. })
  57. describe('normally', function () {
  58. beforeEach(function (done) {
  59. return this.LatexRunner.runLatex(
  60. this.project_id,
  61. {
  62. directory: this.directory,
  63. mainFile: this.mainFile,
  64. compiler: this.compiler,
  65. timeout: (this.timeout = 42000),
  66. image: this.image,
  67. environment: this.env,
  68. compileGroup: this.compileGroup,
  69. },
  70. (error, output, stats, timings) => {
  71. this.timings = timings
  72. done(error)
  73. }
  74. )
  75. })
  76. it('should run the latex command', function () {
  77. return this.CommandRunner.run
  78. .calledWith(
  79. this.project_id,
  80. sinon.match.any,
  81. this.directory,
  82. this.image,
  83. this.timeout,
  84. this.env,
  85. this.compileGroup
  86. )
  87. .should.equal(true)
  88. })
  89. it('should record the stdout and stderr', function () {
  90. this.fs.writeFile
  91. .calledWith(this.directory + '/' + 'output.stdout', 'this is stdout')
  92. .should.equal(true)
  93. this.fs.writeFile
  94. .calledWith(this.directory + '/' + 'output.stderr', 'this is stderr')
  95. .should.equal(true)
  96. })
  97. it('should not record cpu metrics', function () {
  98. expect(this.timings['cpu-percent']).to.not.exist
  99. expect(this.timings['cpu-time']).to.not.exist
  100. expect(this.timings['sys-time']).to.not.exist
  101. })
  102. })
  103. describe('with time -v', function () {
  104. beforeEach(function (done) {
  105. this.CommandRunner.run = sinon.stub().callsArgWith(7, null, {
  106. stdout: 'this is stdout',
  107. stderr:
  108. '\tCommand being timed: "sh -c timeout 1 yes > /dev/null"\n' +
  109. '\tUser time (seconds): 0.28\n' +
  110. '\tSystem time (seconds): 0.70\n' +
  111. '\tPercent of CPU this job got: 98%\n',
  112. })
  113. this.LatexRunner.runLatex(
  114. this.project_id,
  115. {
  116. directory: this.directory,
  117. mainFile: this.mainFile,
  118. compiler: this.compiler,
  119. timeout: (this.timeout = 42000),
  120. image: this.image,
  121. environment: this.env,
  122. compileGroup: this.compileGroup,
  123. },
  124. (error, output, stats, timings) => {
  125. this.timings = timings
  126. done(error)
  127. }
  128. )
  129. })
  130. it('should record cpu metrics', function () {
  131. expect(this.timings['cpu-percent']).to.equal(98)
  132. expect(this.timings['cpu-time']).to.equal(0.28)
  133. expect(this.timings['sys-time']).to.equal(0.7)
  134. })
  135. })
  136. describe('with an .Rtex main file', function () {
  137. beforeEach(function () {
  138. return this.LatexRunner.runLatex(
  139. this.project_id,
  140. {
  141. directory: this.directory,
  142. mainFile: 'main-file.Rtex',
  143. compiler: this.compiler,
  144. image: this.image,
  145. timeout: (this.timeout = 42000),
  146. },
  147. this.callback
  148. )
  149. })
  150. return it('should run the latex command on the equivalent .tex file', function () {
  151. const command = this.CommandRunner.run.args[0][1]
  152. const mainFile = command.slice(-1)[0]
  153. return mainFile.should.equal('$COMPILE_DIR/main-file.tex')
  154. })
  155. })
  156. return describe('with a flags option', function () {
  157. beforeEach(function () {
  158. return this.LatexRunner.runLatex(
  159. this.project_id,
  160. {
  161. directory: this.directory,
  162. mainFile: this.mainFile,
  163. compiler: this.compiler,
  164. image: this.image,
  165. timeout: (this.timeout = 42000),
  166. flags: ['-shell-restricted', '-halt-on-error'],
  167. },
  168. this.callback
  169. )
  170. })
  171. return it('should include the flags in the command', function () {
  172. const command = this.CommandRunner.run.args[0][1]
  173. const flags = command.filter(
  174. arg => arg === '-shell-restricted' || arg === '-halt-on-error'
  175. )
  176. flags.length.should.equal(2)
  177. flags[0].should.equal('-shell-restricted')
  178. return flags[1].should.equal('-halt-on-error')
  179. })
  180. })
  181. })
  182. })