test(contrib): add unit test for opensergo.go (#2137)
parent
13c33fc4d3
commit
3905182e98
@ -0,0 +1,385 @@ |
|||||||
|
package opensergo |
||||||
|
|
||||||
|
import ( |
||||||
|
"io/ioutil" |
||||||
|
"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 := ioutil.WriteFile("test.json", []byte(fileContent), 0o644) |
||||||
|
if err != nil { |
||||||
|
t.Fatalf("ioutil.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 |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue