diff --git a/services/web/app/src/Features/Compile/ClsiCookieManager.js b/services/web/app/src/Features/Compile/ClsiCookieManager.js index db215a9524..bb4f9787a5 100644 --- a/services/web/app/src/Features/Compile/ClsiCookieManager.js +++ b/services/web/app/src/Features/Compile/ClsiCookieManager.js @@ -12,6 +12,7 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ let rclient_secondary +const { URL, URLSearchParams } = require('url') const OError = require('@overleaf/o-error') const Settings = require('@overleaf/settings') const request = require('request').defaults({ timeout: 30 * 1000 }) @@ -38,7 +39,7 @@ module.exports = function (backendGroup) { } }, - _getServerId(project_id, user_id, callback) { + _getServerId(project_id, user_id, compileGroup, callback) { if (callback == null) { callback = function () {} } @@ -52,6 +53,7 @@ module.exports = function (backendGroup) { return this._populateServerIdViaRequest( project_id, user_id, + compileGroup, callback ) } else { @@ -61,12 +63,15 @@ module.exports = function (backendGroup) { ) }, - _populateServerIdViaRequest(project_id, user_id, callback) { + _populateServerIdViaRequest(project_id, user_id, compileGroup, callback) { if (callback == null) { callback = function () {} } - const url = `${Settings.apis.clsi.url}/project/${project_id}/status` - request.post(url, (err, res, body) => { + const u = new URL( + `${Settings.apis.clsi.url}/project/${project_id}/status` + ) + u.search = new URLSearchParams({ compileGroup }).toString() + request.post(u.href, (err, res, body) => { if (err != null) { OError.tag(err, 'error getting initial server id for project', { project_id, @@ -76,6 +81,7 @@ module.exports = function (backendGroup) { this.setServerId( project_id, user_id, + compileGroup, res, null, function (err, serverId) { @@ -100,11 +106,11 @@ module.exports = function (backendGroup) { return cookies != null ? cookies[Settings.clsiCookie.key] : undefined }, - checkIsLoadSheddingEvent(clsiserverid) { + checkIsLoadSheddingEvent(clsiserverid, compileGroup) { request.get( { url: `${Settings.apis.clsi.url}/instance-state`, - qs: { clsiserverid }, + qs: { clsiserverid, compileGroup }, }, (err, res, body) => { if (err) { @@ -123,7 +129,14 @@ module.exports = function (backendGroup) { ) }, - setServerId(project_id, user_id, response, previous, callback) { + setServerId( + project_id, + user_id, + compileGroup, + response, + previous, + callback + ) { if (callback == null) { callback = function () {} } @@ -143,7 +156,7 @@ module.exports = function (backendGroup) { // Initial assignment of a user+project or after clearing cache. Metrics.inc('clsi-lb-assign-initial-backend') } else { - this.checkIsLoadSheddingEvent(previous) + this.checkIsLoadSheddingEvent(previous, compileGroup) } if (rclient_secondary != null) { this._setServerIdInRedis( @@ -181,27 +194,32 @@ module.exports = function (backendGroup) { return rclient.del(this.buildKey(project_id, user_id), callback) }, - getCookieJar(project_id, user_id, callback) { + getCookieJar(project_id, user_id, compileGroup, callback) { if (callback == null) { callback = function () {} } if (!clsiCookiesEnabled) { return callback(null, request.jar(), undefined) } - return this._getServerId(project_id, user_id, (err, serverId) => { - if (err != null) { - OError.tag(err, 'error getting server id', { - project_id, - }) - return callback(err) + return this._getServerId( + project_id, + user_id, + compileGroup, + (err, serverId) => { + if (err != null) { + OError.tag(err, 'error getting server id', { + project_id, + }) + return callback(err) + } + const serverCookie = request.cookie( + `${Settings.clsiCookie.key}=${serverId}` + ) + const jar = request.jar() + jar.setCookie(serverCookie, Settings.apis.clsi.url) + return callback(null, jar, serverId) } - const serverCookie = request.cookie( - `${Settings.clsiCookie.key}=${serverId}` - ) - const jar = request.jar() - jar.setCookie(serverCookie, Settings.apis.clsi.url) - return callback(null, jar, serverId) - }) + ) }, } } diff --git a/services/web/app/src/Features/Compile/ClsiManager.js b/services/web/app/src/Features/Compile/ClsiManager.js index 17c0f427e0..e8c8923cec 100644 --- a/services/web/app/src/Features/Compile/ClsiManager.js +++ b/services/web/app/src/Features/Compile/ClsiManager.js @@ -4,7 +4,7 @@ const request = require('request') const ProjectGetter = require('../Project/ProjectGetter') const ProjectEntityHandler = require('../Project/ProjectEntityHandler') const logger = require('@overleaf/logger') -const { URL } = require('url') +const { URL, URLSearchParams } = require('url') const OError = require('@overleaf/o-error') const ClsiCookieManager = require('./ClsiCookieManager')( @@ -122,8 +122,9 @@ const ClsiManager = { if (options == null) { options = {} } + const { compileGroup } = options const compilerUrl = this._getCompilerUrl( - options.compileGroup, + compileGroup, projectId, userId, 'compile/stop' @@ -132,18 +133,15 @@ const ClsiManager = { url: compilerUrl, method: 'POST', } - ClsiManager._makeRequest(projectId, userId, opts, callback) + ClsiManager._makeRequest(projectId, userId, compileGroup, opts, callback) }, deleteAuxFiles(projectId, userId, options, clsiserverid, callback) { if (options == null) { options = {} } - const compilerUrl = this._getCompilerUrl( - options.compileGroup, - projectId, - userId - ) + const { compileGroup } = options + const compilerUrl = this._getCompilerUrl(compileGroup, projectId, userId) const opts = { url: compilerUrl, method: 'DELETE', @@ -151,6 +149,7 @@ const ClsiManager = { ClsiManager._makeRequestWithClsiServerId( projectId, userId, + compileGroup, opts, clsiserverid, clsiErr => { @@ -274,13 +273,14 @@ const ClsiManager = { _makeRequestWithClsiServerId( projectId, userId, + compileGroup, opts, clsiserverid, callback ) { if (clsiserverid) { // ignore cookies and newBackend, go straight to the clsi node - opts.qs = Object.assign({ clsiserverid }, opts.qs) + opts.qs = Object.assign({ compileGroup, clsiserverid }, opts.qs) request(opts, (err, response, body) => { if (err) { return callback( @@ -290,11 +290,11 @@ const ClsiManager = { callback(null, response, body) }) } else { - ClsiManager._makeRequest(projectId, userId, opts, callback) + ClsiManager._makeRequest(projectId, userId, compileGroup, opts, callback) } }, - _makeRequest(projectId, userId, opts, callback) { + _makeRequest(projectId, userId, compileGroup, opts, callback) { async.series( { currentBackend(cb) { @@ -302,6 +302,7 @@ const ClsiManager = { ClsiCookieManager.getCookieJar( projectId, userId, + compileGroup, (err, jar, clsiServerId) => { if (err != null) { return callback( @@ -327,6 +328,7 @@ const ClsiManager = { ClsiCookieManager.setServerId( projectId, userId, + compileGroup, response, clsiServerId, (err, newClsiServerId) => { @@ -361,6 +363,7 @@ const ClsiManager = { ClsiManager._makeNewBackendRequest( projectId, userId, + compileGroup, opts, (err, response, body) => { if (err != null) { @@ -407,7 +410,7 @@ const ClsiManager = { ) }, - _makeNewBackendRequest(projectId, userId, baseOpts, callback) { + _makeNewBackendRequest(projectId, userId, compileGroup, baseOpts, callback) { if (Settings.apis.clsi_new == null || Settings.apis.clsi_new.url == null) { return callback() } @@ -421,6 +424,7 @@ const ClsiManager = { NewBackendCloudClsiCookieManager.getCookieJar( projectId, userId, + compileGroup, (err, jar, clsiServerId) => { if (err != null) { return callback( @@ -444,6 +448,7 @@ const ClsiManager = { NewBackendCloudClsiCookieManager.setServerId( projectId, userId, + compileGroup, response, clsiServerId, err => { @@ -463,15 +468,15 @@ const ClsiManager = { }, _getCompilerUrl(compileGroup, projectId, userId, action) { - const host = Settings.apis.clsi.url - let path = `/project/${projectId}` + const u = new URL(`/project/${projectId}`, Settings.apis.clsi.url) if (userId != null) { - path += `/user/${userId}` + u.pathname += `/user/${userId}` } if (action != null) { - path += `/${action}` + u.pathname += `/${action}` } - return `${host}${path}` + u.search = new URLSearchParams({ compileGroup }).toString() + return u.href }, _postToClsi(projectId, userId, req, compileGroup, callback) { @@ -489,16 +494,21 @@ const ClsiManager = { ClsiManager._makeRequest( projectId, userId, + compileGroup, opts, (err, response, body, clsiServerId) => { if (err != null) { return callback( - new OError('failed to make request to CLSI', { - projectId, - userId, - compileOptions: req.compile.options, - rootResourcePath: req.compile.rootResourcePath, - }) + new OError( + 'failed to make request to CLSI', + { + projectId, + userId, + compileOptions: req.compile.options, + rootResourcePath: req.compile.rootResourcePath, + }, + err + ) ) } if (response.statusCode >= 200 && response.statusCode < 300) { @@ -655,9 +665,18 @@ const ClsiManager = { ) }, - getOutputFileStream(projectId, userId, buildId, outputFilePath, callback) { + getOutputFileStream( + projectId, + userId, + compileGroup, + clsiServerId, + buildId, + outputFilePath, + callback + ) { const url = `${Settings.apis.clsi.url}/project/${projectId}/user/${userId}/build/${buildId}/output/${outputFilePath}` - ClsiCookieManager.getCookieJar(projectId, userId, (err, jar) => { + // TODO(das7pad): remove one week after landing frontend changes. + ClsiCookieManager.getCookieJar(projectId, userId, '', (err, jar) => { if (err != null) { return callback( OError.tag(err, 'Failed to get cookie jar', { @@ -669,6 +688,10 @@ const ClsiManager = { ) } const options = { url, method: 'GET', timeout: 60 * 1000, jar } + if (clsiServerId) { + options.qs = { compileGroup, clsiserverid: clsiServerId } + delete options.jar + } const readStream = request(options) callback(null, readStream) }) @@ -863,6 +886,7 @@ const ClsiManager = { }, wordCount(projectId, userId, file, options, clsiserverid, callback) { + const { compileGroup } = options ClsiManager._buildRequest(projectId, options, (err, req) => { if (err != null) { return callback( @@ -874,7 +898,7 @@ const ClsiManager = { } const filename = file || req.compile.rootResourcePath const wordCountUrl = ClsiManager._getCompilerUrl( - options.compileGroup, + compileGroup, projectId, userId, 'wordcount' @@ -891,6 +915,7 @@ const ClsiManager = { ClsiManager._makeRequestWithClsiServerId( projectId, userId, + compileGroup, opts, clsiserverid, (err, response, body) => { diff --git a/services/web/app/src/Features/Compile/CompileController.js b/services/web/app/src/Features/Compile/CompileController.js index 95a2707627..451cc52cb8 100644 --- a/services/web/app/src/Features/Compile/CompileController.js +++ b/services/web/app/src/Features/Compile/CompileController.js @@ -336,6 +336,7 @@ module.exports = CompileController = { const limits = { compileGroup: (req.body != null ? req.body.compileGroup : undefined) || + req.query?.compileGroup || Settings.defaultFeatures.compileGroup, } return CompileController.proxyToClsiWithLimits( @@ -489,59 +490,64 @@ module.exports = CompileController = { if (next == null) { next = function () {} } - _getPersistenceOptions(req, project_id, (err, persistenceOptions) => { - let qs - if (err != null) { - OError.tag(err, 'error getting cookie jar for clsi request') - return next(err) - } - // expand any url parameter passed in as {url:..., qs:...} - if (typeof url === 'object') { - ;({ url, qs } = url) - } - const compilerUrl = Settings.apis.clsi.url - url = `${compilerUrl}${url}` - const oneMinute = 60 * 1000 - // the base request - const options = { - url, - method: req.method, - timeout: oneMinute, - ...persistenceOptions, - } - // add any provided query string - if (qs != null) { - options.qs = Object.assign(options.qs || {}, qs) - } - // if we have a build parameter, pass it through to the clsi - if ( - (req.query != null ? req.query.pdfng : undefined) && - (req.query != null ? req.query.build : undefined) != null - ) { - // only for new pdf viewer - if (options.qs == null) { - options.qs = {} + _getPersistenceOptions( + req, + project_id, + limits.compileGroup, + (err, persistenceOptions) => { + let qs + if (err != null) { + OError.tag(err, 'error getting cookie jar for clsi request') + return next(err) } - options.qs.build = req.query.build - } - // if we are byte serving pdfs, pass through If-* and Range headers - // do not send any others, there's a proxying loop if Host: is passed! - if (req.query != null ? req.query.pdfng : undefined) { - const newHeaders = {} - for (const h in req.headers) { - const v = req.headers[h] - if (/^(If-|Range)/i.test(h)) { - newHeaders[h] = req.headers[h] + // expand any url parameter passed in as {url:..., qs:...} + if (typeof url === 'object') { + ;({ url, qs } = url) + } + const compilerUrl = Settings.apis.clsi.url + url = `${compilerUrl}${url}` + const oneMinute = 60 * 1000 + // the base request + const options = { + url, + method: req.method, + timeout: oneMinute, + ...persistenceOptions, + } + // add any provided query string + if (qs != null) { + options.qs = Object.assign(options.qs || {}, qs) + } + // if we have a build parameter, pass it through to the clsi + if ( + (req.query != null ? req.query.pdfng : undefined) && + (req.query != null ? req.query.build : undefined) != null + ) { + // only for new pdf viewer + if (options.qs == null) { + options.qs = {} } + options.qs.build = req.query.build } - options.headers = newHeaders + // if we are byte serving pdfs, pass through If-* and Range headers + // do not send any others, there's a proxying loop if Host: is passed! + if (req.query != null ? req.query.pdfng : undefined) { + const newHeaders = {} + for (const h in req.headers) { + const v = req.headers[h] + if (/^(If-|Range)/i.test(h)) { + newHeaders[h] = req.headers[h] + } + } + options.headers = newHeaders + } + const proxy = request(options) + proxy.pipe(res) + return proxy.on('error', error => + logger.warn({ err: error, url }, 'CLSI proxy error') + ) } - const proxy = request(options) - proxy.pipe(res) - return proxy.on('error', error => - logger.warn({ err: error, url }, 'CLSI proxy error') - ) - }) + ) }, wordCount(req, res, next) { @@ -568,14 +574,19 @@ module.exports = CompileController = { }, } -function _getPersistenceOptions(req, projectId, callback) { +function _getPersistenceOptions(req, projectId, compileGroup, callback) { const { clsiserverid } = req.query const user_id = SessionManager.getLoggedInUserId(req) if (clsiserverid && typeof clsiserverid === 'string') { - callback(null, { qs: { clsiserverid } }) + callback(null, { qs: { clsiserverid, compileGroup } }) } else { - ClsiCookieManager.getCookieJar(projectId, user_id, (err, jar) => { - callback(err, { jar }) - }) + ClsiCookieManager.getCookieJar( + projectId, + user_id, + compileGroup, + (err, jar) => { + callback(err, { jar }) + } + ) } } diff --git a/services/web/app/src/Features/LinkedFiles/ProjectOutputFileAgent.js b/services/web/app/src/Features/LinkedFiles/ProjectOutputFileAgent.js index 730328ea65..9b3678f3b2 100644 --- a/services/web/app/src/Features/LinkedFiles/ProjectOutputFileAgent.js +++ b/services/web/app/src/Features/LinkedFiles/ProjectOutputFileAgent.js @@ -131,6 +131,8 @@ function _sanitizeData(data) { source_project_id: data.source_project_id, source_output_file_path: data.source_output_file_path, build_id: data.build_id, + clsiServerId: data.clsiServerId, + compileGroup: data.compileGroup, } } @@ -168,8 +170,12 @@ function _checkAuth(projectId, data, currentUserId, callback) { function _getFileStream(linkedFileData, userId, callback) { callback = _.once(callback) - const { source_output_file_path: sourceOutputFilePath, build_id: buildId } = - linkedFileData + const { + source_output_file_path: sourceOutputFilePath, + build_id: buildId, + clsiServerId, + compileGroup, + } = linkedFileData LinkedFilesHandler.getSourceProject(linkedFileData, (err, project) => { if (err) { return callback(err) @@ -178,6 +184,8 @@ function _getFileStream(linkedFileData, userId, callback) { ClsiManager.getOutputFileStream( sourceProjectId, userId, + compileGroup, + clsiServerId, buildId, sourceOutputFilePath, (err, readStream) => { @@ -203,7 +211,7 @@ function _compileAndGetFileStream(linkedFileData, userId, callback) { sourceProjectId, userId, {}, - (err, status, outputFiles) => { + (err, status, outputFiles, clsiServerId, limits) => { if (err) { return callback(err) } @@ -221,6 +229,8 @@ function _compileAndGetFileStream(linkedFileData, userId, callback) { ClsiManager.getOutputFileStream( sourceProjectId, userId, + limits.compileGroup, + clsiServerId, buildId, sourceOutputFilePath, (err, readStream) => { diff --git a/services/web/frontend/js/features/file-tree/components/file-tree-create/modes/file-tree-import-from-project.js b/services/web/frontend/js/features/file-tree/components/file-tree-create/modes/file-tree-import-from-project.js index f6ce6e07d2..9d5f50eaba 100644 --- a/services/web/frontend/js/features/file-tree/components/file-tree-create/modes/file-tree-import-from-project.js +++ b/services/web/frontend/js/features/file-tree/components/file-tree-create/modes/file-tree-import-from-project.js @@ -94,6 +94,8 @@ export default function FileTreeImportFromProject() { source_project_id: selectedProject._id, source_output_file_path: selectedProjectOutputFile.path, build_id: selectedProjectOutputFile.build, + clsiServerId: selectedProjectOutputFile.clsiServerId, + compileGroup: selectedProjectOutputFile.compileGroup, }, }) } else { diff --git a/services/web/frontend/js/features/file-tree/hooks/use-project-output-files.js b/services/web/frontend/js/features/file-tree/hooks/use-project-output-files.js index 9ab207de05..0e8e248b03 100644 --- a/services/web/frontend/js/features/file-tree/hooks/use-project-output-files.js +++ b/services/web/frontend/js/features/file-tree/hooks/use-project-output-files.js @@ -31,7 +31,10 @@ export function useProjectOutputFiles(projectId) { const filteredFiles = data.outputFiles.filter(file => file.path.match(/.*\.(pdf|png|jpeg|jpg|gif)/) ) - + data.outputFiles.forEach(file => { + file.clsiServerId = data.clsiServerId + file.compileGroup = data.compileGroup + }) setData(filteredFiles.sort(alphabetical)) } else { setError('linked-project-compile-error') diff --git a/services/web/frontend/js/features/pdf-preview/util/file-list.js b/services/web/frontend/js/features/pdf-preview/util/file-list.js index 44cec32637..2d0c3ee046 100644 --- a/services/web/frontend/js/features/pdf-preview/util/file-list.js +++ b/services/web/frontend/js/features/pdf-preview/util/file-list.js @@ -1,7 +1,7 @@ const topFileTypes = ['bbl', 'gls', 'ind'] const ignoreFiles = ['output.fls', 'output.fdb_latexmk'] -export const buildFileList = (outputFiles, clsiServerId) => { +export const buildFileList = (outputFiles, clsiServerId, compileGroup) => { const files = { top: [], other: [] } if (outputFiles) { @@ -10,6 +10,9 @@ export const buildFileList = (outputFiles, clsiServerId) => { if (clsiServerId) { params.set('clsiserverid', clsiServerId) } + if (compileGroup) { + params.set('compileGroup', compileGroup) + } const queryString = params.toString() diff --git a/services/web/frontend/js/shared/context/local-compile-context.js b/services/web/frontend/js/shared/context/local-compile-context.js index 66f5a10b6a..56642e6411 100644 --- a/services/web/frontend/js/shared/context/local-compile-context.js +++ b/services/web/frontend/js/shared/context/local-compile-context.js @@ -253,7 +253,9 @@ export function LocalCompileProvider({ children }) { setPdfUrl(result.pdfUrl) } - setFileList(buildFileList(outputFiles, data.clsiServerId)) + setFileList( + buildFileList(outputFiles, data.clsiServerId, data.compileGroup) + ) // handle log files // asynchronous (TODO: cancel on new compile?) diff --git a/services/web/test/unit/src/Compile/ClsiCookieManagerTests.js b/services/web/test/unit/src/Compile/ClsiCookieManagerTests.js index 5fe7b2bc50..aeeb4f762c 100644 --- a/services/web/test/unit/src/Compile/ClsiCookieManagerTests.js +++ b/services/web/test/unit/src/Compile/ClsiCookieManagerTests.js @@ -67,6 +67,7 @@ describe('ClsiCookieManager', function () { return this.ClsiCookieManager._getServerId( this.project_id, this.user_id, + '', (err, serverId) => { this.redis.get .calledWith(`clsiserver:${this.project_id}:${this.user_id}`) @@ -80,11 +81,12 @@ describe('ClsiCookieManager', function () { it('should _populateServerIdViaRequest if no key is found', function (done) { this.ClsiCookieManager._populateServerIdViaRequest = sinon .stub() - .callsArgWith(2) + .yields(null) this.redis.get.callsArgWith(1, null) return this.ClsiCookieManager._getServerId( this.project_id, this.user_id, + '', (err, serverId) => { this.ClsiCookieManager._populateServerIdViaRequest .calledWith(this.project_id, this.user_id) @@ -97,11 +99,12 @@ describe('ClsiCookieManager', function () { it('should _populateServerIdViaRequest if no key is blank', function (done) { this.ClsiCookieManager._populateServerIdViaRequest = sinon .stub() - .callsArgWith(2) + .yields(null) this.redis.get.callsArgWith(1, null, '') return this.ClsiCookieManager._getServerId( this.project_id, this.user_id, + '', (err, serverId) => { this.ClsiCookieManager._populateServerIdViaRequest .calledWith(this.project_id, this.user_id) @@ -125,11 +128,13 @@ describe('ClsiCookieManager', function () { return this.ClsiCookieManager._populateServerIdViaRequest( this.project_id, this.user_id, + 'standard', (err, serverId) => { const args = this.ClsiCookieManager.setServerId.args[0] args[0].should.equal(this.project_id) args[1].should.equal(this.user_id) - args[2].should.deep.equal(this.response) + args[2].should.equal('standard') + args[3].should.deep.equal(this.response) return done() } ) @@ -139,6 +144,7 @@ describe('ClsiCookieManager', function () { return this.ClsiCookieManager._populateServerIdViaRequest( this.project_id, this.user_id, + '', (err, serverId) => { serverId.should.equal('clsi-9') return done() @@ -159,6 +165,7 @@ describe('ClsiCookieManager', function () { return this.ClsiCookieManager.setServerId( this.project_id, this.user_id, + 'standard', this.response, null, err => { @@ -178,6 +185,7 @@ describe('ClsiCookieManager', function () { return this.ClsiCookieManager.setServerId( this.project_id, this.user_id, + 'standard', this.response, null, (err, serverId) => { @@ -198,6 +206,7 @@ describe('ClsiCookieManager', function () { return this.ClsiCookieManager.setServerId( this.project_id, this.user_id, + 'standard', this.response, null, (err, serverId) => { @@ -214,6 +223,7 @@ describe('ClsiCookieManager', function () { return this.ClsiCookieManager.setServerId( this.project_id, this.user_id, + 'standard', this.response, null, (err, serverId) => { @@ -243,6 +253,7 @@ describe('ClsiCookieManager', function () { return this.ClsiCookieManager.setServerId( this.project_id, this.user_id, + 'standard', this.response, null, (err, serverId) => { @@ -263,13 +274,14 @@ describe('ClsiCookieManager', function () { beforeEach(function () { return (this.ClsiCookieManager._getServerId = sinon .stub() - .callsArgWith(2, null, 'clsi-11')) + .yields(null, 'clsi-11')) }) it('should return a jar with the cookie set populated from redis', function (done) { return this.ClsiCookieManager.getCookieJar( this.project_id, this.user_id, + '', (err, jar) => { jar._jar.store.idx['clsi.example.com']['/'][ this.settings.clsiCookie.key @@ -293,6 +305,7 @@ describe('ClsiCookieManager', function () { return this.ClsiCookieManager.getCookieJar( this.project_id, this.user_id, + '', (err, jar) => { assert.deepEqual(jar, realRequst.jar()) return done() diff --git a/services/web/test/unit/src/Compile/ClsiManagerTests.js b/services/web/test/unit/src/Compile/ClsiManagerTests.js index d16beb7180..7dbef6d2ed 100644 --- a/services/web/test/unit/src/Compile/ClsiManagerTests.js +++ b/services/web/test/unit/src/Compile/ClsiManagerTests.js @@ -8,7 +8,7 @@ describe('ClsiManager', function () { this.jar = { cookie: 'stuff' } this.ClsiCookieManager = { clearServerId: sinon.stub().yields(), - getCookieJar: sinon.stub().callsArgWith(2, null, this.jar), + getCookieJar: sinon.stub().yields(null, this.jar), setServerId: sinon.stub().yields(null), _getServerId: sinon.stub(), } @@ -491,9 +491,10 @@ describe('ClsiManager', function () { .calledWith( this.project_id, this.user_id, + 'standard', { method: 'DELETE', - url: `${this.settings.apis.clsi.url}/project/${this.project_id}/user/${this.user_id}`, + url: `${this.settings.apis.clsi.url}/project/${this.project_id}/user/${this.user_id}?compileGroup=standard`, }, 'node-1' ) @@ -922,12 +923,7 @@ describe('ClsiManager', function () { beforeEach(function () { this.ClsiManager._makeRequest = sinon .stub() - .callsArgWith( - 3, - null, - { statusCode: 204 }, - (this.body = { mock: 'foo' }) - ) + .yields(null, { statusCode: 204 }, (this.body = { mock: 'foo' })) this.ClsiManager._postToClsi( this.project_id, this.user_id, @@ -938,9 +934,9 @@ describe('ClsiManager', function () { }) it('should send the request to the CLSI', function () { - const url = `${this.settings.apis.clsi.url}/project/${this.project_id}/user/${this.user_id}/compile` + const url = `${this.settings.apis.clsi.url}/project/${this.project_id}/user/${this.user_id}/compile?compileGroup=standard` this.ClsiManager._makeRequest - .calledWith(this.project_id, this.user_id, { + .calledWith(this.project_id, this.user_id, 'standard', { method: 'POST', url, json: this.req, @@ -957,12 +953,7 @@ describe('ClsiManager', function () { beforeEach(function () { this.ClsiManager._makeRequest = sinon .stub() - .callsArgWith( - 3, - null, - { statusCode: 500 }, - (this.body = { mock: 'foo' }) - ) + .yields(null, { statusCode: 500 }, (this.body = { mock: 'foo' })) this.ClsiManager._postToClsi( this.project_id, this.user_id, @@ -983,8 +974,7 @@ describe('ClsiManager', function () { this.ClsiManager._makeRequestWithClsiServerId = sinon .stub() .yields(null, { statusCode: 200 }, (this.body = { mock: 'foo' })) - this.ClsiManager._buildRequest = sinon.stub().callsArgWith( - 2, + this.ClsiManager._buildRequest = sinon.stub().yields( null, (this.req = { compile: { rootResourcePath: 'rootfile.text', options: {} }, @@ -998,7 +988,7 @@ describe('ClsiManager', function () { this.project_id, this.user_id, false, - {}, + { compileGroup: 'standard' }, 'node-1', this.callback ) @@ -1009,9 +999,10 @@ describe('ClsiManager', function () { .calledWith( this.project_id, this.user_id, + 'standard', { method: 'GET', - url: `http://clsi.example.com/project/${this.project_id}/user/${this.user_id}/wordcount`, + url: `http://clsi.example.com/project/${this.project_id}/user/${this.user_id}/wordcount?compileGroup=standard`, qs: { file: 'rootfile.text', image: undefined, @@ -1034,7 +1025,7 @@ describe('ClsiManager', function () { this.project_id, this.user_id, 'main.tex', - {}, + { compileGroup: 'standard' }, 'node-2', this.callback ) @@ -1045,9 +1036,10 @@ describe('ClsiManager', function () { .calledWith( this.project_id, this.user_id, + 'standard', { method: 'GET', - url: `http://clsi.example.com/project/${this.project_id}/user/${this.user_id}/wordcount`, + url: `http://clsi.example.com/project/${this.project_id}/user/${this.user_id}/wordcount?compileGroup=standard`, qs: { file: 'main.tex', image: undefined }, json: true, }, @@ -1065,7 +1057,7 @@ describe('ClsiManager', function () { this.project_id, this.user_id, 'main.tex', - {}, + { compileGroup: 'standard' }, 'node-3', this.callback ) @@ -1076,9 +1068,10 @@ describe('ClsiManager', function () { .calledWith( this.project_id, this.user_id, + 'standard', { method: 'GET', - url: `http://clsi.example.com/project/${this.project_id}/user/${this.user_id}/wordcount`, + url: `http://clsi.example.com/project/${this.project_id}/user/${this.user_id}/wordcount?compileGroup=standard`, qs: { file: 'main.tex', image: this.image }, json: true, }, @@ -1103,6 +1096,7 @@ describe('ClsiManager', function () { this.ClsiManager._makeRequest( this.project_id, this.user_id, + 'standard', this.opts, () => { const args = this.request.args[0] @@ -1118,10 +1112,16 @@ describe('ClsiManager', function () { this.ClsiManager._makeRequest( this.project_id, this.user_id, + 'standard', this.opts, () => { this.ClsiCookieManager.setServerId - .calledWith(this.project_id, this.user_id, this.response) + .calledWith( + this.project_id, + this.user_id, + 'standard', + this.response + ) .should.equal(true) done() } @@ -1144,6 +1144,7 @@ describe('ClsiManager', function () { this.ClsiManager._makeRequestWithClsiServerId( this.project_id, this.user_id, + 'standard', this.opts, undefined, err => { @@ -1162,12 +1163,18 @@ describe('ClsiManager', function () { this.ClsiManager._makeRequestWithClsiServerId( this.project_id, this.user_id, + 'standard', this.opts, undefined, err => { if (err) return done(err) this.ClsiCookieManager.setServerId - .calledWith(this.project_id, this.user_id, this.response) + .calledWith( + this.project_id, + this.user_id, + 'standard', + this.response + ) .should.equal(true) done() } @@ -1180,6 +1187,7 @@ describe('ClsiManager', function () { this.ClsiManager._makeRequestWithClsiServerId( this.project_id, this.user_id, + 'standard', this.opts, 'node-1', err => { @@ -1188,7 +1196,10 @@ describe('ClsiManager', function () { expect(requestOpts.method).to.equal(this.opts.method) expect(requestOpts.url).to.equal(this.opts.url) expect(requestOpts.jar).to.not.exist - expect(requestOpts.qs).to.deep.equal({ clsiserverid: 'node-1' }) + expect(requestOpts.qs).to.deep.equal({ + clsiserverid: 'node-1', + compileGroup: 'standard', + }) done() } ) @@ -1198,6 +1209,7 @@ describe('ClsiManager', function () { this.ClsiManager._makeRequestWithClsiServerId( this.project_id, this.user_id, + 'standard', this.opts, 'node-1', err => { @@ -1216,7 +1228,7 @@ describe('ClsiManager', function () { this.response = { there: 'something' } this.request.callsArgWith(1, null, this.response) this.opts = { - url: this.ClsiManager._getCompilerUrl(null, this.project_id), + url: this.ClsiManager._getCompilerUrl('standard', this.project_id), } }) @@ -1224,11 +1236,12 @@ describe('ClsiManager', function () { this.ClsiManager._makeNewBackendRequest( this.project_id, this.user_id, + 'standard', this.opts, () => { const args = this.request.args[0] args[0].url.should.equal( - `https://compiles.somewhere.test/project/${this.project_id}` + `https://compiles.somewhere.test/project/${this.project_id}?compileGroup=standard` ) done() } @@ -1240,6 +1253,7 @@ describe('ClsiManager', function () { this.ClsiManager._makeNewBackendRequest( this.project_id, this.user_id, + 'standard', this.opts, err => { expect(err).to.equal(undefined) diff --git a/services/web/test/unit/src/Compile/CompileControllerTests.js b/services/web/test/unit/src/Compile/CompileControllerTests.js index e0fd562c0e..2a30a58666 100644 --- a/services/web/test/unit/src/Compile/CompileControllerTests.js +++ b/services/web/test/unit/src/Compile/CompileControllerTests.js @@ -49,7 +49,7 @@ describe('CompileController', function () { } this.jar = { cookie: 'stuff' } this.ClsiCookieManager = { - getCookieJar: sinon.stub().callsArgWith(2, null, this.jar), + getCookieJar: sinon.stub().yields(null, this.jar), } this.SessionManager = { getLoggedInUser: sinon.stub().callsArgWith(1, null, this.user), diff --git a/services/web/test/unit/src/Compile/CompileManagerTests.js b/services/web/test/unit/src/Compile/CompileManagerTests.js index d3fae7e91d..c69547ab59 100644 --- a/services/web/test/unit/src/Compile/CompileManagerTests.js +++ b/services/web/test/unit/src/Compile/CompileManagerTests.js @@ -58,6 +58,7 @@ describe('CompileManager', function () { this.callback = sinon.stub() return (this.limits = { timeout: 42, + compileGroup: 'standard', }) }) @@ -120,6 +121,7 @@ describe('CompileManager', function () { return this.ClsiManager.sendRequest .calledWith(this.project_id, this.user_id, { timeout: this.limits.timeout, + compileGroup: 'standard', }) .should.equal(true) })