Skip to content

Commit

Permalink
Replacing comparison of proto messages (networkservicemesh#601)
Browse files Browse the repository at this point in the history
* Replacing comparison of proto messages

Signed-off-by: Artem Glazychev <artem.glazychev@xored.com>

* Add tests for network service endpoints matching by label

Signed-off-by: Artem Glazychev <artem.glazychev@xored.com>
Signed-off-by: Sergey Ershov <sergey.ershov@xored.com>
  • Loading branch information
glazychev-art authored and Sergey Ershov committed Dec 20, 2020
1 parent 0142c73 commit f98513f
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 9 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/fsnotify/fsnotify v1.4.9
github.com/ghodss/yaml v1.0.0
github.com/golang/protobuf v1.4.3
github.com/google/go-cmp v0.5.2
github.com/google/uuid v1.1.2
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645
github.com/hashicorp/go-multierror v1.0.0
Expand Down
7 changes: 4 additions & 3 deletions pkg/networkservice/common/heal/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ package heal_test
import (
"context"
"io/ioutil"
"reflect"
"testing"
"time"

"google.golang.org/protobuf/proto"

"github.com/networkservicemesh/sdk/pkg/tools/sandbox"

"github.com/golang/protobuf/ptypes/empty"
Expand Down Expand Up @@ -194,11 +195,11 @@ func TestNewClient_MissingConnectionsInInit(t *testing.T) {
defer cancel()
conn, err := client.Request(ctx, &networkservice.NetworkServiceRequest{Connection: conns[0]})
require.Nil(t, err)
require.True(t, reflect.DeepEqual(conn, conns[0]))
require.True(t, proto.Equal(conn, conns[0]))

conn, err = client.Request(ctx, &networkservice.NetworkServiceRequest{Connection: conns[1]})
require.Nil(t, err)
require.True(t, reflect.DeepEqual(conn, conns[1]))
require.True(t, proto.Equal(conn, conns[1]))

eventCh <- &networkservice.ConnectionEvent{
Type: networkservice.ConnectionEventType_INITIAL_STATE_TRANSFER,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
package roundrobin

import (
"reflect"
"testing"

"google.golang.org/protobuf/proto"

"github.com/networkservicemesh/api/pkg/api/registry"
"go.uber.org/goleak"
)
Expand Down Expand Up @@ -228,7 +229,7 @@ func Test_roundRobinSelector_SelectEndpoint(t *testing.T) {
defer goleak.VerifyNone(t, goleak.IgnoreCurrent())
rr := newRoundRobinSelector()
for _, tt := range tests {
if got := rr.selectEndpoint(tt.args.ns, tt.args.networkServiceEndpoints); !reflect.DeepEqual(got, tt.want) {
if got := rr.selectEndpoint(tt.args.ns, tt.args.networkServiceEndpoints); !proto.Equal(got, tt.want) {
t.Errorf("%s: roundRobinSelector.selectEndpoint() = %v, want %v", tt.name, got, tt.want)
}
}
Expand Down
131 changes: 131 additions & 0 deletions pkg/registry/memory/nse_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,134 @@ func TestNetworkServiceEndpointRegistryServer_RegisterAndFindWatch(t *testing.T)

close(ch)
}

func TestNetworkServiceEndpointRegistryServer_RegisterAndFindByLabel(t *testing.T) {
defer goleak.VerifyNone(t, goleak.IgnoreCurrent())
s := next.NewNetworkServiceEndpointRegistryServer(memory.NewNetworkServiceEndpointRegistryServer())

_, err := s.Register(context.Background(), createLabeledNSE1())
require.NoError(t, err)

_, err = s.Register(context.Background(), createLabeledNSE2())
require.NoError(t, err)

_, err = s.Register(context.Background(), createLabeledNSE3())
require.NoError(t, err)

ctx, cancel := context.WithCancel(context.Background())
ch := make(chan *registry.NetworkServiceEndpoint, 1)
_ = s.Find(&registry.NetworkServiceEndpointQuery{
NetworkServiceEndpoint: &registry.NetworkServiceEndpoint{
NetworkServiceLabels: map[string]*registry.NetworkServiceLabels{
"Service1": {
Labels: map[string]string{
"c": "d",
},
},
},
},
}, streamchannel.NewNetworkServiceEndpointFindServer(ctx, ch))

require.Equal(t, createLabeledNSE2(), <-ch)
cancel()
close(ch)
}

func TestNetworkServiceEndpointRegistryServer_RegisterAndFindByLabelWatch(t *testing.T) {
defer goleak.VerifyNone(t, goleak.IgnoreCurrent())
s := next.NewNetworkServiceEndpointRegistryServer(memory.NewNetworkServiceEndpointRegistryServer())

_, err := s.Register(context.Background(), createLabeledNSE1())
require.NoError(t, err)

_, err = s.Register(context.Background(), createLabeledNSE2())
require.NoError(t, err)

_, err = s.Register(context.Background(), createLabeledNSE3())
require.NoError(t, err)

ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ch := make(chan *registry.NetworkServiceEndpoint, 1)
go func() {
_ = s.Find(&registry.NetworkServiceEndpointQuery{
Watch: true,
NetworkServiceEndpoint: &registry.NetworkServiceEndpoint{
NetworkServiceLabels: map[string]*registry.NetworkServiceLabels{
"Service1": {
Labels: map[string]string{
"c": "d",
},
},
},
},
}, streamchannel.NewNetworkServiceEndpointFindServer(ctx, ch))
}()

require.Equal(t, createLabeledNSE2(), <-ch)

expected, err := s.Register(context.Background(), createLabeledNSE2())
require.NoError(t, err)
require.Equal(t, expected, <-ch)

close(ch)
}

func createLabeledNSE1() *registry.NetworkServiceEndpoint {
labels := map[string]*registry.NetworkServiceLabels{
"Service1": {
Labels: map[string]string{
"foo": "bar",
},
},
}
return &registry.NetworkServiceEndpoint{
Name: "nse1",
NetworkServiceNames: []string{
"Service1",
},
NetworkServiceLabels: labels,
}
}

func createLabeledNSE2() *registry.NetworkServiceEndpoint {
labels := map[string]*registry.NetworkServiceLabels{
"Service1": {
Labels: map[string]string{
"a": "b",
"c": "d",
},
},
"Service2": {
Labels: map[string]string{
"1": "2",
"3": "4",
},
},
}
return &registry.NetworkServiceEndpoint{
Name: "nse2",
NetworkServiceNames: []string{
"Service1", "Service2",
},
NetworkServiceLabels: labels,
}
}

func createLabeledNSE3() *registry.NetworkServiceEndpoint {
labels := map[string]*registry.NetworkServiceLabels{
"Service555": {
Labels: map[string]string{
"a": "b",
"c": "d",
},
},
}
return &registry.NetworkServiceEndpoint{
Name: "nse3",
NetworkServiceNames: []string{
"Service1",
},
NetworkServiceLabels: labels,
}
}
26 changes: 22 additions & 4 deletions pkg/tools/matchutils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,47 @@
package matchutils

import (
"reflect"
"strings"

"github.com/google/go-cmp/cmp"
"google.golang.org/protobuf/proto"

"github.com/networkservicemesh/api/pkg/api/registry"
)

// MatchNetworkServices returns true if two network services are matched
func MatchNetworkServices(left, right *registry.NetworkService) bool {
return (left.Name == "" || strings.Contains(right.Name, left.Name)) &&
(left.Payload == "" || left.Payload == right.Payload) &&
(left.Matches == nil || reflect.DeepEqual(left.Matches, right.Matches))
(left.Matches == nil || cmp.Equal(left.Matches, right.Matches, cmp.Comparer(proto.Equal)))
}

// MatchNetworkServiceEndpoints returns true if two network service endpoints are matched
func MatchNetworkServiceEndpoints(left, right *registry.NetworkServiceEndpoint) bool {
return (left.Name == "" || strings.Contains(right.Name, left.Name)) &&
(left.NetworkServiceLabels == nil || reflect.DeepEqual(left.NetworkServiceLabels, right.NetworkServiceLabels)) &&
(left.NetworkServiceLabels == nil || labelsContains(right.NetworkServiceLabels, left.NetworkServiceLabels)) &&
(left.ExpirationTime == nil || left.ExpirationTime.Seconds == right.ExpirationTime.Seconds) &&
(left.NetworkServiceNames == nil || contains(right.NetworkServiceNames, left.NetworkServiceNames)) &&
(left.Url == "" || strings.Contains(right.Url, left.Url))
}

func contains(what, where []string) bool {
func labelsContains(where, what map[string]*registry.NetworkServiceLabels) bool {
for lService, lLabels := range what {
rService, ok := where[lService]
if !ok {
return false
}
for lKey, lVal := range lLabels.Labels {
rVal, ok := rService.Labels[lKey]
if !ok || lVal != rVal {
return false
}
}
}
return true
}

func contains(where, what []string) bool {
set := make(map[string]struct{})
for _, s := range what {
set[s] = struct{}{}
Expand Down

0 comments on commit f98513f

Please sign in to comment.