github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/types/node_info_test.go (about) 1 package types 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/stretchr/testify/assert" 8 "github.com/stretchr/testify/require" 9 10 "github.com/ari-anchor/sei-tendermint/crypto/ed25519" 11 tmnet "github.com/ari-anchor/sei-tendermint/libs/net" 12 "github.com/ari-anchor/sei-tendermint/version" 13 ) 14 15 const testCh = 0x01 16 17 func TestNodeInfoValidate(t *testing.T) { 18 19 // empty fails 20 ni := NodeInfo{} 21 assert.Error(t, ni.Validate()) 22 23 channels := make([]byte, maxNumChannels) 24 for i := 0; i < maxNumChannels; i++ { 25 channels[i] = byte(i) 26 } 27 dupChannels := make([]byte, 5) 28 copy(dupChannels, channels[:5]) 29 dupChannels = append(dupChannels, testCh) 30 31 nonASCII := "¢§µ" 32 emptyTab := "\t" 33 emptySpace := " " 34 35 testCases := []struct { 36 testName string 37 malleateNodeInfo func(*NodeInfo) 38 expectErr bool 39 }{ 40 { 41 "Too Many Channels", 42 func(ni *NodeInfo) { ni.Channels = append(channels, byte(maxNumChannels)) }, // nolint: gocritic 43 true, 44 }, 45 {"Duplicate Channel", func(ni *NodeInfo) { ni.Channels = dupChannels }, true}, 46 {"Good Channels", func(ni *NodeInfo) { ni.Channels = ni.Channels[:5] }, false}, 47 48 {"Invalid NetAddress", func(ni *NodeInfo) { ni.ListenAddr = "not-an-address" }, true}, 49 {"Good NetAddress", func(ni *NodeInfo) { ni.ListenAddr = "0.0.0.0:26656" }, false}, 50 51 {"Non-ASCII Version", func(ni *NodeInfo) { ni.Version = nonASCII }, true}, 52 {"Empty tab Version", func(ni *NodeInfo) { ni.Version = emptyTab }, true}, 53 {"Empty space Version", func(ni *NodeInfo) { ni.Version = emptySpace }, true}, 54 {"Empty Version", func(ni *NodeInfo) { ni.Version = "" }, false}, 55 56 {"Non-ASCII Moniker", func(ni *NodeInfo) { ni.Moniker = nonASCII }, true}, 57 {"Empty tab Moniker", func(ni *NodeInfo) { ni.Moniker = emptyTab }, true}, 58 {"Empty space Moniker", func(ni *NodeInfo) { ni.Moniker = emptySpace }, true}, 59 {"Empty Moniker", func(ni *NodeInfo) { ni.Moniker = "" }, true}, 60 {"Good Moniker", func(ni *NodeInfo) { ni.Moniker = "hey its me" }, false}, 61 62 {"Non-ASCII TxIndex", func(ni *NodeInfo) { ni.Other.TxIndex = nonASCII }, true}, 63 {"Empty tab TxIndex", func(ni *NodeInfo) { ni.Other.TxIndex = emptyTab }, true}, 64 {"Empty space TxIndex", func(ni *NodeInfo) { ni.Other.TxIndex = emptySpace }, true}, 65 {"Empty TxIndex", func(ni *NodeInfo) { ni.Other.TxIndex = "" }, false}, 66 {"Off TxIndex", func(ni *NodeInfo) { ni.Other.TxIndex = "off" }, false}, 67 68 {"Non-ASCII RPCAddress", func(ni *NodeInfo) { ni.Other.RPCAddress = nonASCII }, true}, 69 {"Empty tab RPCAddress", func(ni *NodeInfo) { ni.Other.RPCAddress = emptyTab }, true}, 70 {"Empty space RPCAddress", func(ni *NodeInfo) { ni.Other.RPCAddress = emptySpace }, true}, 71 {"Empty RPCAddress", func(ni *NodeInfo) { ni.Other.RPCAddress = "" }, false}, 72 {"Good RPCAddress", func(ni *NodeInfo) { ni.Other.RPCAddress = "0.0.0.0:26657" }, false}, 73 } 74 75 nodeKeyID := testNodeID() 76 name := "testing" 77 78 // test case passes 79 ni = testNodeInfo(t, nodeKeyID, name) 80 ni.Channels = channels 81 assert.NoError(t, ni.Validate()) 82 83 for _, tc := range testCases { 84 t.Run(tc.testName, func(t *testing.T) { 85 ni := testNodeInfo(t, nodeKeyID, name) 86 ni.Channels = channels 87 tc.malleateNodeInfo(&ni) 88 err := ni.Validate() 89 if tc.expectErr { 90 assert.Error(t, err, tc.testName) 91 } else { 92 assert.NoError(t, err, tc.testName) 93 } 94 }) 95 96 } 97 98 } 99 100 func testNodeID() NodeID { 101 return NodeIDFromPubKey(ed25519.GenPrivKey().PubKey()) 102 } 103 104 func testNodeInfo(t *testing.T, id NodeID, name string) NodeInfo { 105 return testNodeInfoWithNetwork(t, id, name, "testing") 106 } 107 108 func testNodeInfoWithNetwork(t *testing.T, id NodeID, name, network string) NodeInfo { 109 t.Helper() 110 return NodeInfo{ 111 ProtocolVersion: ProtocolVersion{ 112 P2P: version.P2PProtocol, 113 Block: version.BlockProtocol, 114 App: 0, 115 }, 116 NodeID: id, 117 ListenAddr: fmt.Sprintf("127.0.0.1:%d", getFreePort(t)), 118 Network: network, 119 Version: "1.2.3-rc0-deadbeef", 120 Channels: []byte{testCh}, 121 Moniker: name, 122 Other: NodeInfoOther{ 123 TxIndex: "on", 124 RPCAddress: fmt.Sprintf("127.0.0.1:%d", getFreePort(t)), 125 }, 126 } 127 } 128 129 func getFreePort(t *testing.T) int { 130 t.Helper() 131 port, err := tmnet.GetFreePort() 132 require.NoError(t, err) 133 return port 134 } 135 136 func TestNodeInfoCompatible(t *testing.T) { 137 nodeKey1ID := testNodeID() 138 nodeKey2ID := testNodeID() 139 name := "testing" 140 141 var newTestChannel byte = 0x2 142 143 // test NodeInfo is compatible 144 ni1 := testNodeInfo(t, nodeKey1ID, name) 145 ni2 := testNodeInfo(t, nodeKey2ID, name) 146 assert.NoError(t, ni1.CompatibleWith(ni2)) 147 148 // add another channel; still compatible 149 ni2.Channels = []byte{newTestChannel, testCh} 150 assert.NoError(t, ni1.CompatibleWith(ni2)) 151 152 testCases := []struct { 153 testName string 154 malleateNodeInfo func(*NodeInfo) 155 }{ 156 {"Wrong block version", func(ni *NodeInfo) { ni.ProtocolVersion.Block++ }}, 157 {"Wrong network", func(ni *NodeInfo) { ni.Network += "-wrong" }}, 158 {"No common channels", func(ni *NodeInfo) { ni.Channels = []byte{newTestChannel} }}, 159 } 160 161 for _, tc := range testCases { 162 ni := testNodeInfo(t, nodeKey2ID, name) 163 tc.malleateNodeInfo(&ni) 164 assert.Error(t, ni1.CompatibleWith(ni)) 165 } 166 } 167 168 func TestNodeInfoAddChannel(t *testing.T) { 169 nodeInfo := testNodeInfo(t, testNodeID(), "testing") 170 nodeInfo.Channels = []byte{} 171 require.Empty(t, nodeInfo.Channels) 172 173 nodeInfo.AddChannel(2) 174 require.Contains(t, nodeInfo.Channels, byte(0x02)) 175 176 // adding the same channel again shouldn't be a problem 177 nodeInfo.AddChannel(2) 178 require.Contains(t, nodeInfo.Channels, byte(0x02)) 179 } 180 181 func TestParseAddressString(t *testing.T) { 182 testCases := []struct { 183 name string 184 addr string 185 expected string 186 correct bool 187 }{ 188 {"no node id and no protocol", "127.0.0.1:8080", "", false}, 189 {"no node id w/ tcp input", "tcp://127.0.0.1:8080", "", false}, 190 {"no node id w/ udp input", "udp://127.0.0.1:8080", "", false}, 191 192 { 193 "no protocol", 194 "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", 195 "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", 196 true, 197 }, 198 { 199 "tcp input", 200 "tcp://deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", 201 "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", 202 true, 203 }, 204 { 205 "udp input", 206 "udp://deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", 207 "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", 208 true, 209 }, 210 {"malformed tcp input", "tcp//deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", "", false}, 211 {"malformed udp input", "udp//deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", "", false}, 212 213 // {"127.0.0:8080", false}, 214 {"invalid host", "notahost", "", false}, 215 {"invalid port", "127.0.0.1:notapath", "", false}, 216 {"invalid host w/ port", "notahost:8080", "", false}, 217 {"just a port", "8082", "", false}, 218 {"non-existent port", "127.0.0:8080000", "", false}, 219 220 {"too short nodeId", "deadbeef@127.0.0.1:8080", "", false}, 221 {"too short, not hex nodeId", "this-isnot-hex@127.0.0.1:8080", "", false}, 222 {"not hex nodeId", "xxxxbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", "", false}, 223 224 {"too short nodeId w/tcp", "tcp://deadbeef@127.0.0.1:8080", "", false}, 225 {"too short notHex nodeId w/tcp", "tcp://this-isnot-hex@127.0.0.1:8080", "", false}, 226 {"notHex nodeId w/tcp", "tcp://xxxxbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", "", false}, 227 { 228 "correct nodeId w/tcp", 229 "tcp://deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", 230 "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", 231 true, 232 }, 233 234 {"no node id", "tcp://@127.0.0.1:8080", "", false}, 235 {"no node id or IP", "tcp://@", "", false}, 236 {"tcp no host, w/ port", "tcp://:26656", "", false}, 237 {"empty", "", "", false}, 238 {"node id delimiter 1", "@", "", false}, 239 {"node id delimiter 2", " @", "", false}, 240 {"node id delimiter 3", " @ ", "", false}, 241 } 242 243 for _, tc := range testCases { 244 tc := tc 245 t.Run(tc.name, func(t *testing.T) { 246 addr, port, err := ParseAddressString(tc.addr) 247 if tc.correct { 248 require.NoError(t, err, tc.addr) 249 assert.Contains(t, tc.expected, addr.String()) 250 assert.Contains(t, tc.expected, fmt.Sprint(port)) 251 } else { 252 assert.Error(t, err, "%v", tc.addr) 253 } 254 }) 255 } 256 }