-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Write tests to cover all possible states of the Discovery, NodeConnection, and discovered Node during the discovery process #349
Comments
This issue needs a list of edge cases specified, for example:
For every edge case you need to post a diagram what you're attempting to do, and then also a prototype snippet, and also a test log where things didn't go right. See the diagram here in #332 regarding node connection state transitions, this should be relevant to forming your model on what's happening in the discovery. Then the issue title should be changed as well, to list the edgecases. Also list any edgecase you've also covered in the tests. Make sure to write which test name it is. |
A test to cover A3 (the node we're trying to contact is offline) was written, however due to unexpected behaviour it was removed from the codebase. This is the test (inside test('discovering an offline node', async () => {
const discovery = await Discovery.createDiscovery({
db,
keyManager,
gestaltGraph,
identitiesManager,
nodeManager,
sigchain,
logger,
});
const nodeOfflineId = nodeA.keyManager.getNodeId();
await nodeA.stop();
await discovery.queueDiscoveryByNode(nodeOfflineId);
// Need to set node B
await nodeGraph.setNode(nodeB.keyManager.getNodeId(), {
host: nodeB.revProxy.getIngressHost(),
port: nodeB.revProxy.getIngressPort(),
});
await discovery.queueDiscoveryByIdentity(testToken.providerId, identityId);
const gestalt = await poll<Gestalt>(
async () => {
const gestalts = await poll<Array<Gestalt>>(
async () => {
return await gestaltGraph.getGestalts();
},
(_, result) => {
if (result.length === 1) return true;
return false;
},
100,
);
return gestalts[0];
},
(_, result) => {
if (result === undefined) return false;
if (Object.keys(result.matrix).length === 2) return true;
return false;
},
100,
);
const gestaltMatrix = gestalt.matrix;
const gestaltNodes = gestalt.nodes;
const gestaltIdentities = gestalt.identities;
expect(Object.keys(gestaltMatrix)).toHaveLength(1);
expect(Object.keys(gestaltNodes)).toHaveLength(1);
expect(Object.keys(gestaltIdentities)).toHaveLength(1);
const gestaltString = JSON.stringify(gestalt);
expect(gestaltString).not.toContain(nodesUtils.encodeNodeId(nodeOfflineId));
expect(gestaltString).toContain(
nodesUtils.encodeNodeId(nodeB.keyManager.getNodeId()),
);
expect(gestaltString).toContain(identityId);
// Reverse side-effects
await gestaltGraph.unsetNode(nodeB.keyManager.getNodeId());
await gestaltGraph.unsetIdentity(testToken.providerId, identityId);
await discovery.stop();
await discovery.destroy();
await nodeA.start({ password });
await nodeGraph.unsetNode(nodeB.keyManager.getNodeId());
}); It behaves as expected to begin with (i.e. The only other strange thing that happens in the test output is that this error shows up in between when the
The test continues running, meanwhile the
At which point we finally see Note that this entering the
I'm wondering if this is potentially related to #347 in some way? |
Btw that |
Updated output using the correct logger setup:
|
Specification
There are various edge cases that can occur during discovery that have not been covered by our tests. These edge cases are the combinations of the following variables:
A - State of the node we're trying to contact during discovery:
B - State of the Node Connections we have stored in the Node Connection Manager:
C - State of the Node Connection we're using to contact the node:
D - Stage of the discovery process we're in:
E - State of the discovery module:
Some of these situations are normal and should not change the behaviour seen in discovery, whereas others should lead to a known error being thrown and caught. What happens after the error is caught depends on D and E.
Subsequently
Known expected errors for the situations listed above:
NodeConnectionManager.findNode()
should throwErrorNodeGraphNodeIdNotFound
, which should be propagated to the discovery process where it is caughtNodeConnection.createNodeConnection()
should catchErrorGRPCClientTimeout
and rethrow it asErrorNodeConnectionTimeout
, which should be propagated to the discovery process where it is caughtNodeConnection.createNodeConnection()
should throwErrorNodeConnectionDestroyed
, which should be propagated to the discovery process where it is caughtWe should aim to test as many of these combinations as possible. Some may require mocking due to the complexity or randomness of the series of events that lead to their occurrence, and some may not be able to be tested at all. Wherever possible the cases should be fully simulated as much as possible.
We already have tests covering the following combinations in
tests/discovery/Discovery.test.ts
:Additional context
Tasks
The text was updated successfully, but these errors were encountered: