mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 09:09:36 +02:00
Merge pull request #27936 from overleaf/em-unit-tests-mongo
Make Mongo available to unit tests in all services GitOrigin-RevId: b65bbb69883d5bba31d09802b89f35bdc523fe4d
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
// @ts-check
|
||||
|
||||
const { cleanupTestDatabase, dropTestDatabase } = require('./test-utils')
|
||||
|
||||
module.exports = { cleanupTestDatabase, dropTestDatabase }
|
||||
|
||||
55
libraries/mongo-utils/test-utils.js
Normal file
55
libraries/mongo-utils/test-utils.js
Normal file
@@ -0,0 +1,55 @@
|
||||
// @ts-check
|
||||
|
||||
/**
|
||||
* @import { MongoClient } from 'mongodb'
|
||||
* @import { MongoClient as LegacyMongoClient } from 'mongodb-legacy'
|
||||
*/
|
||||
|
||||
/**
|
||||
* Delete all data from the test Mongo database
|
||||
*
|
||||
* This doesn't drop the collections, so indexes are preserved.
|
||||
*
|
||||
* @param {MongoClient | LegacyMongoClient} mongoClient
|
||||
*/
|
||||
async function cleanupTestDatabase(mongoClient) {
|
||||
ensureTestDatabase(mongoClient)
|
||||
const db = mongoClient.db()
|
||||
const allCollections = await db.collections()
|
||||
const collections = allCollections.filter(
|
||||
coll => coll.collectionName !== 'migrations'
|
||||
)
|
||||
await Promise.all(collections.map(coll => coll.deleteMany({})))
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop the test Monto database
|
||||
*
|
||||
* This drops the whole database, including indexes.
|
||||
*
|
||||
* @param {MongoClient | LegacyMongoClient } mongoClient
|
||||
*/
|
||||
async function dropTestDatabase(mongoClient) {
|
||||
ensureTestDatabase(mongoClient)
|
||||
await mongoClient.db().dropDatabase()
|
||||
}
|
||||
/**
|
||||
* Ensure that the given client is connected to a test database.
|
||||
*
|
||||
* This should be called before performing destructive operations on the test
|
||||
* database.
|
||||
*
|
||||
* @param {MongoClient | LegacyMongoClient } mongoClient
|
||||
*/
|
||||
function ensureTestDatabase(mongoClient) {
|
||||
const dbName = mongoClient.db().databaseName
|
||||
const env = process.env.NODE_ENV
|
||||
|
||||
if (dbName !== 'test-overleaf' || env !== 'test') {
|
||||
throw new Error(
|
||||
`Refusing to clear database '${dbName}' in environment '${env}'`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { cleanupTestDatabase, dropTestDatabase }
|
||||
@@ -1,3 +1,5 @@
|
||||
// @ts-check
|
||||
|
||||
const crypto = require('node:crypto')
|
||||
const os = require('node:os')
|
||||
const { promisify } = require('node:util')
|
||||
@@ -168,6 +170,34 @@ async function runWithTimeout({ runner, timeout, context }) {
|
||||
])
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all data from the test Redis instance
|
||||
*
|
||||
* @param {Redis} rclient
|
||||
*/
|
||||
async function cleanupTestRedis(rclient) {
|
||||
ensureTestRedis(rclient)
|
||||
await rclient.flushall()
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the Redis client points to a test database
|
||||
*
|
||||
* In tests, the Redis instance is on a host called redis_test
|
||||
*
|
||||
* @param {Redis} rclient
|
||||
*/
|
||||
function ensureTestRedis(rclient) {
|
||||
const host = rclient.options.host
|
||||
const env = process.env.NODE_ENV
|
||||
if (host !== 'redis_test' || env !== 'test') {
|
||||
throw new Error(
|
||||
`Refusing to clear Redis instance '${host}' in environment '${env}'`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createClient,
|
||||
cleanupTestRedis,
|
||||
}
|
||||
|
||||
7
package-lock.json
generated
7
package-lock.json
generated
@@ -42339,6 +42339,7 @@
|
||||
"dependencies": {
|
||||
"@overleaf/logger": "*",
|
||||
"@overleaf/metrics": "*",
|
||||
"@overleaf/mongo-utils": "*",
|
||||
"@overleaf/settings": "*",
|
||||
"async": "^3.2.5",
|
||||
"body-parser": "^1.20.3",
|
||||
@@ -42491,6 +42492,7 @@
|
||||
"dependencies": {
|
||||
"@overleaf/logger": "*",
|
||||
"@overleaf/metrics": "*",
|
||||
"@overleaf/mongo-utils": "*",
|
||||
"@overleaf/settings": "*",
|
||||
"async": "^3.2.5",
|
||||
"body-parser": "^1.20.3",
|
||||
@@ -42556,6 +42558,7 @@
|
||||
"@overleaf/fetch-utils": "*",
|
||||
"@overleaf/logger": "*",
|
||||
"@overleaf/metrics": "*",
|
||||
"@overleaf/mongo-utils": "*",
|
||||
"@overleaf/o-error": "*",
|
||||
"@overleaf/object-persistor": "*",
|
||||
"@overleaf/promise-utils": "*",
|
||||
@@ -42627,6 +42630,7 @@
|
||||
"dependencies": {
|
||||
"@overleaf/logger": "*",
|
||||
"@overleaf/metrics": "*",
|
||||
"@overleaf/mongo-utils": "*",
|
||||
"@overleaf/o-error": "*",
|
||||
"@overleaf/promise-utils": "*",
|
||||
"@overleaf/ranges-tracker": "*",
|
||||
@@ -44089,6 +44093,7 @@
|
||||
"dependencies": {
|
||||
"@overleaf/logger": "*",
|
||||
"@overleaf/metrics": "*",
|
||||
"@overleaf/mongo-utils": "*",
|
||||
"@overleaf/settings": "*",
|
||||
"async": "^3.2.5",
|
||||
"body-parser": "^1.20.3",
|
||||
@@ -44113,6 +44118,7 @@
|
||||
"@overleaf/fetch-utils": "*",
|
||||
"@overleaf/logger": "*",
|
||||
"@overleaf/metrics": "*",
|
||||
"@overleaf/mongo-utils": "*",
|
||||
"@overleaf/o-error": "*",
|
||||
"@overleaf/promise-utils": "*",
|
||||
"@overleaf/redis-wrapper": "*",
|
||||
@@ -44341,6 +44347,7 @@
|
||||
"@overleaf/fetch-utils": "*",
|
||||
"@overleaf/logger": "*",
|
||||
"@overleaf/metrics": "*",
|
||||
"@overleaf/mongo-utils": "*",
|
||||
"@overleaf/o-error": "*",
|
||||
"@overleaf/settings": "*",
|
||||
"async": "^3.2.5",
|
||||
|
||||
@@ -86,7 +86,6 @@ test: format lint typecheck shellcheck test_unit test_acceptance
|
||||
test_unit:
|
||||
ifneq (,$(wildcard test/unit))
|
||||
$(DOCKER_COMPOSE_TEST_UNIT) run --rm test_unit
|
||||
$(MAKE) test_unit_clean
|
||||
endif
|
||||
|
||||
test_clean: test_unit_clean
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// @ts-check
|
||||
|
||||
import Metrics from '@overleaf/metrics'
|
||||
import Settings from '@overleaf/settings'
|
||||
import MongoUtils from '@overleaf/mongo-utils'
|
||||
import { MongoClient } from 'mongodb'
|
||||
|
||||
export { ObjectId } from 'mongodb'
|
||||
@@ -16,3 +19,7 @@ export const db = {
|
||||
}
|
||||
|
||||
Metrics.mongodb.monitor(mongoClient)
|
||||
|
||||
export async function cleanupTestDatabase() {
|
||||
await MongoUtils.cleanupTestDatabase(mongoClient)
|
||||
}
|
||||
|
||||
@@ -6,10 +6,17 @@ services:
|
||||
test_unit:
|
||||
image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER
|
||||
user: node
|
||||
volumes:
|
||||
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
|
||||
entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
|
||||
command: npm run test:unit:_run
|
||||
environment:
|
||||
MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
|
||||
NODE_ENV: test
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_started
|
||||
|
||||
|
||||
test_acceptance:
|
||||
|
||||
@@ -9,14 +9,20 @@ services:
|
||||
- .:/overleaf/services/chat
|
||||
- ../../node_modules:/overleaf/node_modules
|
||||
- ../../libraries:/overleaf/libraries
|
||||
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
|
||||
working_dir: /overleaf/services/chat
|
||||
environment:
|
||||
MOCHA_GREP: ${MOCHA_GREP}
|
||||
LOG_LEVEL: ${LOG_LEVEL:-}
|
||||
MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
|
||||
NODE_ENV: test
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
|
||||
command: npm run --silent test:unit
|
||||
user: node
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_started
|
||||
|
||||
test_acceptance:
|
||||
image: node:22.18.0
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"test:unit": "npm run test:unit:_run -- --grep=$MOCHA_GREP",
|
||||
"nodemon": "node --watch app.js",
|
||||
"test:acceptance:_run": "mocha --recursive --reporter spec --timeout 15000 --exit $@ test/acceptance/js",
|
||||
"test:unit:_run": "mocha --recursive --reporter spec $@ test/unit/js",
|
||||
"test:unit:_run": "mocha --recursive --reporter spec --exit $@ test/unit/js",
|
||||
"lint": "eslint --max-warnings 0 --format unix .",
|
||||
"format": "prettier --list-different $PWD/'**/*.*js'",
|
||||
"format:fix": "prettier --write $PWD/'**/*.*js'",
|
||||
@@ -20,6 +20,7 @@
|
||||
"dependencies": {
|
||||
"@overleaf/logger": "*",
|
||||
"@overleaf/metrics": "*",
|
||||
"@overleaf/mongo-utils": "*",
|
||||
"@overleaf/settings": "*",
|
||||
"async": "^3.2.5",
|
||||
"body-parser": "^1.20.3",
|
||||
|
||||
@@ -87,7 +87,6 @@ test: format lint typecheck shellcheck test_unit test_acceptance
|
||||
test_unit:
|
||||
ifneq (,$(wildcard test/unit))
|
||||
$(DOCKER_COMPOSE_TEST_UNIT) run --rm test_unit
|
||||
$(MAKE) test_unit_clean
|
||||
endif
|
||||
|
||||
test_clean: test_unit_clean
|
||||
|
||||
@@ -7,6 +7,7 @@ services:
|
||||
image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER
|
||||
command: npm run test:unit:_run
|
||||
environment:
|
||||
MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
|
||||
NODE_ENV: test
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ services:
|
||||
environment:
|
||||
MOCHA_GREP: ${MOCHA_GREP}
|
||||
LOG_LEVEL: ${LOG_LEVEL:-}
|
||||
MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
|
||||
NODE_ENV: test
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
command: npm run --silent test:unit
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"start": "node app.js",
|
||||
"test:acceptance:_run": "mocha --recursive --reporter spec --timeout 15000 --exit $@ test/acceptance/js",
|
||||
"test:acceptance": "npm run test:acceptance:_run -- --grep=$MOCHA_GREP",
|
||||
"test:unit:_run": "mocha --recursive --reporter spec $@ test/unit/js",
|
||||
"test:unit:_run": "mocha --recursive --reporter spec --exit $@ test/unit/js",
|
||||
"test:unit": "npm run test:unit:_run -- --grep=$MOCHA_GREP",
|
||||
"nodemon": "node --watch app.js",
|
||||
"lint": "eslint --max-warnings 0 --format unix .",
|
||||
|
||||
@@ -86,7 +86,6 @@ test: format lint typecheck shellcheck test_unit test_acceptance
|
||||
test_unit:
|
||||
ifneq (,$(wildcard test/unit))
|
||||
$(DOCKER_COMPOSE_TEST_UNIT) run --rm test_unit
|
||||
$(MAKE) test_unit_clean
|
||||
endif
|
||||
|
||||
test_clean: test_unit_clean
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
// @ts-check
|
||||
|
||||
import Metrics from '@overleaf/metrics'
|
||||
import MongoUtils from '@overleaf/mongo-utils'
|
||||
import Settings from '@overleaf/settings'
|
||||
import { MongoClient } from 'mongodb'
|
||||
|
||||
@@ -15,3 +18,7 @@ export const db = {
|
||||
}
|
||||
|
||||
Metrics.mongodb.monitor(mongoClient)
|
||||
|
||||
export async function cleanupTestDatabase() {
|
||||
await MongoUtils.cleanupTestDatabase(mongoClient)
|
||||
}
|
||||
|
||||
@@ -6,10 +6,17 @@ services:
|
||||
test_unit:
|
||||
image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER
|
||||
user: node
|
||||
volumes:
|
||||
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
|
||||
entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
|
||||
command: npm run test:unit:_run
|
||||
environment:
|
||||
MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
|
||||
NODE_ENV: test
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_started
|
||||
|
||||
|
||||
test_acceptance:
|
||||
|
||||
@@ -9,14 +9,20 @@ services:
|
||||
- .:/overleaf/services/contacts
|
||||
- ../../node_modules:/overleaf/node_modules
|
||||
- ../../libraries:/overleaf/libraries
|
||||
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
|
||||
working_dir: /overleaf/services/contacts
|
||||
environment:
|
||||
MOCHA_GREP: ${MOCHA_GREP}
|
||||
LOG_LEVEL: ${LOG_LEVEL:-}
|
||||
MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
|
||||
NODE_ENV: test
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
|
||||
command: npm run --silent test:unit
|
||||
user: node
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_started
|
||||
|
||||
test_acceptance:
|
||||
image: node:22.18.0
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"start": "node app.js",
|
||||
"test:acceptance:_run": "mocha --loader=esmock --recursive --reporter spec --timeout 15000 --exit $@ test/acceptance/js",
|
||||
"test:acceptance": "npm run test:acceptance:_run -- --grep=$MOCHA_GREP",
|
||||
"test:unit:_run": "mocha --loader=esmock --recursive --reporter spec $@ test/unit/js",
|
||||
"test:unit:_run": "mocha --loader=esmock --recursive --reporter spec --exit $@ test/unit/js",
|
||||
"test:unit": "npm run test:unit:_run -- --grep=$MOCHA_GREP",
|
||||
"nodemon": "node --watch app.js",
|
||||
"lint": "eslint --max-warnings 0 --format unix .",
|
||||
@@ -20,6 +20,7 @@
|
||||
"dependencies": {
|
||||
"@overleaf/logger": "*",
|
||||
"@overleaf/metrics": "*",
|
||||
"@overleaf/mongo-utils": "*",
|
||||
"@overleaf/settings": "*",
|
||||
"async": "^3.2.5",
|
||||
"body-parser": "^1.20.3",
|
||||
|
||||
@@ -1,21 +1,16 @@
|
||||
// @ts-check
|
||||
|
||||
import sinon from 'sinon'
|
||||
import { expect } from 'chai'
|
||||
import esmock from 'esmock'
|
||||
import { ObjectId } from 'mongodb'
|
||||
import { cleanupTestDatabase } from '../../../app/js/mongodb.js'
|
||||
import * as ContactManager from '../../../app/js/ContactManager.js'
|
||||
|
||||
describe('ContactManager', function () {
|
||||
beforeEach(cleanupTestDatabase)
|
||||
|
||||
beforeEach(async function () {
|
||||
this.clock = sinon.useFakeTimers(new Date())
|
||||
|
||||
this.db = { contacts: {} }
|
||||
|
||||
this.ContactManager = await esmock('../../../app/js/ContactManager', {
|
||||
'../../../app/js/mongodb': {
|
||||
db: this.db,
|
||||
ObjectId,
|
||||
},
|
||||
})
|
||||
|
||||
this.user_id = new ObjectId().toString()
|
||||
this.contact_id = new ObjectId().toString()
|
||||
})
|
||||
@@ -25,42 +20,24 @@ describe('ContactManager', function () {
|
||||
})
|
||||
|
||||
describe('touchContact', function () {
|
||||
beforeEach(function () {
|
||||
this.db.contacts.updateOne = sinon.stub().resolves()
|
||||
})
|
||||
|
||||
describe('with a valid user_id', function () {
|
||||
it('should increment the contact count and timestamp', async function () {
|
||||
await expect(
|
||||
this.ContactManager.touchContact(this.user_id, 'mock_contact')
|
||||
).not.to.be.rejected
|
||||
|
||||
expect(this.db.contacts.updateOne).to.be.calledWith(
|
||||
{
|
||||
user_id: sinon.match(o => o.toString() === this.user_id),
|
||||
const now = new Date()
|
||||
await ContactManager.touchContact(this.user_id, this.contact_id)
|
||||
const contacts = await ContactManager.getContacts(this.user_id)
|
||||
expect(contacts).to.deep.equal({
|
||||
[this.contact_id]: {
|
||||
n: 1,
|
||||
ts: now,
|
||||
},
|
||||
{
|
||||
$inc: {
|
||||
'contacts.mock_contact.n': 1,
|
||||
},
|
||||
$set: {
|
||||
'contacts.mock_contact.ts': new Date(),
|
||||
},
|
||||
},
|
||||
{
|
||||
upsert: true,
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with an invalid user id', function () {
|
||||
it('should be rejected', async function () {
|
||||
await expect(
|
||||
this.ContactManager.touchContact(
|
||||
'not-valid-object-id',
|
||||
this.contact_id
|
||||
)
|
||||
ContactManager.touchContact('not-valid-object-id', this.contact_id)
|
||||
).to.be.rejectedWith(
|
||||
'input must be a 24 character hex string, 12 byte Uint8Array, or an integer'
|
||||
)
|
||||
@@ -69,29 +46,17 @@ describe('ContactManager', function () {
|
||||
})
|
||||
|
||||
describe('getContacts', function () {
|
||||
beforeEach(function () {
|
||||
this.user = {
|
||||
contacts: ['mock', 'contacts'],
|
||||
}
|
||||
this.db.contacts.findOne = sinon.stub().resolves(this.user)
|
||||
})
|
||||
|
||||
describe('with a valid user_id', function () {
|
||||
it("should find the user's contacts", async function () {
|
||||
await expect(
|
||||
this.ContactManager.getContacts(this.user_id)
|
||||
).to.eventually.deep.equal(this.user.contacts)
|
||||
|
||||
expect(this.db.contacts.findOne).to.be.calledWith({
|
||||
user_id: sinon.match(o => o.toString() === this.user_id),
|
||||
})
|
||||
it('should find an empty contact list', async function () {
|
||||
const contacts = await ContactManager.getContacts(this.user_id)
|
||||
expect(contacts).to.be.undefined
|
||||
})
|
||||
})
|
||||
|
||||
describe('with an invalid user id', function () {
|
||||
it('should be rejected', async function () {
|
||||
await expect(this.ContactManager.getContacts('not-valid-object-id')).to
|
||||
.be.rejected
|
||||
await expect(ContactManager.getContacts('not-valid-object-id')).to.be
|
||||
.rejected
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -86,7 +86,6 @@ test: format lint typecheck shellcheck test_unit test_acceptance
|
||||
test_unit:
|
||||
ifneq (,$(wildcard test/unit))
|
||||
$(DOCKER_COMPOSE_TEST_UNIT) run --rm test_unit
|
||||
$(MAKE) test_unit_clean
|
||||
endif
|
||||
|
||||
test_clean: test_unit_clean
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// @ts-check
|
||||
|
||||
const Metrics = require('@overleaf/metrics')
|
||||
const Settings = require('@overleaf/settings')
|
||||
const MongoUtils = require('@overleaf/mongo-utils')
|
||||
const { MongoClient, ObjectId } = require('mongodb-legacy')
|
||||
|
||||
const mongoClient = new MongoClient(Settings.mongo.url, Settings.mongo.options)
|
||||
@@ -11,8 +14,13 @@ const db = {
|
||||
|
||||
Metrics.mongodb.monitor(mongoClient)
|
||||
|
||||
async function cleanupTestDatabase() {
|
||||
await MongoUtils.cleanupTestDatabase(mongoClient)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
db,
|
||||
mongoClient,
|
||||
ObjectId,
|
||||
cleanupTestDatabase,
|
||||
}
|
||||
|
||||
@@ -6,10 +6,17 @@ services:
|
||||
test_unit:
|
||||
image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER
|
||||
user: node
|
||||
volumes:
|
||||
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
|
||||
entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
|
||||
command: npm run test:unit:_run
|
||||
environment:
|
||||
MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
|
||||
NODE_ENV: test
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_started
|
||||
|
||||
|
||||
test_acceptance:
|
||||
|
||||
@@ -9,14 +9,20 @@ services:
|
||||
- .:/overleaf/services/docstore
|
||||
- ../../node_modules:/overleaf/node_modules
|
||||
- ../../libraries:/overleaf/libraries
|
||||
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
|
||||
working_dir: /overleaf/services/docstore
|
||||
environment:
|
||||
MOCHA_GREP: ${MOCHA_GREP}
|
||||
LOG_LEVEL: ${LOG_LEVEL:-}
|
||||
MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
|
||||
NODE_ENV: test
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
|
||||
command: npm run --silent test:unit
|
||||
user: node
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_started
|
||||
|
||||
test_acceptance:
|
||||
image: node:22.18.0
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"start": "node app.js",
|
||||
"test:acceptance:_run": "mocha --recursive --reporter spec --timeout 15000 --exit $@ test/acceptance/js",
|
||||
"test:acceptance": "npm run test:acceptance:_run -- --grep=$MOCHA_GREP",
|
||||
"test:unit:_run": "mocha --recursive --reporter spec $@ test/unit/js",
|
||||
"test:unit:_run": "mocha --recursive --reporter spec --exit $@ test/unit/js",
|
||||
"test:unit": "npm run test:unit:_run -- --grep=$MOCHA_GREP",
|
||||
"nodemon": "node --watch app.js",
|
||||
"lint": "eslint --max-warnings 0 --format unix .",
|
||||
@@ -20,6 +20,7 @@
|
||||
"@overleaf/fetch-utils": "*",
|
||||
"@overleaf/logger": "*",
|
||||
"@overleaf/metrics": "*",
|
||||
"@overleaf/mongo-utils": "*",
|
||||
"@overleaf/o-error": "*",
|
||||
"@overleaf/object-persistor": "*",
|
||||
"@overleaf/promise-utils": "*",
|
||||
|
||||
@@ -86,7 +86,6 @@ test: format lint typecheck shellcheck test_unit test_acceptance
|
||||
test_unit:
|
||||
ifneq (,$(wildcard test/unit))
|
||||
$(DOCKER_COMPOSE_TEST_UNIT) run --rm test_unit
|
||||
$(MAKE) test_unit_clean
|
||||
endif
|
||||
|
||||
test_clean: test_unit_clean
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
const Settings = require('@overleaf/settings')
|
||||
const rclient = require('@overleaf/redis-wrapper').createClient(
|
||||
Settings.redis.documentupdater
|
||||
)
|
||||
const RedisWrapper = require('@overleaf/redis-wrapper')
|
||||
const logger = require('@overleaf/logger')
|
||||
const OError = require('@overleaf/o-error')
|
||||
const { promisifyAll } = require('@overleaf/promise-utils')
|
||||
@@ -11,6 +9,8 @@ const crypto = require('node:crypto')
|
||||
const async = require('async')
|
||||
const { docIsTooLarge } = require('./Limits')
|
||||
|
||||
const rclient = RedisWrapper.createClient(Settings.redis.documentupdater)
|
||||
|
||||
// Sometimes Redis calls take an unexpectedly long time. We have to be
|
||||
// quick with Redis calls because we're holding a lock that expires
|
||||
// after 30 seconds. We can't let any errors in the rest of the stack
|
||||
@@ -777,6 +777,10 @@ const RedisManager = {
|
||||
// binary in node < v5
|
||||
return crypto.createHash('sha1').update(docLines, 'utf8').digest('hex')
|
||||
},
|
||||
|
||||
async cleanupTestRedis() {
|
||||
await RedisWrapper.cleanupTestRedis(rclient)
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = RedisManager
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
// @ts-check
|
||||
|
||||
const Metrics = require('@overleaf/metrics')
|
||||
const MongoUtils = require('@overleaf/mongo-utils')
|
||||
const Settings = require('@overleaf/settings')
|
||||
const { MongoClient, ObjectId } = require('mongodb-legacy')
|
||||
|
||||
@@ -20,9 +23,14 @@ async function healthCheck() {
|
||||
|
||||
Metrics.mongodb.monitor(mongoClient)
|
||||
|
||||
async function cleanupTestDatabase() {
|
||||
await MongoUtils.cleanupTestDatabase(mongoClient)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
db,
|
||||
ObjectId,
|
||||
mongoClient,
|
||||
healthCheck: require('node:util').callbackify(healthCheck),
|
||||
cleanupTestDatabase,
|
||||
}
|
||||
|
||||
@@ -6,10 +6,23 @@ services:
|
||||
test_unit:
|
||||
image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER
|
||||
user: node
|
||||
volumes:
|
||||
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
|
||||
entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
|
||||
command: npm run test:unit:_run
|
||||
environment:
|
||||
MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
|
||||
NODE_ENV: test
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
REDIS_HOST: redis_test
|
||||
QUEUES_REDIS_HOST: redis_test
|
||||
HISTORY_REDIS_HOST: redis_test
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis_test
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_started
|
||||
redis_test:
|
||||
condition: service_healthy
|
||||
|
||||
|
||||
test_acceptance:
|
||||
@@ -17,10 +30,10 @@ services:
|
||||
image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER
|
||||
environment:
|
||||
ELASTIC_SEARCH_DSN: es:9200
|
||||
REDIS_HOST: redis
|
||||
QUEUES_REDIS_HOST: redis
|
||||
HISTORY_REDIS_HOST: redis
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis
|
||||
REDIS_HOST: redis_test
|
||||
QUEUES_REDIS_HOST: redis_test
|
||||
HISTORY_REDIS_HOST: redis_test
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis_test
|
||||
MONGO_HOST: mongo
|
||||
POSTGRES_HOST: postgres
|
||||
MOCHA_GREP: ${MOCHA_GREP}
|
||||
@@ -31,7 +44,7 @@ services:
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_started
|
||||
redis:
|
||||
redis_test:
|
||||
condition: service_healthy
|
||||
user: node
|
||||
entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
|
||||
@@ -45,7 +58,7 @@ services:
|
||||
- ./:/tmp/build/
|
||||
command: tar -czf /tmp/build/build.tar.gz --exclude=build.tar.gz --exclude-vcs .
|
||||
user: root
|
||||
redis:
|
||||
redis_test:
|
||||
image: redis:7.4.3
|
||||
healthcheck:
|
||||
test: ping="$$(redis-cli ping)" && [ "$$ping" = 'PONG' ]
|
||||
|
||||
@@ -9,14 +9,26 @@ services:
|
||||
- .:/overleaf/services/document-updater
|
||||
- ../../node_modules:/overleaf/node_modules
|
||||
- ../../libraries:/overleaf/libraries
|
||||
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
|
||||
working_dir: /overleaf/services/document-updater
|
||||
environment:
|
||||
MOCHA_GREP: ${MOCHA_GREP}
|
||||
LOG_LEVEL: ${LOG_LEVEL:-}
|
||||
MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
|
||||
NODE_ENV: test
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
REDIS_HOST: redis_test
|
||||
HISTORY_REDIS_HOST: redis_test
|
||||
QUEUES_REDIS_HOST: redis_test
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis_test
|
||||
entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
|
||||
command: npm run --silent test:unit
|
||||
user: node
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_started
|
||||
redis_test:
|
||||
condition: service_healthy
|
||||
|
||||
test_acceptance:
|
||||
image: node:22.18.0
|
||||
@@ -28,10 +40,10 @@ services:
|
||||
working_dir: /overleaf/services/document-updater
|
||||
environment:
|
||||
ELASTIC_SEARCH_DSN: es:9200
|
||||
REDIS_HOST: redis
|
||||
HISTORY_REDIS_HOST: redis
|
||||
QUEUES_REDIS_HOST: redis
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis
|
||||
REDIS_HOST: redis_test
|
||||
HISTORY_REDIS_HOST: redis_test
|
||||
QUEUES_REDIS_HOST: redis_test
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis_test
|
||||
MONGO_HOST: mongo
|
||||
POSTGRES_HOST: postgres
|
||||
MOCHA_GREP: ${MOCHA_GREP}
|
||||
@@ -42,12 +54,12 @@ services:
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_started
|
||||
redis:
|
||||
redis_test:
|
||||
condition: service_healthy
|
||||
entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
|
||||
command: npm run --silent test:acceptance
|
||||
|
||||
redis:
|
||||
redis_test:
|
||||
image: redis:7.4.3
|
||||
healthcheck:
|
||||
test: ping=$$(redis-cli ping) && [ "$$ping" = 'PONG' ]
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"start": "node app.js",
|
||||
"test:acceptance:_run": "mocha --recursive --reporter spec --timeout 15000 --exit $@ test/acceptance/js",
|
||||
"test:acceptance": "npm run test:acceptance:_run -- --grep=$MOCHA_GREP",
|
||||
"test:unit:_run": "mocha --recursive --reporter spec $@ test/unit/js",
|
||||
"test:unit:_run": "mocha --recursive --reporter spec --exit $@ test/unit/js",
|
||||
"test:unit": "npm run test:unit:_run -- --grep=$MOCHA_GREP",
|
||||
"nodemon": "node --watch app.js",
|
||||
"benchmark:apply": "node benchmarks/apply",
|
||||
@@ -20,6 +20,7 @@
|
||||
"dependencies": {
|
||||
"@overleaf/logger": "*",
|
||||
"@overleaf/metrics": "*",
|
||||
"@overleaf/mongo-utils": "*",
|
||||
"@overleaf/o-error": "*",
|
||||
"@overleaf/promise-utils": "*",
|
||||
"@overleaf/ranges-tracker": "*",
|
||||
|
||||
@@ -87,7 +87,6 @@ test: format lint typecheck shellcheck test_unit test_acceptance
|
||||
test_unit:
|
||||
ifneq (,$(wildcard test/unit))
|
||||
$(DOCKER_COMPOSE_TEST_UNIT) run --rm test_unit
|
||||
$(MAKE) test_unit_clean
|
||||
endif
|
||||
|
||||
test_clean: test_unit_clean
|
||||
|
||||
@@ -11,6 +11,7 @@ services:
|
||||
user: node
|
||||
command: npm run test:unit:_run
|
||||
environment:
|
||||
MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
|
||||
NODE_ENV: test
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ services:
|
||||
environment:
|
||||
MOCHA_GREP: ${MOCHA_GREP}
|
||||
LOG_LEVEL: ${LOG_LEVEL:-}
|
||||
MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
|
||||
NODE_ENV: test
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
command: npm run --silent test:unit
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"format": "prettier --list-different $PWD/'**/*.*js'",
|
||||
"format:fix": "prettier --write $PWD/'**/*.*js'",
|
||||
"test:acceptance:_run": "mocha --recursive --reporter spec --timeout 15000 --exit $@ test/acceptance/js",
|
||||
"test:unit:_run": "mocha --recursive --reporter spec $@ test/unit/js",
|
||||
"test:unit:_run": "mocha --recursive --reporter spec --exit $@ test/unit/js",
|
||||
"lint:fix": "eslint --fix .",
|
||||
"types:check": "tsc --noEmit"
|
||||
},
|
||||
|
||||
@@ -86,7 +86,6 @@ test: format lint typecheck shellcheck test_unit test_acceptance
|
||||
test_unit:
|
||||
ifneq (,$(wildcard test/unit))
|
||||
$(DOCKER_COMPOSE_TEST_UNIT) run --rm test_unit
|
||||
$(MAKE) test_unit_clean
|
||||
endif
|
||||
|
||||
test_clean: test_unit_clean
|
||||
|
||||
@@ -9,10 +9,23 @@ services:
|
||||
test_unit:
|
||||
image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER
|
||||
user: node
|
||||
volumes:
|
||||
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
|
||||
entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
|
||||
command: npm run test:unit:_run
|
||||
environment:
|
||||
MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
|
||||
NODE_ENV: test
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
REDIS_HOST: redis_test
|
||||
QUEUES_REDIS_HOST: redis_test
|
||||
HISTORY_REDIS_HOST: redis_test
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis_test
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_started
|
||||
redis_test:
|
||||
condition: service_healthy
|
||||
|
||||
|
||||
test_acceptance:
|
||||
@@ -20,10 +33,10 @@ services:
|
||||
image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER
|
||||
environment:
|
||||
ELASTIC_SEARCH_DSN: es:9200
|
||||
REDIS_HOST: redis
|
||||
QUEUES_REDIS_HOST: redis
|
||||
HISTORY_REDIS_HOST: redis
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis
|
||||
REDIS_HOST: redis_test
|
||||
QUEUES_REDIS_HOST: redis_test
|
||||
HISTORY_REDIS_HOST: redis_test
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis_test
|
||||
MONGO_HOST: mongo
|
||||
POSTGRES_HOST: postgres
|
||||
AWS_S3_ENDPOINT: https://minio:9000
|
||||
@@ -44,7 +57,7 @@ services:
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_started
|
||||
redis:
|
||||
redis_test:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
@@ -68,7 +81,7 @@ services:
|
||||
- ./:/tmp/build/
|
||||
command: tar -czf /tmp/build/build.tar.gz --exclude=build.tar.gz --exclude-vcs .
|
||||
user: root
|
||||
redis:
|
||||
redis_test:
|
||||
image: redis:7.4.3
|
||||
healthcheck:
|
||||
test: ping="$$(redis-cli ping)" && [ "$$ping" = 'PONG' ]
|
||||
|
||||
@@ -15,14 +15,26 @@ services:
|
||||
- .:/overleaf/services/history-v1
|
||||
- ../../node_modules:/overleaf/node_modules
|
||||
- ../../libraries:/overleaf/libraries
|
||||
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
|
||||
working_dir: /overleaf/services/history-v1
|
||||
environment:
|
||||
MOCHA_GREP: ${MOCHA_GREP}
|
||||
LOG_LEVEL: ${LOG_LEVEL:-}
|
||||
MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
|
||||
NODE_ENV: test
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
REDIS_HOST: redis_test
|
||||
HISTORY_REDIS_HOST: redis_test
|
||||
QUEUES_REDIS_HOST: redis_test
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis_test
|
||||
entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
|
||||
command: npm run --silent test:unit
|
||||
user: node
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_started
|
||||
redis_test:
|
||||
condition: service_healthy
|
||||
|
||||
test_acceptance:
|
||||
build:
|
||||
@@ -38,10 +50,10 @@ services:
|
||||
working_dir: /overleaf/services/history-v1
|
||||
environment:
|
||||
ELASTIC_SEARCH_DSN: es:9200
|
||||
REDIS_HOST: redis
|
||||
HISTORY_REDIS_HOST: redis
|
||||
QUEUES_REDIS_HOST: redis
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis
|
||||
REDIS_HOST: redis_test
|
||||
HISTORY_REDIS_HOST: redis_test
|
||||
QUEUES_REDIS_HOST: redis_test
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis_test
|
||||
MONGO_HOST: mongo
|
||||
POSTGRES_HOST: postgres
|
||||
AWS_S3_ENDPOINT: https://minio:9000
|
||||
@@ -61,7 +73,7 @@ services:
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_started
|
||||
redis:
|
||||
redis_test:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
@@ -76,7 +88,7 @@ services:
|
||||
entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
|
||||
command: npm run --silent test:acceptance
|
||||
|
||||
redis:
|
||||
redis_test:
|
||||
image: redis:7.4.3
|
||||
healthcheck:
|
||||
test: ping=$$(redis-cli ping) && [ "$$ping" = 'PONG' ]
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
"format:fix": "prettier --write $PWD/'**/*.*js'",
|
||||
"test:unit": "npm run test:unit:_run -- --grep=$MOCHA_GREP",
|
||||
"test:acceptance": "npm run test:acceptance:_run -- --grep=$MOCHA_GREP",
|
||||
"test:unit:_run": "mocha --recursive --reporter spec $@ test/unit/js",
|
||||
"test:unit:_run": "mocha --recursive --reporter spec --exit $@ test/unit/js",
|
||||
"test:acceptance:_run": "mocha --recursive --reporter spec --timeout 15000 --exit $@ test/acceptance/js",
|
||||
"nodemon": "node --watch app.js",
|
||||
"migrate": "knex migrate:latest",
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
// @ts-check
|
||||
|
||||
const Metrics = require('@overleaf/metrics')
|
||||
const MongoUtils = require('@overleaf/mongo-utils')
|
||||
|
||||
const config = require('config')
|
||||
const { MongoClient } = require('mongodb')
|
||||
@@ -18,6 +21,10 @@ const backedUpBlobs = db.collection('projectHistoryBackedUpBlobs')
|
||||
|
||||
Metrics.mongodb.monitor(client)
|
||||
|
||||
async function cleanupTestDatabase() {
|
||||
await MongoUtils.cleanupTestDatabase(client)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
client,
|
||||
db,
|
||||
@@ -27,4 +34,5 @@ module.exports = {
|
||||
projects,
|
||||
shardedBlobs,
|
||||
backedUpBlobs,
|
||||
cleanupTestDatabase,
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// @ts-check
|
||||
|
||||
const config = require('config')
|
||||
const redis = require('@overleaf/redis-wrapper')
|
||||
|
||||
@@ -11,9 +13,14 @@ async function disconnect() {
|
||||
await Promise.all([rclientHistory.disconnect(), rclientLock.disconnect()])
|
||||
}
|
||||
|
||||
async function cleanupTestRedis() {
|
||||
await redis.cleanupTestRedis(rclientHistory)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
rclientHistory,
|
||||
rclientLock,
|
||||
redis,
|
||||
disconnect,
|
||||
cleanupTestRedis,
|
||||
}
|
||||
|
||||
@@ -86,7 +86,6 @@ test: format lint typecheck shellcheck test_unit test_acceptance
|
||||
test_unit:
|
||||
ifneq (,$(wildcard test/unit))
|
||||
$(DOCKER_COMPOSE_TEST_UNIT) run --rm test_unit
|
||||
$(MAKE) test_unit_clean
|
||||
endif
|
||||
|
||||
test_clean: test_unit_clean
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
// @ts-check
|
||||
|
||||
const Metrics = require('@overleaf/metrics')
|
||||
const MongoUtils = require('@overleaf/mongo-utils')
|
||||
const Settings = require('@overleaf/settings')
|
||||
const { MongoClient, ObjectId } = require('mongodb-legacy')
|
||||
|
||||
@@ -11,8 +14,13 @@ const db = {
|
||||
|
||||
Metrics.mongodb.monitor(mongoClient)
|
||||
|
||||
async function cleanupTestDatabase() {
|
||||
await MongoUtils.cleanupTestDatabase(mongoClient)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
db,
|
||||
mongoClient,
|
||||
ObjectId,
|
||||
cleanupTestDatabase,
|
||||
}
|
||||
|
||||
@@ -6,10 +6,17 @@ services:
|
||||
test_unit:
|
||||
image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER
|
||||
user: node
|
||||
volumes:
|
||||
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
|
||||
entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
|
||||
command: npm run test:unit:_run
|
||||
environment:
|
||||
MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
|
||||
NODE_ENV: test
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_started
|
||||
|
||||
|
||||
test_acceptance:
|
||||
|
||||
@@ -9,14 +9,20 @@ services:
|
||||
- .:/overleaf/services/notifications
|
||||
- ../../node_modules:/overleaf/node_modules
|
||||
- ../../libraries:/overleaf/libraries
|
||||
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
|
||||
working_dir: /overleaf/services/notifications
|
||||
environment:
|
||||
MOCHA_GREP: ${MOCHA_GREP}
|
||||
LOG_LEVEL: ${LOG_LEVEL:-}
|
||||
MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
|
||||
NODE_ENV: test
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
|
||||
command: npm run --silent test:unit
|
||||
user: node
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_started
|
||||
|
||||
test_acceptance:
|
||||
image: node:22.18.0
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"start": "node app.js",
|
||||
"test:acceptance:_run": "mocha --recursive --reporter spec --timeout 15000 --exit $@ test/acceptance/js",
|
||||
"test:acceptance": "npm run test:acceptance:_run -- --grep=$MOCHA_GREP",
|
||||
"test:unit:_run": "mocha --recursive --reporter spec $@ test/unit/js",
|
||||
"test:unit:_run": "mocha --recursive --reporter spec --exit $@ test/unit/js",
|
||||
"test:unit": "npm run test:unit:_run -- --grep=$MOCHA_GREP",
|
||||
"nodemon": "node --watch app.js",
|
||||
"lint": "eslint --max-warnings 0 --format unix .",
|
||||
@@ -21,6 +21,7 @@
|
||||
"dependencies": {
|
||||
"@overleaf/logger": "*",
|
||||
"@overleaf/metrics": "*",
|
||||
"@overleaf/mongo-utils": "*",
|
||||
"@overleaf/settings": "*",
|
||||
"async": "^3.2.5",
|
||||
"body-parser": "^1.20.3",
|
||||
|
||||
@@ -86,7 +86,6 @@ test: format lint typecheck shellcheck test_unit test_acceptance
|
||||
test_unit:
|
||||
ifneq (,$(wildcard test/unit))
|
||||
$(DOCKER_COMPOSE_TEST_UNIT) run --rm test_unit
|
||||
$(MAKE) test_unit_clean
|
||||
endif
|
||||
|
||||
test_clean: test_unit_clean
|
||||
|
||||
@@ -365,6 +365,10 @@ async function clearCachedHistoryId(projectId) {
|
||||
await rclient.del(key)
|
||||
}
|
||||
|
||||
async function cleanupTestRedis() {
|
||||
await redis.cleanupTestRedis(rclient)
|
||||
}
|
||||
|
||||
// EXPORTS
|
||||
|
||||
const countUnprocessedUpdatesCb = callbackify(countUnprocessedUpdates)
|
||||
@@ -442,4 +446,5 @@ export const promises = {
|
||||
getCachedHistoryId,
|
||||
setCachedHistoryId,
|
||||
clearCachedHistoryId,
|
||||
cleanupTestRedis,
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import Metrics from '@overleaf/metrics'
|
||||
import MongoUtils from '@overleaf/mongo-utils'
|
||||
import Settings from '@overleaf/settings'
|
||||
import mongodb from 'mongodb-legacy'
|
||||
const { MongoClient, ObjectId } = mongodb
|
||||
|
||||
/**
|
||||
* @import { ProjectHistoryFailure } from './mongo-types.ts'
|
||||
* @import { ProjectHistoryFailure } from './mongo-types'
|
||||
*/
|
||||
|
||||
export { ObjectId }
|
||||
@@ -17,6 +18,10 @@ const mongoDb = mongoClient.db()
|
||||
|
||||
Metrics.mongodb.monitor(mongoClient)
|
||||
|
||||
async function cleanupTestDatabase() {
|
||||
await MongoUtils.cleanupTestDatabase(mongoClient)
|
||||
}
|
||||
|
||||
export const db = {
|
||||
deletedProjects: mongoDb.collection('deletedProjects'),
|
||||
projects: mongoDb.collection('projects'),
|
||||
@@ -24,4 +29,5 @@ export const db = {
|
||||
projectHistoryFailures: mongoDb.collection('projectHistoryFailures'),
|
||||
projectHistoryLabels: mongoDb.collection('projectHistoryLabels'),
|
||||
projectHistorySyncState: mongoDb.collection('projectHistorySyncState'),
|
||||
cleanupTestDatabase,
|
||||
}
|
||||
|
||||
@@ -6,10 +6,23 @@ services:
|
||||
test_unit:
|
||||
image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER
|
||||
user: node
|
||||
volumes:
|
||||
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
|
||||
entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
|
||||
command: npm run test:unit:_run
|
||||
environment:
|
||||
MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
|
||||
NODE_ENV: test
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
REDIS_HOST: redis_test
|
||||
QUEUES_REDIS_HOST: redis_test
|
||||
HISTORY_REDIS_HOST: redis_test
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis_test
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_started
|
||||
redis_test:
|
||||
condition: service_healthy
|
||||
|
||||
|
||||
test_acceptance:
|
||||
@@ -17,10 +30,10 @@ services:
|
||||
image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER
|
||||
environment:
|
||||
ELASTIC_SEARCH_DSN: es:9200
|
||||
REDIS_HOST: redis
|
||||
QUEUES_REDIS_HOST: redis
|
||||
HISTORY_REDIS_HOST: redis
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis
|
||||
REDIS_HOST: redis_test
|
||||
QUEUES_REDIS_HOST: redis_test
|
||||
HISTORY_REDIS_HOST: redis_test
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis_test
|
||||
MONGO_HOST: mongo
|
||||
POSTGRES_HOST: postgres
|
||||
MOCHA_GREP: ${MOCHA_GREP}
|
||||
@@ -31,7 +44,7 @@ services:
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_started
|
||||
redis:
|
||||
redis_test:
|
||||
condition: service_healthy
|
||||
user: node
|
||||
entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
|
||||
@@ -45,7 +58,7 @@ services:
|
||||
- ./:/tmp/build/
|
||||
command: tar -czf /tmp/build/build.tar.gz --exclude=build.tar.gz --exclude-vcs .
|
||||
user: root
|
||||
redis:
|
||||
redis_test:
|
||||
image: redis:7.4.3
|
||||
healthcheck:
|
||||
test: ping="$$(redis-cli ping)" && [ "$$ping" = 'PONG' ]
|
||||
|
||||
@@ -9,14 +9,26 @@ services:
|
||||
- .:/overleaf/services/project-history
|
||||
- ../../node_modules:/overleaf/node_modules
|
||||
- ../../libraries:/overleaf/libraries
|
||||
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
|
||||
working_dir: /overleaf/services/project-history
|
||||
environment:
|
||||
MOCHA_GREP: ${MOCHA_GREP}
|
||||
LOG_LEVEL: ${LOG_LEVEL:-}
|
||||
MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
|
||||
NODE_ENV: test
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
REDIS_HOST: redis_test
|
||||
HISTORY_REDIS_HOST: redis_test
|
||||
QUEUES_REDIS_HOST: redis_test
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis_test
|
||||
entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
|
||||
command: npm run --silent test:unit
|
||||
user: node
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_started
|
||||
redis_test:
|
||||
condition: service_healthy
|
||||
|
||||
test_acceptance:
|
||||
image: node:22.18.0
|
||||
@@ -28,10 +40,10 @@ services:
|
||||
working_dir: /overleaf/services/project-history
|
||||
environment:
|
||||
ELASTIC_SEARCH_DSN: es:9200
|
||||
REDIS_HOST: redis
|
||||
HISTORY_REDIS_HOST: redis
|
||||
QUEUES_REDIS_HOST: redis
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis
|
||||
REDIS_HOST: redis_test
|
||||
HISTORY_REDIS_HOST: redis_test
|
||||
QUEUES_REDIS_HOST: redis_test
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis_test
|
||||
MONGO_HOST: mongo
|
||||
POSTGRES_HOST: postgres
|
||||
MOCHA_GREP: ${MOCHA_GREP}
|
||||
@@ -42,12 +54,12 @@ services:
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_started
|
||||
redis:
|
||||
redis_test:
|
||||
condition: service_healthy
|
||||
entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
|
||||
command: npm run --silent test:acceptance
|
||||
|
||||
redis:
|
||||
redis_test:
|
||||
image: redis:7.4.3
|
||||
healthcheck:
|
||||
test: ping=$$(redis-cli ping) && [ "$$ping" = 'PONG' ]
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"start": "node app.js",
|
||||
"nodemon": "node --watch app.js",
|
||||
"test:acceptance:_run": "mocha --loader=esmock --recursive --reporter spec --timeout 15000 --exit $@ test/acceptance/js",
|
||||
"test:unit:_run": "mocha --loader=esmock --recursive --reporter spec $@ test/unit/js",
|
||||
"test:unit:_run": "mocha --loader=esmock --recursive --reporter spec --exit $@ test/unit/js",
|
||||
"lint": "eslint --max-warnings 0 --format unix .",
|
||||
"format": "prettier --list-different $PWD/'**/*.*js'",
|
||||
"format:fix": "prettier --write $PWD/'**/*.*js'",
|
||||
@@ -21,6 +21,7 @@
|
||||
"@overleaf/fetch-utils": "*",
|
||||
"@overleaf/logger": "*",
|
||||
"@overleaf/metrics": "*",
|
||||
"@overleaf/mongo-utils": "*",
|
||||
"@overleaf/o-error": "*",
|
||||
"@overleaf/promise-utils": "*",
|
||||
"@overleaf/redis-wrapper": "*",
|
||||
|
||||
@@ -86,7 +86,6 @@ test: format lint typecheck shellcheck test_unit test_acceptance
|
||||
test_unit:
|
||||
ifneq (,$(wildcard test/unit))
|
||||
$(DOCKER_COMPOSE_TEST_UNIT) run --rm test_unit
|
||||
$(MAKE) test_unit_clean
|
||||
endif
|
||||
|
||||
test_clean: test_unit_clean
|
||||
|
||||
@@ -8,8 +8,16 @@ services:
|
||||
user: node
|
||||
command: npm run test:unit:_run
|
||||
environment:
|
||||
MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
|
||||
NODE_ENV: test
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
REDIS_HOST: redis_test
|
||||
QUEUES_REDIS_HOST: redis_test
|
||||
HISTORY_REDIS_HOST: redis_test
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis_test
|
||||
depends_on:
|
||||
redis_test:
|
||||
condition: service_healthy
|
||||
|
||||
|
||||
test_acceptance:
|
||||
@@ -17,17 +25,17 @@ services:
|
||||
image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER
|
||||
environment:
|
||||
ELASTIC_SEARCH_DSN: es:9200
|
||||
REDIS_HOST: redis
|
||||
QUEUES_REDIS_HOST: redis
|
||||
HISTORY_REDIS_HOST: redis
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis
|
||||
REDIS_HOST: redis_test
|
||||
QUEUES_REDIS_HOST: redis_test
|
||||
HISTORY_REDIS_HOST: redis_test
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis_test
|
||||
MONGO_HOST: mongo
|
||||
POSTGRES_HOST: postgres
|
||||
MOCHA_GREP: ${MOCHA_GREP}
|
||||
NODE_ENV: test
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
depends_on:
|
||||
redis:
|
||||
redis_test:
|
||||
condition: service_healthy
|
||||
user: node
|
||||
command: npm run test:acceptance
|
||||
@@ -40,7 +48,7 @@ services:
|
||||
- ./:/tmp/build/
|
||||
command: tar -czf /tmp/build/build.tar.gz --exclude=build.tar.gz --exclude-vcs .
|
||||
user: root
|
||||
redis:
|
||||
redis_test:
|
||||
image: redis:7.4.3
|
||||
healthcheck:
|
||||
test: ping="$$(redis-cli ping)" && [ "$$ping" = 'PONG' ]
|
||||
|
||||
@@ -13,10 +13,18 @@ services:
|
||||
environment:
|
||||
MOCHA_GREP: ${MOCHA_GREP}
|
||||
LOG_LEVEL: ${LOG_LEVEL:-}
|
||||
MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
|
||||
NODE_ENV: test
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
REDIS_HOST: redis_test
|
||||
HISTORY_REDIS_HOST: redis_test
|
||||
QUEUES_REDIS_HOST: redis_test
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis_test
|
||||
command: npm run --silent test:unit
|
||||
user: node
|
||||
depends_on:
|
||||
redis_test:
|
||||
condition: service_healthy
|
||||
|
||||
test_acceptance:
|
||||
image: node:22.18.0
|
||||
@@ -27,10 +35,10 @@ services:
|
||||
working_dir: /overleaf/services/real-time
|
||||
environment:
|
||||
ELASTIC_SEARCH_DSN: es:9200
|
||||
REDIS_HOST: redis
|
||||
HISTORY_REDIS_HOST: redis
|
||||
QUEUES_REDIS_HOST: redis
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis
|
||||
REDIS_HOST: redis_test
|
||||
HISTORY_REDIS_HOST: redis_test
|
||||
QUEUES_REDIS_HOST: redis_test
|
||||
ANALYTICS_QUEUES_REDIS_HOST: redis_test
|
||||
MONGO_HOST: mongo
|
||||
POSTGRES_HOST: postgres
|
||||
MOCHA_GREP: ${MOCHA_GREP}
|
||||
@@ -39,11 +47,11 @@ services:
|
||||
NODE_OPTIONS: "--unhandled-rejections=strict"
|
||||
user: node
|
||||
depends_on:
|
||||
redis:
|
||||
redis_test:
|
||||
condition: service_healthy
|
||||
command: npm run --silent test:acceptance
|
||||
|
||||
redis:
|
||||
redis_test:
|
||||
image: redis:7.4.3
|
||||
healthcheck:
|
||||
test: ping=$$(redis-cli ping) && [ "$$ping" = 'PONG' ]
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"start": "node app.js",
|
||||
"test:acceptance:_run": "mocha --recursive --reporter spec --timeout 15000 --exit $@ test/acceptance/js",
|
||||
"test:acceptance": "npm run test:acceptance:_run -- --grep=$MOCHA_GREP",
|
||||
"test:unit:_run": "mocha --recursive --reporter spec $@ test/unit/js",
|
||||
"test:unit:_run": "mocha --recursive --reporter spec --exit $@ test/unit/js",
|
||||
"test:unit": "npm run test:unit:_run -- --grep=$MOCHA_GREP",
|
||||
"nodemon": "node --watch app.js",
|
||||
"lint": "eslint --max-warnings 0 --format unix .",
|
||||
|
||||
@@ -20,18 +20,7 @@ function client(feature) {
|
||||
|
||||
async function cleanupTestRedis() {
|
||||
const rclient = client()
|
||||
ensureTestRedis(rclient)
|
||||
await rclient.flushall()
|
||||
}
|
||||
|
||||
function ensureTestRedis(rclient) {
|
||||
const host = rclient.options.host
|
||||
const env = process.env.NODE_ENV
|
||||
if (host !== 'redis_test' || env !== 'test') {
|
||||
throw new Error(
|
||||
`Refusing to clear Redis instance '${host}' in environment '${env}'`
|
||||
)
|
||||
}
|
||||
await redis.cleanupTestRedis(rclient)
|
||||
}
|
||||
|
||||
module.exports = { client, cleanupTestRedis }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
const mongodb = require('mongodb-legacy')
|
||||
const OError = require('@overleaf/o-error')
|
||||
const Settings = require('@overleaf/settings')
|
||||
const MongoUtils = require('@overleaf/mongo-utils')
|
||||
const Mongoose = require('./Mongoose')
|
||||
const { addConnectionDrainer } = require('./GracefulShutdown')
|
||||
|
||||
@@ -93,32 +94,11 @@ async function getCollectionNames() {
|
||||
}
|
||||
|
||||
async function cleanupTestDatabase() {
|
||||
ensureTestDatabase()
|
||||
const collectionNames = await getCollectionNames()
|
||||
const collections = []
|
||||
for (const name of collectionNames) {
|
||||
if (name in db && name !== 'migrations') {
|
||||
collections.push(db[name])
|
||||
}
|
||||
}
|
||||
await Promise.all(collections.map(coll => coll.deleteMany({})))
|
||||
await MongoUtils.cleanupTestDatabase(mongoClient)
|
||||
}
|
||||
|
||||
async function dropTestDatabase() {
|
||||
ensureTestDatabase()
|
||||
await mongoClient.db().dropDatabase()
|
||||
}
|
||||
|
||||
function ensureTestDatabase() {
|
||||
const internalDb = mongoClient.db()
|
||||
const dbName = internalDb.databaseName
|
||||
const env = process.env.NODE_ENV
|
||||
|
||||
if (dbName !== 'test-overleaf' || env !== 'test') {
|
||||
throw new OError(
|
||||
`Refusing to clear database '${dbName}' in environment '${env}'`
|
||||
)
|
||||
}
|
||||
await MongoUtils.dropTestDatabase(mongoClient)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user