mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2024-12-27 17:18:52 +00:00
ecbe9ee9f9
Change-type: patch Closes: #1636 Signed-off-by: Miguel Casqueira <miguel@balena.io>
183 lines
5.0 KiB
TypeScript
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,
|
|
};
|
|
}
|