mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-04-07 19:34:17 +00:00
Split compose/network test in unit/integration
Integration tests are ran in the engine instead of mockerode.
This commit is contained in:
parent
4113dde45d
commit
cdc9868d29
188
test/integration/compose/network.spec.ts
Normal file
188
test/integration/compose/network.spec.ts
Normal file
@ -0,0 +1,188 @@
|
||||
import { expect } from 'chai';
|
||||
|
||||
import { Network } from '~/src/compose/network';
|
||||
import { createNetwork, withMockerode } from '~/test-lib/mockerode';
|
||||
|
||||
import * as 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: {},
|
||||
});
|
||||
|
||||
// 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] },
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
@ -3,11 +3,10 @@ import * as sinon from 'sinon';
|
||||
|
||||
import { Network } from '~/src/compose/network';
|
||||
import { NetworkInspectInfo } from 'dockerode';
|
||||
import { createNetwork, withMockerode } from '~/test-lib/mockerode';
|
||||
|
||||
import { log } from '~/lib/supervisor-console';
|
||||
|
||||
describe('compose/network', () => {
|
||||
describe('compose/network: unit tests', () => {
|
||||
describe('creating a network from a compose object', () => {
|
||||
it('creates a default network configuration if no config is given', () => {
|
||||
const network = Network.fromComposeObject(
|
||||
@ -509,221 +508,4 @@ describe('compose/network', () => {
|
||||
).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
describe('creating networks', () => {
|
||||
it('creates a new network on the engine with the given data', 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: {},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
// Create the network
|
||||
await network.create();
|
||||
|
||||
// Check that the create function was called with proper arguments
|
||||
expect(mockerode.createNetwork).to.have.been.calledOnceWith({
|
||||
Name: 'deadbeef_default',
|
||||
Driver: 'bridge',
|
||||
CheckDuplicate: true,
|
||||
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: {},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
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.then((error) =>
|
||||
expect(error).to.have.property('name', 'Unknown engine error'),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('removing a network', () => {
|
||||
it('removes the legacy network from the engine if it exists', async () => {
|
||||
// Create a mock network to add to the mock engine
|
||||
const dockerNetwork = createNetwork({
|
||||
Id: 'aaaaaaa',
|
||||
Name: '12345_default',
|
||||
});
|
||||
|
||||
await withMockerode(
|
||||
async (mockerode) => {
|
||||
// Check that the engine has the network
|
||||
expect(await mockerode.listNetworks()).to.have.lengthOf(1);
|
||||
|
||||
// Create a dummy network object
|
||||
const network = Network.fromComposeObject(
|
||||
'default',
|
||||
12345,
|
||||
'deadbeef',
|
||||
{},
|
||||
);
|
||||
|
||||
// Perform the operation
|
||||
await network.remove();
|
||||
|
||||
// The removal step should delete the object from the engine data
|
||||
expect(mockerode.removeNetwork).to.have.been.calledOnceWith(
|
||||
'aaaaaaa',
|
||||
);
|
||||
},
|
||||
{ networks: [dockerNetwork] },
|
||||
);
|
||||
});
|
||||
|
||||
it('removes the network from the engine if it exists', async () => {
|
||||
// Create a mock network to add to the mock engine
|
||||
const dockerNetwork = createNetwork({
|
||||
Id: 'deadbeef',
|
||||
Name: 'a173bdb734884b778f5cc3dffd18733e_default',
|
||||
Labels: {
|
||||
'io.balena.supervised': 'true',
|
||||
'io.balena.app-id': '12345',
|
||||
},
|
||||
});
|
||||
|
||||
await withMockerode(
|
||||
async (mockerode) => {
|
||||
// Check that the engine has the network
|
||||
expect(await mockerode.listNetworks()).to.have.lengthOf(1);
|
||||
|
||||
// Create a dummy network object
|
||||
const network = Network.fromComposeObject(
|
||||
'default',
|
||||
12345,
|
||||
'a173bdb734884b778f5cc3dffd18733e',
|
||||
{},
|
||||
);
|
||||
|
||||
// Perform the operation
|
||||
await network.remove();
|
||||
|
||||
// The removal step should delete the object from the engine data
|
||||
expect(mockerode.removeNetwork).to.have.been.calledOnceWith(
|
||||
'deadbeef',
|
||||
);
|
||||
},
|
||||
{ networks: [dockerNetwork] },
|
||||
);
|
||||
});
|
||||
|
||||
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
|
||||
const mockNetwork = createNetwork({
|
||||
Id: 'aaaaaaaa',
|
||||
Name: 'some_network',
|
||||
});
|
||||
|
||||
await withMockerode(
|
||||
async (mockerode) => {
|
||||
// Check that the engine has the network
|
||||
expect(await mockerode.listNetworks()).to.have.lengthOf(1);
|
||||
|
||||
// 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
|
||||
expect(await mockerode.listNetworks()).to.have.lengthOf(1);
|
||||
},
|
||||
{ networks: [mockNetwork] },
|
||||
);
|
||||
});
|
||||
|
||||
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] },
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user