-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tests: client and server integration tests
- Loading branch information
1 parent
a401594
commit cf13564
Showing
3 changed files
with
227 additions
and
1 deletion.
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 |
---|---|---|
@@ -0,0 +1,175 @@ | ||
import type { | ||
ClientStreamHandler, | ||
DuplexStreamHandler, | ||
ServerStreamHandler, | ||
UnaryHandler, | ||
} from '@/RPC/types'; | ||
import type { ConnectionInfo } from '@/network/types'; | ||
import type { JSONValue } from '@/types'; | ||
import { fc, testProp } from '@fast-check/jest'; | ||
import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; | ||
import RPCServer from '@/RPC/RPCServer'; | ||
import RPCClient from '@/RPC/RPCClient'; | ||
import * as rpcTestUtils from './utils'; | ||
|
||
describe('RPC', () => { | ||
const logger = new Logger(`RPC Test`, LogLevel.WARN, [new StreamHandler()]); | ||
|
||
const methodName = 'testMethod'; | ||
|
||
testProp( | ||
'RPC communication with duplex stream', | ||
[fc.array(rpcTestUtils.safeJsonValueArb, { minLength: 1 })], | ||
async (values) => { | ||
const { clientPair, serverPair } = rpcTestUtils.createTapPairs< | ||
Buffer, | ||
Buffer | ||
>(); | ||
|
||
const container = {}; | ||
const rpc = await RPCServer.createRPCServer({ container, logger }); | ||
|
||
const duplexHandler: DuplexStreamHandler<JSONValue, JSONValue> = | ||
async function* (input, _container, _connectionInfo, _ctx) { | ||
for await (const val of input) { | ||
yield val; | ||
} | ||
}; | ||
|
||
rpc.registerDuplexStreamHandler(methodName, duplexHandler); | ||
rpc.handleStream(serverPair, {} as ConnectionInfo); | ||
|
||
const rpcClient = await RPCClient.createRPCClient({ | ||
streamPairCreateCallback: async () => clientPair, | ||
logger, | ||
}); | ||
|
||
const callerInterface = await rpcClient.duplexStreamCaller( | ||
methodName, | ||
{}, | ||
); | ||
for (const value of values) { | ||
await callerInterface.write(value); | ||
expect((await callerInterface.read()).value).toStrictEqual(value); | ||
} | ||
await callerInterface.end(); | ||
expect((await callerInterface.read()).value).toBeUndefined(); | ||
expect((await callerInterface.read()).done).toBeTrue(); | ||
}, | ||
); | ||
|
||
testProp( | ||
'RPC communication with client stream', | ||
[fc.integer({ min: 1, max: 100 })], | ||
async (value) => { | ||
const { clientPair, serverPair } = rpcTestUtils.createTapPairs< | ||
Buffer, | ||
Buffer | ||
>(); | ||
|
||
const container = {}; | ||
const rpc = await RPCServer.createRPCServer({ container, logger }); | ||
|
||
const serverStreamHandler: ServerStreamHandler<number, number> = | ||
async function* (input, _container, _connectionInfo, _ctx) { | ||
for (let i = 0; i < input; i++) { | ||
yield i; | ||
} | ||
}; | ||
|
||
rpc.registerServerStreamHandler(methodName, serverStreamHandler); | ||
rpc.handleStream(serverPair, {} as ConnectionInfo); | ||
|
||
const rpcClient = await RPCClient.createRPCClient({ | ||
streamPairCreateCallback: async () => clientPair, | ||
logger, | ||
}); | ||
|
||
const callerInterface = await rpcClient.serverStreamCaller< | ||
number, | ||
number | ||
>(methodName, value, {}); | ||
|
||
const outputs: Array<number> = []; | ||
for await (const num of callerInterface.outputGenerator) { | ||
outputs.push(num); | ||
} | ||
expect(outputs.length).toEqual(value); | ||
}, | ||
{ numRuns: 1 }, | ||
); | ||
|
||
testProp( | ||
'RPC communication with server stream', | ||
[fc.array(fc.integer(), { minLength: 1 })], | ||
async (values) => { | ||
const { clientPair, serverPair } = rpcTestUtils.createTapPairs< | ||
Buffer, | ||
Buffer | ||
>(); | ||
|
||
const container = {}; | ||
const rpc = await RPCServer.createRPCServer({ container, logger }); | ||
|
||
const clientStreamhandler: ClientStreamHandler<number, number> = async ( | ||
input, | ||
) => { | ||
let acc = 0; | ||
for await (const number of input) { | ||
acc += number; | ||
} | ||
return acc; | ||
}; | ||
rpc.registerClientStreamHandler(methodName, clientStreamhandler); | ||
rpc.handleStream(serverPair, {} as ConnectionInfo); | ||
|
||
const rpcClient = await RPCClient.createRPCClient({ | ||
streamPairCreateCallback: async () => clientPair, | ||
logger, | ||
}); | ||
|
||
const callerInterface = await rpcClient.clientStreamCaller< | ||
number, | ||
number | ||
>(methodName, {}); | ||
for (const value of values) { | ||
await callerInterface.write(value); | ||
} | ||
await callerInterface.end(); | ||
|
||
const expectedResult = values.reduce((p, c) => p + c); | ||
await expect(callerInterface.result).resolves.toEqual(expectedResult); | ||
}, | ||
); | ||
|
||
testProp( | ||
'RPC communication with unary call', | ||
[rpcTestUtils.safeJsonValueArb], | ||
async (value) => { | ||
const { clientPair, serverPair } = rpcTestUtils.createTapPairs< | ||
Buffer, | ||
Buffer | ||
>(); | ||
|
||
const container = {}; | ||
const rpc = await RPCServer.createRPCServer({ container, logger }); | ||
|
||
const unaryCaller: UnaryHandler<JSONValue, JSONValue> = async (input) => | ||
input; | ||
rpc.registerUnaryHandler(methodName, unaryCaller); | ||
rpc.handleStream(serverPair, {} as ConnectionInfo); | ||
|
||
const rpcClient = await RPCClient.createRPCClient({ | ||
streamPairCreateCallback: async () => clientPair, | ||
logger, | ||
}); | ||
|
||
const result = await rpcClient.unaryCaller<JSONValue, JSONValue>( | ||
methodName, | ||
value, | ||
{}, | ||
); | ||
expect(result).toStrictEqual(value); | ||
}, | ||
); | ||
}); |
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