overleaf-cep/server-ce/test/filestore-migration.spec.ts
Jakob Ackermann 81f0807fc6 [web] prepare filestore migration for Server Pro/CE (#27230)
* [web] prepare filestore migration for Server Pro/CE

* [history-v1] remove unused USER_FILES_BUCKET_NAME env var from script

* [server-ce] tests: write default docker-compose.override.yml on startup

* [server-ce] tests: extend access logging of host-admin for response

* [server-ce] tests: test text and binary file upload

* [server-ce] tests: add tests for filestore migration

* [web] simplify feature gate for filestore/project-history-blobs logic

Co-authored-by: Brian Gough <brian.gough@overleaf.com>

* [server-ce] test: fix flaky test helper

---------

Co-authored-by: Brian Gough <brian.gough@overleaf.com>
GitOrigin-RevId: f89bdab2749e2b7a49d609e2eac6bf621c727966
2025-07-22 08:06:58 +00:00

104 lines
3.2 KiB
TypeScript

import { ensureUserExists, login } from './helpers/login'
import {
createProject,
openProjectById,
prepareFileUploadTest,
} from './helpers/project'
import { isExcludedBySharding, startWith } from './helpers/config'
import { prepareWaitForNextCompileSlot } from './helpers/compile'
import { beforeWithReRunOnTestRetry } from './helpers/beforeWithReRunOnTestRetry'
import { v4 as uuid } from 'uuid'
import { purgeFilestoreData, runScript } from './helpers/hostAdminClient'
describe('filestore migration', function () {
if (isExcludedBySharding('CE_CUSTOM_3')) return
startWith({ withDataDir: true, resetData: true, vars: {} })
ensureUserExists({ email: 'user@example.com' })
let projectName: string
let projectId: string
let waitForCompileRateLimitCoolOff: (fn: () => void) => void
const previousBinaryFiles: (() => void)[] = []
beforeWithReRunOnTestRetry(function () {
projectName = `project-${uuid()}`
login('user@example.com')
createProject(projectName, { type: 'Example project' }).then(
id => (projectId = id)
)
let queueReset
;({ waitForCompileRateLimitCoolOff, queueReset } =
prepareWaitForNextCompileSlot())
queueReset()
previousBinaryFiles.push(prepareFileUploadTest(true))
})
beforeEach(() => {
login('user@example.com')
waitForCompileRateLimitCoolOff(() => {
openProjectById(projectId)
})
})
function checkFilesAreAccessible() {
it('can upload new binary file and read previous uploads', function () {
previousBinaryFiles.push(prepareFileUploadTest(true))
for (const check of previousBinaryFiles) {
check()
}
})
it('renders frog jpg', () => {
cy.findByTestId('file-tree').findByText('frog.jpg').click()
cy.get('[alt="frog.jpg"]')
.should('be.visible')
.and('have.prop', 'naturalWidth')
.should('be.greaterThan', 0)
})
}
describe('OVERLEAF_FILESTORE_MIGRATION_LEVEL not set', function () {
startWith({ withDataDir: true, vars: {} })
checkFilesAreAccessible()
})
describe('OVERLEAF_FILESTORE_MIGRATION_LEVEL=0', function () {
startWith({
withDataDir: true,
vars: { OVERLEAF_FILESTORE_MIGRATION_LEVEL: '0' },
})
checkFilesAreAccessible()
describe('OVERLEAF_FILESTORE_MIGRATION_LEVEL=1', function () {
startWith({
withDataDir: true,
vars: { OVERLEAF_FILESTORE_MIGRATION_LEVEL: '1' },
})
checkFilesAreAccessible()
describe('OVERLEAF_FILESTORE_MIGRATION_LEVEL=2', function () {
startWith({
withDataDir: true,
vars: { OVERLEAF_FILESTORE_MIGRATION_LEVEL: '1' },
})
before(async function () {
await runScript({
cwd: 'services/history-v1',
script: 'storage/scripts/back_fill_file_hash.mjs',
})
})
startWith({
withDataDir: true,
vars: { OVERLEAF_FILESTORE_MIGRATION_LEVEL: '2' },
})
checkFilesAreAccessible()
describe('purge filestore data', function () {
before(async function () {
await purgeFilestoreData()
})
checkFilesAreAccessible()
})
})
})
})
})