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<void>(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);
|
|
});
|
|
});
|
|
});
|
|
});
|