mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #19270 from overleaf/jpa-faster-e2e-in-ci
[server-pro] faster e2e test CI wall time GitOrigin-RevId: eeb6d3044d888acd4d52919507c0bc566d7e0b46
This commit is contained in:
parent
c3ed95bc48
commit
eb32d3c8be
21 changed files with 154 additions and 103 deletions
|
@ -9,6 +9,8 @@ export PWD = $(shell pwd)
|
||||||
export TEX_LIVE_DOCKER_IMAGE ?= quay.io/sharelatex/texlive-full:2023.1
|
export TEX_LIVE_DOCKER_IMAGE ?= quay.io/sharelatex/texlive-full:2023.1
|
||||||
export ALL_TEX_LIVE_DOCKER_IMAGES ?= quay.io/sharelatex/texlive-full:2023.1,quay.io/sharelatex/texlive-full:2022.1
|
export ALL_TEX_LIVE_DOCKER_IMAGES ?= quay.io/sharelatex/texlive-full:2023.1,quay.io/sharelatex/texlive-full:2022.1
|
||||||
export IMAGE_TAG_PRO ?= quay.io/sharelatex/sharelatex-pro:latest
|
export IMAGE_TAG_PRO ?= quay.io/sharelatex/sharelatex-pro:latest
|
||||||
|
export CYPRESS_SHARD ?=
|
||||||
|
export COMPOSE_PROJECT_NAME ?= test
|
||||||
|
|
||||||
test-e2e-native:
|
test-e2e-native:
|
||||||
docker compose -f docker-compose.yml -f docker-compose.native.yml up --build --no-log-prefix sharelatex host-admin -d
|
docker compose -f docker-compose.yml -f docker-compose.native.yml up --build --no-log-prefix sharelatex host-admin -d
|
||||||
|
@ -23,11 +25,27 @@ test-e2e-open:
|
||||||
clean:
|
clean:
|
||||||
docker compose down --volumes --timeout 0
|
docker compose down --volumes --timeout 0
|
||||||
|
|
||||||
prefetch:
|
prefetch: prefetch_default
|
||||||
docker compose pull e2e mongo redis saml ldap
|
prefetch_default: prefetch_default_compose
|
||||||
|
prefetch_default_compose:
|
||||||
|
docker compose pull e2e mongo redis
|
||||||
|
|
||||||
|
prefetch_default: prefetch_default_compose_build
|
||||||
|
prefetch_default_compose_build:
|
||||||
docker compose build
|
docker compose build
|
||||||
|
|
||||||
|
prefetch: prefetch_custom
|
||||||
|
prefetch_custom: prefetch_custom_compose_pull
|
||||||
|
prefetch_custom_compose_pull:
|
||||||
|
docker compose pull saml ldap
|
||||||
|
|
||||||
|
prefetch_custom: prefetch_custom_texlive
|
||||||
|
prefetch_custom_texlive:
|
||||||
echo -n "$$ALL_TEX_LIVE_DOCKER_IMAGES" | xargs -d, -I% \
|
echo -n "$$ALL_TEX_LIVE_DOCKER_IMAGES" | xargs -d, -I% \
|
||||||
sh -exc 'tag=%; re_tag=quay.io/sharelatex/$${tag#*/}; docker pull $$tag; docker tag $$tag $$re_tag'
|
sh -exc 'tag=%; re_tag=quay.io/sharelatex/$${tag#*/}; docker pull $$tag; docker tag $$tag $$re_tag'
|
||||||
|
|
||||||
|
prefetch_custom: prefetch_old
|
||||||
|
prefetch_old:
|
||||||
docker pull $(IMAGE_TAG_PRO:latest=4.2)
|
docker pull $(IMAGE_TAG_PRO:latest=4.2)
|
||||||
docker pull $(IMAGE_TAG_PRO:latest=5.0.1-RC1)
|
docker pull $(IMAGE_TAG_PRO:latest=5.0.1-RC1)
|
||||||
docker pull $(IMAGE_TAG_PRO:latest=5.0)
|
docker pull $(IMAGE_TAG_PRO:latest=5.0)
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { createMongoUser, ensureUserExists, login } from './helpers/login'
|
import { createMongoUser, ensureUserExists, login } from './helpers/login'
|
||||||
import { startWith } from './helpers/config'
|
import { isExcludedBySharding, startWith } from './helpers/config'
|
||||||
|
|
||||||
describe('Accounts', function () {
|
describe('Accounts', function () {
|
||||||
|
if (isExcludedBySharding('CE_DEFAULT')) return
|
||||||
startWith({})
|
startWith({})
|
||||||
ensureUserExists({ email: 'user@example.com' })
|
ensureUserExists({ email: 'user@example.com' })
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { startWith } from './helpers/config'
|
import { isExcludedBySharding, startWith } from './helpers/config'
|
||||||
import { activateUser, ensureUserExists, login } from './helpers/login'
|
import { activateUser, ensureUserExists, login } from './helpers/login'
|
||||||
import { v4 as uuid } from 'uuid'
|
import { v4 as uuid } from 'uuid'
|
||||||
import { createProject } from './helpers/project'
|
import { createProject } from './helpers/project'
|
||||||
|
@ -20,6 +20,7 @@ describe('admin panel', function () {
|
||||||
return cy.findByText(projectName).parent().parent()
|
return cy.findByText(projectName).parent().parent()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isExcludedBySharding('PRO_DEFAULT_2')) return
|
||||||
startWith({
|
startWith({
|
||||||
pro: true,
|
pro: true,
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { ensureUserExists, login } from './helpers/login'
|
import { ensureUserExists, login } from './helpers/login'
|
||||||
import { createProject } from './helpers/project'
|
import { createProject } from './helpers/project'
|
||||||
import { startWith } from './helpers/config'
|
import { isExcludedBySharding, startWith } from './helpers/config'
|
||||||
import { throttledRecompile } from './helpers/compile'
|
import { throttledRecompile } from './helpers/compile'
|
||||||
|
|
||||||
describe('Project creation and compilation', function () {
|
describe('Project creation and compilation', function () {
|
||||||
|
if (isExcludedBySharding('CE_DEFAULT')) return
|
||||||
startWith({})
|
startWith({})
|
||||||
ensureUserExists({ email: 'user@example.com' })
|
ensureUserExists({ email: 'user@example.com' })
|
||||||
ensureUserExists({ email: 'collaborator@example.com' })
|
ensureUserExists({ email: 'collaborator@example.com' })
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { startWith } from './helpers/config'
|
import { isExcludedBySharding, startWith } from './helpers/config'
|
||||||
|
|
||||||
describe('Customization', () => {
|
describe('Customization', () => {
|
||||||
|
if (isExcludedBySharding('CE_CUSTOM_1')) return
|
||||||
startWith({
|
startWith({
|
||||||
vars: {
|
vars: {
|
||||||
OVERLEAF_APP_NAME: 'CUSTOM APP NAME',
|
OVERLEAF_APP_NAME: 'CUSTOM APP NAME',
|
||||||
|
|
|
@ -23,6 +23,6 @@ module.exports = defineConfig({
|
||||||
specPattern,
|
specPattern,
|
||||||
},
|
},
|
||||||
retries: {
|
retries: {
|
||||||
runMode: 1,
|
runMode: 3,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -57,6 +57,7 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- ./:/e2e
|
- ./:/e2e
|
||||||
environment:
|
environment:
|
||||||
|
CYPRESS_SHARD:
|
||||||
CYPRESS_BASE_URL: http://sharelatex
|
CYPRESS_BASE_URL: http://sharelatex
|
||||||
SPEC_PATTERN: '**/*.spec.{js,jsx,ts,tsx}'
|
SPEC_PATTERN: '**/*.spec.{js,jsx,ts,tsx}'
|
||||||
depends_on:
|
depends_on:
|
||||||
|
@ -76,6 +77,7 @@ services:
|
||||||
- /tmp/.X11-unix:/tmp/.X11-unix
|
- /tmp/.X11-unix:/tmp/.X11-unix
|
||||||
user: "${DOCKER_USER:-1000:1000}"
|
user: "${DOCKER_USER:-1000:1000}"
|
||||||
environment:
|
environment:
|
||||||
|
CYPRESS_SHARD:
|
||||||
CYPRESS_BASE_URL: http://sharelatex
|
CYPRESS_BASE_URL: http://sharelatex
|
||||||
SPEC_PATTERN: '**/*.spec.{js,jsx,ts,tsx}'
|
SPEC_PATTERN: '**/*.spec.{js,jsx,ts,tsx}'
|
||||||
DISPLAY: ${DISPLAY:-:0}
|
DISPLAY: ${DISPLAY:-:0}
|
||||||
|
@ -96,6 +98,8 @@ services:
|
||||||
stop_grace_period: 0s
|
stop_grace_period: 0s
|
||||||
environment:
|
environment:
|
||||||
PWD:
|
PWD:
|
||||||
|
CYPRESS_SHARD:
|
||||||
|
COMPOSE_PROJECT_NAME:
|
||||||
TEX_LIVE_DOCKER_IMAGE:
|
TEX_LIVE_DOCKER_IMAGE:
|
||||||
ALL_TEX_LIVE_DOCKER_IMAGES:
|
ALL_TEX_LIVE_DOCKER_IMAGES:
|
||||||
IMAGE_TAG_CE: ${IMAGE_TAG_CE:-sharelatex/sharelatex:latest}
|
IMAGE_TAG_CE: ${IMAGE_TAG_CE:-sharelatex/sharelatex:latest}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { createProject } from './helpers/project'
|
import { createProject } from './helpers/project'
|
||||||
import { startWith } from './helpers/config'
|
import { isExcludedBySharding, startWith } from './helpers/config'
|
||||||
import { ensureUserExists, login } from './helpers/login'
|
import { ensureUserExists, login } from './helpers/login'
|
||||||
import { v4 as uuid } from 'uuid'
|
import { v4 as uuid } from 'uuid'
|
||||||
import { beforeWithReRunOnTestRetry } from './helpers/beforeWithReRunOnTestRetry'
|
import { beforeWithReRunOnTestRetry } from './helpers/beforeWithReRunOnTestRetry'
|
||||||
|
|
||||||
describe('editor', () => {
|
describe('editor', () => {
|
||||||
|
if (isExcludedBySharding('PRO_DEFAULT_1')) return
|
||||||
startWith({ pro: true })
|
startWith({ pro: true })
|
||||||
ensureUserExists({ email: 'user@example.com' })
|
ensureUserExists({ email: 'user@example.com' })
|
||||||
ensureUserExists({ email: 'collaborator@example.com' })
|
ensureUserExists({ email: 'collaborator@example.com' })
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { startWith } from './helpers/config'
|
import { isExcludedBySharding, startWith } from './helpers/config'
|
||||||
|
|
||||||
describe('SAML', () => {
|
describe('SAML', () => {
|
||||||
|
if (isExcludedBySharding('PRO_CUSTOM_1')) return
|
||||||
const overleafPublicHost = Cypress.env('OVERLEAF_PUBLIC_HOST') || 'sharelatex'
|
const overleafPublicHost = Cypress.env('OVERLEAF_PUBLIC_HOST') || 'sharelatex'
|
||||||
const samlPublicHost = Cypress.env('SAML_PUBLIC_HOST') || 'saml'
|
const samlPublicHost = Cypress.env('SAML_PUBLIC_HOST') || 'saml'
|
||||||
|
|
||||||
|
@ -36,6 +37,7 @@ describe('SAML', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('LDAP', () => {
|
describe('LDAP', () => {
|
||||||
|
if (isExcludedBySharding('PRO_CUSTOM_1')) return
|
||||||
startWith({
|
startWith({
|
||||||
pro: true,
|
pro: true,
|
||||||
vars: {
|
vars: {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { startWith } from './helpers/config'
|
import { isExcludedBySharding, startWith } from './helpers/config'
|
||||||
import { ensureUserExists, login } from './helpers/login'
|
import { ensureUserExists, login } from './helpers/login'
|
||||||
import { createProject } from './helpers/project'
|
import { createProject } from './helpers/project'
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ describe('git-bridge', function () {
|
||||||
Cypress.env('GIT_BRIDGE_PUBLIC_HOST') || 'sharelatex'
|
Cypress.env('GIT_BRIDGE_PUBLIC_HOST') || 'sharelatex'
|
||||||
|
|
||||||
describe('enabled in Server Pro', function () {
|
describe('enabled in Server Pro', function () {
|
||||||
|
if (isExcludedBySharding('PRO_CUSTOM_1')) return
|
||||||
startWith({
|
startWith({
|
||||||
pro: true,
|
pro: true,
|
||||||
vars: ENABLED_VARS,
|
vars: ENABLED_VARS,
|
||||||
|
@ -272,6 +273,7 @@ Hello world
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('disabled in Server Pro', () => {
|
describe('disabled in Server Pro', () => {
|
||||||
|
if (isExcludedBySharding('PRO_DEFAULT_1')) return
|
||||||
startWith({
|
startWith({
|
||||||
pro: true,
|
pro: true,
|
||||||
})
|
})
|
||||||
|
@ -279,6 +281,7 @@ Hello world
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('unavailable in CE', () => {
|
describe('unavailable in CE', () => {
|
||||||
|
if (isExcludedBySharding('CE_CUSTOM_1')) return
|
||||||
startWith({
|
startWith({
|
||||||
pro: false,
|
pro: false,
|
||||||
vars: ENABLED_VARS,
|
vars: ENABLED_VARS,
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
|
import { ensureUserExists, login } from './helpers/login'
|
||||||
import {
|
import {
|
||||||
ensureUserExists,
|
isExcludedBySharding,
|
||||||
login,
|
STARTUP_TIMEOUT,
|
||||||
resetCreatedUsersCache,
|
startWith,
|
||||||
} from './helpers/login'
|
} from './helpers/config'
|
||||||
import { STARTUP_TIMEOUT, startWith } from './helpers/config'
|
import { dockerCompose, getRedisKeys } from './helpers/hostAdminClient'
|
||||||
import {
|
|
||||||
dockerCompose,
|
|
||||||
getRedisKeys,
|
|
||||||
resetData,
|
|
||||||
} from './helpers/hostAdminClient'
|
|
||||||
import { createProject } from './helpers/project'
|
import { createProject } from './helpers/project'
|
||||||
import { throttledRecompile } from './helpers/compile'
|
import { throttledRecompile } from './helpers/compile'
|
||||||
|
|
||||||
|
@ -23,13 +19,11 @@ function bringServerProBackUp() {
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('GracefulShutdown', function () {
|
describe('GracefulShutdown', function () {
|
||||||
before(async () => {
|
if (isExcludedBySharding('PRO_CUSTOM_1')) return
|
||||||
resetCreatedUsersCache()
|
|
||||||
await resetData()
|
|
||||||
})
|
|
||||||
startWith({
|
startWith({
|
||||||
pro: true,
|
pro: true,
|
||||||
withDataDir: true,
|
withDataDir: true,
|
||||||
|
resetData: true,
|
||||||
})
|
})
|
||||||
ensureUserExists({ email: USER })
|
ensureUserExists({ email: USER })
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,24 @@
|
||||||
import { reconfigure } from './hostAdminClient'
|
import { reconfigure } from './hostAdminClient'
|
||||||
|
import { resetCreatedUsersCache } from './login'
|
||||||
|
|
||||||
export const STARTUP_TIMEOUT =
|
export const STARTUP_TIMEOUT =
|
||||||
parseInt(Cypress.env('STARTUP_TIMEOUT'), 10) || 120_000
|
parseInt(Cypress.env('STARTUP_TIMEOUT'), 10) || 120_000
|
||||||
|
|
||||||
|
export function isExcludedBySharding(
|
||||||
|
shard:
|
||||||
|
| 'CE_DEFAULT'
|
||||||
|
| 'CE_CUSTOM_1'
|
||||||
|
| 'CE_CUSTOM_2'
|
||||||
|
| 'PRO_DEFAULT_1'
|
||||||
|
| 'PRO_DEFAULT_2'
|
||||||
|
| 'PRO_CUSTOM_1'
|
||||||
|
| 'PRO_CUSTOM_2'
|
||||||
|
| 'PRO_CUSTOM_3'
|
||||||
|
) {
|
||||||
|
const SHARD = Cypress.env('SHARD')
|
||||||
|
return SHARD && shard !== SHARD
|
||||||
|
}
|
||||||
|
|
||||||
let lastConfig: string
|
let lastConfig: string
|
||||||
|
|
||||||
export function startWith({
|
export function startWith({
|
||||||
|
@ -11,6 +27,7 @@ export function startWith({
|
||||||
vars = {},
|
vars = {},
|
||||||
varsFn = () => ({}),
|
varsFn = () => ({}),
|
||||||
withDataDir = false,
|
withDataDir = false,
|
||||||
|
resetData = false,
|
||||||
}) {
|
}) {
|
||||||
before(async function () {
|
before(async function () {
|
||||||
Object.assign(vars, varsFn())
|
Object.assign(vars, varsFn())
|
||||||
|
@ -20,10 +37,15 @@ export function startWith({
|
||||||
vars,
|
vars,
|
||||||
withDataDir,
|
withDataDir,
|
||||||
})
|
})
|
||||||
if (lastConfig === cfg) return
|
if (resetData) {
|
||||||
|
resetCreatedUsersCache()
|
||||||
|
// no return here, always reconfigure when resetting data
|
||||||
|
} else if (lastConfig === cfg) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
this.timeout(STARTUP_TIMEOUT)
|
this.timeout(STARTUP_TIMEOUT)
|
||||||
await reconfigure({ pro, version, vars, withDataDir })
|
await reconfigure({ pro, version, vars, withDataDir, resetData })
|
||||||
lastConfig = cfg
|
lastConfig = cfg
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,23 +9,12 @@ export async function dockerCompose(cmd: string, ...args: string[]) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function mongoInit() {
|
|
||||||
return await fetchJSON(`${hostAdminUrl}/mongo/init`, {
|
|
||||||
method: 'POST',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function resetData() {
|
|
||||||
return await fetchJSON(`${hostAdminUrl}/reset/data`, {
|
|
||||||
method: 'POST',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function reconfigure({
|
export async function reconfigure({
|
||||||
pro = false,
|
pro = false,
|
||||||
version = 'latest',
|
version = 'latest',
|
||||||
vars = {},
|
vars = {},
|
||||||
withDataDir = false,
|
withDataDir = false,
|
||||||
|
resetData = false,
|
||||||
}) {
|
}) {
|
||||||
return await fetchJSON(`${hostAdminUrl}/reconfigure`, {
|
return await fetchJSON(`${hostAdminUrl}/reconfigure`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
@ -34,6 +23,7 @@ export async function reconfigure({
|
||||||
version,
|
version,
|
||||||
vars,
|
vars,
|
||||||
withDataDir,
|
withDataDir,
|
||||||
|
resetData,
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { createProject } from './helpers/project'
|
import { createProject } from './helpers/project'
|
||||||
import { throttledRecompile } from './helpers/compile'
|
import { throttledRecompile } from './helpers/compile'
|
||||||
import { ensureUserExists, login } from './helpers/login'
|
import { ensureUserExists, login } from './helpers/login'
|
||||||
import { startWith } from './helpers/config'
|
import { isExcludedBySharding, startWith } from './helpers/config'
|
||||||
|
|
||||||
describe('History', function () {
|
describe('History', function () {
|
||||||
|
if (isExcludedBySharding('CE_DEFAULT')) return
|
||||||
startWith({})
|
startWith({})
|
||||||
ensureUserExists({ email: 'user@example.com' })
|
ensureUserExists({ email: 'user@example.com' })
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
|
|
|
@ -10,12 +10,19 @@ const {
|
||||||
} = require('celebrate')
|
} = require('celebrate')
|
||||||
const YAML = require('js-yaml')
|
const YAML = require('js-yaml')
|
||||||
|
|
||||||
|
const DATA_DIR = Path.join(
|
||||||
|
__dirname,
|
||||||
|
'data',
|
||||||
|
// Give each shard their own data dir.
|
||||||
|
process.env.CYPRESS_SHARD || 'default'
|
||||||
|
)
|
||||||
const PATHS = {
|
const PATHS = {
|
||||||
DOCKER_COMPOSE_FILE: 'docker-compose.yml',
|
DOCKER_COMPOSE_FILE: 'docker-compose.yml',
|
||||||
DOCKER_COMPOSE_OVERRIDE: 'docker-compose.override.yml',
|
// Give each shard their own override file.
|
||||||
|
DOCKER_COMPOSE_OVERRIDE: `docker-compose.${process.env.CYPRESS_SHARD || 'override'}.yml`,
|
||||||
DOCKER_COMPOSE_NATIVE: 'docker-compose.native.yml',
|
DOCKER_COMPOSE_NATIVE: 'docker-compose.native.yml',
|
||||||
DATA_DIR: Path.join(__dirname, 'data'),
|
DATA_DIR,
|
||||||
SANDBOXED_COMPILES_HOST_DIR: Path.join(__dirname, 'data/compiles'),
|
SANDBOXED_COMPILES_HOST_DIR: Path.join(DATA_DIR, 'compiles'),
|
||||||
}
|
}
|
||||||
const IMAGES = {
|
const IMAGES = {
|
||||||
CE: process.env.IMAGE_TAG_CE.replace(/:.+/, ''),
|
CE: process.env.IMAGE_TAG_CE.replace(/:.+/, ''),
|
||||||
|
@ -245,7 +252,8 @@ app.post(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
function mongoInit(callback) {
|
function maybeMongoInit(mongoInit, callback) {
|
||||||
|
if (!mongoInit) return callback()
|
||||||
runDockerCompose(
|
runDockerCompose(
|
||||||
'up',
|
'up',
|
||||||
['--detach', '--wait', 'mongo'],
|
['--detach', '--wait', 'mongo'],
|
||||||
|
@ -271,11 +279,30 @@ function mongoInit(callback) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
app.post('/mongo/init', (req, res) => {
|
function maybeResetData(resetData, callback) {
|
||||||
mongoInit((error, stdout, stderr) => {
|
if (!resetData) return callback()
|
||||||
res.json({ error, stdout, stderr })
|
|
||||||
})
|
runDockerCompose(
|
||||||
})
|
'stop',
|
||||||
|
['--timeout=0', 'sharelatex'],
|
||||||
|
(error, stdout, stderr) => {
|
||||||
|
if (error) return callback(error, stdout, stderr)
|
||||||
|
|
||||||
|
try {
|
||||||
|
purgeDataDir()
|
||||||
|
} catch (error) {
|
||||||
|
return callback(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
mongoIsInitialized = false
|
||||||
|
runDockerCompose(
|
||||||
|
'down',
|
||||||
|
['--timeout=0', '--volumes', 'mongo', 'redis'],
|
||||||
|
callback
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
app.post(
|
app.post(
|
||||||
'/reconfigure',
|
'/reconfigure',
|
||||||
|
@ -286,56 +313,35 @@ app.post(
|
||||||
version: Joi.string().required(),
|
version: Joi.string().required(),
|
||||||
vars: allowedVars,
|
vars: allowedVars,
|
||||||
withDataDir: Joi.boolean().optional(),
|
withDataDir: Joi.boolean().optional(),
|
||||||
|
resetData: Joi.boolean().optional(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ allowUnknown: false }
|
{ allowUnknown: false }
|
||||||
),
|
),
|
||||||
(req, res) => {
|
(req, res) => {
|
||||||
const { pro, version, vars, withDataDir } = req.body
|
const { pro, version, vars, withDataDir, resetData } = req.body
|
||||||
try {
|
maybeResetData(resetData, (error, stdout, stderr) => {
|
||||||
setVarsDockerCompose({ pro, version, vars, withDataDir })
|
|
||||||
} catch (error) {
|
|
||||||
return res.json({ error })
|
|
||||||
}
|
|
||||||
|
|
||||||
const doMongoInit = mongoIsInitialized ? cb => cb() : mongoInit
|
|
||||||
doMongoInit((error, stdout, stderr) => {
|
|
||||||
if (error) return res.json({ error, stdout, stderr })
|
|
||||||
runDockerCompose(
|
|
||||||
'up',
|
|
||||||
['--detach', '--wait', 'sharelatex'],
|
|
||||||
(error, stdout, stderr) => {
|
|
||||||
res.json({ error, stdout, stderr })
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
app.post('/reset/data', (req, res) => {
|
|
||||||
runDockerCompose(
|
|
||||||
'stop',
|
|
||||||
['--timeout=0', 'sharelatex'],
|
|
||||||
(error, stdout, stderr) => {
|
|
||||||
if (error) return res.json({ error, stdout, stderr })
|
if (error) return res.json({ error, stdout, stderr })
|
||||||
|
|
||||||
try {
|
try {
|
||||||
purgeDataDir()
|
setVarsDockerCompose({ pro, version, vars, withDataDir })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return res.json({ error })
|
return res.json({ error })
|
||||||
}
|
}
|
||||||
|
|
||||||
mongoIsInitialized = false
|
maybeMongoInit(!mongoIsInitialized, (error, stdout, stderr) => {
|
||||||
runDockerCompose(
|
if (error) return res.json({ error, stdout, stderr })
|
||||||
'down',
|
runDockerCompose(
|
||||||
['--timeout=0', '--volumes', 'mongo', 'redis'],
|
'up',
|
||||||
(error, stdout, stderr) => {
|
['--detach', '--wait', 'sharelatex'],
|
||||||
res.json({ error, stdout, stderr })
|
(error, stdout, stderr) => {
|
||||||
}
|
res.json({ error, stdout, stderr })
|
||||||
)
|
}
|
||||||
}
|
)
|
||||||
)
|
})
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
app.get('/redis/keys', (req, res) => {
|
app.get('/redis/keys', (req, res) => {
|
||||||
runDockerCompose(
|
runDockerCompose(
|
||||||
|
@ -352,7 +358,7 @@ app.use(handleValidationErrors())
|
||||||
purgeDataDir()
|
purgeDataDir()
|
||||||
|
|
||||||
// Init on startup
|
// Init on startup
|
||||||
mongoInit(err => {
|
maybeMongoInit(true, err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error('mongo init failed', err)
|
console.error('mongo init failed', err)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { startWith } from './helpers/config'
|
import { isExcludedBySharding, startWith } from './helpers/config'
|
||||||
import { ensureUserExists, login } from './helpers/login'
|
import { ensureUserExists, login } from './helpers/login'
|
||||||
import { v4 as uuid } from 'uuid'
|
import { v4 as uuid } from 'uuid'
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ describe('LearnWiki', function () {
|
||||||
ensureUserExists({ email: REGULAR_USER })
|
ensureUserExists({ email: REGULAR_USER })
|
||||||
|
|
||||||
describe('enabled in Pro', () => {
|
describe('enabled in Pro', () => {
|
||||||
|
if (isExcludedBySharding('PRO_CUSTOM_2')) return
|
||||||
startWith({
|
startWith({
|
||||||
pro: true,
|
pro: true,
|
||||||
vars: {
|
vars: {
|
||||||
|
@ -64,11 +65,13 @@ describe('LearnWiki', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('disabled in Pro', () => {
|
describe('disabled in Pro', () => {
|
||||||
|
if (isExcludedBySharding('PRO_DEFAULT_1')) return
|
||||||
startWith({ pro: true })
|
startWith({ pro: true })
|
||||||
checkDisabled()
|
checkDisabled()
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('unavailable in CE', () => {
|
describe('unavailable in CE', () => {
|
||||||
|
if (isExcludedBySharding('CE_CUSTOM_1')) return
|
||||||
startWith({
|
startWith({
|
||||||
pro: false,
|
pro: false,
|
||||||
vars: {
|
vars: {
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
import { ensureUserExists, login } from './helpers/login'
|
import { ensureUserExists, login } from './helpers/login'
|
||||||
import { createProject } from './helpers/project'
|
import { createProject } from './helpers/project'
|
||||||
import { startWith } from './helpers/config'
|
import { isExcludedBySharding, startWith } from './helpers/config'
|
||||||
import { v4 as uuid } from 'uuid'
|
import { v4 as uuid } from 'uuid'
|
||||||
|
|
||||||
const WITHOUT_PROJECTS_USER = 'user-without-projects@example.com'
|
const WITHOUT_PROJECTS_USER = 'user-without-projects@example.com'
|
||||||
const REGULAR_USER = 'user@example.com'
|
const REGULAR_USER = 'user@example.com'
|
||||||
|
|
||||||
describe('Project List', () => {
|
describe('Project List', () => {
|
||||||
|
if (isExcludedBySharding('PRO_DEFAULT_2')) return
|
||||||
startWith({ pro: true })
|
startWith({ pro: true })
|
||||||
|
|
||||||
const findProjectRow = (projectName: string) => {
|
const findProjectRow = (projectName: string) => {
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import { v4 as uuid } from 'uuid'
|
import { v4 as uuid } from 'uuid'
|
||||||
import { startWith } from './helpers/config'
|
import { isExcludedBySharding, startWith } from './helpers/config'
|
||||||
import { ensureUserExists, login } from './helpers/login'
|
import { ensureUserExists, login } from './helpers/login'
|
||||||
import { createProject } from './helpers/project'
|
import { createProject } from './helpers/project'
|
||||||
import { throttledRecompile } from './helpers/compile'
|
import { throttledRecompile } from './helpers/compile'
|
||||||
import { beforeWithReRunOnTestRetry } from './helpers/beforeWithReRunOnTestRetry'
|
import { beforeWithReRunOnTestRetry } from './helpers/beforeWithReRunOnTestRetry'
|
||||||
|
|
||||||
describe('Project Sharing', function () {
|
describe('Project Sharing', function () {
|
||||||
|
if (isExcludedBySharding('CE_CUSTOM_2')) return
|
||||||
ensureUserExists({ email: 'user@example.com' })
|
ensureUserExists({ email: 'user@example.com' })
|
||||||
startWith({ withDataDir: true })
|
startWith({ withDataDir: true })
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { ensureUserExists, login } from './helpers/login'
|
import { ensureUserExists, login } from './helpers/login'
|
||||||
import { createProject } from './helpers/project'
|
import { createProject } from './helpers/project'
|
||||||
import { startWith } from './helpers/config'
|
import { isExcludedBySharding, startWith } from './helpers/config'
|
||||||
import { throttledRecompile } from './helpers/compile'
|
import { throttledRecompile } from './helpers/compile'
|
||||||
import { v4 as uuid } from 'uuid'
|
import { v4 as uuid } from 'uuid'
|
||||||
import { waitUntilScrollingFinished } from './helpers/waitUntilScrollingFinished'
|
import { waitUntilScrollingFinished } from './helpers/waitUntilScrollingFinished'
|
||||||
|
@ -19,6 +19,7 @@ describe('SandboxedCompiles', function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('enabled in Server Pro', () => {
|
describe('enabled in Server Pro', () => {
|
||||||
|
if (isExcludedBySharding('PRO_CUSTOM_2')) return
|
||||||
startWith({
|
startWith({
|
||||||
pro: true,
|
pro: true,
|
||||||
vars: enabledVars,
|
vars: enabledVars,
|
||||||
|
@ -215,6 +216,7 @@ describe('SandboxedCompiles', function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('disabled in Server Pro', () => {
|
describe('disabled in Server Pro', () => {
|
||||||
|
if (isExcludedBySharding('PRO_DEFAULT_2')) return
|
||||||
startWith({ pro: true })
|
startWith({ pro: true })
|
||||||
|
|
||||||
checkUsesDefaultCompiler()
|
checkUsesDefaultCompiler()
|
||||||
|
@ -223,6 +225,7 @@ describe('SandboxedCompiles', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe.skip('unavailable in CE', () => {
|
describe.skip('unavailable in CE', () => {
|
||||||
|
if (isExcludedBySharding('CE_CUSTOM_1')) return
|
||||||
startWith({ pro: false, vars: enabledVars })
|
startWith({ pro: false, vars: enabledVars })
|
||||||
|
|
||||||
checkUsesDefaultCompiler()
|
checkUsesDefaultCompiler()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { startWith } from './helpers/config'
|
import { isExcludedBySharding, startWith } from './helpers/config'
|
||||||
import { ensureUserExists, login } from './helpers/login'
|
import { ensureUserExists, login } from './helpers/login'
|
||||||
import { createProject } from './helpers/project'
|
import { createProject } from './helpers/project'
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ describe('Templates', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('enabled in Server Pro', () => {
|
describe('enabled in Server Pro', () => {
|
||||||
|
if (isExcludedBySharding('PRO_CUSTOM_2')) return
|
||||||
startWith({
|
startWith({
|
||||||
pro: true,
|
pro: true,
|
||||||
varsFn,
|
varsFn,
|
||||||
|
@ -238,11 +239,13 @@ describe('Templates', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('disabled Server Pro', () => {
|
describe('disabled Server Pro', () => {
|
||||||
|
if (isExcludedBySharding('PRO_DEFAULT_2')) return
|
||||||
startWith({ pro: true })
|
startWith({ pro: true })
|
||||||
checkDisabled()
|
checkDisabled()
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('unavailable in CE', () => {
|
describe('unavailable in CE', () => {
|
||||||
|
if (isExcludedBySharding('CE_CUSTOM_1')) return
|
||||||
startWith({
|
startWith({
|
||||||
pro: false,
|
pro: false,
|
||||||
varsFn,
|
varsFn,
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
import {
|
import { ensureUserExists, login } from './helpers/login'
|
||||||
ensureUserExists,
|
import { isExcludedBySharding, startWith } from './helpers/config'
|
||||||
login,
|
import { dockerCompose, runScript } from './helpers/hostAdminClient'
|
||||||
resetCreatedUsersCache,
|
|
||||||
} from './helpers/login'
|
|
||||||
import { startWith } from './helpers/config'
|
|
||||||
import { dockerCompose, resetData, runScript } from './helpers/hostAdminClient'
|
|
||||||
import { createProject } from './helpers/project'
|
import { createProject } from './helpers/project'
|
||||||
import { throttledRecompile } from './helpers/compile'
|
import { throttledRecompile } from './helpers/compile'
|
||||||
import { v4 as uuid } from 'uuid'
|
import { v4 as uuid } from 'uuid'
|
||||||
|
@ -13,6 +9,8 @@ const USER = 'user@example.com'
|
||||||
const PROJECT_NAME = 'Old Project'
|
const PROJECT_NAME = 'Old Project'
|
||||||
|
|
||||||
describe('Upgrading', function () {
|
describe('Upgrading', function () {
|
||||||
|
if (isExcludedBySharding('PRO_CUSTOM_3')) return
|
||||||
|
|
||||||
function testUpgrade(
|
function testUpgrade(
|
||||||
steps: {
|
steps: {
|
||||||
version: string
|
version: string
|
||||||
|
@ -24,16 +22,13 @@ describe('Upgrading', function () {
|
||||||
const startOptions = steps.shift()!
|
const startOptions = steps.shift()!
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
cy.log('Reset mongo/redis/on-disk data')
|
|
||||||
resetCreatedUsersCache()
|
|
||||||
await resetData()
|
|
||||||
|
|
||||||
cy.log('Create old instance')
|
cy.log('Create old instance')
|
||||||
})
|
})
|
||||||
startWith({
|
startWith({
|
||||||
pro: true,
|
pro: true,
|
||||||
version: startOptions.version,
|
version: startOptions.version,
|
||||||
withDataDir: true,
|
withDataDir: true,
|
||||||
|
resetData: true,
|
||||||
vars: startOptions.vars,
|
vars: startOptions.vars,
|
||||||
})
|
})
|
||||||
before(function () {
|
before(function () {
|
||||||
|
|
Loading…
Reference in a new issue