diff --git a/config/config-example.js b/config/config-example.js index 58059876c2..8289fe3b6c 100644 --- a/config/config-example.js +++ b/config/config-example.js @@ -25,6 +25,15 @@ exports.bindaddress = '0.0.0.0'; */ 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: exports.wsdeflate = { diff --git a/server/friends.ts b/server/friends.ts index 5a76237267..30bc8a88fd 100644 --- a/server/friends.ts +++ b/server/friends.ts @@ -167,7 +167,7 @@ export class FriendsDatabase { } private async query(input: DatabaseRequest) { const process = PM.acquire(); - if (!process || !Config.usesqlite) { + if (!process || !Config.usesqlite || !Config.usesqlitefriends) { return null; } const result = await process.query(input); @@ -431,7 +431,7 @@ export const PM = new ProcessManager.QueryProcessManager { diff --git a/test/main.js b/test/main.js index 946a9dcf7c..5c2495e002 100644 --- a/test/main.js +++ b/test/main.js @@ -29,12 +29,16 @@ config.crashguard = false; config.watchconfig = false; // Don't try to write to file system 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; // Test a normal ladder config.fakeladder = false; // Don't log monitor messages to the console (necessary so that chat monitor tests don't clog up stdout) 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; diff --git a/test/server/chat-plugins/friends.js b/test/server/chat-plugins/friends.js index 7eb04b449e..25aec02464 100644 --- a/test/server/chat-plugins/friends.js +++ b/test/server/chat-plugins/friends.js @@ -8,7 +8,7 @@ const assert = require('../../assert'); describe.skip("Friends lists", () => { 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", () => { assert.doesNotThrow(() => FriendsDatabase.setupDatabase(':memory:')); }); diff --git a/test/server/modlog.js b/test/server/modlog.js index eb5b751a40..a4ab3835ce 100644 --- a/test/server/modlog.js +++ b/test/server/modlog.js @@ -5,12 +5,8 @@ 'use strict'; -const ModlogConstructor = Config.usesqlite ? (require('../../dist/server/modlog')).Modlog : null; -const modlog = ModlogConstructor ? new ModlogConstructor(':memory:', {}) : null; const assert = require('assert').strict; -Config.usesqlitemodlog = true; - const DATASET_A = [ { 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 }, @@ -38,23 +34,26 @@ async function lastLine(database, roomid) { return database.get(prepared, [roomid]); } -(Config.usesqlite ? describe : describe.skip)('Modlog', () => { +(Config.usesqlite && Config.usesqlitemodlog ? describe : describe.skip)('Modlog', () => { 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', () => { 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.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')); }); 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.args.includes('WEEKLOCK')); }); @@ -62,20 +61,20 @@ async function lastLine(database, roomid) { describe('Modlog#getSharedID', () => { it('should detect shared modlogs', () => { - assert(modlog.getSharedID('battle-gen8randombattle-42')); - assert(modlog.getSharedID('groupchat-annika-shitposting')); - assert(modlog.getSharedID('help-mePleaseIAmTrappedInAUnitTestFactory')); + assert(Rooms.Modlog.getSharedID('battle-gen8randombattle-42')); + assert(Rooms.Modlog.getSharedID('groupchat-annika-shitposting')); + assert(Rooms.Modlog.getSharedID('help-mePleaseIAmTrappedInAUnitTestFactory')); - assert(!modlog.getSharedID('1v1')); - assert(!modlog.getSharedID('development')); + assert(!Rooms.Modlog.getSharedID('1v1')); + assert(!Rooms.Modlog.getSharedID('development')); }); }); describe('Modlog#write', () => { it('should write messages serially to the modlog', async () => { - await modlog.write('development', { note: 'This message is logged first', action: 'UNITTEST' }); - await modlog.write('development', { note: 'This message is logged second', action: 'UNITTEST' }); - const lines = await modlog.database.all(await modlog.database.prepare( + await Rooms.Modlog.write('development', { note: 'This message is logged first', action: 'UNITTEST' }); + await Rooms.Modlog.write('development', { note: 'This message is logged second', action: 'UNITTEST' }); + 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 `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 () => { - await modlog.write('battle-gen8randombattle-1337', { note: "I'm testing overrideID", action: 'UNITTEST' }, 'heyadora'); - const line = await lastLine(modlog.database, 'battle-gen8randombattle-1337'); + await Rooms.Modlog.write('battle-gen8randombattle-1337', { note: "I'm testing overrideID", action: 'UNITTEST' }, 'heyadora'); + const line = await lastLine(Rooms.Modlog.database, 'battle-gen8randombattle-1337'); assert.equal(line.note, "I'm testing overrideID"); assert.equal(line.visual_roomid, 'heyadora'); }); @@ -96,17 +95,17 @@ async function lastLine(database, roomid) { it('should rename modlogs', async () => { const entry = { note: 'This is in a modlog that will be renamed!', action: 'UNITTEST' }; - await modlog.write('oldroom', entry); - await modlog.rename('oldroom', 'newroom'); - const line = await lastLine(modlog.database, 'newroom'); + await Rooms.Modlog.write('oldroom', entry); + await Rooms.Modlog.rename('oldroom', 'newroom'); + const line = await lastLine(Rooms.Modlog.database, 'newroom'); assert.equal(entry.action, line.action); assert.equal(entry.note, line.note); 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.note, newLine.note); @@ -116,23 +115,23 @@ async function lastLine(database, roomid) { describe('Modlog#search', () => { before(async () => { for (const entry of DATASET_A) { - await modlog.write('readingtest', entry); + await Rooms.Modlog.write('readingtest', entry); } 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 () => { - 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); }); it('user searches should be case-insensitive', async () => { - const notExactUpper = await 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 exactUpper = await 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 notExactUpper = await Rooms.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 Rooms.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(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 // this could be redesigned, but is what we currently test for. it('note searches should respect isExact', async () => { - const notExact = await 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 notExact = await Rooms.Modlog.search('readingtest', { note: [{ search: 'has man', isExact: false }], 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(notExact.results.length); }); it('should be LIFO (last-in, first-out)', async () => { - await modlog.write('lifotest', { note: 'firstwrite', action: 'UNITTEST', timestamp: 1 }); - await modlog.write('lifotest', { note: 'secondwrite', action: 'UNITTEST', timestamp: 2 }); - const search = await modlog.search('lifotest'); + await Rooms.Modlog.write('lifotest', { note: 'firstwrite', action: 'UNITTEST', timestamp: 1 }); + await Rooms.Modlog.write('lifotest', { note: 'secondwrite', action: 'UNITTEST', timestamp: 2 }); + const search = await Rooms.Modlog.search('lifotest'); // secondwrite was last in, so it should be first out (results[0]) 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 () => { - const unlimited = await modlog.search('readingtest'); - const limited = await modlog.search('readingtest', { note: [], user: [], ip: [], action: [], actionTaker: [] }, 5); + const unlimited = await Rooms.Modlog.search('readingtest'); + const limited = await Rooms.Modlog.search('readingtest', { note: [], user: [], ip: [], action: [], actionTaker: [] }, 5); assert.equal(limited.results.length, 5); 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 () => { - const all = (await 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 all = (await Rooms.Modlog.search('readingtest2', { note: [], user: [], ip: [], action: [], actionTaker: [] }, 20, false)).results; + const onlyPunishments = (await Rooms.Modlog.search('readingtest2', { note: [], user: [], ip: [], action: [], actionTaker: [] }, 20, true)).results; assert(all.length > onlyPunishments.length); assert.equal(