From fc16cd38331dce50ad2f240e93099578467853e6 Mon Sep 17 00:00:00 2001 From: waiting <1661926154@qq.com> Date: Tue, 12 Nov 2024 18:34:55 +0800 Subject: [PATCH] test(grpc): add case base-app-stream-meta --- .../base-app-stream-meta/package.json | 3 + .../src/config/config.default.ts | 11 ++ .../base-app-stream-meta/src/configuration.ts | 14 +++ .../base-app-stream-meta/src/interface.ts | 41 ++++++ .../base-app-stream-meta/src/provider/math.ts | 119 ++++++++++++++++++ packages/grpc/test/index.test.ts | 98 +++++++++++++++ 6 files changed, 286 insertions(+) create mode 100644 packages/grpc/test/fixtures/base-app-stream-meta/package.json create mode 100644 packages/grpc/test/fixtures/base-app-stream-meta/src/config/config.default.ts create mode 100644 packages/grpc/test/fixtures/base-app-stream-meta/src/configuration.ts create mode 100644 packages/grpc/test/fixtures/base-app-stream-meta/src/interface.ts create mode 100644 packages/grpc/test/fixtures/base-app-stream-meta/src/provider/math.ts diff --git a/packages/grpc/test/fixtures/base-app-stream-meta/package.json b/packages/grpc/test/fixtures/base-app-stream-meta/package.json new file mode 100644 index 000000000000..621cdc6a4174 --- /dev/null +++ b/packages/grpc/test/fixtures/base-app-stream-meta/package.json @@ -0,0 +1,3 @@ +{ + "name": "ali-demo" +} diff --git a/packages/grpc/test/fixtures/base-app-stream-meta/src/config/config.default.ts b/packages/grpc/test/fixtures/base-app-stream-meta/src/config/config.default.ts new file mode 100644 index 000000000000..498f37c2c253 --- /dev/null +++ b/packages/grpc/test/fixtures/base-app-stream-meta/src/config/config.default.ts @@ -0,0 +1,11 @@ +import { join } from 'path'; + +export const grpcServer = { + url: 'localhost:6571', + services: [ + { + protoPath: join(__dirname, '../../../proto/math.proto'), + package: 'math', + } + ], +} diff --git a/packages/grpc/test/fixtures/base-app-stream-meta/src/configuration.ts b/packages/grpc/test/fixtures/base-app-stream-meta/src/configuration.ts new file mode 100644 index 000000000000..3067a0e8cf81 --- /dev/null +++ b/packages/grpc/test/fixtures/base-app-stream-meta/src/configuration.ts @@ -0,0 +1,14 @@ +import { Configuration } from '@midwayjs/core'; +import * as grpc from '../../../../src'; +import { join } from 'path'; + +@Configuration({ + imports: [ + grpc + ], + importConfigs: [ + join(__dirname, './config'), + ] +}) +export class AutoConfiguration { +} diff --git a/packages/grpc/test/fixtures/base-app-stream-meta/src/interface.ts b/packages/grpc/test/fixtures/base-app-stream-meta/src/interface.ts new file mode 100644 index 000000000000..8ad8ae763091 --- /dev/null +++ b/packages/grpc/test/fixtures/base-app-stream-meta/src/interface.ts @@ -0,0 +1,41 @@ +import { + IClientDuplexStreamService, + IClientReadableStreamService, + IClientUnaryService, + IClientWritableStreamService +} from '../../../../src'; + +export namespace math { + export interface AddArgs { + id?: number; + num?: number; + } + export interface Num { + id?: number; + num?: number; + } + + /** + * server interface + */ + export interface Math { + add(data: AddArgs): Promise; + addMore(data: AddArgs): Promise; + // 服务端推,客户端读 + sumMany(fibArgs: AddArgs): Promise + // 客户端端推,服务端读 + addMany(num: AddArgs): Promise; + } + + /** + * client interface + */ + export interface MathClient { + add(): IClientUnaryService; + addMore(): IClientDuplexStreamService; + // 服务端推,客户端读 + sumMany(): IClientReadableStreamService; + // 客户端端推,服务端读 + addMany(): IClientWritableStreamService; + } +} diff --git a/packages/grpc/test/fixtures/base-app-stream-meta/src/provider/math.ts b/packages/grpc/test/fixtures/base-app-stream-meta/src/provider/math.ts new file mode 100644 index 000000000000..602c6f72c022 --- /dev/null +++ b/packages/grpc/test/fixtures/base-app-stream-meta/src/provider/math.ts @@ -0,0 +1,119 @@ +import * as assert from 'assert'; +import { GrpcMethod, GrpcStreamTypeEnum, Inject, MSProviderType, Provide, Provider } from '@midwayjs/core'; +import { Context } from '../../../../../src'; +import { math } from '../interface'; +import { Metadata } from '@grpc/grpc-js'; + +/** + */ +@Provide() +@Provider(MSProviderType.GRPC, { package: 'math' }) +export class Math implements math.Math { + + @Inject() + ctx: Context; + + sumDataList = []; + + @GrpcMethod() + async add(data: math.AddArgs): Promise { + assert(this.ctx, 'should get context'); + const { metadata } = this.ctx; + assert(metadata, 'should get metadata'); + + const rpcDefinition = metadata.get('rpc.definition'); + assert(rpcDefinition[0] === 'math.Math', `should get rpc.definition, but got "${rpcDefinition}"`); + + const rpcMethod = metadata.get('rpc.method'); + assert(rpcMethod[0] === 'Add', `should get rpc.method, but got "${rpcMethod[0]}"`); + + const rpcMethodType = metadata.get('rpc.method.type'); + assert(rpcMethodType[0] === 'unary', `should get rpc.method.type, but got "${rpcMethodType[0]}"`); + + return { + num: data.num + 2, + } + } + + @GrpcMethod({type: GrpcStreamTypeEnum.DUPLEX, onEnd: 'duplexEnd' }) + async addMore(message: math.AddArgs) { + const { metadata } = this.ctx; + assert(metadata, 'should get metadata'); + + const rpcDefinition = metadata.get('rpc.definition'); + assert(rpcDefinition[0] === 'math.Math', `should get rpc.definition, but got "${rpcDefinition}"`); + + const rpcMethod = metadata.get('rpc.method'); + assert(rpcMethod[0] === 'AddMore', `should get rpc.method, but got "${rpcMethod[0]}"`); + + const rpcMethodType = metadata.get('rpc.method.type'); + assert(rpcMethodType[0] === 'bidi', `should get rpc.method.type, but got "${rpcMethodType[0]}"`); + + this.ctx.write({ + id: message.id, + num: message.num + 10, + }); + } + + async duplexEnd() { + console.log('got client end message'); + } + + @GrpcMethod({type: GrpcStreamTypeEnum.WRITEABLE }) + async sumMany(args: math.AddArgs) { + const { metadata } = this.ctx; + assert(metadata, 'should get metadata'); + + const rpcDefinition = metadata.get('rpc.definition'); + assert(rpcDefinition[0] === 'math.Math', `should get rpc.definition, but got "${rpcDefinition}"`); + + const rpcMethod = metadata.get('rpc.method'); + assert(rpcMethod[0] === 'SumMany', `should get rpc.method, but got "${rpcMethod[0]}"`); + + const rpcMethodType = metadata.get('rpc.method.type'); + assert(rpcMethodType[0] === 'server', `should get rpc.method.type, but got "${rpcMethodType[0]}"`); + + this.ctx.write({ + num: 1 + args.num + }); + this.ctx.write({ + num: 2 + args.num + }); + this.ctx.write({ + num: 3 + args.num + }); + + const meta = new Metadata(); + meta.add('xxx', 'bbb'); + + this.ctx.sendMetadata(meta); + this.ctx.end(); + } + + @GrpcMethod({type: GrpcStreamTypeEnum.READABLE, onEnd: 'sumEnd' }) + async addMany(data: math.Num) { + const { metadata } = this.ctx; + assert(metadata, 'should get metadata'); + + const rpcDefinition = metadata.get('rpc.definition'); + assert(rpcDefinition[0] === 'math.Math', `should get rpc.definition, but got "${rpcDefinition}"`); + + const rpcMethod = metadata.get('rpc.method'); + assert(rpcMethod[0] === 'AddMany', `should get rpc.method, but got "${rpcMethod[0]}"`); + + const rpcMethodType = metadata.get('rpc.method.type'); + assert(rpcMethodType[0] === 'client', `should get rpc.method.type, but got "${rpcMethodType[0]}"`); + + this.sumDataList.push(data); + } + + async sumEnd(): Promise { + const total = this.sumDataList.reduce((pre, cur) => { + return { + num: pre.num + cur.num, + } + }); + return total; + } + +} diff --git a/packages/grpc/test/index.test.ts b/packages/grpc/test/index.test.ts index 6abc1e5752ce..9cbfcc9bd025 100644 --- a/packages/grpc/test/index.test.ts +++ b/packages/grpc/test/index.test.ts @@ -254,6 +254,104 @@ describe('/test/index.test.ts', function () { await closeApp(app); }); + it('should support publish stream metadata gRPC server', async () => { + const app = await createServer('base-app-stream-meta'); + + const service = await createGRPCConsumer({ + package: 'math', + protoPath: join(__dirname, 'fixtures/proto/math.proto'), + url: 'localhost:6571' + }); + + // 使用发送消息的写法 + let result1 = await service.add().sendMessage({ + num: 2, + }); + + expect(result1.num).toEqual(4); + + // 服务端推送 + let total = 0; + let result2 = await service.sumMany().sendMessage({ + num: 1, + }); + + result2.forEach(data => { + total += data.num; + }); + + expect(total).toEqual(9); + + // 客户端推送 + const data = await service.addMany() + .sendMessage({num: 1}) + .sendMessage({num: 2}) + .sendMessage({num: 3}) + .end(); + + expect(data.num).toEqual(6); + + // 双向流 + const result3= await new Promise((resolve, reject) => { + const duplexCall = service.addMore().getCall(); + total = 0; + let idx = 0; + + duplexCall.on('data', (data: math.Num) => { + total += data.num; + idx++; + if (idx === 2) { + duplexCall.end(); + resolve(total); + } + }); + + duplexCall.write({ + num: 3, + }); + + duplexCall.write({ + num: 6, + }); + }); + + expect(result3).toEqual(29); + + + // 保证顺序的双向流 + const t = service.addMore({ + messageKey: 'id' + }); + + const result4 = await new Promise((resolve, reject) => { + total = 0; + t.sendMessage({ + num: 2 + }) + .then(res => { + expect(res.num).toEqual(12); + total += res.num; + }) + .catch(err => console.error(err)) + ; + t.sendMessage({ + num: 5 + }) + .then(res => { + expect(res.num).toEqual(15); + total += res.num; + resolve(total); + }) + .catch(err => console.error(err)) + ; + t.end(); + }); + + expect(result4).toEqual(27); + + await closeApp(app); + }); + it('should test multi-package service', async () => { const app = await createServer('base-app-multiple-package');