Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
perf(pull): Read atvise server nodes in parallel
- Loading branch information
1 parent
b0aef0c
commit 5a34ef0
Showing
2 changed files
with
74 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,90 +1,79 @@ | ||
import { spy, stub } from 'sinon'; | ||
import { StatusCodes } from 'node-opcua'; | ||
import expect from '../../../expect'; | ||
|
||
import NodeId from '../../../../src/lib/server/NodeId'; | ||
import ReadStream from '../../../../src/lib/server/ReadStream'; | ||
|
||
/** @test {ReadStream} */ | ||
describe('ReadStream', function() { | ||
const validNodeId = new NodeId('ns=0;i=2262'); // ProductUri | ||
/** @test {ReadStream#processErrorMessage} */ | ||
describe('#processErrorMessage', function() { | ||
it('should include node id', function() { | ||
const nodeId = new NodeId('ns=1;s=AGENT.DISPLAYS.Main'); | ||
expect(ReadStream.prototype.processErrorMessage({ nodeId }), 'to contain', nodeId.value); | ||
}); | ||
}); | ||
|
||
/** @test {ReadStream#readNode} */ | ||
describe('#readNode', function() { | ||
it('should fail if an error occurs', function() { | ||
/** @test {ReadStream#processChunk} */ | ||
describe('#processChunk', function() { | ||
it('should error without results', function() { | ||
const stream = new ReadStream(); | ||
|
||
stream.once('session-open', () => { | ||
stream.session.read = (node, cb) => cb(new Error('Failed')); | ||
stream.session.read = (node, cb) => cb(null, [node], undefined); | ||
}); | ||
|
||
return expect([{ nodeId: validNodeId }], 'when piped through', stream, | ||
'to error with', `Reading ${validNodeId.toString()} failed: Failed`); | ||
return expect([{ nodeId: new NodeId('ns=1;s=AGENT.DISPLAYS.Main') }], | ||
'when piped through', stream, | ||
'to error with', /No results/); | ||
}); | ||
|
||
it('should with no or empty results', function() { | ||
it('should error with empty results', function() { | ||
const stream = new ReadStream(); | ||
|
||
stream.once('session-open', () => { | ||
stream.session.read = (node, cb) => cb(null, []); | ||
stream.session.read = (node, cb) => cb(null, [node], []); | ||
}); | ||
|
||
return expect([{ nodeId: validNodeId }], 'when piped through', stream, | ||
'to error with', `Reading ${validNodeId.toString()} failed: No results`); | ||
return expect([{ nodeId: new NodeId('ns=1;s=AGENT.DISPLAYS.Main') }], | ||
'when piped through', stream, | ||
'to error with', /No results/); | ||
}); | ||
|
||
it('should fail with non-good status code', function() { | ||
it('should error when reading fails', function() { | ||
const stream = new ReadStream(); | ||
const nodeId = new NodeId('ns=123;i=2262'); // This node does not exist | ||
|
||
return expect([{ nodeId }], 'when piped through', stream, | ||
'to error with', /Reading ns=123;i=2262 failed: Status BadNodeIdUnknown/); | ||
}); | ||
|
||
it('should read variables', function() { | ||
const stream = new ReadStream(); | ||
|
||
return expect([{ nodeId: validNodeId }], 'when piped through', stream, | ||
'to yield objects satisfying', [{ | ||
nodeId: validNodeId, | ||
value: { value: 'http://www.atvise.com' }, | ||
}]); | ||
}); | ||
}); | ||
|
||
/** @test {ReadStream#_transform} */ | ||
describe('#_transform', function() { | ||
it('should wait for session to open', function(done) { | ||
const stream = new ReadStream(); | ||
stub(stream, 'readNode', (node, cb) => cb(null)); | ||
spy(stream, '_transform'); | ||
|
||
stream.on('data', () => {}); // Unpause readable stream | ||
stream.write(new NodeId('ns=1;s=AGENT.DISPLAYS')); | ||
|
||
expect(stream._transform.calledOnce, 'to be', true); | ||
expect(stream.readNode.callCount, 'to equal', 0); | ||
|
||
stream.once('end', () => { | ||
expect(stream._transform.calledOnce, 'to be', true); | ||
expect(stream.readNode.calledOnce, 'to be', true); | ||
done(); | ||
stream.once('session-open', () => { | ||
stream.session.read = (node, cb) => cb(new Error('Test'), [node], []); | ||
}); | ||
stream.end(); | ||
|
||
return expect([{ nodeId: new NodeId('ns=1;s=AGENT.DISPLAYS.Main') }], | ||
'when piped through', stream, | ||
'to error with', /Test/); | ||
}); | ||
|
||
it('should read immediate if session is open', function(done) { | ||
it('should push result when reading succeeds', function() { | ||
const stream = new ReadStream(); | ||
stub(stream, 'readNode', (node, cb) => cb(null)); | ||
|
||
stream.on('data', () => {}); // Unpause readable stream | ||
const result = { | ||
value: 'test', | ||
sourceTimestamp: new Date(), | ||
statusCode: StatusCodes.Good, | ||
}; | ||
|
||
stream.once('session-open', () => { | ||
stream.write(new NodeId('ns=1;s=AGENT.DISPLAYS')); | ||
expect(stream.readNode.calledOnce, 'to be true'); | ||
stream.end(); | ||
stream.session.read = (node, cb) => cb(null, [node], [result]); | ||
}); | ||
|
||
stream.on('end', done); | ||
const nodeId = new NodeId('ns=1;s=AGENT.DISPLAYS.Main'); | ||
return expect([{ nodeId }], | ||
'when piped through', stream, | ||
'to yield objects satisfying', [ | ||
expect.it('to equal', { | ||
nodeId, | ||
value: result.value, | ||
referenceDescription: { nodeId }, | ||
mtime: result.sourceTimestamp, | ||
}), | ||
]); | ||
}); | ||
}); | ||
}); |