[web] Remove split-tests compile-backend-class* and compile-timeout-20s* (#17700)

* Remove split-tests of `compile-timeout-20s` and `compile-timeout-20s-existing-users`

* Remove `NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF` variables

* Revert timeout override `60` -> `20`

* Update settings.overrides.saas.js: `compileTimeout: 20`

* Remove `compile-backend-class-n2d`

* Remove `force_new_compile_timeout`

* Remove `showNewCompileTimeoutUI`

* Remove `compileTimeChanging`

* Simplify code by removing segmentation object

* Remove `CompileTimeoutChangingSoon`

* Remove `user.features.compileTimeout = '20 (with 10s prompt)'`

* Remove `CompileTimeWarning`

* Remove `TimeoutUpgradePrompt` (old)

* Remove `compile-backend-class`

* Remove unused translations

* Update tests

* Fix: Show `CompileTimeout` even if `!window.ExposedSettings.enableSubscriptions`

* Create script to migrate users to 20s compileTimeout

* migration script: exclude `compileTimeout: 20` from the match

* migration script: use `batchedUpdate`

* Remove `showFasterCompilesFeedbackUI` and `FasterCompilesFeedback`

Helped-by: Jakob Ackermann <jakob.ackermann@overleaf.com>

* Remove `_getCompileBackendClassDetails`, simplify definition of `limits` object

* Remove `Settings.apis.clsi.defaultBackendClass`

* Remove unnecessary second scan of the whole user collection in dry mode

* Override `timeout` to 20 for users having `compileGroup === 'standard' && compileTimeout <= 60`

* Remove second `logCount`: re-run the script in dry-mode if you want to see that count

* Use secondary readPreference when counting users

* Fix script setup and exit 0

* Fix: Remove `user.` from query path!

* Add acceptance test on script migration_compile_timeout_60s_to_20s.js

GitOrigin-RevId: 3cb65130e6d7fbd9c54005f4c213066d0473e9d8
This commit is contained in:
Antoine Clausse
2024-04-15 08:04:24 +00:00
committed by Copybot
parent 03fb015f8f
commit 2dd10c7fee
27 changed files with 302 additions and 980 deletions
@@ -0,0 +1,134 @@
const { expect } = require('chai')
const { promisify } = require('node:util')
const { exec } = require('node:child_process')
const logger = require('@overleaf/logger')
const { db } = require('../../../app/src/infrastructure/mongodb')
async function runScript(args = []) {
try {
return await promisify(exec)(
['node', 'scripts/migration_compile_timeout_60s_to_20s.js', ...args].join(
' '
)
)
} catch (error) {
logger.error({ error }, 'script failed')
throw error
}
}
describe('MigrateUserFeatureTimeoutTests', function () {
const usersInput = {
noFeatures: {},
noFeatureTimeout: { features: {} },
timeout10s: { features: { compileTimeout: 10, other: 'val1' }, bar: '1' },
timeout20s: { features: { compileTimeout: 20, other: 'val2' }, bar: '2' },
timeout30s: { features: { compileTimeout: 30, other: 'val3' }, bar: '3' },
timeout60s: { features: { compileTimeout: 60, other: 'val4' }, bar: '4' },
timeout120s: { features: { compileTimeout: 120, other: 'val5' }, bar: '5' },
timeout180s: { features: { compileTimeout: 180, other: 'val6' }, bar: '6' },
}
const usersKeys = Object.keys(usersInput)
const userIds = {}
beforeEach('insert users', async function () {
const usersInsertedValues = await db.users.insertMany(
usersKeys.map(key => ({
...usersInput[key],
email: `${key}@example.com`,
}))
)
usersKeys.forEach(
(key, index) => (userIds[key] = usersInsertedValues.insertedIds[index])
)
})
it('gives correct counts in dry mode', async function () {
const users = await db.users.find().toArray()
expect(users).to.have.lengthOf(usersKeys.length)
const result = await runScript([])
expect(result.stderr).to.contain(
'Doing dry run. Add --commit to commit changes'
)
expect(result.stdout).to.contain(
'Found 3 users with compileTimeout <= 60s && != 20s'
)
expect(result.stdout).to.contain('Found 1 users with compileTimeout == 20s')
expect(result.stdout).not.to.contain('Updated')
const usersAfter = await db.users.find().toArray()
expect(usersAfter).to.deep.equal(users)
})
it("updates users compileTimeout when '--commit' is set", async function () {
const users = await db.users.find().toArray()
expect(users).to.have.lengthOf(usersKeys.length)
const result = await runScript(['--commit'])
expect(result.stdout).to.contain(
'Found 3 users with compileTimeout <= 60s && != 20s'
)
expect(result.stdout).to.contain('Found 1 users with compileTimeout == 20s')
expect(result.stdout).to.contain('Updated 3 records')
const usersAfter = await db.users.find().toArray()
expect(usersAfter).to.deep.equal([
{ _id: userIds.noFeatures, email: 'noFeatures@example.com' },
{
_id: userIds.noFeatureTimeout,
email: 'noFeatureTimeout@example.com',
features: {},
},
{
_id: userIds.timeout10s,
email: 'timeout10s@example.com',
features: { compileTimeout: 20, other: 'val1' },
bar: '1',
},
{
_id: userIds.timeout20s,
email: 'timeout20s@example.com',
features: { compileTimeout: 20, other: 'val2' },
bar: '2',
},
{
_id: userIds.timeout30s,
email: 'timeout30s@example.com',
features: { compileTimeout: 20, other: 'val3' },
bar: '3',
},
{
_id: userIds.timeout60s,
email: 'timeout60s@example.com',
features: { compileTimeout: 20, other: 'val4' },
bar: '4',
},
{
_id: userIds.timeout120s,
email: 'timeout120s@example.com',
features: { compileTimeout: 120, other: 'val5' },
bar: '5',
},
{
_id: userIds.timeout180s,
email: 'timeout180s@example.com',
features: { compileTimeout: 180, other: 'val6' },
bar: '6',
},
])
const result2 = await runScript([])
expect(result2.stdout).to.contain(
'Found 0 users with compileTimeout <= 60s && != 20s'
)
expect(result2.stdout).to.contain(
'Found 4 users with compileTimeout == 20s'
)
})
})
@@ -314,7 +314,7 @@ describe('<PdfPreview/>', function () {
'project-too-large': 'Project too large',
'rate-limited': 'Compile rate limit hit',
terminated: 'Compilation cancelled',
timedout: 'Timed out',
timedout: 'Your compile timed out',
'too-recently-compiled':
'This project was compiled very recently, so this compile has been skipped.',
unavailable:
@@ -120,7 +120,6 @@ describe('ClsiManager', function () {
},
clsi: {
url: `http://${CLSI_HOST}`,
defaultBackendClass: 'e2',
submissionBackendClass: 'n2d',
},
clsi_priority: {
@@ -32,7 +32,6 @@ describe('CompileController', function () {
apis: {
clsi: {
url: 'http://clsi.example.com',
defaultBackendClass: 'e2',
submissionBackendClass: 'n2d',
},
clsi_priority: {
@@ -23,7 +23,7 @@ describe('CompileManager', function () {
requires: {
'@overleaf/settings': (this.settings = {
apis: {
clsi: { defaultBackendClass: 'e2', submissionBackendClass: 'n2d' },
clsi: { submissionBackendClass: 'n2d' },
},
redis: { web: { host: 'localhost', port: 42 } },
rateLimit: { autoCompile: {} },
@@ -235,9 +235,8 @@ describe('CompileManager', function () {
.calledWith(null, {
timeout: this.timeout,
compileGroup: this.group,
compileBackendClass: 'e2',
compileBackendClass: 'c2d',
ownerAnalyticsId: 'abc',
showFasterCompilesFeedbackUI: false,
})
.should.equal(true)
})
@@ -303,7 +302,7 @@ describe('CompileManager', function () {
this.callback
)
this.callback
.calledWith(null, sinon.match({ timeout: 60 }))
.calledWith(null, sinon.match({ timeout: 20 }))
.should.equal(true)
})
describe('user is in the compile-timeout-20s-existing-users treatment', function () {
@@ -388,20 +387,12 @@ describe('CompileManager', function () {
this.callback
)
this.callback
.calledWith(null, sinon.match({ timeout: 60 }))
.calledWith(null, sinon.match({ timeout: 20 }))
.should.equal(true)
})
})
describe('user signed up after the second phase rollout', function () {
beforeEach(function () {
const signUpDate = new Date(
this.CompileManager.NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF_DEFAULT_BASELINE
)
signUpDate.setDate(signUpDate.getDate() + 1)
this.user.signUpDate = signUpDate
})
it('should reduce compile timeout to 20s', function () {
this.CompileManager.getProjectCompileLimits(
this.project_id,
@@ -441,13 +432,12 @@ describe('CompileManager', function () {
variant: 'default',
})
})
it('should return the e2 class and disable the ui', function (done) {
it('should return the n2d class and disable the ui', function (done) {
this.CompileManager.getProjectCompileLimits(
this.project_id,
(err, { compileBackendClass, showFasterCompilesFeedbackUI }) => {
(err, { compileBackendClass }) => {
if (err) return done(err)
expect(compileBackendClass).to.equal('e2')
expect(showFasterCompilesFeedbackUI).to.equal(false)
expect(compileBackendClass).to.equal('n2d')
done()
}
)
@@ -463,10 +453,9 @@ describe('CompileManager', function () {
it('should return the n2d class and disable the ui', function (done) {
this.CompileManager.getProjectCompileLimits(
this.project_id,
(err, { compileBackendClass, showFasterCompilesFeedbackUI }) => {
(err, { compileBackendClass }) => {
if (err) return done(err)
expect(compileBackendClass).to.equal('n2d')
expect(showFasterCompilesFeedbackUI).to.equal(false)
done()
}
)
@@ -489,10 +478,9 @@ describe('CompileManager', function () {
it('should return the default class and disable ui', function (done) {
this.CompileManager.getProjectCompileLimits(
this.project_id,
(err, { compileBackendClass, showFasterCompilesFeedbackUI }) => {
(err, { compileBackendClass }) => {
if (err) return done(err)
expect(compileBackendClass).to.equal('e2')
expect(showFasterCompilesFeedbackUI).to.equal(false)
expect(compileBackendClass).to.equal('c2d')
done()
}
)
@@ -510,10 +498,9 @@ describe('CompileManager', function () {
it('should return the default class and enable ui', function (done) {
this.CompileManager.getProjectCompileLimits(
this.project_id,
(err, { compileBackendClass, showFasterCompilesFeedbackUI }) => {
(err, { compileBackendClass }) => {
if (err) return done(err)
expect(compileBackendClass).to.equal('e2')
expect(showFasterCompilesFeedbackUI).to.equal(true)
expect(compileBackendClass).to.equal('c2d')
done()
}
)
@@ -530,10 +517,9 @@ describe('CompileManager', function () {
it('should return the c2d class and enable ui', function (done) {
this.CompileManager.getProjectCompileLimits(
this.project_id,
(err, { compileBackendClass, showFasterCompilesFeedbackUI }) => {
(err, { compileBackendClass }) => {
if (err) return done(err)
expect(compileBackendClass).to.equal('c2d')
expect(showFasterCompilesFeedbackUI).to.equal(true)
done()
}
)