mirror of
https://fuchsia.googlesource.com/third_party/pigweed.googlesource.com/pigweed/pigweed
synced 2024-09-18 21:00:07 +00:00
967f7bfce4
Change-Id: Ia9a89f40fa346344cf02aadab5da9f12945c120c Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/185144 Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com> Commit-Queue: Asad Memon <asadmemon@google.com> Reviewed-by: Anthony DiGirolamo <tonymd@google.com>
173 lines
5.0 KiB
TypeScript
173 lines
5.0 KiB
TypeScript
// Copyright 2022 The Pigweed Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
// use this file except in compliance with the License. You may obtain a copy of
|
|
// the License at
|
|
//
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
// License for the specific language governing permissions and limitations under
|
|
// the License.
|
|
|
|
/* eslint-env browser */
|
|
import { SerialMock } from '../transport/serial_mock';
|
|
import { Device } from './';
|
|
import { ProtoCollection } from 'pigweedjs/protos/collection';
|
|
import { WebSerialTransport } from '../transport/web_serial_transport';
|
|
import { Serial } from 'pigweedjs/types/serial';
|
|
import { Message } from 'google-protobuf';
|
|
import {
|
|
RpcPacket,
|
|
PacketType,
|
|
} from 'pigweedjs/protos/pw_rpc/internal/packet_pb';
|
|
import {
|
|
Method,
|
|
ServerStreamingMethodStub,
|
|
UnaryMethodStub,
|
|
} from 'pigweedjs/pw_rpc';
|
|
import { Status } from 'pigweedjs/pw_status';
|
|
import { Response } from 'pigweedjs/protos/pw_rpc/ts/test_pb';
|
|
|
|
import { EchoMessage } from 'pigweedjs/protos/pw_rpc/echo_pb';
|
|
|
|
describe('WebSerialTransport', () => {
|
|
let device: Device;
|
|
let serialMock: SerialMock;
|
|
|
|
function newResponse(payload = '._.'): Message {
|
|
const response = new Response();
|
|
response.setPayload(payload);
|
|
return response;
|
|
}
|
|
|
|
function generateResponsePacket(
|
|
channelId: number,
|
|
method: Method,
|
|
status: Status,
|
|
callId: number,
|
|
response?: Message,
|
|
) {
|
|
const packet = new RpcPacket();
|
|
packet.setType(PacketType.RESPONSE);
|
|
packet.setChannelId(channelId);
|
|
packet.setServiceId(method.service.id);
|
|
packet.setMethodId(method.id);
|
|
packet.setCallId(callId);
|
|
packet.setStatus(status);
|
|
if (response === undefined) {
|
|
packet.setPayload(new Uint8Array(0));
|
|
} else {
|
|
packet.setPayload(response.serializeBinary());
|
|
}
|
|
return packet.serializeBinary();
|
|
}
|
|
|
|
function generateStreamingPacket(
|
|
channelId: number,
|
|
method: Method,
|
|
response: Message,
|
|
callId: number,
|
|
status: Status = Status.OK,
|
|
) {
|
|
const packet = new RpcPacket();
|
|
packet.setType(PacketType.SERVER_STREAM);
|
|
packet.setChannelId(channelId);
|
|
packet.setServiceId(method.service.id);
|
|
packet.setMethodId(method.id);
|
|
packet.setCallId(callId);
|
|
packet.setPayload(response.serializeBinary());
|
|
packet.setStatus(status);
|
|
return packet.serializeBinary();
|
|
}
|
|
|
|
beforeEach(() => {
|
|
serialMock = new SerialMock();
|
|
device = new Device(
|
|
new ProtoCollection(),
|
|
new WebSerialTransport(serialMock as Serial),
|
|
);
|
|
});
|
|
|
|
it('has rpcs defined', () => {
|
|
expect(device.rpcs).toBeDefined();
|
|
expect(device.rpcs.pw.rpc.EchoService.Echo).toBeDefined();
|
|
});
|
|
|
|
it('has method arguments data', () => {
|
|
expect(device.getMethodArguments('pw.rpc.EchoService.Echo')).toStrictEqual([
|
|
'msg',
|
|
]);
|
|
expect(device.getMethodArguments('pw.test2.Alpha.Unary')).toStrictEqual([
|
|
'magic_number',
|
|
]);
|
|
});
|
|
|
|
it('unary rpc sends request to serial', async () => {
|
|
const methodStub = device.client
|
|
.channel()!
|
|
.methodStub('pw.rpc.EchoService.Echo')! as UnaryMethodStub;
|
|
const responseMsg = new EchoMessage();
|
|
responseMsg.setMsg('hello');
|
|
await device.connect();
|
|
const nextCallId = methodStub.rpcs.nextCallId;
|
|
setTimeout(() => {
|
|
device.client.processPacket(
|
|
generateResponsePacket(
|
|
1,
|
|
methodStub.method,
|
|
Status.OK,
|
|
nextCallId,
|
|
responseMsg,
|
|
),
|
|
);
|
|
}, 10);
|
|
const [status, response] =
|
|
await device.rpcs.pw.rpc.EchoService.Echo('hello');
|
|
expect(response.getMsg()).toBe('hello');
|
|
expect(status).toBe(0);
|
|
});
|
|
|
|
it('server streaming rpc sends response', async () => {
|
|
await device.connect();
|
|
const response1 = newResponse('!!!');
|
|
const response2 = newResponse('?');
|
|
const serverStreaming = device.client
|
|
.channel()
|
|
?.methodStub(
|
|
'pw.rpc.test1.TheTestService.SomeServerStreaming',
|
|
) as ServerStreamingMethodStub;
|
|
const nextCallId = serverStreaming.rpcs.nextCallId;
|
|
const onNext = jest.fn();
|
|
const onCompleted = jest.fn();
|
|
const onError = jest.fn();
|
|
|
|
device.rpcs.pw.rpc.test1.TheTestService.SomeServerStreaming(
|
|
4,
|
|
onNext,
|
|
onCompleted,
|
|
onError,
|
|
);
|
|
device.client.processPacket(
|
|
generateStreamingPacket(1, serverStreaming.method, response1, nextCallId),
|
|
);
|
|
device.client.processPacket(
|
|
generateStreamingPacket(1, serverStreaming.method, response2, nextCallId),
|
|
);
|
|
device.client.processPacket(
|
|
generateResponsePacket(
|
|
1,
|
|
serverStreaming.method,
|
|
Status.ABORTED,
|
|
nextCallId,
|
|
),
|
|
);
|
|
|
|
expect(onNext).toBeCalledWith(response1);
|
|
expect(onNext).toBeCalledWith(response2);
|
|
expect(onCompleted).toBeCalledWith(Status.ABORTED);
|
|
});
|
|
});
|