import { expect } from "chai"; import "mocha"; import { Microservice, MicroserviceState } from "../../src"; class StateControlledMicroservice extends Microservice { public readonly quitState: MicroserviceState; public hasBooted = false; public hasStarted = false; public hasRun = false; public shutdownCalls = 0; public constructor(quitState: MicroserviceState) { super(); this.quitState = quitState; } protected override async boot() { let result = await super.boot(); if (this.quitState === MicroserviceState.Booting) { this.quit(25); } else { this.hasBooted = true; } return result; } protected override async start() { let result = await super.start(); if (this.quitState === MicroserviceState.Starting) { this.quit(50); } else { this.hasStarted = true; } return result; } protected override async run() { this.hasRun = true; return await super.run(); } protected override async shutdown() { this.shutdownCalls++; let result = super.shutdown(); if (this.quitState === MicroserviceState.Quitting) { this.quit(100); } return result; } } describe("Microservice", () => { describe("Basic state management", () => { describe("Initial state", () => { let microservice = new Microservice(); it("should be idle", () => { expect(microservice.state()).to.equal(MicroserviceState.Idle); }); }); describe("Running state", () => { let microservice = new Microservice(); it("should be running", async () => { let cb = new Promise(fulfill => microservice.on("ready", fulfill)); microservice.exec(); await cb; expect(microservice.state()).to.equal(MicroserviceState.Running); }); }); // describe("Finished State", () => { // let microservice = new Microservice(); // let cb = microservice.exec(); // microservice.quit(); // it("Should be in a finished state", async () => { // await cb; // expect(microservice.state()).to.equal(MicroserviceState.Finished); // }); // }); }); describe("Quit state control flow", () => { describe("Quit before executing process", async () => { let microservice = new Microservice(); microservice.quit(); it("should be in finished state", () => { expect(microservice.state()).to.equal(MicroserviceState.Finished); }); }); describe("Quit during boot state", () => { let microservice = new StateControlledMicroservice(MicroserviceState.Booting); it("should have the correct exit code", async () => { let exitCode = await microservice.exec(); expect(exitCode).to.equal(25); }); it("should be in finished state", () => { expect(microservice.state()).to.equal(MicroserviceState.Finished); }); it("should not have booted", () => { expect(microservice.hasBooted).to.be.false; }); it("should not have started", () => { expect(microservice.hasStarted).to.be.false; }); it("should have shutdown", () => { expect(microservice.shutdownCalls).to.equal(1); }); }); describe("Quit during starting state", () => { let microservice = new StateControlledMicroservice(MicroserviceState.Starting); it("should have the correct exit code", async () => { let exitCode = await microservice.exec(); expect(exitCode).to.equal(50); }); it("should be in finished state", () => { expect(microservice.state()).to.equal(MicroserviceState.Finished); }); it("should have booted", () => { expect(microservice.hasBooted).to.be.true; }); it("should not have started", () => { expect(microservice.hasStarted).to.be.false; }); it("should have shutdown", () => { expect(microservice.shutdownCalls).to.equal(1); }); }); describe("Quit during running state", () => { let microservice = new StateControlledMicroservice(MicroserviceState.Running); let runningPromise = microservice.exec(); setImmediate(() => microservice.quit(75)); it("should have the correct exit code", async () => { let exitCode = await runningPromise; expect(exitCode).to.equal(75); }); it("should be in finished state", () => { expect(microservice.state()).to.equal(MicroserviceState.Finished); }); it("should have booted", () => { expect(microservice.hasBooted).to.be.true; }); it("should have started", () => { expect(microservice.hasStarted).to.be.true; }); it("should have shutdown", () => { expect(microservice.shutdownCalls).to.equal(1); }); }); describe("Quit during quitting state", () => { let microservice = new StateControlledMicroservice(MicroserviceState.Quitting); microservice.once("ready", microservice.quit); let runningPromise = microservice.exec(); it("should have the correct exit code", async () => { let exitCode = await runningPromise; expect(exitCode).to.equal(0); }); it("should be in finished state", () => { expect(microservice.state()).to.equal(MicroserviceState.Finished); }); it("should have booted", () => { expect(microservice.hasBooted).to.be.true; }); it("should have started", () => { expect(microservice.hasStarted).to.be.true; }); it("should have shutdown only once", () => { expect(microservice.shutdownCalls).to.equal(1); }); }); }); });