From 6c9dab481c9eade931ca55e671439e4afd6164ab Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Fri, 15 Jan 2021 11:33:09 +0300 Subject: [PATCH] [#311] control: Cover StableMarshal methods with unit tests Signed-off-by: Leonard Lyubich --- pkg/services/control/common_test.go | 36 +++++++++ pkg/services/control/service_test.go | 55 +++++++++++++ pkg/services/control/types_test.go | 114 +++++++++++++++++++++++++++ 3 files changed, 205 insertions(+) create mode 100644 pkg/services/control/common_test.go create mode 100644 pkg/services/control/service_test.go create mode 100644 pkg/services/control/types_test.go diff --git a/pkg/services/control/common_test.go b/pkg/services/control/common_test.go new file mode 100644 index 000000000..546aa37ca --- /dev/null +++ b/pkg/services/control/common_test.go @@ -0,0 +1,36 @@ +package control_test + +import ( + "crypto/rand" + "testing" + + "github.com/mr-tron/base58" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" +) + +type protoMessage interface { + StableMarshal([]byte) ([]byte, error) + proto.Message +} + +func testStableMarshal(t *testing.T, m1, m2 protoMessage, cmp func(m1, m2 protoMessage) bool) { + data, err := m1.StableMarshal(nil) + require.NoError(t, err) + + require.NoError(t, proto.Unmarshal(data, m2)) + + require.True(t, cmp(m1, m2)) +} + +func testData(sz int) []byte { + d := make([]byte, sz) + + _, _ = rand.Read(d) + + return d +} + +func testString() string { + return base58.Encode(testData(10)) +} diff --git a/pkg/services/control/service_test.go b/pkg/services/control/service_test.go new file mode 100644 index 000000000..78732b2e7 --- /dev/null +++ b/pkg/services/control/service_test.go @@ -0,0 +1,55 @@ +package control_test + +import ( + "testing" + + "github.com/nspcc-dev/neofs-node/pkg/services/control" +) + +func TestHealthCheckResponse_Body_StableMarshal(t *testing.T) { + testStableMarshal(t, + generateHealthCheckResponseBody(), + new(control.HealthCheckResponse_Body), + func(m1, m2 protoMessage) bool { + return equalHealthCheckResponseBodies( + m1.(*control.HealthCheckResponse_Body), + m2.(*control.HealthCheckResponse_Body), + ) + }, + ) +} + +func generateHealthCheckResponseBody() *control.HealthCheckResponse_Body { + body := new(control.HealthCheckResponse_Body) + body.SetStatus(control.HealthStatus_ONLINE) + + return body +} + +func equalHealthCheckResponseBodies(b1, b2 *control.HealthCheckResponse_Body) bool { + return b1.GetStatus() == b2.GetStatus() +} + +func TestNetmapSnapshotResponse_Body_StableMarshal(t *testing.T) { + testStableMarshal(t, + generateNetmapSnapshotResponseBody(), + new(control.NetmapSnapshotResponse_Body), + func(m1, m2 protoMessage) bool { + return equalNetmapSnapshotResponseBodies( + m1.(*control.NetmapSnapshotResponse_Body), + m2.(*control.NetmapSnapshotResponse_Body), + ) + }, + ) +} + +func generateNetmapSnapshotResponseBody() *control.NetmapSnapshotResponse_Body { + body := new(control.NetmapSnapshotResponse_Body) + body.SetNetmap(generateNetmap()) + + return body +} + +func equalNetmapSnapshotResponseBodies(b1, b2 *control.NetmapSnapshotResponse_Body) bool { + return equalNetmaps(b1.GetNetmap(), b2.GetNetmap()) +} diff --git a/pkg/services/control/types_test.go b/pkg/services/control/types_test.go new file mode 100644 index 000000000..aa7237e3b --- /dev/null +++ b/pkg/services/control/types_test.go @@ -0,0 +1,114 @@ +package control_test + +import ( + "bytes" + "testing" + + "github.com/nspcc-dev/neofs-node/pkg/services/control" +) + +func TestNetmap_StableMarshal(t *testing.T) { + testStableMarshal(t, generateNetmap(), new(control.Netmap), func(m1, m2 protoMessage) bool { + return equalNetmaps(m1.(*control.Netmap), m2.(*control.Netmap)) + }) +} + +func generateNetmap() *control.Netmap { + nm := new(control.Netmap) + nm.SetEpoch(13) + + const nodeCount = 2 + + nodes := make([]*control.NodeInfo, 0, nodeCount) + + for i := 0; i < nodeCount; i++ { + n := new(control.NodeInfo) + n.SetPublicKey(testData(33)) + n.SetAddress(testString()) + n.SetState(control.HealthStatus_ONLINE) + + const attrCount = 2 + + attrs := make([]*control.NodeInfo_Attribute, 0, attrCount) + + for j := 0; j < attrCount; j++ { + a := new(control.NodeInfo_Attribute) + a.SetKey(testString()) + a.SetValue(testString()) + + const parentsCount = 2 + + parents := make([]string, 0, parentsCount) + + for k := 0; k < parentsCount; k++ { + parents = append(parents, testString()) + } + + a.SetParents(parents) + + attrs = append(attrs, a) + } + + n.SetAttributes(attrs) + + nodes = append(nodes, n) + } + + nm.SetNodes(nodes) + + return nm +} + +func equalNetmaps(nm1, nm2 *control.Netmap) bool { + if nm1.GetEpoch() != nm2.GetEpoch() { + return false + } + + n1, n2 := nm1.GetNodes(), nm2.GetNodes() + + if len(n1) != len(n2) { + return false + } + + for i := range n1 { + if !equalNodeInfos(n1[i], n2[i]) { + return false + } + } + + return true +} + +func equalNodeInfos(n1, n2 *control.NodeInfo) bool { + if !bytes.Equal(n1.GetPublicKey(), n2.GetPublicKey()) || + n1.GetAddress() != n2.GetAddress() || + n1.GetState() != n2.GetState() { + return false + } + + a1, a2 := n1.GetAttributes(), n2.GetAttributes() + + if len(a1) != len(a2) { + return false + } + + for i := range a1 { + if a1[i].GetKey() != a2[i].GetKey() || a1[i].GetValue() != a2[i].GetValue() { + return false + } + + p1, p2 := a1[i].GetParents(), a2[i].GetParents() + + if len(p1) != len(p2) { + return false + } + + for j := range p1 { + if p1[j] != p2[j] { + return false + } + } + } + + return true +}