balena-supervisor/test/integration/compose/network.spec.ts

190 lines
4.7 KiB
TypeScript
Raw Normal View History

import { expect } from 'chai';
import { Network } from '~/src/compose/network';
import { createNetwork, withMockerode } from '~/test-lib/mockerode';
import Docker from 'dockerode';
describe('compose/network: integration tests', () => {
const docker = new Docker();
after(async () => {
const allNetworks = await docker.listNetworks();
// Delete any remaining networks
await Promise.all(
allNetworks
.filter(({ Name }) => !['bridge', 'host', 'none'].includes(Name)) // exclude docker default network from the cleanup
.map(({ Name }) => docker.getNetwork(Name).remove()),
);
});
describe('creating and removing networks', () => {
// This tests the happy path on the engine, including create and remove
it('creates a new network on the engine with the given data', async () => {
const network = Network.fromComposeObject('default', 12345, 'deadbeef', {
ipam: {
driver: 'default',
config: [
{
subnet: '172.20.0.0/16',
ip_range: '172.20.10.0/24',
gateway: '172.20.0.1',
},
],
options: {},
},
});
// Create the network
await network.create();
const dockerNetworkName = Network.generateDockerName(
network.appUuid!,
network.name,
);
// This should not throw
const dockerNetwork = await docker
.getNetwork(dockerNetworkName)
.inspect();
// Check that the create function was called with proper arguments
expect(dockerNetwork).to.deep.include({
Name: 'deadbeef_default',
Driver: 'bridge',
IPAM: {
Driver: 'default',
Config: [
{
Subnet: '172.20.0.0/16',
IPRange: '172.20.10.0/24',
Gateway: '172.20.0.1',
},
],
Options: {},
},
EnableIPv6: false,
Internal: false,
Labels: {
'io.balena.supervised': 'true',
'io.balena.app-id': '12345',
},
Options: {},
ConfigOnly: false,
});
// Test network removal
await network.remove();
// The network should no longer exist
await expect(docker.getNetwork(dockerNetwork).inspect()).to.be.rejected;
});
it('throws the error if there is a problem while creating the network', async () => {
await withMockerode(async (mockerode) => {
const network = Network.fromComposeObject(
'default',
12345,
'deadbeef',
{
ipam: {
driver: 'default',
config: [
{
subnet: '172.20.0.0/16',
ip_range: '172.20.10.0/24',
gateway: '172.20.0.1',
},
],
options: {},
},
},
);
// Re-define the dockerode.createNetwork to throw
mockerode.createNetwork.rejects('Unknown engine error');
// Creating the network should fail
return expect(network.create()).to.be.rejected;
});
});
});
describe('removing a network', () => {
it('removes a legacy network from the engine if it exists', async () => {
// Creates a legacy network
await docker.createNetwork({ Name: '12345_default' });
// Create a dummy network object
const network = Network.fromComposeObject(
'default',
12345,
'deadbeef',
{},
);
// Perform the operation
await network.remove();
await expect(docker.getNetwork('12345_default').inspect()).to.be.rejected;
});
it('ignores the request if the given network does not exist on the engine', async () => {
// Create a mock network to add to the mock engine
await docker.createNetwork({
Name: 'some_network',
});
// Create a dummy network object
const network = Network.fromComposeObject(
'default',
12345,
'deadbeef',
{},
);
// This should not fail
await expect(network.remove()).to.not.be.rejected;
// We expect the network state to remain constant
await expect(docker.getNetwork('some_network').inspect()).to.not.be
.rejected;
// Cleanup
await docker.getNetwork('some_network').remove();
});
it('throws the error if there is a problem while removing the network', async () => {
// Create a mock network to add to the mock engine
const mockNetwork = createNetwork({
Id: 'aaaaaaaa',
Name: 'a173bdb734884b778f5cc3dffd18733e_default',
Labels: {
'io.balena.app-id': '12345',
},
});
await withMockerode(
async (mockerode) => {
// We can change the return value of the mockerode removeNetwork
// to have the remove operation fail
mockerode.removeNetwork.throws({
statusCode: 500,
message: 'Failed to remove the network',
});
// Create a dummy network object
const network = Network.fromComposeObject(
'default',
12345,
'a173bdb734884b778f5cc3dffd18733e',
{},
);
await expect(network.remove()).to.be.rejected;
},
{ networks: [mockNetwork] },
);
});
});
});