balena-supervisor/test/44-volume-manager.spec.ts
Miguel Casqueira ecbe9ee9f9 Patch list volumes to always return an array
Change-type: patch
Closes: #1636
Signed-off-by: Miguel Casqueira <miguel@balena.io>
2021-04-01 20:31:09 -04:00

183 lines
5.0 KiB
TypeScript

import { expect } from 'chai';
import { stub, SinonStub } from 'sinon';
import * as mockedDockerode from './lib/mocked-dockerode';
import * as volumeManager from '../src/compose/volume-manager';
import log from '../src/lib/supervisor-console';
import Volume from '../src/compose/volume';
import { VolumeInspectInfo } from 'dockerode';
describe('Volume Manager', () => {
let logDebug: SinonStub;
before(() => {
logDebug = stub(log, 'debug');
});
after(() => {
logDebug.restore();
});
afterEach(() => {
// Clear Dockerode actions recorded for each test
mockedDockerode.resetHistory();
logDebug.reset();
});
it('gets all supervised Volumes', async () => {
// Setup volume data
const volumeData = [
createVolumeInspectInfo(Volume.generateDockerName(1, 'redis'), {
'io.balena.supervised': '1', // Recently created volumes contain io.balena.supervised label
}),
createVolumeInspectInfo(Volume.generateDockerName(1, 'mysql'), {
'io.balena.supervised': '1', // Recently created volumes contain io.balena.supervised label
}),
createVolumeInspectInfo(Volume.generateDockerName(1, 'backend')), // Old Volumes will not have labels
createVolumeInspectInfo('user_created_volume'), // Volume not created by the Supervisor
createVolumeInspectInfo('decoy', { 'io.balena.supervised': '1' }), // Added decoy to really test the inference (should not return)
];
// Perform test
await mockedDockerode.testWithData({ volumes: volumeData }, async () => {
await expect(volumeManager.getAll()).to.eventually.deep.equal([
{
appId: 1,
config: {
driver: 'local',
driverOpts: {},
labels: {
'io.balena.supervised': '1',
},
},
name: 'redis',
},
{
appId: 1,
config: {
driver: 'local',
driverOpts: {},
labels: {
'io.balena.supervised': '1',
},
},
name: 'mysql',
},
{
appId: 1,
config: {
driver: 'local',
driverOpts: {},
labels: {},
},
name: 'backend',
},
]);
// Check that debug message was logged saying we found a Volume not created by us
expect(logDebug.lastCall.lastArg).to.equal('Cannot parse Volume: decoy');
});
});
it('can parse null Volumes', async () => {
// Setup volume data
// @ts-ignore
const volumeData: VolumeInspectInfo[] = null;
// Perform test
await mockedDockerode.testWithData({ volumes: volumeData }, async () => {
await expect(volumeManager.getAll()).to.eventually.deep.equal([]);
});
});
it('gets a Volume for an application', async () => {
// Setup volume data
const volumeData = [
createVolumeInspectInfo(Volume.generateDockerName(111, 'app'), {
'io.balena.supervised': '1',
}),
createVolumeInspectInfo(Volume.generateDockerName(222, 'otherApp'), {
'io.balena.supervised': '1',
}),
];
// Perform test
await mockedDockerode.testWithData({ volumes: volumeData }, async () => {
await expect(volumeManager.getAllByAppId(111)).to.eventually.deep.equal([
{
appId: 111,
config: {
driver: 'local',
driverOpts: {},
labels: {
'io.balena.supervised': '1',
},
},
name: 'app',
},
]);
});
});
it('creates a Volume', async () => {
// Setup volume data
const volumeData: Dictionary<any> = [];
// Perform test
await mockedDockerode.testWithData({ volumes: volumeData }, async () => {
// Volume to create
const volume = Volume.fromComposeObject('main', 111, {});
stub(volume, 'create');
// Create volume
await volumeManager.create(volume);
// Check volume was created
expect(volume.create as SinonStub).to.be.calledOnce;
});
});
it('does not try to create a volume that already exists', async () => {
// Setup volume data
const volumeData = [
createVolumeInspectInfo(Volume.generateDockerName(111, 'main'), {
'io.balena.supervised': '1',
}),
];
// Perform test
await mockedDockerode.testWithData({ volumes: volumeData }, async () => {
// Volume to try again create
const volume = Volume.fromComposeObject('main', 111, {});
stub(volume, 'create');
// Create volume
await volumeManager.create(volume);
// Check volume was not created
expect(volume.create as SinonStub).to.not.be.called;
});
});
it('removes a Volume', async () => {
// Setup volume data
const volumeData = [
createVolumeInspectInfo(Volume.generateDockerName(111, 'main'), {
'io.balena.supervised': '1',
}),
];
// Perform test
await mockedDockerode.testWithData({ volumes: volumeData }, async () => {
// Volume to remove
const volume = Volume.fromComposeObject('main', 111, {});
stub(volume, 'remove');
// Remove volume
await volumeManager.remove(volume);
// Check volume was removed
expect(volume.remove as SinonStub).to.be.calledOnce;
});
});
});
function createVolumeInspectInfo(
name: string,
labels: { [key: string]: string } = {},
driver: string = 'local',
options: { [key: string]: string } | null = null,
) {
return {
Name: name,
Driver: driver,
Labels: labels,
Options: options,
};
}