You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
385 lines
8.6 KiB
385 lines
8.6 KiB
2 years ago
|
package opensergo
|
||
|
|
||
|
import (
|
||
|
"net"
|
||
|
"os"
|
||
|
"path/filepath"
|
||
|
"reflect"
|
||
|
"testing"
|
||
|
|
||
|
srvContractPb "github.com/opensergo/opensergo-go/proto/service_contract/v1"
|
||
|
"golang.org/x/net/context"
|
||
|
"google.golang.org/genproto/googleapis/api/annotations"
|
||
|
"google.golang.org/grpc"
|
||
|
"google.golang.org/protobuf/proto"
|
||
|
"google.golang.org/protobuf/reflect/protodesc"
|
||
|
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||
|
"google.golang.org/protobuf/reflect/protoregistry"
|
||
|
"google.golang.org/protobuf/types/descriptorpb"
|
||
|
)
|
||
|
|
||
|
type testMetadataServiceServer struct {
|
||
|
srvContractPb.UnimplementedMetadataServiceServer
|
||
|
}
|
||
|
|
||
|
func (m *testMetadataServiceServer) ReportMetadata(ctx context.Context, req *srvContractPb.ReportMetadataRequest) (*srvContractPb.ReportMetadataReply, error) {
|
||
|
return &srvContractPb.ReportMetadataReply{}, nil
|
||
|
}
|
||
|
|
||
|
type testAppInfo struct {
|
||
|
id string
|
||
|
name string
|
||
|
version string
|
||
|
metaData map[string]string
|
||
|
endpoint []string
|
||
|
}
|
||
|
|
||
|
func (t testAppInfo) ID() string {
|
||
|
return t.id
|
||
|
}
|
||
|
|
||
|
func (t testAppInfo) Name() string {
|
||
|
return t.name
|
||
|
}
|
||
|
|
||
|
func (t testAppInfo) Version() string {
|
||
|
return t.version
|
||
|
}
|
||
|
|
||
|
func (t testAppInfo) Metadata() map[string]string {
|
||
|
return t.metaData
|
||
|
}
|
||
|
|
||
|
func (t testAppInfo) Endpoint() []string {
|
||
|
return t.endpoint
|
||
|
}
|
||
|
|
||
|
func TestWithEndpoint(t *testing.T) {
|
||
|
o := &options{}
|
||
|
v := "127.0.0.1:9090"
|
||
|
WithEndpoint(v)(o)
|
||
|
if !reflect.DeepEqual(v, o.Endpoint) {
|
||
|
t.Fatalf("o.Endpoint:%s is not equal to v:%s", o.Endpoint, v)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestOptionsParseJSON(t *testing.T) {
|
||
|
want := &options{
|
||
|
Endpoint: "127.0.0.1:9090",
|
||
|
}
|
||
|
o := &options{}
|
||
|
if err := o.ParseJSON([]byte(`{"endpoint":"127.0.0.1:9090"}`)); err != nil {
|
||
|
t.Fatalf("o.ParseJSON(v) error:%s", err)
|
||
|
}
|
||
|
if !reflect.DeepEqual(o, want) {
|
||
|
t.Fatalf("o:%v is not equal to want:%v", o, want)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestListDescriptors(t *testing.T) {
|
||
|
testPb := &descriptorpb.FileDescriptorProto{
|
||
|
Syntax: proto.String("proto3"),
|
||
|
Name: proto.String("test.proto"),
|
||
|
Package: proto.String("test"),
|
||
|
MessageType: []*descriptorpb.DescriptorProto{
|
||
|
{
|
||
|
Name: proto.String("TestMessage"),
|
||
|
Field: []*descriptorpb.FieldDescriptorProto{
|
||
|
{
|
||
|
Name: proto.String("id"),
|
||
|
JsonName: proto.String("id"),
|
||
|
Number: proto.Int32(1),
|
||
|
Type: descriptorpb.FieldDescriptorProto_Type(pref.Int32Kind).Enum(),
|
||
|
},
|
||
|
{
|
||
|
Name: proto.String("name"),
|
||
|
JsonName: proto.String("name"),
|
||
|
Number: proto.Int32(2),
|
||
|
Type: descriptorpb.FieldDescriptorProto_Type(pref.StringKind).Enum(),
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
Service: []*descriptorpb.ServiceDescriptorProto{
|
||
|
{
|
||
|
Name: proto.String("TestService"),
|
||
|
Method: []*descriptorpb.MethodDescriptorProto{
|
||
|
{
|
||
|
Name: proto.String("Create"),
|
||
|
InputType: proto.String("TestMessage"),
|
||
|
OutputType: proto.String("TestMessage"),
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
fd, err := protodesc.NewFile(testPb, nil)
|
||
|
if err != nil {
|
||
|
t.Fatalf("protodesc.NewFile(pb, nil) error:%s", err)
|
||
|
}
|
||
|
|
||
|
protoregistry.GlobalFiles = new(protoregistry.Files)
|
||
|
err = protoregistry.GlobalFiles.RegisterFile(fd)
|
||
|
if err != nil {
|
||
|
t.Fatalf("protoregistry.GlobalFiles.RegisterFile(fd) error:%s", err)
|
||
|
}
|
||
|
|
||
|
want := struct {
|
||
|
services []*srvContractPb.ServiceDescriptor
|
||
|
types []*srvContractPb.TypeDescriptor
|
||
|
}{
|
||
|
services: []*srvContractPb.ServiceDescriptor{
|
||
|
{
|
||
|
Name: "TestService",
|
||
|
Methods: []*srvContractPb.MethodDescriptor{
|
||
|
{
|
||
|
Name: "Create",
|
||
|
InputTypes: []string{"test.TestMessage"},
|
||
|
OutputTypes: []string{"test.TestMessage"},
|
||
|
ClientStreaming: proto.Bool(false),
|
||
|
ServerStreaming: proto.Bool(false),
|
||
|
Description: nil,
|
||
|
HttpPaths: []string{""},
|
||
|
HttpMethods: []string{""},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
types: []*srvContractPb.TypeDescriptor{
|
||
|
{
|
||
|
Name: "TestMessage",
|
||
|
Fields: []*srvContractPb.FieldDescriptor{
|
||
|
{
|
||
|
Name: "id",
|
||
|
Number: int32(1),
|
||
|
Type: srvContractPb.FieldDescriptor_TYPE_INT32,
|
||
|
TypeName: proto.String("int32"),
|
||
|
},
|
||
|
{
|
||
|
Name: "name",
|
||
|
Number: int32(2),
|
||
|
Type: srvContractPb.FieldDescriptor_TYPE_STRING,
|
||
|
TypeName: proto.String("string"),
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
services, types, err := listDescriptors()
|
||
|
if err != nil {
|
||
|
t.Fatalf("listDescriptors error:%s", err)
|
||
|
}
|
||
|
|
||
|
if !reflect.DeepEqual(services, want.services) {
|
||
|
t.Fatalf("services:%v is not equal to want.services:%v", services, want.services)
|
||
|
}
|
||
|
if !reflect.DeepEqual(types, want.types) {
|
||
|
t.Fatalf("types:%v is not equal to want.types:%v", types, want.types)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestHTTPPatternInfo(t *testing.T) {
|
||
|
type args struct {
|
||
|
pattern interface{}
|
||
|
}
|
||
|
tests := []struct {
|
||
|
name string
|
||
|
args args
|
||
|
wantMethod string
|
||
|
wantPath string
|
||
|
}{
|
||
|
{
|
||
|
name: "get",
|
||
|
args: args{
|
||
|
pattern: &annotations.HttpRule_Get{Get: "/foo"},
|
||
|
},
|
||
|
wantMethod: "GET",
|
||
|
wantPath: "/foo",
|
||
|
},
|
||
|
{
|
||
|
name: "post",
|
||
|
args: args{
|
||
|
pattern: &annotations.HttpRule_Post{Post: "/foo"},
|
||
|
},
|
||
|
wantMethod: "POST",
|
||
|
wantPath: "/foo",
|
||
|
},
|
||
|
{
|
||
|
name: "put",
|
||
|
args: args{
|
||
|
pattern: &annotations.HttpRule_Put{Put: "/foo"},
|
||
|
},
|
||
|
wantMethod: "PUT",
|
||
|
wantPath: "/foo",
|
||
|
},
|
||
|
{
|
||
|
name: "delete",
|
||
|
args: args{
|
||
|
pattern: &annotations.HttpRule_Delete{Delete: "/foo"},
|
||
|
},
|
||
|
wantMethod: "DELETE",
|
||
|
wantPath: "/foo",
|
||
|
},
|
||
|
{
|
||
|
name: "patch",
|
||
|
args: args{
|
||
|
pattern: &annotations.HttpRule_Patch{Patch: "/foo"},
|
||
|
},
|
||
|
wantMethod: "PATCH",
|
||
|
wantPath: "/foo",
|
||
|
},
|
||
|
{
|
||
|
name: "custom",
|
||
|
args: args{
|
||
|
pattern: &annotations.HttpRule_Custom{
|
||
|
Custom: &annotations.CustomHttpPattern{
|
||
|
Kind: "CUSTOM",
|
||
|
Path: "/foo",
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
wantMethod: "CUSTOM",
|
||
|
wantPath: "/foo",
|
||
|
},
|
||
|
{
|
||
|
name: "other",
|
||
|
args: args{
|
||
|
pattern: nil,
|
||
|
},
|
||
|
wantMethod: "",
|
||
|
wantPath: "",
|
||
|
},
|
||
|
}
|
||
|
for _, tt := range tests {
|
||
|
t.Run(tt.name, func(t *testing.T) {
|
||
|
gotMethod, gotPath := HTTPPatternInfo(tt.args.pattern)
|
||
|
if gotMethod != tt.wantMethod {
|
||
|
t.Errorf("HTTPPatternInfo() gotMethod = %v, want %v", gotMethod, tt.wantMethod)
|
||
|
}
|
||
|
if gotPath != tt.wantPath {
|
||
|
t.Errorf("HTTPPatternInfo() gotPath = %v, want %v", gotPath, tt.wantPath)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestOpenSergo(t *testing.T) {
|
||
|
srv := grpc.NewServer()
|
||
|
srvContractPb.RegisterMetadataServiceServer(srv, new(testMetadataServiceServer))
|
||
|
lis, err := net.Listen("tcp", "127.0.0.1:9090")
|
||
|
if err != nil {
|
||
|
t.Fatalf("net.Listen error:%s", err)
|
||
|
}
|
||
|
go func() {
|
||
|
err := srv.Serve(lis)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
}()
|
||
|
|
||
|
app := &testAppInfo{
|
||
|
name: "testApp",
|
||
|
endpoint: []string{"//example.com:9090", "//foo.com:9090"},
|
||
|
}
|
||
|
|
||
|
type args struct {
|
||
|
opts []Option
|
||
|
}
|
||
|
tests := []struct {
|
||
|
name string
|
||
|
args args
|
||
|
preFunc func(t *testing.T)
|
||
|
deferFunc func(t *testing.T)
|
||
|
wantErr bool
|
||
|
}{
|
||
|
{
|
||
|
name: "test_with_opts",
|
||
|
args: args{
|
||
|
opts: []Option{
|
||
|
WithEndpoint("127.0.0.1:9090"),
|
||
|
},
|
||
|
},
|
||
|
wantErr: false,
|
||
|
},
|
||
|
{
|
||
|
name: "test_with_env_endpoint",
|
||
|
args: args{
|
||
|
opts: []Option{},
|
||
|
},
|
||
|
preFunc: func(t *testing.T) {
|
||
|
err := os.Setenv("OPENSERGO_ENDPOINT", "127.0.0.1:9090")
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
},
|
||
|
wantErr: false,
|
||
|
},
|
||
|
{
|
||
|
name: "test_with_env_config_file",
|
||
|
args: args{
|
||
|
opts: []Option{},
|
||
|
},
|
||
|
preFunc: func(t *testing.T) {
|
||
|
err := os.Setenv("OPENSERGO_BOOTSTRAP", `{"endpoint": "127.0.0.1:9090"}`)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
},
|
||
|
wantErr: false,
|
||
|
},
|
||
|
{
|
||
|
name: "test_with_env_bootstrap",
|
||
|
args: args{
|
||
|
opts: []Option{},
|
||
|
},
|
||
|
preFunc: func(t *testing.T) {
|
||
|
fileContent := `{"endpoint": "127.0.0.1:9090"}`
|
||
|
err := os.WriteFile("test.json", []byte(fileContent), 0o644)
|
||
|
if err != nil {
|
||
|
t.Fatalf("os.WriteFile error:%s", err)
|
||
|
}
|
||
|
confPath, err := filepath.Abs("./test.json")
|
||
|
if err != nil {
|
||
|
t.Fatalf("filepath.Abs error:%s", err)
|
||
|
}
|
||
|
err = os.Setenv("OPENSERGO_BOOTSTRAP_CONFIG", confPath)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
},
|
||
|
deferFunc: func(t *testing.T) {
|
||
|
path := os.Getenv("OPENSERGO_BOOTSTRAP_CONFIG")
|
||
|
if path != "" {
|
||
|
err := os.Remove(path)
|
||
|
if err != nil {
|
||
|
t.Fatalf("os.Remove error:%s", err)
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
wantErr: false,
|
||
|
},
|
||
|
}
|
||
|
for _, tt := range tests {
|
||
|
t.Run(tt.name, func(t *testing.T) {
|
||
|
if tt.preFunc != nil {
|
||
|
tt.preFunc(t)
|
||
|
}
|
||
|
if tt.deferFunc != nil {
|
||
|
defer tt.deferFunc(t)
|
||
|
}
|
||
|
osServer, err := New(tt.args.opts...)
|
||
|
if (err != nil) != tt.wantErr {
|
||
|
t.Errorf("New() error = %v, wantErr %v", err, tt.wantErr)
|
||
|
return
|
||
|
}
|
||
|
err = osServer.ReportMetadata(context.Background(), app)
|
||
|
if (err != nil) != tt.wantErr {
|
||
|
t.Errorf("ReportMetadata() error = %v, wantErr %v", err, tt.wantErr)
|
||
|
return
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|