Skip to content

Commit

Permalink
feat(zigbee2mqtt): Some fixes after testing
Browse files Browse the repository at this point in the history
  • Loading branch information
cicoub13 committed Oct 20, 2023
1 parent 79d5075 commit b79005b
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 9 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ node_modules
*.db
*.db-shm
*.db-wal
*.dbfile-shm
*.dbfile-wal
apidoc
jsdoc
*.lcov
Expand Down
8 changes: 5 additions & 3 deletions server/lib/system/system.inspectContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@ const { PlatformNotCompatible } = require('../../utils/coreErrors');

/**
* @description Return description of a container.
* @param {object} container - Container to inspect.
* @param {string} containerId - Container id.
* @param {object} options - Options for inspection (see https://docs.docker.com/engine/api/v1.37/#operation/ContainerInspect).
* @returns {Promise} Resolve with container description.
* @example
* const containerDescription = await inspectContainer();
*/
async function inspectContainer(container) {
async function inspectContainer(containerId, options = {}) {
if (!this.dockerode) {
throw new PlatformNotCompatible('SYSTEM_NOT_RUNNING_DOCKER');
}
const containerDescription = await container.inspect();
const container = this.dockerode.getContainer(containerId);
const containerDescription = await container.inspect(options);
return containerDescription;
}

Expand Down
12 changes: 7 additions & 5 deletions server/services/zigbee2mqtt/lib/installZ2mContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,18 @@ async function installZ2mContainer(config) {
});
let [container] = dockerContainers;

// Manage case where Zigbee USB Dongle Path has changed by removing the container. It will be created with good config later
/*
* Manage case where Zigbee USB Dongle Path has changed by removing the container.
* It will be created with good config later
*/
if (dockerContainers.length > 0) {
const containerDescription = await this.gladys.system.inspectContainer(container);
if (containerDescription.devices[0].PathOnHost !== z2mDriverPath) {
const containerDescription = await this.gladys.system.inspectContainer(container.id);
if (containerDescription.HostConfig.Devices[0].PathOnHost !== z2mDriverPath) {
logger.info(
`Zigbee2mqtt container with USB dongle path ${containerDescription.devices[0].PathOnHost} should be removed (new USB dongle path ${z2mDriverPath} configured)...`,
`Zigbee2mqtt container with USB dongle path ${containerDescription.HostConfig.Devices[0].PathOnHost} should be removed (new USB dongle path ${z2mDriverPath} configured)...`,
);
await this.gladys.system.stopContainer(container.id);
await this.gladys.system.removeContainer(container.id);

creationNeeded = true;
}
}
Expand Down
Binary file not shown.
Empty file.
8 changes: 8 additions & 0 deletions server/test/lib/system/DockerApiMock.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ const containers = [
Status: 'Up 16 hours',
HostConfig: {
NetworkMode: 'host',
Devices: [
{
PathOnHost: '/dev/ttyUSB0',
PathInContainer: '/dev/ttyACM0',
CgroupPermissions: 'rwm',
},
],
},
Mounts: [
{
Expand All @@ -45,6 +52,7 @@ const containers = [
},
},
},
SizeRw: 152635,
},
{
Id: 'b594e692-e6d3-4531-bdcc-f0afcf515113',
Expand Down
1 change: 1 addition & 0 deletions server/test/lib/system/DockerodeMock.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Docker.prototype.getContainer = fake.returns({
},
],
},
SizeRw: 152635,
}),
restart: fake.resolves(true),
remove: fake.resolves(true),
Expand Down
80 changes: 80 additions & 0 deletions server/test/lib/system/system.inspectContainer.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
const { expect } = require('chai');
const sinon = require('sinon');

const { fake, assert } = sinon;

const proxyquire = require('proxyquire').noCallThru();

const { PlatformNotCompatible } = require('../../../utils/coreErrors');
const DockerodeMock = require('./DockerodeMock.test');

const System = proxyquire('../../../lib/system', {
dockerode: DockerodeMock,
});
const Job = require('../../../lib/job');

const sequelize = {
close: fake.resolves(null),
};

const event = {
on: fake.resolves(null),
emit: fake.resolves(null),
};

const job = new Job(event);

const config = {
tempFolder: '/tmp/gladys',
};

describe('system.inspectContainer', () => {
let system;

beforeEach(async () => {
system = new System(sequelize, event, config, job);
await system.init();
// Reset all fakes invoked within init call
sinon.reset();
});

afterEach(() => {
sinon.reset();
});

it('should failed as not on docker env', async () => {
system.dockerode = undefined;

try {
await system.inspectContainer('e90e34656806');
assert.fail('should have fail');
} catch (e) {
expect(e).be.instanceOf(PlatformNotCompatible);

assert.notCalled(sequelize.close);
assert.notCalled(event.on);
}
});

it('should inspect container', async () => {
const containerDescriptor = await system.inspectContainer('e90e34656806');

expect(containerDescriptor).be.instanceOf(Object);
expect(containerDescriptor).to.have.property('HostConfig');

assert.notCalled(sequelize.close);
assert.notCalled(event.on);
});

it('should inspect container with options', async () => {
const options = { size: true };

const containerDescriptor = await system.inspectContainer('e90e34656806', options);
expect(containerDescriptor).be.instanceOf(Object);
expect(containerDescriptor).to.have.property('HostConfig');
expect(containerDescriptor).to.have.property('SizeRw');

assert.notCalled(sequelize.close);
assert.notCalled(event.on);
});
});
18 changes: 17 additions & 1 deletion server/test/services/zigbee2mqtt/lib/installZ2mContainer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,20 @@ const containerStopped = {
state: 'stopped',
};

const containerDescription = {
Id: 'a8293feec54547a797aa2e52cc14b93f89a007d6c5608c587e30491feec8ee61',
HostConfig: {
NetworkMode: 'host',
Devices: [
{
PathOnHost: '/dev/ttyUSB0',
PathInContainer: '/dev/ttyACM0',
CgroupPermissions: 'rwm',
},
],
},
};

const serviceId = 'f87b7af2-ca8e-44fc-b754-444354b42fee';
const basePathOnContainer = path.join(__dirname, 'container');

Expand All @@ -47,9 +61,11 @@ describe('zigbee2mqtt installz2mContainer', () => {
},
system: {
getContainers: fake.resolves([containerStopped]),
inspectContainer: fake.resolves(containerDescription),
stopContainer: fake.resolves(true),
pull: fake.resolves(true),
restartContainer: fake.resolves(true),
removeContainer: fake.resolves(true),
createContainer: fake.resolves(true),
getGladysBasePath: fake.resolves({
basePathOnHost: path.join(__dirname, 'host'),
Expand Down Expand Up @@ -118,7 +134,7 @@ describe('zigbee2mqtt installz2mContainer', () => {

it('it should fail to start z2m container', async () => {
// PREPARE
const config = {};
const config = { z2mDriverPath: '/dev/ttyUSB0' };
gladys.system.getContainers = fake.resolves([containerStopped]);
gladys.system.restartContainer = fake.throws(new Error('docker fail'));
// EXECUTE
Expand Down

0 comments on commit b79005b

Please sign in to comment.