github.com/avahowell/sia@v0.5.1-beta.0.20160524050156-83dcc3d37c94/modules/gateway/nodes_test.go (about) 1 package gateway 2 3 import ( 4 "strconv" 5 "testing" 6 "time" 7 8 "github.com/NebulousLabs/Sia/encoding" 9 "github.com/NebulousLabs/Sia/modules" 10 ) 11 12 const dummyNode = "111.111.111.111:1111" 13 14 func TestAddNode(t *testing.T) { 15 g := newTestingGateway("TestAddNode", t) 16 defer g.Close() 17 id := g.mu.Lock() 18 defer g.mu.Unlock(id) 19 if err := g.addNode(dummyNode); err != nil { 20 t.Fatal("addNode failed:", err) 21 } 22 if err := g.addNode(dummyNode); err == nil { 23 t.Error("addNode added duplicate node") 24 } 25 if err := g.addNode("foo"); err == nil { 26 t.Error("addNode added unroutable address") 27 } 28 if err := g.addNode("foo:9981"); err == nil { 29 t.Error("addNode added a non-IP address") 30 } 31 if err := g.addNode("[::]:9981"); err == nil { 32 t.Error("addNode added unspecified address") 33 } 34 } 35 36 func TestRemoveNode(t *testing.T) { 37 g := newTestingGateway("TestRemoveNode", t) 38 defer g.Close() 39 id := g.mu.Lock() 40 defer g.mu.Unlock(id) 41 if err := g.addNode(dummyNode); err != nil { 42 t.Fatal("addNode failed:", err) 43 } 44 if err := g.removeNode(dummyNode); err != nil { 45 t.Fatal("removeNode failed:", err) 46 } 47 if err := g.removeNode("bar"); err == nil { 48 t.Fatal("removeNode removed nonexistent node") 49 } 50 } 51 52 func TestRandomNode(t *testing.T) { 53 g := newTestingGateway("TestRandomNode", t) 54 defer g.Close() 55 56 // Test with 0 nodes. 57 id := g.mu.RLock() 58 _, err := g.randomNode() 59 g.mu.RUnlock(id) 60 if err != errNoPeers { 61 t.Fatal("randomNode should fail when the gateway has 0 nodes") 62 } 63 64 // Test with 1 node. 65 id = g.mu.Lock() 66 if err = g.addNode(dummyNode); err != nil { 67 t.Fatal(err) 68 } 69 g.mu.Unlock(id) 70 id = g.mu.RLock() 71 addr, err := g.randomNode() 72 g.mu.RUnlock(id) 73 if err != nil { 74 t.Fatal("randomNode failed:", err) 75 } else if addr != dummyNode { 76 t.Fatal("randomNode returned wrong address:", addr) 77 } 78 79 // Test again with 0 nodes. 80 id = g.mu.Lock() 81 err = g.removeNode(dummyNode) 82 g.mu.Unlock(id) 83 if err != nil { 84 t.Fatal(err) 85 } 86 id = g.mu.RLock() 87 _, err = g.randomNode() 88 g.mu.RUnlock(id) 89 if err != errNoPeers { 90 t.Fatalf("randomNode returned wrong error: expected %v, got %v", errNoPeers, err) 91 } 92 93 // Test with 3 nodes. 94 nodes := map[modules.NetAddress]int{ 95 "111.111.111.111:1111": 0, 96 "111.111.111.111:2222": 0, 97 "111.111.111.111:3333": 0, 98 } 99 id = g.mu.Lock() 100 for addr := range nodes { 101 err := g.addNode(addr) 102 if err != nil { 103 t.Error(err) 104 } 105 } 106 g.mu.Unlock(id) 107 108 for i := 0; i < len(nodes)*10; i++ { 109 id = g.mu.RLock() 110 addr, err := g.randomNode() 111 g.mu.RUnlock(id) 112 if err != nil { 113 t.Fatal("randomNode failed:", err) 114 } 115 nodes[addr]++ 116 } 117 for node, count := range nodes { 118 if count == 0 { // 1-in-200000 chance of occurring naturally 119 t.Errorf("node %v was never selected", node) 120 } 121 } 122 } 123 124 func TestShareNodes(t *testing.T) { 125 if testing.Short() { 126 t.SkipNow() 127 } 128 g1 := newTestingGateway("TestShareNodes1", t) 129 defer g1.Close() 130 g2 := newTestingGateway("TestShareNodes2", t) 131 defer g2.Close() 132 133 // add a node to g2 134 id := g2.mu.Lock() 135 err := g2.addNode(dummyNode) 136 g2.mu.Unlock(id) 137 if err != nil { 138 t.Fatal(err) 139 } 140 141 // connect 142 err = g1.Connect(g2.Address()) 143 if err != nil { 144 t.Fatal("couldn't connect:", err) 145 } 146 147 // g1 should have received the node 148 time.Sleep(100 * time.Millisecond) 149 id = g1.mu.Lock() 150 err = g1.addNode(dummyNode) 151 g1.mu.Unlock(id) 152 if err == nil { 153 t.Fatal("gateway did not receive nodes during Connect:", g1.nodes) 154 } 155 156 // remove all nodes from both peers 157 id = g1.mu.Lock() 158 g1.nodes = map[modules.NetAddress]struct{}{} 159 g1.mu.Unlock(id) 160 id = g2.mu.Lock() 161 g2.nodes = map[modules.NetAddress]struct{}{} 162 g2.mu.Unlock(id) 163 164 // SharePeers should now return no peers 165 var nodes []modules.NetAddress 166 err = g1.RPC(g2.Address(), "ShareNodes", func(conn modules.PeerConn) error { 167 return encoding.ReadObject(conn, &nodes, maxSharedNodes*maxAddrLength) 168 }) 169 if err != nil { 170 t.Fatal(err) 171 } 172 if len(nodes) != 0 { 173 t.Fatal("gateway gave non-existent addresses:", nodes) 174 } 175 176 // sharing should be capped at maxSharedNodes 177 for i := 1; i < maxSharedNodes+11; i++ { 178 id := g2.mu.Lock() 179 err := g2.addNode(modules.NetAddress("111.111.111.111:" + strconv.Itoa(i))) 180 g2.mu.Unlock(id) 181 if err != nil { 182 t.Fatal(err) 183 } 184 } 185 err = g1.RPC(g2.Address(), "ShareNodes", func(conn modules.PeerConn) error { 186 return encoding.ReadObject(conn, &nodes, maxSharedNodes*maxAddrLength) 187 }) 188 if err != nil { 189 t.Fatal(err) 190 } 191 if len(nodes) != maxSharedNodes { 192 t.Fatalf("gateway gave wrong number of nodes: expected %v, got %v", maxSharedNodes, len(nodes)) 193 } 194 } 195 196 func TestRelayNodes(t *testing.T) { 197 if testing.Short() { 198 t.SkipNow() 199 } 200 g1 := newTestingGateway("TestRelayNodes1", t) 201 defer g1.Close() 202 g2 := newTestingGateway("TestRelayNodes2", t) 203 defer g2.Close() 204 g3 := newTestingGateway("TestRelayNodes3", t) 205 defer g3.Close() 206 207 // normally the Gateway will only register this RPC if has discovered its 208 // IP through external means. 209 g3.RegisterConnectCall("RelayNode", g3.sendAddress) 210 211 // connect g2 to g1 212 err := g2.Connect(g1.Address()) 213 if err != nil { 214 t.Fatal("couldn't connect:", err) 215 } 216 217 // connect g3 to g1 218 err = g3.Connect(g1.Address()) 219 if err != nil { 220 t.Fatal("couldn't connect:", err) 221 } 222 223 // g2 should have received g3's address from g1 224 time.Sleep(200 * time.Millisecond) 225 id := g2.mu.Lock() 226 defer g2.mu.Unlock(id) 227 if _, ok := g2.nodes[g3.Address()]; !ok { 228 t.Fatal("node was not relayed:", g2.nodes) 229 } 230 }