Merge pull request #7867 from overleaf/jpa-compile-group

[web] pass compileGroup to clsi-lb

GitOrigin-RevId: c15adbff27e702b3e0f29be5b57f7a9520d8d02f
This commit is contained in:
Jakob Ackermann 2022-05-13 10:35:31 +01:00 committed by Copybot
parent 8157616f85
commit 52073a13a9
12 changed files with 245 additions and 142 deletions

View file

@ -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)
})
)
},
}
}

View file

@ -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) => {

View file

@ -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 })
}
)
}
}

View file

@ -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) => {

View file

@ -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 {

View file

@ -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')

View file

@ -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()

View file

@ -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?)

View file

@ -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()

View file

@ -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)

View file

@ -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),

View file

@ -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)
})