Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
3be0566550 | |||
e6feca2fb1 | |||
37fa3d6696 | |||
47940a5ca2 | |||
d667bbee0c | |||
96dd5d869a | |||
ea90948315 | |||
a382ea7d45 | |||
|
cdfeaa7e20 | ||
|
c09674ae92 | ||
|
0d497ca0df |
@@ -5,8 +5,8 @@ on:
|
||||
- 'master'
|
||||
- 'v3'
|
||||
schedule:
|
||||
- cron: '* * * * *'
|
||||
#- cron: '@hourly'
|
||||
#- cron: '* * * * *'
|
||||
- cron: '@hourly'
|
||||
|
||||
jobs:
|
||||
autoupdate:
|
||||
|
@@ -20,4 +20,4 @@ jobs:
|
||||
- name: test
|
||||
env:
|
||||
INTEGRATION_TESTS: yes
|
||||
run: go test -mod readonly -v ./...
|
||||
run: go test -v -mod readonly -race -coverprofile=coverage.txt -covermode=atomic ./...
|
94
micro.go
Normal file
94
micro.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package micro
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"go.unistack.org/micro/v4/broker"
|
||||
"go.unistack.org/micro/v4/client"
|
||||
"go.unistack.org/micro/v4/codec"
|
||||
"go.unistack.org/micro/v4/flow"
|
||||
"go.unistack.org/micro/v4/fsm"
|
||||
"go.unistack.org/micro/v4/logger"
|
||||
"go.unistack.org/micro/v4/meter"
|
||||
"go.unistack.org/micro/v4/register"
|
||||
"go.unistack.org/micro/v4/resolver"
|
||||
"go.unistack.org/micro/v4/router"
|
||||
"go.unistack.org/micro/v4/selector"
|
||||
"go.unistack.org/micro/v4/server"
|
||||
"go.unistack.org/micro/v4/store"
|
||||
"go.unistack.org/micro/v4/sync"
|
||||
"go.unistack.org/micro/v4/tracer"
|
||||
)
|
||||
|
||||
func As(b any, target any) bool {
|
||||
if b == nil {
|
||||
return false
|
||||
}
|
||||
if target == nil {
|
||||
return false
|
||||
}
|
||||
val := reflect.ValueOf(target)
|
||||
typ := val.Type()
|
||||
if typ.Kind() != reflect.Ptr || val.IsNil() {
|
||||
return false
|
||||
}
|
||||
targetType := typ.Elem()
|
||||
if targetType.Kind() != reflect.Interface {
|
||||
switch {
|
||||
case targetType.Implements(brokerType):
|
||||
break
|
||||
case targetType.Implements(loggerType):
|
||||
break
|
||||
case targetType.Implements(clientType):
|
||||
break
|
||||
case targetType.Implements(serverType):
|
||||
break
|
||||
case targetType.Implements(codecType):
|
||||
break
|
||||
case targetType.Implements(flowType):
|
||||
break
|
||||
case targetType.Implements(fsmType):
|
||||
break
|
||||
case targetType.Implements(meterType):
|
||||
break
|
||||
case targetType.Implements(registerType):
|
||||
break
|
||||
case targetType.Implements(resolverType):
|
||||
break
|
||||
case targetType.Implements(selectorType):
|
||||
break
|
||||
case targetType.Implements(storeType):
|
||||
break
|
||||
case targetType.Implements(syncType):
|
||||
break
|
||||
case targetType.Implements(serviceType):
|
||||
break
|
||||
case targetType.Implements(routerType):
|
||||
break
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
if reflect.TypeOf(b).AssignableTo(targetType) {
|
||||
val.Elem().Set(reflect.ValueOf(b))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var brokerType = reflect.TypeOf((*broker.Broker)(nil)).Elem()
|
||||
var loggerType = reflect.TypeOf((*logger.Logger)(nil)).Elem()
|
||||
var clientType = reflect.TypeOf((*client.Client)(nil)).Elem()
|
||||
var serverType = reflect.TypeOf((*server.Server)(nil)).Elem()
|
||||
var codecType = reflect.TypeOf((*codec.Codec)(nil)).Elem()
|
||||
var flowType = reflect.TypeOf((*flow.Flow)(nil)).Elem()
|
||||
var fsmType = reflect.TypeOf((*fsm.FSM)(nil)).Elem()
|
||||
var meterType = reflect.TypeOf((*meter.Meter)(nil)).Elem()
|
||||
var registerType = reflect.TypeOf((*register.Register)(nil)).Elem()
|
||||
var resolverType = reflect.TypeOf((*resolver.Resolver)(nil)).Elem()
|
||||
var routerType = reflect.TypeOf((*router.Router)(nil)).Elem()
|
||||
var selectorType = reflect.TypeOf((*selector.Selector)(nil)).Elem()
|
||||
var storeType = reflect.TypeOf((*store.Store)(nil)).Elem()
|
||||
var syncType = reflect.TypeOf((*sync.Sync)(nil)).Elem()
|
||||
var tracerType = reflect.TypeOf((*tracer.Tracer)(nil)).Elem()
|
||||
var serviceType = reflect.TypeOf((*Service)(nil)).Elem()
|
103
micro_test.go
Normal file
103
micro_test.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package micro
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"go.unistack.org/micro/v4/broker"
|
||||
"go.unistack.org/micro/v4/fsm"
|
||||
"go.unistack.org/micro/v4/options"
|
||||
)
|
||||
|
||||
func TestAs(t *testing.T) {
|
||||
var b *bro
|
||||
broTarget := &bro{name: "kafka"}
|
||||
fsmTarget := &fsmT{name: "fsm"}
|
||||
|
||||
testCases := []struct {
|
||||
b any
|
||||
target any
|
||||
match bool
|
||||
want any
|
||||
}{
|
||||
{
|
||||
broTarget,
|
||||
&b,
|
||||
true,
|
||||
broTarget,
|
||||
},
|
||||
{
|
||||
nil,
|
||||
&b,
|
||||
false,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
fsmTarget,
|
||||
&b,
|
||||
false,
|
||||
nil,
|
||||
},
|
||||
}
|
||||
for i, tc := range testCases {
|
||||
name := fmt.Sprintf("%d:As(Errorf(..., %v), %v)", i, tc.b, tc.target)
|
||||
// Clear the target pointer, in case it was set in a previous test.
|
||||
rtarget := reflect.ValueOf(tc.target)
|
||||
rtarget.Elem().Set(reflect.Zero(reflect.TypeOf(tc.target).Elem()))
|
||||
t.Run(name, func(t *testing.T) {
|
||||
match := As(tc.b, tc.target)
|
||||
if match != tc.match {
|
||||
t.Fatalf("match: got %v; want %v", match, tc.match)
|
||||
}
|
||||
if !match {
|
||||
return
|
||||
}
|
||||
if got := rtarget.Elem().Interface(); got != tc.want {
|
||||
t.Fatalf("got %#v, want %#v", got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type bro struct {
|
||||
name string
|
||||
}
|
||||
|
||||
func (p *bro) Name() string { return p.name }
|
||||
func (p *bro) Init(opts ...options.Option) error { return nil }
|
||||
|
||||
// Options returns broker options
|
||||
func (p *bro) Options() broker.Options { return broker.Options{} }
|
||||
|
||||
// Address return configured address
|
||||
func (p *bro) Address() string { return "" }
|
||||
|
||||
// Connect connects to broker
|
||||
func (p *bro) Connect(ctx context.Context) error { return nil }
|
||||
|
||||
// Disconnect disconnect from broker
|
||||
func (p *bro) Disconnect(ctx context.Context) error { return nil }
|
||||
|
||||
// Publish message, msg can be single broker.Message or []broker.Message
|
||||
func (p *bro) Publish(ctx context.Context, msg interface{}, opts ...options.Option) error { return nil }
|
||||
|
||||
// Subscribe subscribes to topic message via handler
|
||||
func (p *bro) Subscribe(ctx context.Context, topic string, handler interface{}, opts ...options.Option) (broker.Subscriber, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// String type of broker
|
||||
func (p *bro) String() string { return p.name }
|
||||
|
||||
type fsmT struct {
|
||||
name string
|
||||
}
|
||||
|
||||
func (f *fsmT) Start(ctx context.Context, a interface{}, o ...Option) (interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (f *fsmT) Current() string { return f.name }
|
||||
func (f *fsmT) Reset() {}
|
||||
func (f *fsmT) State(s string, sf fsm.StateFunc) {}
|
@@ -151,9 +151,19 @@ func ContentType(ct string) Option {
|
||||
}
|
||||
|
||||
// Metadata pass additional metadata
|
||||
func Metadata(md metadata.Metadata) Option {
|
||||
func Metadata(md any) Option {
|
||||
result := metadata.Metadata{}
|
||||
switch vt := md.(type) {
|
||||
case metadata.Metadata:
|
||||
result = metadata.Copy(vt)
|
||||
case map[string]string:
|
||||
result = metadata.Copy(vt)
|
||||
case []string:
|
||||
result.Set(vt...)
|
||||
}
|
||||
|
||||
return func(src interface{}) error {
|
||||
return Set(src, metadata.Copy(md), ".Metadata")
|
||||
return Set(src, result, ".Metadata")
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,10 +1,13 @@
|
||||
package options_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"go.unistack.org/micro/v4/codec"
|
||||
"go.unistack.org/micro/v4/metadata"
|
||||
"go.unistack.org/micro/v4/options"
|
||||
"go.unistack.org/micro/v4/util/reflect"
|
||||
)
|
||||
|
||||
func TestAddress(t *testing.T) {
|
||||
@@ -84,3 +87,69 @@ func TestLabels(t *testing.T) {
|
||||
t.Fatal("failed to set labels")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetadataAny(t *testing.T) {
|
||||
type s struct {
|
||||
Metadata metadata.Metadata
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
Name string
|
||||
Data any
|
||||
Expected metadata.Metadata
|
||||
}{
|
||||
{
|
||||
"strings_even",
|
||||
[]string{"key1", "val1", "key2", "val2"},
|
||||
metadata.Metadata{
|
||||
"Key1": "val1",
|
||||
"Key2": "val2",
|
||||
},
|
||||
},
|
||||
{
|
||||
"strings_odd",
|
||||
[]string{"key1", "val1", "key2"},
|
||||
metadata.Metadata{
|
||||
"Key1": "val1",
|
||||
},
|
||||
},
|
||||
{
|
||||
"map",
|
||||
map[string]string{
|
||||
"key1": "val1",
|
||||
"key2": "val2",
|
||||
},
|
||||
metadata.Metadata{
|
||||
"Key1": "val1",
|
||||
"Key2": "val2",
|
||||
},
|
||||
},
|
||||
{
|
||||
"metadata.Metadata",
|
||||
metadata.Metadata{
|
||||
"key1": "val1",
|
||||
"key2": "val2",
|
||||
},
|
||||
metadata.Metadata{
|
||||
"Key1": "val1",
|
||||
"Key2": "val2",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range testCases {
|
||||
t.Run(tt.Name, func(t *testing.T) {
|
||||
src := &s{}
|
||||
var opts []options.Option
|
||||
opts = append(opts, options.Metadata(tt.Data))
|
||||
for _, o := range opts {
|
||||
if err := o(src); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.Equal(tt.Expected, src.Metadata) {
|
||||
t.Fatal(fmt.Sprintf("expected: %v, actual: %v", tt.Expected, src.Metadata))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user