Skip to content

Commit

Permalink
Back: Add new test for satellites
Browse files Browse the repository at this point in the history
  • Loading branch information
MathieuAndrade committed Oct 14, 2023
1 parent 899a381 commit 7e2d021
Show file tree
Hide file tree
Showing 10 changed files with 317 additions and 28 deletions.
4 changes: 2 additions & 2 deletions apps/server/src/api/routes/v1/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export default class PluginRouter {
path: '/stop/:id',
authenticated: true,
rateLimit: false,
aclMethod: 'patch',
aclMethod: 'update',
aclResource: 'plugin',
})
stop = async (req: Request, res: Response) => {
Expand All @@ -125,7 +125,7 @@ export default class PluginRouter {
path: '/restart/:id',
authenticated: true,
rateLimit: false,
aclMethod: 'patch',
aclMethod: 'update',
aclResource: 'plugin',
})
restart = async (req: Request, res: Response) => {
Expand Down
4 changes: 2 additions & 2 deletions apps/server/src/api/routes/v1/satellite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ export default class SatelliteRouter {
path: '/stop/plugins/:id',
authenticated: true,
rateLimit: false,
aclMethod: 'patch',
aclMethod: 'update',
aclResource: 'satellite',
})
stopAllPlugins = async (req: Request, res: Response) => {
Expand All @@ -236,7 +236,7 @@ export default class SatelliteRouter {
path: '/restart/plugins/:id',
authenticated: true,
rateLimit: false,
aclMethod: 'patch',
aclMethod: 'update',
aclResource: 'satellite',
})
restartAllPlugins = async (req: Request, res: Response) => {
Expand Down
7 changes: 6 additions & 1 deletion apps/server/src/config/acl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default {
[UserRole.HABITANT]: {
grants: [
{
resource: ['*', '!variable', '!plugin', '!user'],
resource: ['*', '!variable', '!plugin', '!satellite', '!user'],
action: '*',
attributes: ['*'],
},
Expand All @@ -41,6 +41,11 @@ export default {
action: ['read', 'create', 'login', '!create', '!update', '!delete'],
attributes: ['*'],
},
{
resource: 'satellite',
action: ['read', '!create', '!update', '!delete'],
attributes: ['*'],
},
{
resource: 'user',
action: ['*', '!create', '!update', '!delete'],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import Docker from '@friday-ai/docker';
import { expect } from 'chai';
import { Container } from 'dockerode';
import Plugin from '../../../../../src/core/plugin/plugin';
import { admin, guest, habitant } from '../../../../utils/apiToken';
import server from '../../../../utils/request';

let plugin: Plugin;
let docker: Docker;
let container: Container;

describe('PATCH /api/v1/satellite/restart/plugins/:id', () => {
// Create a fake container and save docker id on plugin
before(async function before() {
plugin = global.FRIDAY.plugin;
docker = global.FRIDAY.docker;

container = await docker.createContainer({
Image: 'alpine',
AttachStdin: false,
AttachStdout: true,
AttachStderr: true,
Tty: true,
OpenStdin: false,
StdinOnce: false,
});

await container.start();
});

// Only update container id before each hook to prevent multiple useless container created
beforeEach(async function beforeEach() {
this.timeout(15000);
await plugin.update('88b48273-15e6-4729-9199-0682677475f4', {
dockerId: container.id,
});
});

after(async function after() {
this.timeout(15000);
await container.remove({ force: true });
});

it('should restart all plugins of a satellite', async function restart() {
this.timeout(15000);
await server
.patch('/api/v1/satellite/restart/plugins/4801badb-55d7-4bcd-9bf0-37a6cffe0bb1')
.expect(200)
.then((res) => {
expect(res.body.success).to.equal(true);
});
});

it('admin should have access to restart all plugins of a satellite', async function restart() {
this.timeout(15000);
await server
.patch('/api/v1/satellite/restart/plugins/4801badb-55d7-4bcd-9bf0-37a6cffe0bb1', admin)
.expect(200)
.then((res) => {
expect(res.body.success).to.equal(true);
});
});
});

describe('PATCH /api/v1/satellite/restart/plugins/:id', () => {
it("habitant should't have access to restart all plugins of a satellite", async () => {
await server.patch('/api/v1/satellite/restart/plugins/4801badb-55d7-4bcd-9bf0-37a6cffe0bb1', habitant).expect(403);
});

it("guest should't have access to restart all plugins of a satellite", async () => {
await server.patch('/api/v1/satellite/restart/plugins/4801badb-55d7-4bcd-9bf0-37a6cffe0bb1', guest).expect(403);
});

it('should not found a satellite', async () => {
await server.patch('/api/v1/satellite/restart/plugins/5801badb-55d7-4bcd-9bf0-37a6cffe0bb1').expect(404);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import Docker from '@friday-ai/docker';
import { expect } from 'chai';
import { Container } from 'dockerode';
import Plugin from '../../../../../src/core/plugin/plugin';
import { admin, guest, habitant } from '../../../../utils/apiToken';
import server from '../../../../utils/request';

let plugin: Plugin;
let docker: Docker;
let container: Container;

describe('PATCH /api/v1/satellite/stop/plugins/:id', () => {
// Create a fake container and save docker id on plugin
before(async function before() {
plugin = global.FRIDAY.plugin;
docker = global.FRIDAY.docker;

container = await docker.createContainer({
Image: 'alpine',
AttachStdin: false,
AttachStdout: true,
AttachStderr: true,
Tty: true,
OpenStdin: false,
StdinOnce: false,
});

await container.start();
});

// Only update container id before each hook to prevent multiple useless container created
beforeEach(async function beforeEach() {
this.timeout(15000);
await plugin.update('88b48273-15e6-4729-9199-0682677475f4', {
dockerId: container.id,
});
});

after(async function after() {
this.timeout(15000);
await container.remove({ force: true });
});

it('should stop all plugins of a satellite', async function restart() {
this.timeout(15000);
await server
.patch('/api/v1/satellite/stop/plugins/4801badb-55d7-4bcd-9bf0-37a6cffe0bb1')
.expect(200)
.then((res) => {
expect(res.body.success).to.equal(true);
});
});

it('admin should have access to stop all plugins of a satellite', async function restart() {
this.timeout(15000);
await server
.patch('/api/v1/satellite/stop/plugins/4801badb-55d7-4bcd-9bf0-37a6cffe0bb1', admin)
.expect(200)
.then((res) => {
expect(res.body.success).to.equal(true);
});
});
});

describe('PATCH /api/v1/satellite/stop/plugins/:id', () => {
it("habitant should't have access to stop all plugins of a satellite", async () => {
await server.patch('/api/v1/satellite/stop/plugins/4801badb-55d7-4bcd-9bf0-37a6cffe0bb1', habitant).expect(403);
});

it("guest should't have access to stop all plugins of a satellite", async () => {
await server.patch('/api/v1/satellite/stop/plugins/4801badb-55d7-4bcd-9bf0-37a6cffe0bb1', guest).expect(403);
});

it('should not found a satellite', async () => {
await server.patch('/api/v1/satellite/stop/plugins/5801badb-55d7-4bcd-9bf0-37a6cffe0bb1').expect(404);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { AvailableState, EventsType } from '@friday-ai/shared';
import { assert, expect } from 'chai';
import { Container } from 'dockerode';
import sinon from 'sinon';
import Satellite from '../../../src/core/satellite/satellite';
import { NotFoundError } from '../../../src/utils/decorators/error';

let satellite: Satellite;
let container: Container;

describe('Satellite.restartAllPlugins', () => {
before(async () => {
satellite = global.FRIDAY.satellite;

// Create a fake container and save docker id on plugin
container = await global.FRIDAY.docker.createContainer({
Image: 'alpine',
AttachStdin: false,
AttachStdout: true,
AttachStderr: true,
Tty: true,
OpenStdin: false,
StdinOnce: false,
});

await container.start();
});

// Only update container id before each hook to prevent multiple useless container created
beforeEach(async function beforeEach() {
this.timeout(15000);
await global.FRIDAY.plugin.update('88b48273-15e6-4729-9199-0682677475f4', {
dockerId: container.id,
});
});

after(async function after() {
this.timeout(15000);
await container.remove({ force: true });
});

it('should restart all plugins of a satellite', async function stop() {
this.timeout(15000);

const listener = sinon.spy();
global.FRIDAY.event.on(EventsType.WEBSOCKET_SEND_ALL, listener);

const promise = satellite.restartAllPlugins('4801badb-55d7-4bcd-9bf0-37a6cffe0bb1');

await assert.isFulfilled(promise);
expect(listener.called).equal(true);
expect(listener.args[0][0].type).to.equal(AvailableState.PLUGIN_STOPPED);
});

it('should not found satellite', async () => {
const promise = satellite.update('4017c89a-8d02-4d9b-9aec-1e1bcb93a3a7', {});
await assert.isRejected(promise, NotFoundError);
});
});
59 changes: 59 additions & 0 deletions apps/server/test/core/satellite/satellite.stopAllPlugins.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { AvailableState, EventsType } from '@friday-ai/shared';
import { assert, expect } from 'chai';
import { Container } from 'dockerode';
import sinon from 'sinon';
import Satellite from '../../../src/core/satellite/satellite';
import { NotFoundError } from '../../../src/utils/decorators/error';

let satellite: Satellite;
let container: Container;

describe('Satellite.stopAllPlugins', () => {
before(async () => {
satellite = global.FRIDAY.satellite;

// Create a fake container and save docker id on plugin
container = await global.FRIDAY.docker.createContainer({
Image: 'alpine',
AttachStdin: false,
AttachStdout: true,
AttachStderr: true,
Tty: true,
OpenStdin: false,
StdinOnce: false,
});

await container.start();
});

// Only update container id before each hook to prevent multiple useless container created
beforeEach(async function beforeEach() {
this.timeout(15000);
await global.FRIDAY.plugin.update('88b48273-15e6-4729-9199-0682677475f4', {
dockerId: container.id,
});
});

after(async function after() {
this.timeout(15000);
await container.remove({ force: true });
});

it('should stop all plugins of a satellite', async function stop() {
this.timeout(15000);

const listener = sinon.spy();
global.FRIDAY.event.on(EventsType.WEBSOCKET_SEND_ALL, listener);

const promise = satellite.stopAllPlugins('4801badb-55d7-4bcd-9bf0-37a6cffe0bb1');

await assert.isFulfilled(promise);
expect(listener.called).equal(true);
expect(listener.args[0][0].type).to.equal(AvailableState.PLUGIN_STOPPED);
});

it('should not found satellite', async () => {
const promise = satellite.update('4017c89a-8d02-4d9b-9aec-1e1bcb93a3a7', {});
await assert.isRejected(promise, NotFoundError);
});
});
20 changes: 12 additions & 8 deletions apps/server/test/core/system/system.init.test.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
import { expect } from 'chai';
import Docker from '@friday-ai/docker';
import { SystemVariablesNames, VariableOwner } from '@friday-ai/shared';
import { expect } from 'chai';
import * as database from '../../../src/config/database';
import User from '../../../src/core/user/user';
import Variable from '../../../src/core/variable/variable';
import jobs from '../../../src/config/jobs';
import House from '../../../src/core/house/house';
import Plugin from '../../../src/core/plugin/plugin';
import Room from '../../../src/core/room/room';
import Satellite from '../../../src/core/satellite/satellite';
import House from '../../../src/core/house/house';
import Event from '../../../src/utils/event';
import State from '../../../src/core/state/state';
import Scheduler from '../../../src/utils/scheduler';
import jobs from '../../../src/config/jobs';
import System from '../../../src/core/system/system';
import User from '../../../src/core/user/user';
import Variable from '../../../src/core/variable/variable';
import Event from '../../../src/utils/event';
import Scheduler from '../../../src/utils/scheduler';

describe('System.init', () => {
const event = Event;
const variable = new Variable();
const state = new State(event, variable);
const user = new User(state);
const room = new Room(state);
const satellite = new Satellite(state);
const docker = new Docker();
const plugin = new Plugin(event, docker, state);
const satellite = new Satellite(state, plugin);
const house = new House(state);
const scheduler = new Scheduler(event, jobs);
const system = new System(variable, house, room, satellite, user, state, scheduler, database);
Expand Down
Loading

0 comments on commit 7e2d021

Please sign in to comment.