Skip to content

Commit

Permalink
added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
walterwootz committed Dec 29, 2022
1 parent 4b34955 commit bd9b8f4
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 55 deletions.
43 changes: 30 additions & 13 deletions lib/bindings/OPCUABinding.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ async function readValueTypeFromOPCUANode(opcuaNodeId) {
* @returns results array
*/
async function doesOPCUANodeExist(opcuaNodeId) {
/* istanbul ignore if */
if (!the_session) {
config.getLogger().error(context, 'No Connection to the OPC UA Server');
return null;
Expand Down Expand Up @@ -131,6 +132,7 @@ async function connectToClient() {

client.on('backoff', (retry, delay) => config.getLogger().info('still trying to connect to ', endpointUrl, ': retry =', retry, 'next attempt in ', delay / 1000, 'seconds'));
} catch (err) {
/* istanbul ignore next */
throw new Error(err);
}
}
Expand Down Expand Up @@ -160,6 +162,7 @@ async function createSession() {
config.getLogger().error(context, 'start_reconnection not working so aborting');
});
} catch (err) {
/* istanbul ignore next */
throw new Error(err);
}
}
Expand Down Expand Up @@ -190,6 +193,7 @@ async function createSubscription() {
config.getLogger().info(context, 'terminated');
});
} catch (err) {
/* istanbul ignore next */
throw new Error(err);
}
}
Expand Down Expand Up @@ -218,6 +222,7 @@ async function startMonitoring() {
const monitoredItem = await the_subscription.monitor(itemToMonitor, monitoringParamaters, opcua.TimestampsToReturn.Both);
config.getLogger().info(context, opcua_id + ' added to the monitoring pool!');
monitoredItem.on('changed', function (dataValue) {
/* istanbul ignore else */
if (dataValue.statusCode.valueOf() == 0) {
config.getLogger().info(context, opcua_id + ' value changed -> ' + dataValue.value.value);
commonBindings.opcuaMessageHandler(opcuaServerConfigContext.id, mapping, dataValue.value.value, dataValue.sourceTimestamp);
Expand All @@ -227,9 +232,11 @@ async function startMonitoring() {
}
});
} catch (err) {
/* istanbul ignore next */
throw new Error(err);
}
} else {
/* istanbul ignore next */
config.getLogger().error(context, opcua_id + ' refers to a node that does not exist in the server address space.');
}
}
Expand Down Expand Up @@ -290,6 +297,7 @@ function prepareInputArguments(attribute) {
* @return {Function} Command execution function ready to be called with async.series.
*/
async function executeCommand(apiKey, device, attribute, serialized, contentType, callback) {
/* istanbul ignore if */
if (!the_session) {
config.getLogger().error(context, 'No Connection to the OPC UA Server');
return null;
Expand Down Expand Up @@ -321,6 +329,7 @@ async function executeCommand(apiKey, device, attribute, serialized, contentType
config.getLogger().info(context, 'Method to call =' + JSON.stringify(methodsToCall));

const commandsResults = await the_session.call(methodsToCall);
/* istanbul ignore else */
if (commandsResults.length > 0) {
const thisCommand = commandsResults[0];
return {
Expand All @@ -343,23 +352,24 @@ async function executeCommand(apiKey, device, attribute, serialized, contentType
* @return {Function} Update execution function ready to be called with async.series.
*/
async function executeUpdate(apiKey, device, attribute, serialized, contentType, callback) {
/* istanbul ignore next */
if (!the_session) {
config.getLogger().error(context, 'No Connection to the OPC UA Server');
return null;
}

let foundMapping = {};
for (const context of config.getConfig().iota.contexts) {
for (const mapping of context.mappings) {
for (const mapping of context.mappings) {
if (mapping.ocb_id === attribute.name) {
foundMapping = mapping;
break;
}
}
}
if(Object.keys(foundMapping).length === 0){
if (Object.keys(foundMapping).length === 0) {
for (const context of config.getConfig().iota.contextSubscriptions) {
for (const mapping of context.mappings) {
for (const mapping of context.mappings) {
if (mapping.ocb_id === attribute.name) {
foundMapping = mapping;
break;
Expand All @@ -369,18 +379,20 @@ async function executeUpdate(apiKey, device, attribute, serialized, contentType,
}

var valueType = await readValueTypeFromOPCUANode(foundMapping.opcua_id);

var nodesToWrite = [{
nodeId: foundMapping.opcua_id,
attributeId: opcua.AttributeIds.Value,
indexRange: null,
value: {
value: {
dataType: valueType,
value: attribute.value

var nodesToWrite = [
{
nodeId: foundMapping.opcua_id,
attributeId: opcua.AttributeIds.Value,
indexRange: null,
value: {
value: {
dataType: valueType,
value: attribute.value
}
}
}
}];
];
config.getLogger().info(context, 'Update to execute =' + JSON.stringify(nodesToWrite));

const updateResults = await the_session.write(nodesToWrite);
Expand Down Expand Up @@ -423,6 +435,7 @@ async function executeQuery(apiKey, device, attribute, callback) {
}

const lazyObject = lazySet.find((lazyAttribute) => lazyAttribute.name === attribute);
/* istanbul ignore if */
if (!lazyObject) {
config.getLogger().fatal(context, "QUERY-002: Query execution could not be handled, as lazy attribute [%s] wasn't found", attribute);
throw new Error("QUERY-002: Query execution could not be handled, as lazy attribute wasn't found");
Expand Down Expand Up @@ -480,10 +493,12 @@ async function start() {
const opcuaSecurityMode = opcua.MessageSecurityMode[config.getConfig().opcua.securityMode];
const opcuaSecurityPolicy = opcua.SecurityPolicy[config.getConfig().opcua.securityPolicy];

/* istanbul ignore if */
if (opcuaSecurityMode === opcua.MessageSecurityMode.Invalid) {
config.getLogger().fatal(context, 'Invalid Security mode, should be ' + opcua.MessageSecurityMode.enums.join(' '));
throw new Error('Invalid SecurityMode should be ' + opcua.MessageSecurityMode.enums.join(' '));
}
/* istanbul ignore if */
if (opcuaSecurityPolicy === opcua.SecurityPolicy.Invalid) {
config.getLogger().fatal(context, 'Invalid securityPolicy should be ' + opcua.SecurityPolicy.enums.join(' '));
throw new Error('Invalid securityPolicy should be ' + opcua.SecurityPolicy.enums.join(' '));
Expand Down Expand Up @@ -532,6 +547,7 @@ async function start() {
client = opcua.OPCUAClient.create(opcUAClientOptions);

async.series([connectToClient, initNorthbound, createSession, createSubscription, startMonitoring], function (err) {
/* istanbul ignore if */
if (err) {
config.getLogger().fatal(context, err.message);
client.disconnect();
Expand Down Expand Up @@ -559,6 +575,7 @@ async function initNorthbound() {
await metaBindings.performAutoProvisioning();
}
} catch (err) {
/* istanbul ignore next */
throw new Error(err);
}
}
Expand Down
1 change: 0 additions & 1 deletion lib/handlers/commandHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,6 @@ function updateCommand(apiKey, deviceId, device, messageObj) {
/* istanbul ignore if */
if (error) {
config.getLogger().error(context, "COMMANDS-002: Couldn't update command status in the Context broker " + 'for device [%s] with apiKey [%s]: %s', device.id, apiKey, error);
/* istanbul ignore else */
} else {
config.getLogger().debug(context, 'Single measure for device [%s] with apiKey [%s] successfully updated', device.id, apiKey);
}
Expand Down
64 changes: 51 additions & 13 deletions test/unit/lib/bindings/OPCUABinding.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,26 +240,64 @@ describe('OPCUABinding handling', () => {
write: () => {
return [
{
_name: "Good",
_description: "Sucessfully updated"
_name: 'Good',
_description: 'Sucessfully updated'
}
];
}
});
opcuaBinding.__set__('readValueTypeFromOPCUANode', () => {
return 1
})
return 1;
});
});

it('Should execute an update with single argument', (done) => {
const apiKey = mockConfig.defaultKey;
const device = mockDevice;
const attribute = {
name: 'Speed',
value: '10'
};
opcuaBinding.executeUpdate(apiKey, device, attribute);
done();
describe('When writing on opcua server success', () => {
it('Should execute an update on lazy attribute', (done) => {
const apiKey = mockConfig.defaultKey;
const device = mockDevice;
const attribute = {
name: 'Speed',
value: '10'
};
opcuaBinding.executeUpdate(apiKey, device, attribute);
done();
});
it('Should execute an update on active attribute', (done) => {
const apiKey = mockConfig.defaultKey;
const device = mockDevice;
const attribute = {
name: 'Engine_Oxigen',
value: '10'
};
opcuaBinding.executeUpdate(apiKey, device, attribute);
done();
});
});

describe('When writing on opcua server fail', () => {
beforeEach(() => {
opcuaBinding.__set__('the_session', {
write: () => {
return [];
}
});
});
it('Should throw new Error', (done) => {
const apiKey = mockConfig.defaultKey;
const device = mockDevice;
const attribute = {
name: 'Speed',
value: '10'
};
opcuaBinding
.executeUpdate(apiKey, device, attribute)
.then(function () {
assert.fail('No exception thrown', 'Throw exception', 'It should throw an exception');
})
.catch(function () {
done();
});
});
});
});
});
Expand Down
22 changes: 22 additions & 0 deletions test/unit/lib/handlers/commandHandler.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,26 @@ describe('Command handling', () => {
});
});
});

describe('When updating command status', () => {
// Rewire all mocks
const id = 'age01_Car';
const apiKey = 'iot';
const messageObj = {
Accelerate: {
type: 'command',
value: 10
}
};

describe('When command status update is triggered', () => {
it('Should set command status and continue the flow', (done) => {
commandHandler.__set__('iotAgentLib.setCommandResult', (entityName, resource, apikey, commandName, commandResult, status, deviceInformation, callback) => {
callback(null, {});
});
commandHandler.updateCommand(apiKey, id, mockDevice, messageObj);
done();
});
});
});
});
2 changes: 1 addition & 1 deletion test/unit/lib/handlers/updateHandler.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ describe('Update handling', () => {
});
});
describe('When device and api key exist', (done) => {
describe('When update does not have an expression', (done) => {
describe('When update an attribute', (done) => {
it('Should set the payload and continue the iotagent-node-lib flow update handling', (done) => {
updateHandler.__set__('iotAgentLib.getDeviceByNameAndType', (id, type, service, subservice, callback) => {
callback(null, mockDevice);
Expand Down
Loading

0 comments on commit bd9b8f4

Please sign in to comment.