import { Eltro as t, assert, stub } from 'eltro' import fs from 'fs/promises' import Core from '../core/core.mjs' import Util from '../core/util.mjs' import { createFakeLog } from './helpers.mjs' import StaticProvider from '../core/providers/static.mjs' import lowdb from '../core/db.mjs' const util = new Util(import.meta.url) const log = createFakeLog() let db t.before(function() { return lowdb({}, log, null).then(function(res) { db = res }) }) t.describe('#init()', function() { const assertProviderName = 'Kyousuu Gakku Gogyou Kikan' let core let fakeUtil let fakeProvider let fakeProviderConfig function FakeProvider(config) { fakeProvider(config) this.static = true this.checkConfig = fakeProviderConfig } t.beforeEach(function() { log.error.reset() core = new Core(db, util, log) core.util = fakeUtil = { verifyConfig: stub(), getAppNames: stub().returns([]), } fakeProvider = stub() fakeProviderConfig = stub() Core.providers.set(assertProviderName, FakeProvider) core.isSlave = true }) t.after(function() { return Promise.all([ fs.rm('./log_test_1.log', { recursive: true, force: true }).catch(function() {}), ]) }) t.test('should not call provider checkConfig if isSlave', async function() { const assertAppName = 'Zetsubou' const assertConfig = { [assertAppName]: { provider: assertProviderName, } } db.config = assertConfig process.env.CLUSTER_APP_NAME = assertAppName const assertError = new Error('Shousou') fakeProviderConfig.rejects(assertError) fakeUtil.getAppNames.returns([assertAppName]) await core.init() assert.notOk(fakeProviderConfig.called) }) t.test('should only create an application with the environment app name', async function() { const assertAppName = 'Yasashii Ketsumatsu' const assertAppSecondaryName = 'Big Time' const assertTestString = 'Serozore no Omoi' const assertConfig = { [assertAppName]: { provider: assertProviderName, teststring: assertTestString, }, [assertAppSecondaryName]: { provider: assertProviderName, teststring: assertTestString, }, } db.config = assertConfig process.env.CLUSTER_APP_NAME = assertAppName fakeUtil.getAppNames.returns([assertAppSecondaryName, assertAppName]) assert.strictEqual(core.applications.length, 0) await core.init() assert.strictEqual(core.applications.length, 1) assert.ok(core.getApplication(assertAppName)) assert.notOk(core.getApplication(assertAppSecondaryName)) let application = core.getApplication(assertAppName) assert.strictEqual(core.applications[0], application) assert.strictEqual(application.name, assertAppName) assert.strictEqual(application.ctx.db, core.db) assert.strictEqual(application.ctx.util, core.util) assert.notStrictEqual(application.ctx.log, core.log) assert.strictEqual(application.ctx.core, core) assert.strictEqual(application.config.teststring, assertTestString) assert.ok(application.fresh) assert.ok(application.provider instanceof FakeProvider) }) }) t.describe('#run()', function() { let core let testAppOneName let testAppTwoName let stubRunApplication t.beforeEach(function() { testAppOneName = 'Tenshi' testAppTwoName = 'no CLOVER' db.data.core = { [testAppOneName]: { versions: [] }, [testAppTwoName]: { versions: [] }, } core = new Core(db, util, log) core.runApplication = stubRunApplication = stub().resolves() core.isSlave = true db.write = stub().resolves() log.info.reset() log.warn.reset() log.error.reset() for (let name of [testAppOneName, testAppTwoName]) { let onOrOnce = stub() let app = { name: name, fresh: false, on: onOrOnce, once: onOrOnce, ctx: { log: { info: stub(), warn: stub(), error: stub(), fatal: stub(), }, }, runVersion: stub().resolves(), update: stub().resolves(), startAutoupdater: stub(), } core.applicationMap.set(name, app) core.applications.push(app) } process.env.CLUSTER_APP_NAME = testAppTwoName }) t.test('should not call update', async function() { const assertFirstError = new Error('Manatsu') const assertSecondError = new Error('no Photograph') core.applicationMap.get(testAppOneName).update.rejects(assertFirstError) core.applicationMap.get(testAppTwoName).update.rejects(assertSecondError) await core.run() assert.notOk(core.applications[0].update.called) assert.notOk(core.applications[1].update.called) }) t.test('app.on updated should not be hooked', async function() { assert.notOk(core.applicationMap.get(testAppOneName).once.called) assert.notOk(core.applicationMap.get(testAppTwoName).once.called) assert.notOk(core.applicationMap.get(testAppOneName).on.called) assert.notOk(core.applicationMap.get(testAppTwoName).on.called) core.runApplication.returnWith(function(app) { assert.notOk(app.once.called) assert.notOk(app.on.called) return Promise.resolve() }) await core.run() assert.notOk(core.applicationMap.get(testAppOneName).once.called) assert.notOk(core.applicationMap.get(testAppTwoName).once.called) assert.notOk(core.applicationMap.get(testAppOneName).on.called) assert.notOk(core.applicationMap.get(testAppTwoName).on.called) }) t.test('should not call startAutoupdater', async function() { stubRunApplication.rejects(new Error('not seen')) assert.notOk(core.applications[0].startAutoupdater.called) assert.notOk(core.applications[1].startAutoupdater.called) await core.run() assert.notOk(core.applications[0].startAutoupdater.called) assert.notOk(core.applications[1].startAutoupdater.called) }) t.test('should be safe to call multiple times', async function() { await core.run() assert.strictEqual(core.applicationMap.get(testAppOneName).runVersion.callCount, 0) assert.strictEqual(core.applicationMap.get(testAppTwoName).runVersion.callCount, 1) await core.run() await core.run() await core.run() await core.run() assert.strictEqual(core.applicationMap.get(testAppOneName).runVersion.callCount, 0) assert.strictEqual(core.applicationMap.get(testAppTwoName).runVersion.callCount, 1) }) t.test('should call runVersion on selected application', async function() { const assertFirstError = new Error('Manatsu') const assertSecondError = new Error('no Photograph') const assertVersion = 'v11.22.33' core.applicationMap.get(testAppOneName).runVersion.rejects(assertFirstError) core.applicationMap.get(testAppTwoName).runVersion.rejects(assertSecondError) process.env.CLUSTER_APP_NAME = testAppTwoName process.env.CLUSTER_APP_VERSION = assertVersion let err = await assert.isRejected(core.run()) let app = core.applicationMap.get(testAppTwoName) assert.strictEqual(core.applicationMap.get(testAppOneName).runVersion.callCount, 0) assert.strictEqual(app.runVersion.callCount, 1) assert.strictEqual(app.runVersion.firstCall[0], assertVersion) assert.strictEqual(app.ctx.log.fatal.callCount, 1) assert.strictEqual(app.ctx.log.fatal.firstCall[0], assertSecondError) assert.strictEqual(err, assertSecondError) }) })