SafeExecTests.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. const chai = require('chai')
  2. const should = chai.should()
  3. const { expect } = chai
  4. const modulePath = '../../../app/js/SafeExec'
  5. const SandboxedModule = require('sandboxed-module')
  6. describe('SafeExec', function() {
  7. let settings, options, safeExec
  8. beforeEach(function() {
  9. settings = { enableConversions: true }
  10. options = { timeout: 10 * 1000, killSignal: 'SIGTERM' }
  11. safeExec = SandboxedModule.require(modulePath, {
  12. globals: { process },
  13. requires: {
  14. 'settings-sharelatex': settings
  15. }
  16. })
  17. })
  18. describe('safeExec', function() {
  19. it('should execute a valid command', function(done) {
  20. safeExec(['/bin/echo', 'hello'], options, (err, stdout, stderr) => {
  21. stdout.should.equal('hello\n')
  22. stderr.should.equal('')
  23. should.not.exist(err)
  24. done()
  25. })
  26. })
  27. it('should error when conversions are disabled', function(done) {
  28. settings.enableConversions = false
  29. safeExec(['/bin/echo', 'hello'], options, err => {
  30. expect(err).to.exist
  31. done()
  32. })
  33. })
  34. it('should execute a command with non-zero exit status', function(done) {
  35. safeExec(['/usr/bin/env', 'false'], options, err => {
  36. expect(err).to.exist
  37. expect(err.name).to.equal('FailedCommandError')
  38. expect(err.code).to.equal(1)
  39. expect(err.stdout).to.equal('')
  40. expect(err.stderr).to.equal('')
  41. done()
  42. })
  43. })
  44. it('should handle an invalid command', function(done) {
  45. safeExec(['/bin/foobar'], options, err => {
  46. err.code.should.equal('ENOENT')
  47. done()
  48. })
  49. })
  50. it('should handle a command that runs too long', function(done) {
  51. safeExec(
  52. ['/bin/sleep', '10'],
  53. { timeout: 500, killSignal: 'SIGTERM' },
  54. err => {
  55. expect(err).to.exist
  56. expect(err.name).to.equal('FailedCommandError')
  57. expect(err.code).to.equal('SIGTERM')
  58. done()
  59. }
  60. )
  61. })
  62. })
  63. describe('as a promise', function() {
  64. beforeEach(function() {
  65. safeExec = safeExec.promises
  66. })
  67. it('should execute a valid command', async function() {
  68. const { stdout, stderr } = await safeExec(['/bin/echo', 'hello'], options)
  69. stdout.should.equal('hello\n')
  70. stderr.should.equal('')
  71. })
  72. it('should throw a ConversionsDisabledError when appropriate', async function() {
  73. settings.enableConversions = false
  74. try {
  75. await safeExec(['/bin/echo', 'hello'], options)
  76. } catch (err) {
  77. expect(err.name).to.equal('ConversionsDisabledError')
  78. return
  79. }
  80. expect('method did not throw an error').not.to.exist
  81. })
  82. it('should throw a FailedCommandError when appropriate', async function() {
  83. try {
  84. await safeExec(['/usr/bin/env', 'false'], options)
  85. } catch (err) {
  86. expect(err.name).to.equal('FailedCommandError')
  87. expect(err.code).to.equal(1)
  88. return
  89. }
  90. expect('method did not throw an error').not.to.exist
  91. })
  92. })
  93. })