Further update tests after startup refactor (#11521)

- Adds config.lazysockets to prevent listening to the network
- Fixes modlog tests
This commit is contained in:
Slayer95 2026-01-25 07:58:21 -05:00 committed by GitHub
parent 712867050c
commit b0dc94f196
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 59 additions and 45 deletions

View File

@ -25,6 +25,15 @@ exports.bindaddress = '0.0.0.0';
*/ */
exports.wsdeflate = null; exports.wsdeflate = null;
/**
* lazysockets - disables eager initialization of network services
* Turn this on if you'd prefer to manually connect Showdown to the network,
* or you intend to run it offline.
*
* @type {boolean}
*/
exports.lazysockets = false;
/* /*
// example: // example:
exports.wsdeflate = { exports.wsdeflate = {

View File

@ -167,7 +167,7 @@ export class FriendsDatabase {
} }
private async query(input: DatabaseRequest) { private async query(input: DatabaseRequest) {
const process = PM.acquire(); const process = PM.acquire();
if (!process || !Config.usesqlite) { if (!process || !Config.usesqlite || !Config.usesqlitefriends) {
return null; return null;
} }
const result = await process.query(input); const result = await process.query(input);
@ -431,7 +431,7 @@ export const PM = new ProcessManager.QueryProcessManager<DatabaseRequest, Databa
if (!PM.isParentProcess) { if (!PM.isParentProcess) {
ConfigLoader.ensureLoaded(); ConfigLoader.ensureLoaded();
if (Config.usesqlite) { if (Config.usesqlite && Config.usesqlitefriends) {
FriendsDatabase.setupDatabase(); FriendsDatabase.setupDatabase();
} }
global.Monitor = { global.Monitor = {

View File

@ -127,7 +127,9 @@ function setupGlobals() {
global.TeamValidatorAsync = TeamValidatorAsync; global.TeamValidatorAsync = TeamValidatorAsync;
global.Sockets = Sockets; global.Sockets = Sockets;
Sockets.start(Config.subprocessescache); if (!Config.lazysockets) {
Sockets.start(Config.subprocessescache);
}
} }
export const readyPromise = cleanupStale().then(() => { export const readyPromise = cleanupStale().then(() => {

View File

@ -29,12 +29,16 @@ config.crashguard = false;
config.watchconfig = false; config.watchconfig = false;
// Don't try to write to file system // Don't try to write to file system
config.nofswriting = true; config.nofswriting = true;
// allow renaming without a token // Don't try to listen to the network
config.lazysockets = true;
// Allow renaming without a token
config.noguestsecurity = true; config.noguestsecurity = true;
// Test a normal ladder // Test a normal ladder
config.fakeladder = false; config.fakeladder = false;
// Don't log monitor messages to the console (necessary so that chat monitor tests don't clog up stdout) // Don't log monitor messages to the console (necessary so that chat monitor tests don't clog up stdout)
config.loglevel = 3; config.loglevel = 3;
// If sqlite is enabled at all, run tests in server/modlog
config.usesqlitemodlog = true;
require('./../dist/lib/process-manager').ProcessManager.disabled = true; require('./../dist/lib/process-manager').ProcessManager.disabled = true;

View File

@ -8,7 +8,7 @@ const assert = require('../../assert');
describe.skip("Friends lists", () => { describe.skip("Friends lists", () => {
const { FriendsDatabase } = require('../../../dist/server/friends'); const { FriendsDatabase } = require('../../../dist/server/friends');
const test = (Config.usesqlite ? it : it.skip); const test = (Config.usesqlite && Config.usesqlitefriends ? it : it.skip);
test("Should properly setup database", () => { test("Should properly setup database", () => {
assert.doesNotThrow(() => FriendsDatabase.setupDatabase(':memory:')); assert.doesNotThrow(() => FriendsDatabase.setupDatabase(':memory:'));
}); });

View File

@ -5,12 +5,8 @@
'use strict'; 'use strict';
const ModlogConstructor = Config.usesqlite ? (require('../../dist/server/modlog')).Modlog : null;
const modlog = ModlogConstructor ? new ModlogConstructor(':memory:', {}) : null;
const assert = require('assert').strict; const assert = require('assert').strict;
Config.usesqlitemodlog = true;
const DATASET_A = [ const DATASET_A = [
{ action: 'ROOMBAN', userid: 'sometroll', ip: '127.0.0.1', loggedBy: 'annika', note: 'FIRST ENTRY', time: 1 }, { action: 'ROOMBAN', userid: 'sometroll', ip: '127.0.0.1', loggedBy: 'annika', note: 'FIRST ENTRY', time: 1 },
{ action: 'LOCK', userid: 'sometroll', ip: '127.0.0.1', loggedBy: 'annika', note: 'ENTRY 2', time: 2 }, { action: 'LOCK', userid: 'sometroll', ip: '127.0.0.1', loggedBy: 'annika', note: 'ENTRY 2', time: 2 },
@ -38,23 +34,26 @@ async function lastLine(database, roomid) {
return database.get(prepared, [roomid]); return database.get(prepared, [roomid]);
} }
(Config.usesqlite ? describe : describe.skip)('Modlog', () => { (Config.usesqlite && Config.usesqlitemodlog ? describe : describe.skip)('Modlog', () => {
before(async () => { before(async () => {
if (modlog.readyPromise) await modlog.readyPromise; if (Rooms.Modlog.readyPromise) {
await Rooms.Modlog.readyPromise;
}
if (!Rooms.Modlog.databaseReady) throw new Error(`Failed to ready up modlog database`);
}); });
describe('Modlog#prepareSQLSearch', () => { describe('Modlog#prepareSQLSearch', () => {
it('should respect the maxLines parameter', async () => { it('should respect the maxLines parameter', async () => {
const query = modlog.prepareSQLSearch(['lobby'], 1337, false, { note: [], user: [], ip: [], action: [], actionTaker: [] }); const query = Rooms.Modlog.prepareSQLSearch(['lobby'], 1337, false, { note: [], user: [], ip: [], action: [], actionTaker: [] });
assert(query.queryText.endsWith('LIMIT ?')); assert(query.queryText.endsWith('LIMIT ?'));
assert(query.args.includes(1337)); assert(query.args.includes(1337));
const noMaxLines = modlog.prepareSQLSearch(['lobby'], 0, false, { note: [], user: [], ip: [], action: [], actionTaker: [] }); const noMaxLines = Rooms.Modlog.prepareSQLSearch(['lobby'], 0, false, { note: [], user: [], ip: [], action: [], actionTaker: [] });
assert(!noMaxLines.queryText.includes('LIMIT')); assert(!noMaxLines.queryText.includes('LIMIT'));
}); });
it('should attempt to respect onlyPunishments', async () => { it('should attempt to respect onlyPunishments', async () => {
const query = modlog.prepareSQLSearch(['lobby'], 0, true, { note: [], user: [], ip: [], action: [], actionTaker: [] }); const query = Rooms.Modlog.prepareSQLSearch(['lobby'], 0, true, { note: [], user: [], ip: [], action: [], actionTaker: [] });
assert(query.queryText.includes('action IN (')); assert(query.queryText.includes('action IN ('));
assert(query.args.includes('WEEKLOCK')); assert(query.args.includes('WEEKLOCK'));
}); });
@ -62,20 +61,20 @@ async function lastLine(database, roomid) {
describe('Modlog#getSharedID', () => { describe('Modlog#getSharedID', () => {
it('should detect shared modlogs', () => { it('should detect shared modlogs', () => {
assert(modlog.getSharedID('battle-gen8randombattle-42')); assert(Rooms.Modlog.getSharedID('battle-gen8randombattle-42'));
assert(modlog.getSharedID('groupchat-annika-shitposting')); assert(Rooms.Modlog.getSharedID('groupchat-annika-shitposting'));
assert(modlog.getSharedID('help-mePleaseIAmTrappedInAUnitTestFactory')); assert(Rooms.Modlog.getSharedID('help-mePleaseIAmTrappedInAUnitTestFactory'));
assert(!modlog.getSharedID('1v1')); assert(!Rooms.Modlog.getSharedID('1v1'));
assert(!modlog.getSharedID('development')); assert(!Rooms.Modlog.getSharedID('development'));
}); });
}); });
describe('Modlog#write', () => { describe('Modlog#write', () => {
it('should write messages serially to the modlog', async () => { it('should write messages serially to the modlog', async () => {
await modlog.write('development', { note: 'This message is logged first', action: 'UNITTEST' }); await Rooms.Modlog.write('development', { note: 'This message is logged first', action: 'UNITTEST' });
await modlog.write('development', { note: 'This message is logged second', action: 'UNITTEST' }); await Rooms.Modlog.write('development', { note: 'This message is logged second', action: 'UNITTEST' });
const lines = await modlog.database.all(await modlog.database.prepare( const lines = await Rooms.Modlog.database.all(await Rooms.Modlog.database.prepare(
// Order by modlog_id since the writes most likely happen at the same second // Order by modlog_id since the writes most likely happen at the same second
`SELECT * FROM modlog WHERE roomid = 'development' ORDER BY modlog_id DESC LIMIT 2` `SELECT * FROM modlog WHERE roomid = 'development' ORDER BY modlog_id DESC LIMIT 2`
)); ));
@ -85,8 +84,8 @@ async function lastLine(database, roomid) {
}); });
it('should use overrideID if specified', async () => { it('should use overrideID if specified', async () => {
await modlog.write('battle-gen8randombattle-1337', { note: "I'm testing overrideID", action: 'UNITTEST' }, 'heyadora'); await Rooms.Modlog.write('battle-gen8randombattle-1337', { note: "I'm testing overrideID", action: 'UNITTEST' }, 'heyadora');
const line = await lastLine(modlog.database, 'battle-gen8randombattle-1337'); const line = await lastLine(Rooms.Modlog.database, 'battle-gen8randombattle-1337');
assert.equal(line.note, "I'm testing overrideID"); assert.equal(line.note, "I'm testing overrideID");
assert.equal(line.visual_roomid, 'heyadora'); assert.equal(line.visual_roomid, 'heyadora');
}); });
@ -96,17 +95,17 @@ async function lastLine(database, roomid) {
it('should rename modlogs', async () => { it('should rename modlogs', async () => {
const entry = { note: 'This is in a modlog that will be renamed!', action: 'UNITTEST' }; const entry = { note: 'This is in a modlog that will be renamed!', action: 'UNITTEST' };
await modlog.write('oldroom', entry); await Rooms.Modlog.write('oldroom', entry);
await modlog.rename('oldroom', 'newroom'); await Rooms.Modlog.rename('oldroom', 'newroom');
const line = await lastLine(modlog.database, 'newroom'); const line = await lastLine(Rooms.Modlog.database, 'newroom');
assert.equal(entry.action, line.action); assert.equal(entry.action, line.action);
assert.equal(entry.note, line.note); assert.equal(entry.note, line.note);
const newEntry = { note: 'This modlog has been renamed!', action: 'UNITTEST' }; const newEntry = { note: 'This modlog has been renamed!', action: 'UNITTEST' };
await modlog.write('newroom', newEntry); await Rooms.Modlog.write('newroom', newEntry);
const newLine = await lastLine(modlog.database, 'newroom'); const newLine = await lastLine(Rooms.Modlog.database, 'newroom');
assert.equal(newEntry.action, newLine.action); assert.equal(newEntry.action, newLine.action);
assert.equal(newEntry.note, newLine.note); assert.equal(newEntry.note, newLine.note);
@ -116,23 +115,23 @@ async function lastLine(database, roomid) {
describe('Modlog#search', () => { describe('Modlog#search', () => {
before(async () => { before(async () => {
for (const entry of DATASET_A) { for (const entry of DATASET_A) {
await modlog.write('readingtest', entry); await Rooms.Modlog.write('readingtest', entry);
} }
for (const entry of DATASET_B) { for (const entry of DATASET_B) {
await modlog.write('readingtest2', entry); await Rooms.Modlog.write('readingtest2', entry);
} }
}); });
it('should be capable of reading the entire modlog file', async () => { it('should be capable of reading the entire modlog file', async () => {
const results = await modlog.search('readingtest2', { note: [], user: [], ip: [], action: [], actionTaker: [] }, 10000); const results = await Rooms.Modlog.search('readingtest2', { note: [], user: [], ip: [], action: [], actionTaker: [] }, 10000);
assert.equal(results.results.length, DATASET_B.length); assert.equal(results.results.length, DATASET_B.length);
}); });
it('user searches should be case-insensitive', async () => { it('user searches should be case-insensitive', async () => {
const notExactUpper = await modlog.search('readingtest', { user: [{ search: 'sOmETRoll', isExact: false }], note: [], ip: [], action: [], actionTaker: [] }); const notExactUpper = await Rooms.Modlog.search('readingtest', { user: [{ search: 'sOmETRoll', isExact: false }], note: [], ip: [], action: [], actionTaker: [] });
const notExactLower = await modlog.search('readingtest', { user: [{ search: 'sometroll', isExact: false }], note: [], ip: [], action: [], actionTaker: [] }); const notExactLower = await Rooms.Modlog.search('readingtest', { user: [{ search: 'sometroll', isExact: false }], note: [], ip: [], action: [], actionTaker: [] });
const exactUpper = await modlog.search('readingtest', { user: [{ search: 'sOMEtroLL', isExact: true }], note: [], ip: [], action: [], actionTaker: [] }); const exactUpper = await Rooms.Modlog.search('readingtest', { user: [{ search: 'sOMEtroLL', isExact: true }], note: [], ip: [], action: [], actionTaker: [] });
const exactLower = await modlog.search('readingtest', { user: [{ search: 'sometroll', isExact: true }], note: [], ip: [], action: [], actionTaker: [] }); const exactLower = await Rooms.Modlog.search('readingtest', { user: [{ search: 'sometroll', isExact: true }], note: [], ip: [], action: [], actionTaker: [] });
assert.deepEqual(notExactUpper.results, notExactLower.results); assert.deepEqual(notExactUpper.results, notExactLower.results);
assert.deepEqual(exactUpper.results, exactLower.results); assert.deepEqual(exactUpper.results, exactLower.results);
@ -141,17 +140,17 @@ async function lastLine(database, roomid) {
// isExact is currently set up to search for the entire note equalling the search // isExact is currently set up to search for the entire note equalling the search
// this could be redesigned, but is what we currently test for. // this could be redesigned, but is what we currently test for.
it('note searches should respect isExact', async () => { it('note searches should respect isExact', async () => {
const notExact = await modlog.search('readingtest', { note: [{ search: 'has man', isExact: false }], user: [], ip: [], action: [], actionTaker: [] }); const notExact = await Rooms.Modlog.search('readingtest', { note: [{ search: 'has man', isExact: false }], user: [], ip: [], action: [], actionTaker: [] });
const exact = await modlog.search('readingtest', { note: [{ search: 'has man', isExact: true }], user: [], ip: [], action: [], actionTaker: [] }); const exact = await Rooms.Modlog.search('readingtest', { note: [{ search: 'has man', isExact: true }], user: [], ip: [], action: [], actionTaker: [] });
assert.equal(exact.results.length, 0); assert.equal(exact.results.length, 0);
assert(notExact.results.length); assert(notExact.results.length);
}); });
it('should be LIFO (last-in, first-out)', async () => { it('should be LIFO (last-in, first-out)', async () => {
await modlog.write('lifotest', { note: 'firstwrite', action: 'UNITTEST', timestamp: 1 }); await Rooms.Modlog.write('lifotest', { note: 'firstwrite', action: 'UNITTEST', timestamp: 1 });
await modlog.write('lifotest', { note: 'secondwrite', action: 'UNITTEST', timestamp: 2 }); await Rooms.Modlog.write('lifotest', { note: 'secondwrite', action: 'UNITTEST', timestamp: 2 });
const search = await modlog.search('lifotest'); const search = await Rooms.Modlog.search('lifotest');
// secondwrite was last in, so it should be first out (results[0]) // secondwrite was last in, so it should be first out (results[0])
assert.notEqual(search.results[0].note, 'firstwrite'); assert.notEqual(search.results[0].note, 'firstwrite');
@ -163,8 +162,8 @@ async function lastLine(database, roomid) {
}); });
it('should support limiting the number of responses', async () => { it('should support limiting the number of responses', async () => {
const unlimited = await modlog.search('readingtest'); const unlimited = await Rooms.Modlog.search('readingtest');
const limited = await modlog.search('readingtest', { note: [], user: [], ip: [], action: [], actionTaker: [] }, 5); const limited = await Rooms.Modlog.search('readingtest', { note: [], user: [], ip: [], action: [], actionTaker: [] }, 5);
assert.equal(limited.results.length, 5); assert.equal(limited.results.length, 5);
assert(unlimited.results.length > limited.results.length); assert(unlimited.results.length > limited.results.length);
@ -180,8 +179,8 @@ async function lastLine(database, roomid) {
}); });
it('should support filtering out non-punishment-related logs', async () => { it('should support filtering out non-punishment-related logs', async () => {
const all = (await modlog.search('readingtest2', { note: [], user: [], ip: [], action: [], actionTaker: [] }, 20, false)).results; const all = (await Rooms.Modlog.search('readingtest2', { note: [], user: [], ip: [], action: [], actionTaker: [] }, 20, false)).results;
const onlyPunishments = (await modlog.search('readingtest2', { note: [], user: [], ip: [], action: [], actionTaker: [] }, 20, true)).results; const onlyPunishments = (await Rooms.Modlog.search('readingtest2', { note: [], user: [], ip: [], action: [], actionTaker: [] }, 20, true)).results;
assert(all.length > onlyPunishments.length); assert(all.length > onlyPunishments.length);
assert.equal( assert.equal(