import { Eltro as t, assert, stub } from 'eltro' import fs from 'fs/promises' import Application from '../core/application.mjs' import Util from '../core/util.mjs' import lowdb from '../core/db.mjs' import StaticProvider from '../core/providers/static.mjs' import { createFakeContext } from './helpers.mjs' import HttpServer from '../core/http.mjs' const util = new Util(import.meta.url) t.describe('#runVersion("version") cluster mode', function() { const assertPort = 22345 const assertClusterSize = Math.floor(Math.random() * (8 - 2 + 1) + 2) const http = new HttpServer() let handler let cluster let workers let ctx let app t.beforeEach(function() { return createFakeContext({ testnoexisting: { cluster: assertClusterSize } }, util, null) .then(function(res) { workers = [] ctx = res let provider = new StaticProvider() cluster = { on: stub(), off: stub(), fork: stub().returnWith(function() { let worker = { on: stub(), once: stub(), process: { kill: stub(), } } workers.push(worker) return worker }), isWorker: false, } app = new Application(ctx, provider, 'testnoexisting', { cluster }) app.config.port = assertPort app.workerDied = stub() return app.ctx.db.write() }) }) t.afterEach(function() { return Promise.all([ app.closeServer(), ]) }) t.before(function() { handler = function(req, res) { res.writeHead(200) res.end('{}') } let server = http.createServer(function(req, res) { req.on('error', function() { }) res.on('error', function() { }) res.on('finish', function() { }) handler(req, res) }) return server.listenAsync(assertPort) }) t.after(function() { return http.closeServer() }) t.test('should call fork for entire cluster and attach handlers correctly', async function() { let lastErr = null for (let i = 1; i <= assertClusterSize; i++) { assert.strictEqual(app.workers[i], null) } handler = function(req, res) { try { assert.notOk(cluster.on.called) assert.notOk(app.__clusterWorkerDied) lastErr = false } catch (err) { lastErr = err } res.writeHead(200) res.end('{}') } const assertVersion = 'v11.22.33' await app.runVersion(assertVersion) assert.strictEqual(cluster.fork.callCount, assertClusterSize) for (let i = 1; i <= assertClusterSize; i++) { assert.ok(app.workers[i]) assert.strictEqual(app.workers[i], workers[i - 1]) assert.strictEqual(cluster.fork.getCallN(i)[0].CLUSTER_APP_NAME, app.name) assert.strictEqual(cluster.fork.getCallN(i)[0].CLUSTER_APP_VERSION, assertVersion) assert.strictEqual(app.workers[i].w_id, i) assert.strictEqual(app.workers[i].listening, false) assert.ok(app.workers[i].started) assert.ok(new Date() - app.workers[i].started < 100 && new Date() - app.workers[i].started >= 0) } assert.strictEqual(lastErr, false) assert.strictEqual(cluster.on.callCount, 1) assert.ok(app.__clusterWorkerDied) assert.strictEqual(cluster.on.firstCall[0], 'exit') assert.strictEqual(cluster.on.firstCall[1], app.__clusterWorkerDied) assert.notStrictEqual(app.workerDied, app.__clusterWorkerDied) assert.notOk(app.workerDied.called) app.__clusterWorkerDied() assert.ok(app.workerDied.called) }) })