2020-07-29 11:46:02 +00:00
|
|
|
import * as _ from 'lodash';
|
2020-05-08 20:04:21 +00:00
|
|
|
import { Router } from 'express';
|
|
|
|
import { fs } from 'mz';
|
|
|
|
|
|
|
|
import { ApplicationManager } from '../../src/application-manager';
|
2020-06-11 10:05:43 +00:00
|
|
|
import * as networkManager from '../../src/compose/network-manager';
|
2020-06-15 10:31:26 +00:00
|
|
|
import * as serviceManager from '../../src/compose/service-manager';
|
2020-06-11 10:43:03 +00:00
|
|
|
import * as volumeManager from '../../src/compose/volume-manager';
|
2020-06-02 13:29:05 +00:00
|
|
|
import * as config from '../../src/config';
|
2020-05-28 17:15:33 +00:00
|
|
|
import * as db from '../../src/db';
|
2020-05-08 20:04:21 +00:00
|
|
|
import { createV1Api } from '../../src/device-api/v1';
|
|
|
|
import { createV2Api } from '../../src/device-api/v2';
|
2020-07-21 09:45:37 +00:00
|
|
|
import * as APIBinder from '../../src/api-binder';
|
2020-05-08 20:04:21 +00:00
|
|
|
import DeviceState from '../../src/device-state';
|
|
|
|
import SupervisorAPI from '../../src/supervisor-api';
|
|
|
|
|
|
|
|
const DB_PATH = './test/data/supervisor-api.sqlite';
|
2020-05-15 19:18:20 +00:00
|
|
|
// Holds all values used for stubbing
|
|
|
|
const STUBBED_VALUES = {
|
|
|
|
config: {
|
|
|
|
apiSecret: 'secure_api_secret',
|
|
|
|
currentCommit: '7fc9c5bea8e361acd49886fe6cc1e1cd',
|
|
|
|
},
|
|
|
|
services: [
|
|
|
|
{
|
|
|
|
appId: 1,
|
|
|
|
imageId: 1111,
|
|
|
|
status: 'Running',
|
|
|
|
releaseId: 99999,
|
|
|
|
createdAt: new Date('2020-04-25T04:15:23.111Z'),
|
|
|
|
serviceName: 'main',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
appId: 1,
|
|
|
|
imageId: 2222,
|
|
|
|
status: 'Running',
|
|
|
|
releaseId: 99999,
|
|
|
|
createdAt: new Date('2020-04-25T04:15:23.111Z'),
|
|
|
|
serviceName: 'redis',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
appId: 2,
|
|
|
|
imageId: 3333,
|
2020-07-29 11:46:02 +00:00
|
|
|
containerId: 'abc123',
|
2020-05-15 19:18:20 +00:00
|
|
|
status: 'Running',
|
|
|
|
releaseId: 77777,
|
|
|
|
createdAt: new Date('2020-05-15T19:33:06.088Z'),
|
|
|
|
serviceName: 'main',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
images: [],
|
|
|
|
networks: [],
|
|
|
|
volumes: [],
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* THIS MOCKED API CONTAINS STUBS THAT MIGHT CAUSE UNEXPECTED RESULTS
|
|
|
|
* IF YOU WANT TO ADD/MODIFY STUBS THAT INVOLVE API OPERATIONS
|
|
|
|
* AND MULTIPLE TEST CASES WILL USE THEM THEN ADD THEM HERE
|
|
|
|
* OTHERWISE YOU CAN ADD STUBS ON A PER TEST CASE BASIS
|
|
|
|
*
|
2020-07-29 15:55:22 +00:00
|
|
|
* EXAMPLE: We stub ApplicationManager so there is at least 1 running app
|
2020-05-15 19:18:20 +00:00
|
|
|
*
|
|
|
|
* You can see all the stubbed values convientiely in STUBBED_VALUES.
|
|
|
|
*
|
|
|
|
*/
|
2020-05-08 20:04:21 +00:00
|
|
|
|
|
|
|
async function create(): Promise<SupervisorAPI> {
|
|
|
|
// Get SupervisorAPI construct options
|
2020-06-04 09:21:39 +00:00
|
|
|
const { deviceState, apiBinder } = await createAPIOpts();
|
2020-05-15 19:18:20 +00:00
|
|
|
// Stub functions
|
|
|
|
setupStubs();
|
2020-05-08 20:04:21 +00:00
|
|
|
// Create ApplicationManager
|
|
|
|
const appManager = new ApplicationManager({
|
|
|
|
deviceState,
|
|
|
|
apiBinder: null,
|
|
|
|
});
|
|
|
|
// Create SupervisorAPI
|
|
|
|
const api = new SupervisorAPI({
|
2020-06-05 13:16:43 +00:00
|
|
|
routers: [deviceState.router, buildRoutes(appManager)],
|
2020-05-20 01:27:36 +00:00
|
|
|
healthchecks: [deviceState.healthcheck, apiBinder.healthcheck],
|
2020-05-08 20:04:21 +00:00
|
|
|
});
|
2020-06-05 13:16:43 +00:00
|
|
|
|
|
|
|
const macAddress = await config.get('macAddress');
|
|
|
|
deviceState.reportCurrentState({
|
|
|
|
mac_address: macAddress,
|
|
|
|
});
|
|
|
|
|
2020-05-08 20:04:21 +00:00
|
|
|
// Return SupervisorAPI that is not listening yet
|
|
|
|
return api;
|
|
|
|
}
|
|
|
|
|
|
|
|
async function cleanUp(): Promise<void> {
|
|
|
|
try {
|
|
|
|
// clean up test data
|
|
|
|
await fs.unlink(DB_PATH);
|
|
|
|
} catch (e) {
|
|
|
|
/* noop */
|
|
|
|
}
|
2020-05-15 19:18:20 +00:00
|
|
|
// Restore created SinonStubs
|
|
|
|
return restoreStubs();
|
2020-05-08 20:04:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async function createAPIOpts(): Promise<SupervisorAPIOpts> {
|
2020-05-28 17:15:33 +00:00
|
|
|
await db.initialized;
|
2020-05-15 19:18:20 +00:00
|
|
|
// Initialize and set values for mocked Config
|
2020-06-02 13:29:05 +00:00
|
|
|
await initConfig();
|
2020-05-08 20:04:21 +00:00
|
|
|
// Create deviceState
|
|
|
|
const deviceState = new DeviceState({
|
|
|
|
apiBinder: null as any,
|
|
|
|
});
|
2020-07-21 09:45:37 +00:00
|
|
|
const apiBinder = APIBinder;
|
2020-05-08 20:04:21 +00:00
|
|
|
return {
|
|
|
|
deviceState,
|
2020-05-20 01:27:36 +00:00
|
|
|
apiBinder,
|
2020-05-08 20:04:21 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-06-02 13:29:05 +00:00
|
|
|
async function initConfig(): Promise<void> {
|
|
|
|
// Initialize this config
|
|
|
|
await config.initialized;
|
2020-05-15 19:18:20 +00:00
|
|
|
// Set testing secret
|
|
|
|
await config.set({
|
|
|
|
apiSecret: STUBBED_VALUES.config.apiSecret,
|
|
|
|
});
|
|
|
|
// Set a currentCommit
|
|
|
|
await config.set({
|
|
|
|
currentCommit: STUBBED_VALUES.config.currentCommit,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-05-08 20:04:21 +00:00
|
|
|
function buildRoutes(appManager: ApplicationManager): Router {
|
|
|
|
// Create new Router
|
|
|
|
const router = Router();
|
|
|
|
// Add V1 routes
|
|
|
|
createV1Api(router, appManager);
|
|
|
|
// Add V2 routes
|
|
|
|
createV2Api(router, appManager);
|
|
|
|
// Return modified Router
|
|
|
|
return router;
|
|
|
|
}
|
|
|
|
|
2020-06-11 10:05:43 +00:00
|
|
|
const originalNetGetAll = networkManager.getAllByAppId;
|
2020-06-11 10:43:03 +00:00
|
|
|
const originalVolGetAll = volumeManager.getAllByAppId;
|
2020-07-29 11:46:02 +00:00
|
|
|
const originalSvcGetAppId = serviceManager.getAllByAppId;
|
2020-06-15 10:31:26 +00:00
|
|
|
const originalSvcGetStatus = serviceManager.getStatus;
|
2020-07-29 11:46:02 +00:00
|
|
|
|
2020-05-15 19:18:20 +00:00
|
|
|
function setupStubs() {
|
2020-06-11 10:05:43 +00:00
|
|
|
// @ts-expect-error Assigning to a RO property
|
2020-06-15 10:31:26 +00:00
|
|
|
networkManager.getAllByAppId = async () => STUBBED_VALUES.networks;
|
|
|
|
// @ts-expect-error Assigning to a RO property
|
|
|
|
volumeManager.getAllByAppId = async () => STUBBED_VALUES.volumes;
|
2020-06-11 10:43:03 +00:00
|
|
|
// @ts-expect-error Assigning to a RO property
|
2020-06-15 10:31:26 +00:00
|
|
|
serviceManager.getStatus = async () => STUBBED_VALUES.services;
|
2020-07-29 11:46:02 +00:00
|
|
|
// @ts-expect-error Assigning to a RO property
|
|
|
|
serviceManager.getAllByAppId = async (appId) =>
|
|
|
|
_.filter(STUBBED_VALUES.services, (service) => service.appId === appId);
|
2020-05-15 19:18:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function restoreStubs() {
|
2020-06-11 10:05:43 +00:00
|
|
|
// @ts-expect-error Assigning to a RO property
|
|
|
|
networkManager.getAllByAppId = originalNetGetAll;
|
2020-06-11 10:43:03 +00:00
|
|
|
// @ts-expect-error Assigning to a RO property
|
|
|
|
volumeManager.getAllByAppId = originalVolGetAll;
|
2020-06-15 10:31:26 +00:00
|
|
|
// @ts-expect-error Assigning to a RO property
|
|
|
|
serviceManager.getStatus = originalSvcGetStatus;
|
2020-07-29 11:46:02 +00:00
|
|
|
// @ts-expect-error Assigning to a RO property
|
|
|
|
serviceManager.getAllByAppId = originalSvcGetAppId;
|
2020-05-15 19:18:20 +00:00
|
|
|
}
|
|
|
|
|
2020-05-08 20:04:21 +00:00
|
|
|
interface SupervisorAPIOpts {
|
|
|
|
deviceState: DeviceState;
|
2020-07-21 09:45:37 +00:00
|
|
|
apiBinder: typeof APIBinder;
|
2020-05-08 20:04:21 +00:00
|
|
|
}
|
|
|
|
|
2020-05-15 19:18:20 +00:00
|
|
|
export = { create, cleanUp, STUBBED_VALUES };
|