Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions docs/data.rst
Original file line number Diff line number Diff line change
Expand Up @@ -452,3 +452,49 @@ In an :class:`Input`, you can obtain the selected member as a string::
if (input.samples.get(0).getString('my_union#') == 'point') {
value = input.samples.get(0).getNumber('my_union.point.x')
}

Accessing key values of disposed samples
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Using the :meth:`Output.write` API, an :class:`Output` can perform write, dispose
Comment thread
samuelraeburn marked this conversation as resolved.
Outdated
and unregister operations.
Depending on which of these operations is performed, the ``instance_state`` of the
received sample will be ``"ALIVE"``, ``"NOT_ALIVE_NO_WRITERS"`` or ``"NOT_ALIVE_DISPOSED"``.
If the instance was disposed, this ``instance_state`` will be ``"NOT_ALIVE_DISPOSED"``.
In this state, it is possible to access the key fields of the received sample.
Comment thread
samuelraeburn marked this conversation as resolved.
Outdated

.. warning::
The ``valid_data`` flag will be false when the sample is in the ``"NOT_ALIVE_DISPOSED"``
state. This is the only situation where it is supported to access the received
Comment thread
samuelraeburn marked this conversation as resolved.
Outdated
sample's fields even though the ``valid_data`` flag is false.

The key fields can be accessed as follows:

.. code-block::

// The output and input are using the following type:
// struct ShapeType {
// @key string<128> color;
// long x;
// long y;
// long shapesize;
// }

output.instance.set('x', 4)
output.instance.set('color', 'Green')
// Assume that some data associated with this instance has already been sent
output.write({ action: 'dispose' })
await input.wait()
input.take()
let sample = input.samples.get(0)

if (sample.info.get('instance_state') === 'NOT_ALIVE_DISPOSED') {
// sample.info.get('valid_data') will be false in this situation
// Accessing a non-key field using get() or getType() API returns null
let x = sample.get('x') // null
x = sample.getNumber('x') // also null
let color = sample.get('color') // 'Green'
// Can also access use getJson() to get all of the key fields in a JSON object
Comment thread
samuelraeburn marked this conversation as resolved.
Outdated
// The obtained JSON object will not contain non-key fields
let keyValues = sample.getJson() // { 'color': 'Green' }
}
6 changes: 6 additions & 0 deletions docs/input.rst
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,12 @@ After calling :meth:`Input.read()` or :meth:`Input.take()`,

:meth:`SampleIterator.getJson()` retrieves all the fields of a sample.

Unless the :attr:`Samples.validDataIter` is used, it is necessary to check if the
Comment thread
samuelraeburn marked this conversation as resolved.
Outdated
sample contains valid data before accessing the fields. The only exception to this
rule is if the ``instance_state`` of the sample is ``"NOT_ALIVE_DISPOSED"``.
See :ref:`Accessing key values of disposed samples` for more information on this use
case.

If you don't need to access the meta-data (see :ref:`Accessing the SampleInfo`),
the simplest way to access the data is to use :attr:`Samples.validDataIter`
to skip samples with invalid data:
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@
"url": "https://github.com/rticommunity/rticonnextdds-connector-js.git"
},
"dependencies": {
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"events": "*",
"ffi": "github:rticommunity/node-ffi#node-12",
"ref": "github:rticommunity/ref#node-12",
"sinon": "^9.0.2",
"sleep": "*"
},
"keywords": [
Expand Down
34 changes: 17 additions & 17 deletions test/nodejs/test_rticonnextdds_data_access.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ describe('Data access tests with a pre-populated input', function () {
} catch (err) {
console.log('Caught err: ' + err)
// Fail the test
expect(true).to.deep.equals(false)
throw(err)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is the error captured and rethrown only to log a message? Just let it fail without a try/catch

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't do that, the test will not fail, the test will pass but mocha will detect UnhandledPromiseRejection thrown.
This message would be printed to stdout:

(node:29903) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): AssertionError: assert.fail()
(node:29903) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

So it sounds like in future versions of Node.js they will make it fail the process, but at the moment that is not the case.

The common solution online is to return the promise to mocha (which has promise handling, and can therefore detect the failure). But since our tests usually have multiple Promises within them (i.e., multiple await calls) I had thought that this wasn't an option. but it looks like I might have been wrong:
https://stackoverflow.com/questions/42493113/async-mocha-test-with-chai-assertion-library-should-fail-but-is-marked-as-pas
I'm not sure how that works, but it looks like you can do something like:

return await output.write()
return await input.wait()

If you like I can investigate this option

}
// Write data on the the output
output.instance.setFromJson(testJsonObject)
Expand All @@ -81,7 +81,7 @@ describe('Data access tests with a pre-populated input', function () {
} catch (err) {
console.log('Caught err: ' + err)
// Fail the test
expect(true).to.deep.equals(false)
throw(err)
}
// Take the data on the input so that we can access it from the test
prepopulatedInput.take()
Expand Down Expand Up @@ -388,7 +388,7 @@ describe('Tests with a testOutput and testInput', () => {
expect(newMatches).to.deep.equals(1)
} catch (err) {
console.log('Caught err ' + err)
expect(true).to.deep.equals(false)
throw(err)
}
})

Expand Down Expand Up @@ -512,7 +512,7 @@ describe('Tests with a testOutput and testInput', () => {
await testInput.wait(testExpectSuccessTimeout)
} catch (err) {
console.log('Caught err: ' + err)
expect(true).to.deep.equals(false)
throw(err)
}
testInput.take()
const received = testInput.samples.get(0).get('my_int_sequence')
Expand All @@ -531,7 +531,7 @@ describe('Tests with a testOutput and testInput', () => {
await testInput.wait(testExpectSuccessTimeout)
} catch (err) {
console.log('Caught error: ' + err)
expect(true).to.deep.equals(false)
throw(err)
}
testInput.take()
const received = testInput.samples.get(0).get('my_point_sequence')
Expand All @@ -545,7 +545,7 @@ describe('Tests with a testOutput and testInput', () => {
await testInput.wait(testExpectSuccessTimeout)
} catch (err) {
console.log('Caught error: ' + err)
expect(true).to.deep.equals(false)
throw(err)
}
testInput.take()
const sample = testInput.samples.get(0)
Expand Down Expand Up @@ -1017,14 +1017,14 @@ describe('Tests with two readers and two writers', () => {
expect(newMatches).to.deep.equals(1)
} catch (err) {
console.log('Caught err: ' + err)
expect(true).to.deep.equals(false)
throw(err)
}
try {
const newMatches = await testOutput2.waitForSubscriptions(testExpectSuccessTimeout)
expect(newMatches).to.deep.equals(1)
} catch (err) {
console.log('Caught err: ' + err)
expect(true).to.deep.equals(false)
throw(err)
}
})

Expand All @@ -1041,7 +1041,7 @@ describe('Tests with two readers and two writers', () => {
try {
await connector.wait(testExpectFailureTimeout)
console.log('Expected connector.wait to timeout but it did not')
expect(true).to.deep.equals(false)
throw(err)
} catch (err) {
expect(err).to.be.an.instanceof(rti.TimeoutError)
}
Expand All @@ -1051,7 +1051,7 @@ describe('Tests with two readers and two writers', () => {
try {
await testInput1.wait(testExpectFailureTimeout)
console.log('Expected testInput1.wait to timeout but it did not')
expect(true).to.deep.equals(false)
throw(err)
} catch (err) {
expect(err).to.be.an.instanceof(rti.TimeoutError)
}
Expand All @@ -1061,7 +1061,7 @@ describe('Tests with two readers and two writers', () => {
try {
await testInput2.wait(testExpectFailureTimeout)
console.log('Expected testInput2.wait to timeout but it did not')
expect(true).to.deep.equals(false)
throw(err)
} catch (err) {
expect(err).to.be.an.instanceof(rti.TimeoutError)
}
Expand All @@ -1073,7 +1073,7 @@ describe('Tests with two readers and two writers', () => {
await connector.wait(testExpectSuccessTimeout)
} catch (err) {
console.log('Caught err: ' + err)
expect(true).to.deep.equals(false)
throw(err)
}
})

Expand All @@ -1083,7 +1083,7 @@ describe('Tests with two readers and two writers', () => {
await testInput1.wait(testExpectSuccessTimeout)
} catch (err) {
console.log('Caught err: ' + err)
expect(true).to.deep.equals(false)
throw(err)
}
})

Expand All @@ -1092,7 +1092,7 @@ describe('Tests with two readers and two writers', () => {
try {
await testInput2.wait(testExpectFailureTimeout)
console.log('Expected testInput2.wait to timeout but it did not')
expect(true).to.deep.equals(false)
throw(err)
} catch (err) {
expect(err).to.be.an.instanceof(rti.TimeoutError)
}
Expand All @@ -1104,7 +1104,7 @@ describe('Tests with two readers and two writers', () => {
await connector.wait(testExpectSuccessTimeout)
} catch (err) {
console.log('Caught err: ' + err)
expect(true).to.deep.equals(false)
throw(err)
}
})

Expand All @@ -1114,7 +1114,7 @@ describe('Tests with two readers and two writers', () => {
await testInput2.wait(testExpectSuccessTimeout)
} catch (err) {
console.log('Caught err: ' + err)
expect(true).to.deep.equals(false)
throw(err)
}
})

Expand All @@ -1123,7 +1123,7 @@ describe('Tests with two readers and two writers', () => {
try {
await testInput1.wait(testExpectFailureTimeout)
console.log('Expected testInput2.wait to timeout but it did not')
expect(true).to.deep.equals(false)
throw(err)
} catch (err) {
expect(err).to.be.an.instanceof(rti.TimeoutError)
}
Expand Down
4 changes: 2 additions & 2 deletions test/nodejs/test_rticonnextdds_dataflow.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ params.forEach((retrievalMethod) => {
expect(matches).to.be.at.least(1)
} catch (err) {
console.log('Caught err: ' + err)
expect(true).to.deep.equals(false)
throw(err)
}
})

Expand All @@ -57,7 +57,7 @@ params.forEach((retrievalMethod) => {
await input.wait(testExpectSuccessTimeout)
} catch (err) {
console.log('Caught err: ' + err)
expect(true).to.deep.equals(false)
throw(err)
}
input[retrievalMethod]()
expect(input.samples.length).to.be.at.least(1)
Expand Down
8 changes: 4 additions & 4 deletions test/nodejs/test_rticonnextdds_discovery.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ describe('Discovery tests', function () {
} catch (err) {
console.log('Caught error: ' + err)
// Fail the test
expect(true).to.deep.equals(false)
throw(err)
}
}
expect(totalMatches).to.be.at.least(2)
Expand Down Expand Up @@ -223,7 +223,7 @@ describe('Discovery tests', function () {
} catch (err) {
console.log('Caught error: ' + err)
// Fail the test
expect(true).to.deep.equals(false)
throw(err)
}
}
expect(totalMatches).to.be.at.least(2)
Expand Down Expand Up @@ -369,7 +369,7 @@ describe('Discovery tests', function () {
} catch (err) {
console.log('Caught error: ' + err)
// Fail the test
expect(true).to.deep.equals(false)
throw(err)
}

// Get the entity names of the matched subs
Expand All @@ -395,7 +395,7 @@ describe('Discovery tests', function () {
} catch (err) {
console.log('Caught error: ' + err)
// Fail the test
expect(true).to.deep.equals(false)
throw(err)
}
const matches = output.matchedSubscriptions
expect(matches.length).to.deep.equals(1)
Expand Down
2 changes: 1 addition & 1 deletion test/nodejs/test_rticonnextdds_events.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ describe('Connector EventEmitter tests', function () {
.then(() => {
// This should not have been possible
console.log('Error occurred. Expected wait to fail due to waitSetBusy')
expect(true).to.deep.equals(false)
throw(err)
})
.catch((err) => {
expect(err.message).to.deep.equals('Can not concurrently wait on the same Connector object')
Expand Down
2 changes: 1 addition & 1 deletion test/nodejs/test_rticonnextdds_input.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ describe('Subscriber not automatically enabled tests', () => {
expect(newMatches).to.deep.equals(1)
} catch (err) {
console.log('Caught err: ' + err)
expect(true).to.deep.equals(false)
throw(err)
}
})
})
Expand Down
Loading