Parallelize test running (#166)
* Allow specifying DB file explicitely. * Export config getter/setter instead of object Allows dynamically changing configuration * Remove maxWorker Jest limit, parallelize tests * Remove unnecessary slow step in Dockerfile. * Correct error response during login * Fix setting DB permissions in docker entrypoint --------- Co-authored-by: antanst <>
This commit is contained in:
parent
dad0bd45ff
commit
c24bff1882
16 changed files with 51 additions and 30 deletions
|
|
@ -56,10 +56,10 @@ RUN apk add --no-cache --virtual .runtime-deps \
|
|||
WORKDIR /app
|
||||
|
||||
# Copy backend
|
||||
COPY ./backend/ /app/backend/
|
||||
COPY --chown=app:app ./backend/ /app/backend/
|
||||
RUN chmod +x /app/backend/cmd/start.sh
|
||||
|
||||
COPY ./scripts/docker-entrypoint.sh /app/scripts/docker-entrypoint.sh
|
||||
COPY --chown=app:app ./scripts/docker-entrypoint.sh /app/scripts/docker-entrypoint.sh
|
||||
RUN chmod +x /app/scripts/docker-entrypoint.sh
|
||||
|
||||
# Copy frontend
|
||||
|
|
@ -70,8 +70,7 @@ COPY --from=builder --chown=app:app /app/node_modules ./node_modules
|
|||
COPY --from=builder --chown=app:app /app/package.json /app/
|
||||
|
||||
# Create necessary directories
|
||||
RUN mkdir -p /app/backend/db /app/backend/certs && \
|
||||
chown -R app:app /app
|
||||
RUN mkdir -p /app/backend/db /app/backend/certs
|
||||
|
||||
# Cleanup
|
||||
RUN apk del --no-cache .runtime-deps sqlite openssl curl && \
|
||||
|
|
@ -84,6 +83,7 @@ VOLUME ["/app/backend/db"]
|
|||
EXPOSE 3002
|
||||
|
||||
ENV NODE_ENV=production \
|
||||
DB_FILE="db/production.sqlite3" \
|
||||
PORT=3002 \
|
||||
TUDUDI_INTERNAL_SSL_ENABLED=false \
|
||||
TUDUDI_ALLOWED_ORIGINS="http://localhost:8080,http://localhost:3002,http://127.0.0.1:8080,http://127.0.0.1:3002" \
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ const SequelizeStore = require('connect-session-sequelize')(session.Store);
|
|||
const { sequelize } = require('./models');
|
||||
const { initializeTelegramPolling } = require('./services/telegramInitializer');
|
||||
const taskScheduler = require('./services/taskScheduler');
|
||||
const config = require('./config/config');
|
||||
const { setConfig, getConfig } = require('./config/config');
|
||||
const config = getConfig();
|
||||
|
||||
const app = express();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
DB_FILE="db/production.sqlite3"
|
||||
[ "$NODE_ENV" = "development" ] && DB_FILE="db/development.sqlite3"
|
||||
|
||||
# Check if database exists and create/authenticate
|
||||
if [ ! -f "$DB_FILE" ]; then
|
||||
echo "Creating new database..."
|
||||
|
|
|
|||
|
|
@ -14,9 +14,6 @@ if (
|
|||
const environment = process.env.NODE_ENV;
|
||||
const production = process.env.NODE_ENV === 'production';
|
||||
const projectRootPath = path.join(__dirname, '..'); // backend root path
|
||||
const dbDir = process.env.DATABASE_URL
|
||||
? process.env.DATABASE_URL.replace('sqlite:///', '')
|
||||
: path.join(projectRootPath, 'db');
|
||||
|
||||
const credentials = {
|
||||
google: {
|
||||
|
|
@ -40,9 +37,9 @@ const config = {
|
|||
'http://127.0.0.1:9292',
|
||||
],
|
||||
|
||||
dbDir,
|
||||
|
||||
dbFile: path.join(dbDir, `${environment}.sqlite3`),
|
||||
dbFile:
|
||||
process.env.DB_FILE ||
|
||||
path.join(projectRootPath, 'db', `${environment}.sqlite3`),
|
||||
|
||||
disableScheduler: process.env.DISABLE_SCHEDULER === 'true',
|
||||
|
||||
|
|
@ -72,6 +69,16 @@ const config = {
|
|||
production && process.env.TUDUDI_INTERNAL_SSL_ENABLED === 'true',
|
||||
};
|
||||
|
||||
// Configuration logging removed for cleaner test output
|
||||
console.log(`Using database file '${config.dbFile}'`);
|
||||
|
||||
module.exports = config;
|
||||
function setConfig({ dbFile } = {}) {
|
||||
if (dbFile != null) {
|
||||
config.dbFile = dbFile;
|
||||
}
|
||||
}
|
||||
|
||||
function getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
module.exports = { setConfig, getConfig };
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
require('dotenv').config();
|
||||
const path = require('path');
|
||||
const config = require('./config');
|
||||
const { setConfig, getConfig } = require('../config/config');
|
||||
const config = getConfig();
|
||||
|
||||
module.exports = {
|
||||
development: {
|
||||
dialect: 'sqlite',
|
||||
storage: path.join(config.dbDir, 'development.sqlite3'),
|
||||
storage: config.dbFile,
|
||||
logging: console.log,
|
||||
define: {
|
||||
timestamps: true,
|
||||
|
|
@ -16,7 +17,7 @@ module.exports = {
|
|||
},
|
||||
test: {
|
||||
dialect: 'sqlite',
|
||||
storage: path.join(config.dbDir, 'test.sqlite3'),
|
||||
storage: config.dbFile,
|
||||
logging: false,
|
||||
define: {
|
||||
timestamps: true,
|
||||
|
|
@ -27,7 +28,7 @@ module.exports = {
|
|||
},
|
||||
production: {
|
||||
dialect: 'sqlite',
|
||||
storage: path.join(config.dbDir, 'production.sqlite3'),
|
||||
storage: config.dbFile,
|
||||
logging: false,
|
||||
define: {
|
||||
timestamps: true,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ module.exports = {
|
|||
testEnvironment: 'node',
|
||||
setupFilesAfterEnv: ['<rootDir>/tests/helpers/setup.js'],
|
||||
testMatch: ['<rootDir>/tests/**/*.test.js', '<rootDir>/tests/**/*.spec.js'],
|
||||
maxWorkers: 1,
|
||||
collectCoverageFrom: [
|
||||
'routes/**/*.js',
|
||||
'models/**/*.js',
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
const { DataTypes } = require('sequelize');
|
||||
const sequelize = require('../config/database');
|
||||
const { sequelize } = require('./models');
|
||||
|
||||
const CalendarToken = sequelize.define(
|
||||
'CalendarToken',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
const { Sequelize } = require('sequelize');
|
||||
const path = require('path');
|
||||
const config = require('../config/config');
|
||||
const { getConfig } = require('../config/config');
|
||||
const config = getConfig();
|
||||
|
||||
// Database configuration
|
||||
let dbConfig;
|
||||
|
|
|
|||
|
|
@ -57,6 +57,13 @@ router.post('/login', async (req, res) => {
|
|||
|
||||
req.session.userId = user.id;
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
req.session.save((err) => {
|
||||
if (err) reject(err);
|
||||
else resolve();
|
||||
});
|
||||
});
|
||||
|
||||
res.json({
|
||||
user: {
|
||||
id: user.id,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ const express = require('express');
|
|||
const router = express.Router();
|
||||
const { google } = require('googleapis');
|
||||
const { requireAuth } = require('../middleware/auth');
|
||||
const config = require('../config/config');
|
||||
const { setConfig, getConfig } = require('../config/config');
|
||||
const config = getConfig();
|
||||
|
||||
// Google Calendar configuration
|
||||
const SCOPES = ['https://www.googleapis.com/auth/calendar.readonly'];
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
const path = require('path');
|
||||
const { seedDatabase } = require('../seeders/dev-seeder');
|
||||
const config = require('../config/config');
|
||||
const { setConfig, getConfig } = require('../config/config');
|
||||
const config = getConfig();
|
||||
|
||||
console.log('🌱 Starting development data seeding...');
|
||||
console.log(`📁 Database: ${config.dbFile}`);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ const cron = require('node-cron');
|
|||
const { User } = require('../models');
|
||||
const TaskSummaryService = require('./taskSummaryService');
|
||||
const RecurringTaskService = require('./recurringTaskService');
|
||||
const config = require('../config/config');
|
||||
const { setConfig, getConfig } = require('../config/config');
|
||||
const config = getConfig();
|
||||
|
||||
// Create scheduler state
|
||||
const createSchedulerState = () => ({
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
const telegramPoller = require('./telegramPoller');
|
||||
const { User } = require('../models');
|
||||
const config = require('../config/config');
|
||||
const { setConfig, getConfig } = require('../config/config');
|
||||
const config = getConfig();
|
||||
|
||||
async function initializeTelegramPolling() {
|
||||
if (config.environment === 'test' || config.disableTelegram) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
// Set test environment before importing models
|
||||
process.env.NODE_ENV = 'test';
|
||||
// This file is run once per each Jest worker,
|
||||
// so changing the DB in the beginning of this file
|
||||
// works.
|
||||
|
||||
const testId = require('crypto').randomBytes(4).toString('hex');
|
||||
process.env.DB_FILE = `/tmp/test-${testId}.sqlite3`;
|
||||
const { sequelize } = require('../../models');
|
||||
|
||||
beforeAll(async () => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
const request = require('supertest');
|
||||
const app = require('../../app');
|
||||
const { User } = require('../../models');
|
||||
require('../../models');
|
||||
const { createTestUser } = require('../helpers/testUtils');
|
||||
|
||||
describe('Auth Routes', () => {
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ if [ "$CURRENT_UID" != "$PUID" ] || [ "$CURRENT_GID" != "$PGID" ]; then
|
|||
mkdir -p /app/backend/db /app/backend/certs
|
||||
chown -R app:$TARGET_GROUP /app/backend/db /app/backend/certs
|
||||
chmod 770 /app/backend/db /app/backend/certs
|
||||
chmod 660 "$DB_FILE"
|
||||
|
||||
echo "User configuration completed"
|
||||
else
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue