You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

175 lines
5.2 KiB

  1. package types
  2. import (
  3. "fmt"
  4. "testing"
  5. "github.com/stretchr/testify/assert"
  6. "github.com/stretchr/testify/require"
  7. "github.com/tendermint/tendermint/crypto/ed25519"
  8. tmnet "github.com/tendermint/tendermint/libs/net"
  9. "github.com/tendermint/tendermint/version"
  10. )
  11. const testCh = 0x01
  12. func TestNodeInfoValidate(t *testing.T) {
  13. // empty fails
  14. ni := NodeInfo{}
  15. assert.Error(t, ni.Validate())
  16. channels := make([]byte, maxNumChannels)
  17. for i := 0; i < maxNumChannels; i++ {
  18. channels[i] = byte(i)
  19. }
  20. dupChannels := make([]byte, 5)
  21. copy(dupChannels, channels[:5])
  22. dupChannels = append(dupChannels, testCh)
  23. nonASCII := "¢§µ"
  24. emptyTab := "\t"
  25. emptySpace := " "
  26. testCases := []struct {
  27. testName string
  28. malleateNodeInfo func(*NodeInfo)
  29. expectErr bool
  30. }{
  31. {
  32. "Too Many Channels",
  33. func(ni *NodeInfo) { ni.Channels = append(channels, byte(maxNumChannels)) }, // nolint: gocritic
  34. true,
  35. },
  36. {"Duplicate Channel", func(ni *NodeInfo) { ni.Channels = dupChannels }, true},
  37. {"Good Channels", func(ni *NodeInfo) { ni.Channels = ni.Channels[:5] }, false},
  38. {"Invalid NetAddress", func(ni *NodeInfo) { ni.ListenAddr = "not-an-address" }, true},
  39. {"Good NetAddress", func(ni *NodeInfo) { ni.ListenAddr = "0.0.0.0:26656" }, false},
  40. {"Non-ASCII Version", func(ni *NodeInfo) { ni.Version = nonASCII }, true},
  41. {"Empty tab Version", func(ni *NodeInfo) { ni.Version = emptyTab }, true},
  42. {"Empty space Version", func(ni *NodeInfo) { ni.Version = emptySpace }, true},
  43. {"Empty Version", func(ni *NodeInfo) { ni.Version = "" }, false},
  44. {"Non-ASCII Moniker", func(ni *NodeInfo) { ni.Moniker = nonASCII }, true},
  45. {"Empty tab Moniker", func(ni *NodeInfo) { ni.Moniker = emptyTab }, true},
  46. {"Empty space Moniker", func(ni *NodeInfo) { ni.Moniker = emptySpace }, true},
  47. {"Empty Moniker", func(ni *NodeInfo) { ni.Moniker = "" }, true},
  48. {"Good Moniker", func(ni *NodeInfo) { ni.Moniker = "hey its me" }, false},
  49. {"Non-ASCII TxIndex", func(ni *NodeInfo) { ni.Other.TxIndex = nonASCII }, true},
  50. {"Empty tab TxIndex", func(ni *NodeInfo) { ni.Other.TxIndex = emptyTab }, true},
  51. {"Empty space TxIndex", func(ni *NodeInfo) { ni.Other.TxIndex = emptySpace }, true},
  52. {"Empty TxIndex", func(ni *NodeInfo) { ni.Other.TxIndex = "" }, false},
  53. {"Off TxIndex", func(ni *NodeInfo) { ni.Other.TxIndex = "off" }, false},
  54. {"Non-ASCII RPCAddress", func(ni *NodeInfo) { ni.Other.RPCAddress = nonASCII }, true},
  55. {"Empty tab RPCAddress", func(ni *NodeInfo) { ni.Other.RPCAddress = emptyTab }, true},
  56. {"Empty space RPCAddress", func(ni *NodeInfo) { ni.Other.RPCAddress = emptySpace }, true},
  57. {"Empty RPCAddress", func(ni *NodeInfo) { ni.Other.RPCAddress = "" }, false},
  58. {"Good RPCAddress", func(ni *NodeInfo) { ni.Other.RPCAddress = "0.0.0.0:26657" }, false},
  59. }
  60. nodeKeyID := testNodeID()
  61. name := "testing"
  62. // test case passes
  63. ni = testNodeInfo(nodeKeyID, name)
  64. ni.Channels = channels
  65. assert.NoError(t, ni.Validate())
  66. for _, tc := range testCases {
  67. ni := testNodeInfo(nodeKeyID, name)
  68. ni.Channels = channels
  69. tc.malleateNodeInfo(&ni)
  70. err := ni.Validate()
  71. if tc.expectErr {
  72. assert.Error(t, err, tc.testName)
  73. } else {
  74. assert.NoError(t, err, tc.testName)
  75. }
  76. }
  77. }
  78. func testNodeID() NodeID {
  79. return NodeIDFromPubKey(ed25519.GenPrivKey().PubKey())
  80. }
  81. func testNodeInfo(id NodeID, name string) NodeInfo {
  82. return testNodeInfoWithNetwork(id, name, "testing")
  83. }
  84. func testNodeInfoWithNetwork(id NodeID, name, network string) NodeInfo {
  85. return NodeInfo{
  86. ProtocolVersion: ProtocolVersion{
  87. P2P: version.P2PProtocol,
  88. Block: version.BlockProtocol,
  89. App: 0,
  90. },
  91. NodeID: id,
  92. ListenAddr: fmt.Sprintf("127.0.0.1:%d", getFreePort()),
  93. Network: network,
  94. Version: "1.2.3-rc0-deadbeef",
  95. Channels: []byte{testCh},
  96. Moniker: name,
  97. Other: NodeInfoOther{
  98. TxIndex: "on",
  99. RPCAddress: fmt.Sprintf("127.0.0.1:%d", getFreePort()),
  100. },
  101. }
  102. }
  103. func getFreePort() int {
  104. port, err := tmnet.GetFreePort()
  105. if err != nil {
  106. panic(err)
  107. }
  108. return port
  109. }
  110. func TestNodeInfoCompatible(t *testing.T) {
  111. nodeKey1ID := testNodeID()
  112. nodeKey2ID := testNodeID()
  113. name := "testing"
  114. var newTestChannel byte = 0x2
  115. // test NodeInfo is compatible
  116. ni1 := testNodeInfo(nodeKey1ID, name)
  117. ni2 := testNodeInfo(nodeKey2ID, name)
  118. assert.NoError(t, ni1.CompatibleWith(ni2))
  119. // add another channel; still compatible
  120. ni2.Channels = []byte{newTestChannel, testCh}
  121. assert.NoError(t, ni1.CompatibleWith(ni2))
  122. testCases := []struct {
  123. testName string
  124. malleateNodeInfo func(*NodeInfo)
  125. }{
  126. {"Wrong block version", func(ni *NodeInfo) { ni.ProtocolVersion.Block++ }},
  127. {"Wrong network", func(ni *NodeInfo) { ni.Network += "-wrong" }},
  128. {"No common channels", func(ni *NodeInfo) { ni.Channels = []byte{newTestChannel} }},
  129. }
  130. for _, tc := range testCases {
  131. ni := testNodeInfo(nodeKey2ID, name)
  132. tc.malleateNodeInfo(&ni)
  133. assert.Error(t, ni1.CompatibleWith(ni))
  134. }
  135. }
  136. func TestNodeInfoAddChannel(t *testing.T) {
  137. nodeInfo := testNodeInfo(testNodeID(), "testing")
  138. nodeInfo.Channels = []byte{}
  139. require.Empty(t, nodeInfo.Channels)
  140. nodeInfo.AddChannel(2)
  141. require.Contains(t, nodeInfo.Channels, byte(0x02))
  142. // adding the same channel again shouldn't be a problem
  143. nodeInfo.AddChannel(2)
  144. require.Contains(t, nodeInfo.Channels, byte(0x02))
  145. }