[web] disable filestore writes (#23470)
GitOrigin-RevId: 96ccd9205f9bf21420e67aaa68f8bc035eeb87d8
This commit is contained in:
@@ -84,13 +84,15 @@ describe('HistoryTests', function () {
|
||||
expect(body).to.include('2pixel.png')
|
||||
await expectHistoryV1Hit()
|
||||
})
|
||||
it('should work from filestore', async function () {
|
||||
MockV1HistoryApi.reset()
|
||||
const { response, body } = await user.doRequest('GET', downloadZIPURL)
|
||||
expect(response.statusCode).to.equal(200)
|
||||
expect(body).to.include('2pixel.png')
|
||||
await expectFilestoreHit()
|
||||
})
|
||||
if (Features.hasFeature('filestore')) {
|
||||
it('should work from filestore', async function () {
|
||||
MockV1HistoryApi.reset()
|
||||
const { response, body } = await user.doRequest('GET', downloadZIPURL)
|
||||
expect(response.statusCode).to.equal(200)
|
||||
expect(body).to.include('2pixel.png')
|
||||
await expectFilestoreHit()
|
||||
})
|
||||
}
|
||||
it('should not include when missing in both places', async function () {
|
||||
MockFilestoreApi.reset()
|
||||
MockV1HistoryApi.reset()
|
||||
@@ -122,14 +124,16 @@ describe('HistoryTests', function () {
|
||||
expect(response.statusCode).to.equal(404)
|
||||
await expectNoIncrement()
|
||||
})
|
||||
it('should fetch the file size from filestore when missing in history-v1', async function () {
|
||||
MockV1HistoryApi.reset()
|
||||
const { response } = await user.doRequest('HEAD', blobURLWithFallback)
|
||||
expect(response.statusCode).to.equal(200)
|
||||
expect(response.headers['x-served-by']).to.include('filestore')
|
||||
expect(response.headers['content-length']).to.equal('3694')
|
||||
await expectFilestoreHit()
|
||||
})
|
||||
if (Features.hasFeature('filestore')) {
|
||||
it('should fetch the file size from filestore when missing in history-v1', async function () {
|
||||
MockV1HistoryApi.reset()
|
||||
const { response } = await user.doRequest('HEAD', blobURLWithFallback)
|
||||
expect(response.statusCode).to.equal(200)
|
||||
expect(response.headers['x-served-by']).to.include('filestore')
|
||||
expect(response.headers['content-length']).to.equal('3694')
|
||||
await expectFilestoreHit()
|
||||
})
|
||||
}
|
||||
it('should return 404 with both files missing', async function () {
|
||||
MockFilestoreApi.reset()
|
||||
MockV1HistoryApi.reset()
|
||||
@@ -177,17 +181,19 @@ describe('HistoryTests', function () {
|
||||
expect(response.headers).not.to.have.property('cache-control')
|
||||
expect(response.headers).not.to.have.property('etag')
|
||||
})
|
||||
it('should fetch the file size from filestore when missing in history-v1', async function () {
|
||||
MockV1HistoryApi.reset()
|
||||
const { response, body } = await user.doRequest(
|
||||
'GET',
|
||||
blobURLWithFallback
|
||||
)
|
||||
expect(response.statusCode).to.equal(200)
|
||||
expect(response.headers['x-served-by']).to.include('filestore')
|
||||
expect(body).to.equal(fileContent)
|
||||
await expectFilestoreHit()
|
||||
})
|
||||
if (Features.hasFeature('filestore')) {
|
||||
it('should fetch the file size from filestore when missing in history-v1', async function () {
|
||||
MockV1HistoryApi.reset()
|
||||
const { response, body } = await user.doRequest(
|
||||
'GET',
|
||||
blobURLWithFallback
|
||||
)
|
||||
expect(response.statusCode).to.equal(200)
|
||||
expect(response.headers['x-served-by']).to.include('filestore')
|
||||
expect(body).to.equal(fileContent)
|
||||
await expectFilestoreHit()
|
||||
})
|
||||
}
|
||||
it('should return 404 with both files missing', async function () {
|
||||
MockFilestoreApi.reset()
|
||||
MockV1HistoryApi.reset()
|
||||
@@ -210,13 +216,15 @@ describe('HistoryTests', function () {
|
||||
await expectHistoryV1Hit()
|
||||
})
|
||||
}
|
||||
it('should fetch the file size from filestore when missing in history-v1', async function () {
|
||||
MockV1HistoryApi.reset()
|
||||
const { response } = await user.doRequest('HEAD', blobURLWithFallback)
|
||||
expect(response.statusCode).to.equal(200)
|
||||
expect(response.headers['x-served-by']).to.include('filestore')
|
||||
expect(response.headers['content-length']).to.equal('3694')
|
||||
})
|
||||
if (Features.hasFeature('filestore')) {
|
||||
it('should fetch the file size from filestore when missing in history-v1', async function () {
|
||||
MockV1HistoryApi.reset()
|
||||
const { response } = await user.doRequest('HEAD', blobURLWithFallback)
|
||||
expect(response.statusCode).to.equal(200)
|
||||
expect(response.headers['x-served-by']).to.include('filestore')
|
||||
expect(response.headers['content-length']).to.equal('3694')
|
||||
})
|
||||
}
|
||||
it('should return 404 with both files missing', async function () {
|
||||
MockFilestoreApi.reset()
|
||||
MockV1HistoryApi.reset()
|
||||
@@ -251,13 +259,15 @@ describe('HistoryTests', function () {
|
||||
expect(response.headers).not.to.have.property('cache-control')
|
||||
expect(response.headers).not.to.have.property('etag')
|
||||
})
|
||||
it('should fetch the file size from filestore when missing in history-v1', async function () {
|
||||
MockV1HistoryApi.reset()
|
||||
const { response, body } = await user.doRequest('GET', fileURL)
|
||||
expect(response.statusCode).to.equal(200)
|
||||
expect(response.headers['x-served-by']).to.include('filestore')
|
||||
expect(body).to.equal(fileContent)
|
||||
})
|
||||
if (Features.hasFeature('filestore')) {
|
||||
it('should fetch the file size from filestore when missing in history-v1', async function () {
|
||||
MockV1HistoryApi.reset()
|
||||
const { response, body } = await user.doRequest('GET', fileURL)
|
||||
expect(response.statusCode).to.equal(200)
|
||||
expect(response.headers['x-served-by']).to.include('filestore')
|
||||
expect(body).to.equal(fileContent)
|
||||
})
|
||||
}
|
||||
it('should return 404 with both files missing', async function () {
|
||||
MockFilestoreApi.reset()
|
||||
MockV1HistoryApi.reset()
|
||||
|
||||
@@ -7,15 +7,18 @@ import User from './helpers/User.mjs'
|
||||
import UserHelper from './helpers/UserHelper.mjs'
|
||||
import MockDocstoreApiClass from './mocks/MockDocstoreApi.mjs'
|
||||
import MockFilestoreApiClass from './mocks/MockFilestoreApi.mjs'
|
||||
import MockV1HistoryApiClass from './mocks/MockV1HistoryApi.mjs'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import Features from '../../../app/src/infrastructure/Features.js'
|
||||
|
||||
let MockDocstoreApi, MockFilestoreApi
|
||||
let MockDocstoreApi, MockFilestoreApi, MockV1HistoryApi
|
||||
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url))
|
||||
|
||||
before(function () {
|
||||
MockDocstoreApi = MockDocstoreApiClass.instance()
|
||||
MockFilestoreApi = MockFilestoreApiClass.instance()
|
||||
MockV1HistoryApi = MockV1HistoryApiClass.instance()
|
||||
})
|
||||
|
||||
describe('ProjectDuplicateNames', function () {
|
||||
@@ -80,10 +83,19 @@ describe('ProjectDuplicateNames', function () {
|
||||
expect(Object.keys(docs).length).to.equal(2)
|
||||
})
|
||||
|
||||
it('should create one file in the filestore', function () {
|
||||
const files = MockFilestoreApi.files[this.example_project_id]
|
||||
expect(Object.keys(files).length).to.equal(1)
|
||||
})
|
||||
if (Features.hasFeature('project-history-blobs')) {
|
||||
it('should create one file in the history-v1', function () {
|
||||
const files =
|
||||
MockV1HistoryApi.blobs[this.project.overleaf.history.id.toString()]
|
||||
expect(Object.keys(files).length).to.equal(1)
|
||||
})
|
||||
}
|
||||
if (Features.hasFeature('filestore')) {
|
||||
it('should create one file in the filestore', function () {
|
||||
const files = MockFilestoreApi.files[this.example_project_id]
|
||||
expect(Object.keys(files).length).to.equal(1)
|
||||
})
|
||||
}
|
||||
|
||||
describe('for an existing doc', function () {
|
||||
describe('trying to add a doc with the same name', function () {
|
||||
|
||||
@@ -190,91 +190,174 @@ describe('FileStoreHandler', function () {
|
||||
})
|
||||
})
|
||||
|
||||
it('should create read stream', function (done) {
|
||||
this.fs.createReadStream.returns({
|
||||
pipe() {},
|
||||
on(type, cb) {
|
||||
if (type === 'open') {
|
||||
cb()
|
||||
describe('when filestore feature is enabled', function () {
|
||||
beforeEach(function () {
|
||||
this.Features.hasFeature.withArgs('filestore').returns(true)
|
||||
})
|
||||
it('should create read stream', function (done) {
|
||||
this.fs.createReadStream.returns({
|
||||
pipe() {},
|
||||
on(type, cb) {
|
||||
if (type === 'open') {
|
||||
cb()
|
||||
}
|
||||
},
|
||||
})
|
||||
this.handler.uploadFileFromDisk(
|
||||
this.projectId,
|
||||
this.fileArgs,
|
||||
this.fsPath,
|
||||
() => {
|
||||
this.fs.createReadStream.calledWith(this.fsPath).should.equal(true)
|
||||
done()
|
||||
}
|
||||
},
|
||||
)
|
||||
})
|
||||
this.handler.uploadFileFromDisk(
|
||||
this.projectId,
|
||||
this.fileArgs,
|
||||
this.fsPath,
|
||||
() => {
|
||||
this.fs.createReadStream.calledWith(this.fsPath).should.equal(true)
|
||||
done()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it('should pipe the read stream to request', function (done) {
|
||||
this.request.returns(this.writeStream)
|
||||
this.fs.createReadStream.returns({
|
||||
on(type, cb) {
|
||||
if (type === 'open') {
|
||||
cb()
|
||||
}
|
||||
},
|
||||
pipe: o => {
|
||||
this.writeStream.should.equal(o)
|
||||
done()
|
||||
},
|
||||
it('should pipe the read stream to request', function (done) {
|
||||
this.request.returns(this.writeStream)
|
||||
this.fs.createReadStream.returns({
|
||||
on(type, cb) {
|
||||
if (type === 'open') {
|
||||
cb()
|
||||
}
|
||||
},
|
||||
pipe: o => {
|
||||
this.writeStream.should.equal(o)
|
||||
done()
|
||||
},
|
||||
})
|
||||
this.handler.uploadFileFromDisk(
|
||||
this.projectId,
|
||||
this.fileArgs,
|
||||
this.fsPath,
|
||||
() => {}
|
||||
)
|
||||
})
|
||||
this.handler.uploadFileFromDisk(
|
||||
this.projectId,
|
||||
this.fileArgs,
|
||||
this.fsPath,
|
||||
() => {}
|
||||
)
|
||||
})
|
||||
|
||||
it('should pass the correct options to request', function (done) {
|
||||
const fileUrl = this.getFileUrl(this.projectId, this.fileId)
|
||||
this.fs.createReadStream.returns({
|
||||
pipe() {},
|
||||
on(type, cb) {
|
||||
if (type === 'open') {
|
||||
cb()
|
||||
it('should pass the correct options to request', function (done) {
|
||||
const fileUrl = this.getFileUrl(this.projectId, this.fileId)
|
||||
this.fs.createReadStream.returns({
|
||||
pipe() {},
|
||||
on(type, cb) {
|
||||
if (type === 'open') {
|
||||
cb()
|
||||
}
|
||||
},
|
||||
})
|
||||
this.handler.uploadFileFromDisk(
|
||||
this.projectId,
|
||||
this.fileArgs,
|
||||
this.fsPath,
|
||||
() => {
|
||||
this.request.args[0][0].method.should.equal('post')
|
||||
this.request.args[0][0].uri.should.equal(fileUrl)
|
||||
done()
|
||||
}
|
||||
},
|
||||
)
|
||||
})
|
||||
this.handler.uploadFileFromDisk(
|
||||
this.projectId,
|
||||
this.fileArgs,
|
||||
this.fsPath,
|
||||
() => {
|
||||
this.request.args[0][0].method.should.equal('post')
|
||||
this.request.args[0][0].uri.should.equal(fileUrl)
|
||||
done()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it('should callback with the url and fileRef', function (done) {
|
||||
const fileUrl = this.getFileUrl(this.projectId, this.fileId)
|
||||
this.fs.createReadStream.returns({
|
||||
pipe() {},
|
||||
on(type, cb) {
|
||||
if (type === 'open') {
|
||||
cb()
|
||||
it('should callback with the url and fileRef', function (done) {
|
||||
const fileUrl = this.getFileUrl(this.projectId, this.fileId)
|
||||
this.fs.createReadStream.returns({
|
||||
pipe() {},
|
||||
on(type, cb) {
|
||||
if (type === 'open') {
|
||||
cb()
|
||||
}
|
||||
},
|
||||
})
|
||||
this.handler.uploadFileFromDisk(
|
||||
this.projectId,
|
||||
this.fileArgs,
|
||||
this.fsPath,
|
||||
(err, url, fileRef) => {
|
||||
expect(err).to.not.exist
|
||||
expect(url).to.equal(fileUrl)
|
||||
expect(fileRef._id).to.equal(this.fileId)
|
||||
expect(fileRef.hash).to.equal(this.hashValue)
|
||||
done()
|
||||
}
|
||||
},
|
||||
)
|
||||
})
|
||||
describe('when upload to filestore fails', function () {
|
||||
beforeEach(function () {
|
||||
this.writeStream.on = function (type, fn) {
|
||||
if (type === 'response') {
|
||||
fn({ statusCode: 500 })
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
it('should callback with an error', function (done) {
|
||||
this.fs.createReadStream.callCount = 0
|
||||
this.fs.createReadStream.returns({
|
||||
pipe() {},
|
||||
on(type, cb) {
|
||||
if (type === 'open') {
|
||||
cb()
|
||||
}
|
||||
},
|
||||
})
|
||||
this.handler.uploadFileFromDisk(
|
||||
this.projectId,
|
||||
this.fileArgs,
|
||||
this.fsPath,
|
||||
err => {
|
||||
expect(err).to.exist
|
||||
expect(err).to.be.instanceof(Error)
|
||||
expect(this.fs.createReadStream.callCount).to.equal(
|
||||
this.handler.RETRY_ATTEMPTS
|
||||
)
|
||||
done()
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
describe('when filestore feature is disabled', function () {
|
||||
beforeEach(function () {
|
||||
this.Features.hasFeature.withArgs('filestore').returns(false)
|
||||
})
|
||||
it('should not open file handle', function (done) {
|
||||
this.handler.uploadFileFromDisk(
|
||||
this.projectId,
|
||||
this.fileArgs,
|
||||
this.fsPath,
|
||||
() => {
|
||||
expect(this.fs.createReadStream).to.not.have.been.called
|
||||
done()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it('should not talk to filestore', function (done) {
|
||||
this.handler.uploadFileFromDisk(
|
||||
this.projectId,
|
||||
this.fileArgs,
|
||||
this.fsPath,
|
||||
() => {
|
||||
expect(this.request).to.not.have.been.called
|
||||
done()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it('should callback with the url and fileRef', function (done) {
|
||||
const fileUrl = this.getFileUrl(this.projectId, this.fileId)
|
||||
this.handler.uploadFileFromDisk(
|
||||
this.projectId,
|
||||
this.fileArgs,
|
||||
this.fsPath,
|
||||
(err, url, fileRef) => {
|
||||
expect(err).to.not.exist
|
||||
expect(url).to.equal(fileUrl)
|
||||
expect(fileRef._id).to.equal(this.fileId)
|
||||
expect(fileRef.hash).to.equal(this.hashValue)
|
||||
done()
|
||||
}
|
||||
)
|
||||
})
|
||||
this.handler.uploadFileFromDisk(
|
||||
this.projectId,
|
||||
this.fileArgs,
|
||||
this.fsPath,
|
||||
(err, url, fileRef) => {
|
||||
expect(err).to.not.exist
|
||||
expect(url).to.equal(fileUrl)
|
||||
expect(fileRef._id).to.equal(this.fileId)
|
||||
expect(fileRef.hash).to.equal(this.hashValue)
|
||||
done()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
describe('symlink', function () {
|
||||
@@ -312,41 +395,6 @@ describe('FileStoreHandler', function () {
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when upload fails', function () {
|
||||
beforeEach(function () {
|
||||
this.writeStream.on = function (type, fn) {
|
||||
if (type === 'response') {
|
||||
fn({ statusCode: 500 })
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
it('should callback with an error', function (done) {
|
||||
this.fs.createReadStream.callCount = 0
|
||||
this.fs.createReadStream.returns({
|
||||
pipe() {},
|
||||
on(type, cb) {
|
||||
if (type === 'open') {
|
||||
cb()
|
||||
}
|
||||
},
|
||||
})
|
||||
this.handler.uploadFileFromDisk(
|
||||
this.projectId,
|
||||
this.fileArgs,
|
||||
this.fsPath,
|
||||
err => {
|
||||
expect(err).to.exist
|
||||
expect(err).to.be.instanceof(Error)
|
||||
expect(this.fs.createReadStream.callCount).to.equal(
|
||||
this.handler.RETRY_ATTEMPTS
|
||||
)
|
||||
done()
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('deleteFile', function () {
|
||||
|
||||
Reference in New Issue
Block a user