Browse Source

test(service): add unit test for service manager

Signed-off-by: Jiyong Huang <huangjy@emqx.io>
Jiyong Huang 2 years ago
parent
commit
685169bbfb

+ 16 - 17
internal/service/external_service_rule_test.go

@@ -1,4 +1,4 @@
-// Copyright 2021 EMQ Technologies Co., Ltd.
+// Copyright 2021-2023 EMQ Technologies Co., Ltd.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -22,7 +22,6 @@ import (
 	"github.com/golang/protobuf/ptypes/wrappers"
 	"github.com/gorilla/mux"
 	kconf "github.com/lf-edge/ekuiper/internal/conf"
-	pb "github.com/lf-edge/ekuiper/internal/service/test/schemas/helloworld"
 	"github.com/lf-edge/ekuiper/internal/topo/topotest"
 	"github.com/lf-edge/ekuiper/pkg/api"
 	"github.com/msgpack-rpc/msgpack-rpc-go/rpc"
@@ -36,11 +35,11 @@ import (
 	"testing"
 )
 
-type HelloRequest struct {
+type RestHelloRequest struct {
 	Name string `json:"name,omitempty"`
 }
 
-type HelloReply struct {
+type RestHelloReply struct {
 	Message string `json:"message,omitempty"`
 }
 
@@ -104,12 +103,12 @@ func TestRestService(t *testing.T) {
 	count := 0
 	router := mux.NewRouter()
 	router.HandleFunc("/SayHello", func(w http.ResponseWriter, r *http.Request) {
-		body := &HelloRequest{}
+		body := &RestHelloRequest{}
 		err := json.NewDecoder(r.Body).Decode(body)
 		if err != nil {
 			http.Error(w, err.Error(), http.StatusBadRequest)
 		}
-		out := &HelloReply{Message: body.Name}
+		out := &RestHelloReply{Message: body.Name}
 		jsonOut(w, err, out)
 	}).Methods(http.MethodPost)
 	router.HandleFunc("/object_detection", func(w http.ResponseWriter, r *http.Request) {
@@ -710,15 +709,15 @@ func TestMsgpackService(t *testing.T) {
 }
 
 type server struct {
-	pb.UnimplementedGreeterServer
+	UnimplementedGreeterServer
 }
 
-func (s *server) SayHello(_ context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
-	return &pb.HelloReply{Message: in.GetName()}, nil
+func (s *server) SayHello(_ context.Context, in *HelloRequest) (*HelloReply, error) {
+	return &HelloReply{Message: in.GetName()}, nil
 }
 
-func (s *server) ObjectDetection(_ context.Context, in *pb.ObjectDetectionRequest) (*pb.ObjectDetectionResponse, error) {
-	return &pb.ObjectDetectionResponse{
+func (s *server) ObjectDetection(_ context.Context, in *ObjectDetectionRequest) (*ObjectDetectionResponse, error) {
+	return &ObjectDetectionResponse{
 		Info:   in.Cmd,
 		Code:   200,
 		Image:  in.Base64Img,
@@ -727,13 +726,13 @@ func (s *server) ObjectDetection(_ context.Context, in *pb.ObjectDetectionReques
 	}, nil
 }
 
-func (s *server) GetFeature(_ context.Context, v *wrappers.BytesValue) (*pb.FeatureResponse, error) {
+func (s *server) GetFeature(_ context.Context, v *wrappers.BytesValue) (*FeatureResponse, error) {
 	l := len(string(v.Value))
-	return &pb.FeatureResponse{
-		Feature: []*pb.FeatureResult{
+	return &FeatureResponse{
+		Feature: []*FeatureResult{
 			{
 				Features: []float32{-1.444, 2.55452, 5.121},
-				Box: &pb.Box{
+				Box: &Box{
 					X: 153,
 					Y: 107,
 					W: 174,
@@ -742,7 +741,7 @@ func (s *server) GetFeature(_ context.Context, v *wrappers.BytesValue) (*pb.Feat
 			},
 			{
 				Features: []float32{1.444, -2.55452, -5.121},
-				Box: &pb.Box{
+				Box: &Box{
 					X: 257,
 					Y: 92,
 					W: 169,
@@ -763,7 +762,7 @@ func TestGrpcService(t *testing.T) {
 		kconf.Log.Fatalf("failed to listen: %v", err)
 	}
 	s := grpc.NewServer()
-	pb.RegisterGreeterServer(s, &server{})
+	RegisterGreeterServer(s, &server{})
 	go func() {
 		if err := s.Serve(lis); err != nil {
 			kconf.Log.Fatalf("failed to serve: %v", err)

+ 21 - 7
internal/service/test/schemas/helloworld/hw.pb.go

@@ -1,10 +1,24 @@
+// Copyright 2023 EMQ Technologies Co., Ltd.
+//
+// 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
+//
+//     http://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.
+
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.26.0-devel
 // 	protoc        v3.6.1
 // source: hw.proto
 
-package helloworld
+package service
 
 import (
 	empty "github.com/golang/protobuf/ptypes/empty"
@@ -59,7 +73,7 @@ func (x *HelloRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use HelloRequest.ProtoReflect.Descriptor instead.
+// Deprecated: Use RestHelloRequest.ProtoReflect.Descriptor instead.
 func (*HelloRequest) Descriptor() ([]byte, []int) {
 	return file_hw_proto_rawDescGZIP(), []int{0}
 }
@@ -107,7 +121,7 @@ func (x *HelloReply) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use HelloReply.ProtoReflect.Descriptor instead.
+// Deprecated: Use RestHelloReply.ProtoReflect.Descriptor instead.
 func (*HelloReply) Descriptor() ([]byte, []int) {
 	return file_hw_proto_rawDescGZIP(), []int{1}
 }
@@ -668,8 +682,8 @@ func file_hw_proto_rawDescGZIP() []byte {
 
 var file_hw_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
 var file_hw_proto_goTypes = []interface{}{
-	(*HelloRequest)(nil),            // 0: helloworld.HelloRequest
-	(*HelloReply)(nil),              // 1: helloworld.HelloReply
+	(*HelloRequest)(nil),            // 0: helloworld.RestHelloRequest
+	(*HelloReply)(nil),              // 1: helloworld.RestHelloReply
 	(*Response)(nil),                // 2: helloworld.Response
 	(*InferRequest)(nil),            // 3: helloworld.InferRequest
 	(*Box)(nil),                     // 4: helloworld.Box
@@ -684,12 +698,12 @@ var file_hw_proto_goTypes = []interface{}{
 var file_hw_proto_depIdxs = []int32{
 	4,  // 0: helloworld.FeatureResult.box:type_name -> helloworld.Box
 	5,  // 1: helloworld.FeatureResponse.feature:type_name -> helloworld.FeatureResult
-	0,  // 2: helloworld.Greeter.SayHello:input_type -> helloworld.HelloRequest
+	0,  // 2: helloworld.Greeter.SayHello:input_type -> helloworld.RestHelloRequest
 	3,  // 3: helloworld.Greeter.Compute:input_type -> helloworld.InferRequest
 	9,  // 4: helloworld.Greeter.get_feature:input_type -> google.protobuf.BytesValue
 	7,  // 5: helloworld.Greeter.object_detection:input_type -> helloworld.ObjectDetectionRequest
 	10, // 6: helloworld.Greeter.getStatus:input_type -> google.protobuf.Empty
-	1,  // 7: helloworld.Greeter.SayHello:output_type -> helloworld.HelloReply
+	1,  // 7: helloworld.Greeter.SayHello:output_type -> helloworld.RestHelloReply
 	2,  // 8: helloworld.Greeter.Compute:output_type -> helloworld.Response
 	6,  // 9: helloworld.Greeter.get_feature:output_type -> helloworld.FeatureResponse
 	8,  // 10: helloworld.Greeter.object_detection:output_type -> helloworld.ObjectDetectionResponse

+ 15 - 1
internal/service/test/schemas/helloworld/hw_grpc.pb.go

@@ -1,6 +1,20 @@
+// Copyright 2023 EMQ Technologies Co., Ltd.
+//
+// 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
+//
+//     http://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.
+
 // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
 
-package helloworld
+package service
 
 import (
 	context "context"

+ 2 - 1
internal/service/manager.go

@@ -1,4 +1,4 @@
-// Copyright 2021 EMQ Technologies Co., Ltd.
+// Copyright 2021-2023 EMQ Technologies Co., Ltd.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -102,6 +102,7 @@ func GetManager() *Manager {
 	return singleton
 }
 
+// InitByFiles
 /**
  * This function will parse the service definition json files in etc/services.
  * It will validate all json files and their schemaFiles. If invalid, it just prints

File diff suppressed because it is too large
+ 234 - 1
internal/service/manager_test.go


+ 13 - 1
internal/service/schema_test.go

@@ -1,4 +1,4 @@
-// Copyright 2021 EMQ Technologies Co., Ltd.
+// Copyright 2021-2023 EMQ Technologies Co., Ltd.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -45,6 +45,7 @@ func TestConvertParams(t *testing.T) {
 		params  []interface{}
 		iresult []interface{}
 		jresult []byte
+		tresult []byte
 		err     string
 	}{
 		{ //0
@@ -56,6 +57,7 @@ func TestConvertParams(t *testing.T) {
 				"world",
 			},
 			jresult: []byte(`{"name":"world"}`),
+			tresult: []byte(`name:"world"`),
 		},
 		{ //1
 			method: "SayHello",
@@ -68,6 +70,7 @@ func TestConvertParams(t *testing.T) {
 				"world",
 			},
 			jresult: []byte(`{"name":"world"}`),
+			tresult: []byte(`name:"world"`),
 		},
 		{ //2
 			method: "SayHello",
@@ -87,6 +90,7 @@ func TestConvertParams(t *testing.T) {
 				"rid", "uuid", "outlet", "path", []byte("data"), "extra",
 			},
 			jresult: []byte(`{"rid":"rid","uuid":"uuid","outlet":"outlet","path":"path","data":"ZGF0YQ==","extra":"extra"}`),
+			tresult: []byte(`rid:"rid" uuid:"uuid" outlet:"outlet" path:"path" data:"data" extra:"extra"`),
 		},
 		{ //4
 			method: "get_feature",
@@ -97,6 +101,7 @@ func TestConvertParams(t *testing.T) {
 				[]byte("golang"),
 			},
 			jresult: []byte(`"Z29sYW5n"`),
+			tresult: []byte(`value:"golang"`),
 		},
 		//{ //5
 		//	method: "get_similarity",
@@ -119,6 +124,7 @@ func TestConvertParams(t *testing.T) {
 				"{\"name\":\"encoded json\",\"size\":1}",
 			},
 			jresult: []byte("{\"name\":\"encoded json\",\"size\":1}"),
+			tresult: []byte(`value:"{\"name\":\"encoded json\",\"size\":1}"`),
 		},
 	}
 
@@ -136,6 +142,12 @@ func TestConvertParams(t *testing.T) {
 			} else if tt.err == "" && !reflect.DeepEqual(tt.jresult, rj) {
 				t.Errorf("%d.%d \n\njson result mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, j, tt.jresult, rj)
 			}
+			tj, err := descriptor.(textDescriptor).ConvertParamsToText(tt.method, tt.params)
+			if !reflect.DeepEqual(tt.err, testx.Errstring(err)) {
+				t.Errorf("%d.%d : text error mismatch:\n  exp=%s\n  got=%s\n\n", i, j, tt.err, err)
+			} else if tt.err == "" && !reflect.DeepEqual(tt.tresult, tj) {
+				t.Errorf("%d.%d \n\ntext result mismatch:\n\nexp=%s\n\ngot=%s\n\n", i, j, tt.tresult, tj)
+			}
 		}
 	}
 }

+ 26 - 0
internal/service/test/toadd/dynamic.json

@@ -0,0 +1,26 @@
+{
+  "about": {
+    "author": {
+      "name": "EMQ",
+      "email": "contact@emqx.io",
+      "company": "EMQ Technologies Co., Ltd",
+      "website": "https://www.emqx.io"
+    },
+    "helpUrl": {
+      "en_US": "https://github.com/lf-edge/ekuiper/blob/master/docs/en_US/plugins/functions/functions.md",
+      "zh_CN": "https://github.com/lf-edge/ekuiper/blob/master/docs/zh_CN/plugins/functions/functions.md"
+    },
+    "description": {
+      "en_US": "Sample external services to add dynamically, for test only",
+      "zh_CN": "示例外部函数配置,用于动态载入,仅供测试"
+    }
+  },
+  "interfaces": {
+    "tsrpc": {
+      "address": "tcp://localhost:60051",
+      "protocol": "grpc",
+      "schemaType": "protobuf",
+      "schemaFile": "hw2.proto"
+    }
+  }
+}

+ 41 - 0
internal/service/test/toadd/schemas/hw2.proto

@@ -0,0 +1,41 @@
+// Copyright 2021 EMQ Technologies Co., Ltd.
+//
+// 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
+//
+//     http://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.
+
+syntax = "proto3";
+
+option go_package = "grpc/helloworld2";
+option java_multiple_files = true;
+option java_package = "io.grpc.examples.helloworld2";
+option java_outer_classname = "HelloWorldProto2";
+
+package helloworld2;
+
+import "google/protobuf/empty.proto";
+import "google/protobuf/wrappers.proto";
+
+// The greeting service definition.
+service Greeter2 {
+  // Sends a greeting
+  rpc SayHello2(HelloRequest2) returns (HelloReply2) {}
+}
+
+// The request message containing the user's name.
+message HelloRequest2 {
+  string name = 1;
+}
+
+// The response message containing the greetings
+message HelloReply2 {
+  string message = 1;
+}