Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
8 changes: 4 additions & 4 deletions developer-docs/testing-best-practices.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ It would seem like the best order in which to use the control flow utilities is
1. Simply await a Promise if possible and relevant
2. `waitForStreamToEnd` if dealing with ReadableStream
3. `waitForEvent` if dealing with events
4. `waitForCondition` when there is no direct handle to the async-behavior
4. `until` when there is no direct handle to the async-behavior
5. `wait` if nothing else works

### Try to avoid using `wait` when possible.
Expand All @@ -15,10 +15,10 @@ It would seem like the best order in which to use the control flow utilities is
- It increases test run time because we always wait for the pre-determined amount of time even if the required pre-condition has been met.
- We often have to use quite large delays to err on the side of caution, increasing test run time further.

### When using `waitForCondition` favor simple conditions
### When using `until` favor simple conditions
- The utility doesn't provide detailed info on what went wrong; when a condition fails, you will not have much visibility into the "why".
- Use a simple condition for `waitForCondition` and then later on in the test function perform proper assertions using the facilities provided by your test framework.
- E.g. use `waitForCondition` to wait for an array to have elements in it. Then afterwards assert the contents of those elements.
- Use a simple condition for `until` and then later on in the test function perform proper assertions using the facilities provided by your test framework.
- E.g. use `until` to wait for an array to have elements in it. Then afterwards assert the contents of those elements.

### Other
- Usefulness of `waitForEvent` declines in the presence of multiple events from the same emitter with the same event type
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
toDhtAddressRaw
} from '@streamr/dht'
import path from 'path'
import { MetricsContext, waitForCondition } from '@streamr/utils'
import { MetricsContext, until } from '@streamr/utils'

describe('StreamrChallenger', () => {

Expand Down Expand Up @@ -68,7 +68,7 @@ describe('StreamrChallenger', () => {

it('Happy path', async () => {
await runStreamrChallenge('127.0.0.1', '12323', sessionId)
await waitForCondition(() => challengedClientTransport.getConnections().length === 0)
await until(() => challengedClientTransport.getConnections().length === 0)
})

})
6 changes: 3 additions & 3 deletions packages/cli-tools/test/storage-node.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { fetchPrivateKeyWithGas } from '@streamr/test-utils'
import 'jest-extended'
import { StreamID } from '@streamr/sdk'
import { DOCKER_DEV_STORAGE_NODE, createTestClient, runCommand } from './utils'
import { waitForCondition } from '@streamr/utils'
import { until } from '@streamr/utils'

const isStored = async (streamId: StreamID): Promise<boolean> => {
const output = await runCommand(`storage-node list-streams ${DOCKER_DEV_STORAGE_NODE}`)
Expand All @@ -19,11 +19,11 @@ describe('storage node', () => {
await runCommand(`storage-node add-stream ${DOCKER_DEV_STORAGE_NODE} ${stream.id}`, {
privateKey
})
await waitForCondition(async () => await isStored(stream.id) === true, 15 * 1000, 1000)
await until(async () => await isStored(stream.id) === true, 15 * 1000, 1000)
await runCommand(`storage-node remove-stream ${DOCKER_DEV_STORAGE_NODE} ${stream.id}`, {
privateKey
})
await waitForCondition(async () => await isStored(stream.id) === false, 15 * 1000, 1000)
await until(async () => await isStored(stream.id) === false, 15 * 1000, 1000)
}, 80 * 1000)

it('list nodes', async () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/cli-tools/test/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Stream, StreamrClient } from '@streamr/sdk'
import { collect, waitForCondition } from '@streamr/utils'
import { collect, until } from '@streamr/utils'
import { spawn } from 'child_process'
import merge2 from 'merge2'

Expand Down Expand Up @@ -75,7 +75,7 @@ export const createTestClient = (privateKey?: string): StreamrClient => {
}

export const waitForTheGraphToHaveIndexed = async (stream: Stream, client: StreamrClient): Promise<void> => {
await waitForCondition(async () => {
await until(async () => {
// eslint-disable-next-line no-underscore-dangle
for await (const _msg of client.searchStreams(stream.id, undefined)) {
return true
Expand Down
4 changes: 2 additions & 2 deletions packages/dht/src/dht/DhtNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
MetricsContext,
merge,
scheduleAtInterval,
waitForCondition
until
} from '@streamr/utils'
import { EventEmitter } from 'eventemitter3'
import { sample } from 'lodash'
Expand Down Expand Up @@ -621,7 +621,7 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
}

public async waitForNetworkConnectivity(): Promise<void> {
await waitForCondition(
await until(
() => this.connectionsView!.getConnectionCount() > 0,
this.options.networkConnectivityTimeout,
100,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { PeerDescriptor } from '../../generated/packages/dht/protos/PeerDescriptor'
import { DhtNode } from '../../src/dht/DhtNode'
import { ConnectionManager } from '../../src/connection/ConnectionManager'
import { waitForCondition } from '@streamr/utils'
import { until } from '@streamr/utils'
import { createMockPeerDescriptor } from '../utils/utils'
import { areEqualPeerDescriptors } from '../../src/identifiers'

Expand Down Expand Up @@ -60,7 +60,7 @@ describe('Websocket IConnection Requests', () => {
await node2.joinDht([epPeerDescriptor])
await node1.joinDht([epPeerDescriptor])

await waitForCondition(() => { return (connected1 && connected2) })
await until(() => { return (connected1 && connected2) })

expect((node1.getTransport() as ConnectionManager).hasConnection(node2.getNodeId())).toEqual(true)
expect((node2.getTransport() as ConnectionManager).hasConnection(node1.getNodeId())).toEqual(true)
Expand Down
4 changes: 2 additions & 2 deletions packages/dht/test/end-to-end/memory-leak.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import LeakDetector from 'jest-leak-detector'
import { waitForCondition } from '@streamr/utils'
import { until } from '@streamr/utils'
import { DhtNode } from '../../src/dht/DhtNode'
import { Message } from '../../generated/packages/dht/protos/DhtRpc'
import { RpcMessage } from '../../generated/packages/proto-rpc/protos/ProtoRpc'
Expand Down Expand Up @@ -55,7 +55,7 @@ describe('memory leak', () => {
}
}
await sender.send(msg)
await waitForCondition(() => receivedMessage !== undefined)
await until(() => receivedMessage !== undefined)
expect(receivedMessage!.messageId).toEqual(MESSAGE_ID)

await Promise.all([
Expand Down
34 changes: 17 additions & 17 deletions packages/dht/test/integration/ConnectionLocking.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MetricsContext, waitForCondition } from '@streamr/utils'
import { MetricsContext, until } from '@streamr/utils'
import { ConnectionManager } from '../../src/connection/ConnectionManager'
import { DefaultConnectorFacade } from '../../src/connection/ConnectorFacade'
import { LatencyType, Simulator } from '../../src/connection/simulator/Simulator'
Expand Down Expand Up @@ -60,7 +60,7 @@ describe('Connection Locking', () => {
const nodeId1 = toNodeId(mockPeerDescriptor1)
const nodeId2 = toNodeId(mockPeerDescriptor2)
await Promise.all([
waitForCondition(() => connectionManager2.hasRemoteLockedConnection(nodeId1)),
until(() => connectionManager2.hasRemoteLockedConnection(nodeId1)),
connectionManager1.lockConnection(mockPeerDescriptor2, 'testLock')
])
expect(connectionManager1.hasConnection(nodeId2)).toEqual(true)
Expand All @@ -72,11 +72,11 @@ describe('Connection Locking', () => {
const nodeId1 = toNodeId(mockPeerDescriptor1)
const nodeId2 = toNodeId(mockPeerDescriptor2)
await Promise.all([
waitForCondition(() => connectionManager2.hasRemoteLockedConnection(nodeId1)),
until(() => connectionManager2.hasRemoteLockedConnection(nodeId1)),
connectionManager1.lockConnection(mockPeerDescriptor2, 'testLock1')
])
await Promise.all([
waitForCondition(() => connectionManager2.hasRemoteLockedConnection(nodeId1)),
until(() => connectionManager2.hasRemoteLockedConnection(nodeId1)),
connectionManager1.lockConnection(mockPeerDescriptor2, 'testLock2')
])
expect(connectionManager1.hasConnection(nodeId2)).toEqual(true)
Expand All @@ -88,7 +88,7 @@ describe('Connection Locking', () => {
const nodeId1 = toNodeId(mockPeerDescriptor1)
const nodeId2 = toNodeId(mockPeerDescriptor2)
await Promise.all([
waitForCondition(() => connectionManager2.hasRemoteLockedConnection(nodeId1)),
until(() => connectionManager2.hasRemoteLockedConnection(nodeId1)),
connectionManager1.lockConnection(mockPeerDescriptor2, 'testLock')
])
expect(connectionManager1.hasConnection(nodeId2))
Expand All @@ -97,19 +97,19 @@ describe('Connection Locking', () => {

connectionManager1.unlockConnection(mockPeerDescriptor2, 'testLock')
expect(connectionManager1.hasLocalLockedConnection(nodeId2)).toEqual(false)
await waitForCondition(() => connectionManager2.hasRemoteLockedConnection(nodeId1) === false)
await until(() => connectionManager2.hasRemoteLockedConnection(nodeId1) === false)
expect(connectionManager1.hasConnection(nodeId1)).toEqual(false)
})

it('unlocking multiple services', async () => {
const nodeId1 = toNodeId(mockPeerDescriptor1)
const nodeId2 = toNodeId(mockPeerDescriptor2)
await Promise.all([
waitForCondition(() => connectionManager2.hasRemoteLockedConnection(nodeId1)),
until(() => connectionManager2.hasRemoteLockedConnection(nodeId1)),
connectionManager1.lockConnection(mockPeerDescriptor2, 'testLock1')
])
await Promise.all([
waitForCondition(() => connectionManager2.hasRemoteLockedConnection(nodeId1)),
until(() => connectionManager2.hasRemoteLockedConnection(nodeId1)),
connectionManager1.lockConnection(mockPeerDescriptor2, 'testLock2')
])

Expand All @@ -128,8 +128,8 @@ describe('Connection Locking', () => {
const nodeId1 = toNodeId(mockPeerDescriptor1)
const nodeId2 = toNodeId(mockPeerDescriptor2)
await Promise.all([
waitForCondition(() => connectionManager2.hasRemoteLockedConnection(nodeId1)),
waitForCondition(() => connectionManager1.hasRemoteLockedConnection(nodeId2)),
until(() => connectionManager2.hasRemoteLockedConnection(nodeId1)),
until(() => connectionManager1.hasRemoteLockedConnection(nodeId2)),
connectionManager1.lockConnection(mockPeerDescriptor2, 'testLock1'),
connectionManager2.lockConnection(mockPeerDescriptor1, 'testLock1')
])
Expand All @@ -138,7 +138,7 @@ describe('Connection Locking', () => {
expect(connectionManager2.hasLocalLockedConnection(nodeId1))

connectionManager1.unlockConnection(mockPeerDescriptor2, 'testLock1')
await waitForCondition(() =>
await until(() =>
connectionManager1.hasRemoteLockedConnection(nodeId2)
&& !connectionManager1.hasLocalLockedConnection(nodeId2)
&& !connectionManager2.hasRemoteLockedConnection(nodeId1)
Expand All @@ -153,8 +153,8 @@ describe('Connection Locking', () => {
const nodeId1 = toNodeId(mockPeerDescriptor1)
const nodeId2 = toNodeId(mockPeerDescriptor2)
await Promise.all([
waitForCondition(() => connectionManager2.hasRemoteLockedConnection(nodeId1)),
waitForCondition(() => connectionManager1.hasRemoteLockedConnection(nodeId2)),
until(() => connectionManager2.hasRemoteLockedConnection(nodeId1)),
until(() => connectionManager1.hasRemoteLockedConnection(nodeId2)),
connectionManager1.lockConnection(mockPeerDescriptor2, 'testLock1'),
connectionManager2.lockConnection(mockPeerDescriptor1, 'testLock1')
])
Expand All @@ -165,16 +165,16 @@ describe('Connection Locking', () => {
//@ts-expect-error private field
await connectionManager1.gracefullyDisconnectAsync(mockPeerDescriptor2)

await waitForCondition(() =>
await until(() =>
!connectionManager1.hasRemoteLockedConnection(nodeId2)
&& !connectionManager1.hasLocalLockedConnection(nodeId2)
)
await waitForCondition(() =>
await until(() =>
!connectionManager2.hasRemoteLockedConnection(nodeId1)
&& !connectionManager2.hasLocalLockedConnection(nodeId1)
)
await waitForCondition(() => !connectionManager2.hasConnection(nodeId1))
await waitForCondition(() => !connectionManager1.hasConnection(nodeId2))
await until(() => !connectionManager2.hasConnection(nodeId1))
await until(() => !connectionManager1.hasConnection(nodeId2))

expect(connectionManager1.hasConnection(nodeId2)).toEqual(false)
expect(connectionManager2.hasConnection(nodeId1)).toEqual(false)
Expand Down
6 changes: 3 additions & 3 deletions packages/dht/test/integration/ConnectionManager.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Logger, MetricsContext, waitForCondition, waitForEvent3 } from '@streamr/utils'
import { Logger, MetricsContext, until, waitForEvent3 } from '@streamr/utils'
import { MarkOptional } from 'ts-essentials'
import { ConnectionManager } from '../../src/connection/ConnectionManager'
import { DefaultConnectorFacade, DefaultConnectorFacadeOptions } from '../../src/connection/ConnectorFacade'
Expand Down Expand Up @@ -514,11 +514,11 @@ describe('ConnectionManager', () => {
await Promise.all([connectedPromise1, connectedPromise2, connectionManager2.send(msg)])

await connectionManager1.enablePrivateClientMode()
await waitForCondition(() => connectionManager2.getConnections().length === 0)
await until(() => connectionManager2.getConnections().length === 0)
expect(connectionManager1.getConnections().length).toEqual(1)

await connectionManager1.disablePrivateClientMode()
await waitForCondition(() => connectionManager2.getConnections().length === 1)
await until(() => connectionManager2.getConnections().length === 1)
expect(connectionManager1.getConnections().length).toEqual(1)

await connectionManager1.stop()
Expand Down
4 changes: 2 additions & 2 deletions packages/dht/test/integration/DhtNode.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { waitForCondition } from '@streamr/utils'
import { until } from '@streamr/utils'
import { range, without } from 'lodash'
import { DhtNodeRpcLocal } from '../../src/dht/DhtNodeRpcLocal'
import { DhtNode, ListeningRpcCommunicator, toNodeId } from '../../src/exports'
Expand Down Expand Up @@ -59,7 +59,7 @@ describe('DhtNode', () => {
await localNode.joinDht([entryPointPeerDescriptor])
await localNode.waitForNetworkConnectivity()

await waitForCondition(() => localNode.getNeighborCount() === otherPeerDescriptors.length + 1)
await until(() => localNode.getNeighborCount() === otherPeerDescriptors.length + 1)
const expectedNodeIds = without(getAllPeerDescriptors(), localPeerDescriptor).map((n) => toNodeId(n))
const actualNodeIds = localNode.getClosestContacts().map((n) => toNodeId(n))
expect(actualNodeIds).toIncludeSameMembers(expectedNodeIds)
Expand Down
2 changes: 1 addition & 1 deletion packages/dht/test/integration/Layer1-scale.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ describe('Layer1', () => {
// })
// })
//
// await waitForCondition(() => {
// await until(() => {
// return [...receivedMessages.values()].every((set) => {
// return set.size === receivedMessages.size - 1
// })
Expand Down
8 changes: 4 additions & 4 deletions packages/dht/test/integration/RouteMessage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { DhtNode, Events as DhtNodeEvents } from '../../src/dht/DhtNode'
import { Message, RouteMessageWrapper } from '../../generated/packages/dht/protos/DhtRpc'
import { PeerDescriptor, NodeType } from '../../generated/packages/dht/protos/PeerDescriptor'
import { RpcMessage } from '../../generated/packages/proto-rpc/protos/ProtoRpc'
import { Logger, runAndWaitForEvents3, waitForCondition } from '@streamr/utils'
import { Logger, runAndWaitForEvents3, until } from '@streamr/utils'
import { createMockConnectionDhtNode, createWrappedClosestPeersRequest } from '../utils/utils'
import { Simulator } from '../../src/connection/simulator/Simulator'
import { v4 } from 'uuid'
Expand Down Expand Up @@ -117,7 +117,7 @@ describe('Route Message With Mock Connections', () => {
parallelRootNodeIds: []
})
}
await waitForCondition(() => receivedMessages === messageCount)
await until(() => receivedMessages === messageCount)
})

it('From all to all', async () => {
Expand Down Expand Up @@ -158,10 +158,10 @@ describe('Route Message With Mock Connections', () => {
}))
)
)
await waitForCondition(() => receivedMessageCounts[routerNodes[0].getNodeId()] >= routerNodes.length - 1, 30000)
await until(() => receivedMessageCounts[routerNodes[0].getNodeId()] >= routerNodes.length - 1, 30000)
await Promise.all(
Object.keys(receivedMessageCounts).map(async (key) =>
waitForCondition(() => receivedMessageCounts[key as DhtAddress] >= routerNodes.length - 1, 30000)
until(() => receivedMessageCounts[key as DhtAddress] >= routerNodes.length - 1, 30000)
)
)

Expand Down
18 changes: 9 additions & 9 deletions packages/dht/test/integration/SimultaneousConnections.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MetricsContext, waitForCondition } from '@streamr/utils'
import { MetricsContext, until } from '@streamr/utils'
import { ConnectionManager } from '../../src/connection/ConnectionManager'
import { DefaultConnectorFacade, DefaultConnectorFacadeOptions } from '../../src/connection/ConnectorFacade'
import { LatencyType, Simulator } from '../../src/connection/simulator/Simulator'
Expand Down Expand Up @@ -80,8 +80,8 @@ describe('SimultaneousConnections', () => {
simTransport1.send(msg1),
simTransport2.send(msg2)
])
await waitForCondition(() => simTransport2.hasConnection(toNodeId(peerDescriptor1)))
await waitForCondition(() => simTransport1.hasConnection(toNodeId(peerDescriptor2)))
await until(() => simTransport2.hasConnection(toNodeId(peerDescriptor1)))
await until(() => simTransport1.hasConnection(toNodeId(peerDescriptor2)))
})

describe('Websocket 2 servers', () => {
Expand Down Expand Up @@ -161,8 +161,8 @@ describe('SimultaneousConnections', () => {
connectionManager2.send(msg2)
])

await waitForCondition(() => connectionManager1.hasConnection(toNodeId(wsPeerDescriptor2)))
await waitForCondition(() => connectionManager2.hasConnection(toNodeId(wsPeerDescriptor1)))
await until(() => connectionManager1.hasConnection(toNodeId(wsPeerDescriptor2)))
await until(() => connectionManager2.hasConnection(toNodeId(wsPeerDescriptor1)))
})
})

Expand Down Expand Up @@ -241,8 +241,8 @@ describe('SimultaneousConnections', () => {
connectionManager2.send(msg2)
])

await waitForCondition(() => connectionManager1.hasConnection(toNodeId(wsPeerDescriptor2)))
await waitForCondition(() => connectionManager2.hasConnection(toNodeId(wsPeerDescriptor1)))
await until(() => connectionManager1.hasConnection(toNodeId(wsPeerDescriptor2)))
await until(() => connectionManager2.hasConnection(toNodeId(wsPeerDescriptor1)))
})
})

Expand Down Expand Up @@ -309,8 +309,8 @@ describe('SimultaneousConnections', () => {
connectionManager2.send(msg2)
])

await waitForCondition(() => connectionManager1.hasConnection(toNodeId(wrtcPeerDescriptor2)))
await waitForCondition(() => connectionManager2.hasConnection(toNodeId(wrtcPeerDescriptor1)))
await until(() => connectionManager1.hasConnection(toNodeId(wrtcPeerDescriptor2)))
await until(() => connectionManager2.hasConnection(toNodeId(wrtcPeerDescriptor1)))
})
})

Expand Down
Loading