package netmap import ( "fmt" "testing" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/netmap" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/stretchr/testify/require" ) func TestNodeInfo_NetworkEndpoints(t *testing.T) { t.Run("empty", func(t *testing.T) { var n NodeInfo for range n.NetworkEndpoints() { t.Fatalf("handler is called, but it shouldn't") } }) var n NodeInfo n.SetNetworkEndpoints("1", "2", "3") t.Run("break", func(t *testing.T) { var res []string for s := range n.NetworkEndpoints() { if s == "2" { break } res = append(res, s) } require.Equal(t, []string{"1"}, res) }) t.Run("continue", func(t *testing.T) { var res []string for s := range n.NetworkEndpoints() { if s == "2" { continue } res = append(res, s) } require.Equal(t, []string{"1", "3"}, res) }) var res []string for s := range n.NetworkEndpoints() { res = append(res, s) } require.Equal(t, []string{"1", "2", "3"}, res) } func TestNodeInfo_Attributes(t *testing.T) { t.Run("empty", func(t *testing.T) { var n NodeInfo for range n.Attributes() { t.Fatalf("handler is called, but it shouldn't") } }) var n NodeInfo n.SetAttribute("key1", "value1") n.SetAttribute("key2", "value2") n.SetAttribute("key3", "value3") t.Run("break", func(t *testing.T) { var res [][2]string for k, v := range n.Attributes() { if k == "key2" { break } res = append(res, [2]string{k, v}) } require.Equal(t, [][2]string{{"key1", "value1"}}, res) }) t.Run("continue", func(t *testing.T) { var res [][2]string for k, v := range n.Attributes() { if k == "key2" { continue } res = append(res, [2]string{k, v}) } require.Equal(t, [][2]string{{"key1", "value1"}, {"key3", "value3"}}, res) }) var res [][2]string for k, v := range n.Attributes() { res = append(res, [2]string{k, v}) } require.Equal(t, [][2]string{{"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}}, res) } func TestNodeInfo_SetAttribute(t *testing.T) { var n NodeInfo const key = "some key" val := "some value" require.Zero(t, n.Attribute(val)) n.SetAttribute(key, val) require.Equal(t, val, n.Attribute(key)) val = "some other value" n.SetAttribute(key, val) require.Equal(t, val, n.Attribute(key)) } func TestNodeState(t *testing.T) { m := map[NodeState]netmap.NodeState{ UnspecifiedState: netmap.UnspecifiedState, Online: netmap.Online, Offline: netmap.Offline, Maintenance: netmap.Maintenance, } t.Run("from sdk to v2", func(t *testing.T) { for stateSDK, stateV2 := range m { require.Equal(t, stateV2, stateSDK.ToV2()) } }) t.Run("from v2 to sdk", func(t *testing.T) { for stateSDK, stateV2 := range m { var state NodeState state.FromV2(stateV2) require.Equal(t, stateSDK, state) } }) } func TestNodeInfo_Status(t *testing.T) { t.Run("deprecated getters/setters", func(t *testing.T) { var n NodeInfo require.False(t, n.IsOnline()) require.False(t, n.IsOffline()) require.False(t, n.IsMaintenance()) n.SetOnline() require.True(t, n.IsOnline()) require.False(t, n.IsOffline()) require.False(t, n.IsMaintenance()) n.SetOffline() require.True(t, n.IsOffline()) require.False(t, n.IsOnline()) require.False(t, n.IsMaintenance()) n.SetMaintenance() require.True(t, n.IsMaintenance()) require.False(t, n.IsOnline()) require.False(t, n.IsOffline()) }) t.Run("brand new getters/setters", func(t *testing.T) { var n NodeInfo require.False(t, n.Status().IsOnline()) require.False(t, n.Status().IsOffline()) require.False(t, n.Status().IsMaintenance()) n.SetStatus(Online) require.True(t, n.Status().IsOnline()) require.False(t, n.Status().IsOffline()) require.False(t, n.Status().IsMaintenance()) n.SetStatus(Offline) require.False(t, n.Status().IsOnline()) require.True(t, n.Status().IsOffline()) require.False(t, n.Status().IsMaintenance()) n.SetStatus(Maintenance) require.False(t, n.Status().IsOnline()) require.False(t, n.Status().IsOffline()) require.True(t, n.Status().IsMaintenance()) }) } func TestNodeInfo_ExternalAddr(t *testing.T) { var n NodeInfo require.Empty(t, n.ExternalAddresses()) require.Panics(t, func() { n.SetExternalAddresses() }) addr := []string{"1", "2", "3"} n.SetExternalAddresses(addr[0]) require.Equal(t, addr[:1], n.ExternalAddresses()) n.SetExternalAddresses(addr[1:]...) require.Equal(t, addr[1:], n.ExternalAddresses()) } func TestNodeInfo_Clone(t *testing.T) { var ni NodeInfo ni.SetPublicKey([]byte{2, 3}) c := ni.Clone() require.True(t, c != &ni) require.True(t, &(c.PublicKey()[0]) != &(ni.PublicKey()[0])) } func TestNodeInfo_Unmarshal(t *testing.T) { pk, err := keys.NewPrivateKey() require.NoError(t, err) attrs := make([]netmap.Attribute, 2) for i := range attrs { attrs[i].SetKey(fmt.Sprintf("key%d", i)) attrs[i].SetValue(fmt.Sprintf("value%d", i)) } goodNodeInfo := func() netmap.NodeInfo { var nodev2 netmap.NodeInfo nodev2.SetPublicKey(pk.PublicKey().Bytes()) nodev2.SetAddresses("127.0.0.1:2025") nodev2.SetState(netmap.Online) nodev2.SetAttributes(attrs) return nodev2 } // Check that goodNodeInfo indeed returns good node. // Otherwise, the whole test is garbage. require.NoError(t, new(NodeInfo).ReadFromV2(goodNodeInfo())) t.Run("empty public key", func(t *testing.T) { n := goodNodeInfo() n.SetPublicKey(nil) require.ErrorContains(t, new(NodeInfo).ReadFromV2(n), "missing public key") }) t.Run("missing addresses", func(t *testing.T) { n := goodNodeInfo() n.SetAddresses() require.ErrorContains(t, new(NodeInfo).ReadFromV2(n), "missing network endpoints") }) t.Run("empty attribute key", func(t *testing.T) { n := goodNodeInfo() var a netmap.Attribute a.SetValue("non-empty") n.SetAttributes(append(attrs, a)) require.ErrorContains(t, new(NodeInfo).ReadFromV2(n), fmt.Sprintf("empty key of the attribute #%d", len(attrs))) }) t.Run("empty attribute value", func(t *testing.T) { n := goodNodeInfo() var a netmap.Attribute a.SetKey("non-empty-key") n.SetAttributes(append(attrs, a)) require.ErrorContains(t, new(NodeInfo).ReadFromV2(n), "empty value of the attribute non-empty-key") }) t.Run("invalid price attribute", func(t *testing.T) { n := goodNodeInfo() var a netmap.Attribute a.SetKey(attrPrice) a.SetValue("not a number") n.SetAttributes(append(attrs, a)) require.ErrorContains(t, new(NodeInfo).ReadFromV2(n), fmt.Sprintf("invalid %s attribute", attrPrice)) }) t.Run("invalid capacity attribute", func(t *testing.T) { n := goodNodeInfo() var a netmap.Attribute a.SetKey(attrCapacity) a.SetValue("not a number") n.SetAttributes(append(attrs, a)) require.ErrorContains(t, new(NodeInfo).ReadFromV2(n), fmt.Sprintf("invalid %s attribute", attrCapacity)) }) t.Run("duplicate attributes", func(t *testing.T) { n := goodNodeInfo() var a netmap.Attribute a.SetKey("key1") a.SetValue("value3") n.SetAttributes(append(attrs, a)) require.ErrorContains(t, new(NodeInfo).ReadFromV2(n), "duplicate attributes key1") }) }