// pushMetric adds the metric to the end of the list and returns a comma separated string of the // previous 61 entries. We return 61 instead of 60 (an hour) because the chart on the client // tracks deltas between these values - there is nothing to compare the first value against. func pushMetric(history *list.List, ev expvar.Var) string { history.PushBack(ev.String()) if history.Len() > 61 { history.Remove(history.Front()) } return JoinStringList(history) }
func SetRate(m Map, key string, value expvar.Var, timeframe, unit time.Duration) { if value != nil { v, _ := strconv.ParseInt(value.String(), 10, 64) m.Set(key, newRate(v, timeframe, unit)) } else { m.Set(key, zeroValue) } }
func SetAverage(m Map, key string, totalVar, casesVar expvar.Var, scale int64, defaultValue string) { if totalVar != nil && casesVar != nil { total, _ := strconv.ParseInt(totalVar.String(), 10, 64) cases, _ := strconv.ParseInt(casesVar.String(), 10, 64) m.Set(key, newAverage(total, cases, scale, defaultValue)) } else { m.Set(key, zeroValue) } }
// statToValue converts from a stats.Stat type to a JSON representable value. // This is preferred to just calling the String() for things like numbers, so that // InfluxDB can also represent the metrics as numbers. // TODO(aaijazi): this needs to be extended to support better serialization of other types.. // It's probably good to do this after InfluxDB 0.9 is released, as it has has better support // for arbitrary dict values (as tags). func statToValue(v expvar.Var) interface{} { switch v := v.(type) { case *stats.Float: return v.Get() case *stats.Int: return v.Get() case stats.FloatFunc: return v() case stats.IntFunc: return v() default: return v.String() } }
// Requires Internet access and can be flaky if the server or the internet is // slow. func TestDHTLarge(t *testing.T) { if testing.Short() { t.Skip("TestDHTLarge requires internet access and can be flaky. Skipping in short mode.") } defer stats(t) c := NewConfig() c.SaveRoutingTable = false node, err := New(c) if err != nil { t.Fatalf("dht New: %v", err) } if err = node.Start(); err != nil { t.Fatalf("node.Run: %v", err) } realDHTNodes := []string{ "1.a.magnets.im", "router.utorrent.com", } for _, addr := range realDHTNodes { ip, err := net.LookupHost(addr) if err != nil { t.Error(err) continue } node.AddNode(ip[0] + ":6881") } // Test that we can reach at least one node. success := false var ( reachable int v expvar.Var ) for i := 0; i < 10; i++ { v = expvar.Get("totalNodesReached") reachable, err = strconv.Atoi(v.String()) if err != nil { t.Errorf("totalNodesReached conversion to int failed: %v", err) continue } if reachable > 0 { t.Logf("Contacted %d DHT nodes.", reachable) success = true break } time.Sleep(time.Second) } if !success { t.Fatal("No external DHT node could be contacted.") } // Test that we can find peers for a known torrent in a timely fashion. // // Torrent from: http://www.clearbits.net/torrents/244-time-management-for-anarchists-1 infoHash := InfoHash("\xb4\x62\xc0\xa8\xbc\xef\x1c\xe5\xbb\x56\xb9\xfd\xb8\xcf\x37\xff\xd0\x2f\x5f\x59") go node.PeersRequest(string(infoHash), true) var infoHashPeers map[InfoHash][]string select { case infoHashPeers = <-node.PeersRequestResults: t.Logf("Found %d peers.", len(infoHashPeers[infoHash])) case <-time.Tick(10 * time.Second): t.Fatal("Could not find new peers: timed out") } for ih, peers := range infoHashPeers { if infoHash != ih { t.Fatal("Unexpected infohash returned") } if len(peers) == 0 { t.Fatal("Could not find new torrent peers.") } for _, peer := range peers { t.Logf("peer found: %v", nettools.BinaryToDottedPort(peer)) } } }
// Requires Internet access and can be flaky if the server or the internet is // slow. func TestDHTLarge(t *testing.T) { if testing.Short() { t.Skip("TestDHTLarge requires internet access and can be flaky. Skipping in short mode.") } defer stats(t) c := NewConfig() c.Port = 6060 // ... //c.SaveRoutingTable = false node, err := New(c) if err != nil { t.Fatalf("dht New: %v", err) } go node.Run() realDHTNodes := []string{ "1.a.magnets.im", "router.utorrent.com", } for _, addr := range realDHTNodes { ip, err := net.LookupHost(addr) if err != nil { t.Error(err) continue } node.AddNode(ip[0]+":6881", "") } node.AddNode("117.78.1.52:6891", "") node.AddNode("88.183.138.12:52804", "") // Test that we can reach at least one node. success := false var ( reachable int v expvar.Var ) for i := 0; i < 10; i++ { v = expvar.Get("totalNodesReached") reachable, err = strconv.Atoi(v.String()) if err != nil { t.Errorf("totalNodesReached conversion to int failed: %v", err) continue } if reachable > 0 { t.Logf("Contacted %d DHT nodes.", reachable) success = true break } time.Sleep(time.Second) } if !success { t.Fatal("No external DHT node could be contacted.") } // Test that we can find peers for a known torrent in a timely fashion. // // Torrent from: http://www.clearbits.net/torrents/244-time-management-for-anarchists-1 //infoHash := InfoHash("\xb4\x62\xc0\xa8\xbc\xef\x1c\xe5\xbb\x56\xb9\xfd\xb8\xcf\x37\xff\xd0\x2f\x5f\x59") infoHash := InfoHash("\xc0\x66\x42\x34\xb4\x4f\x25\xde\x6c\xc7\xb5\x36\xa7\x98\xc6\x5f\x85\x80\x79\xcb") //c0 66 42 34 b4 4f 25 de 6c c7 b5 36 a7 98 c6 5f 85 80 79 cb go node.PeersRequest(infoHash, true) timeout := make(chan bool, 1) go func() { time.Sleep(30 * time.Second) timeout <- true }() var infoHashPeers map[InfoHash][]string select { case infoHashPeers = <-node.PeersRequestResults: t.Logf("Found %d peers.", len(infoHashPeers[infoHash])) case <-timeout: t.Fatal("Could not find new peers: timed out") } for ih, peers := range infoHashPeers { if infoHash != ih { t.Fatal("Unexpected infohash returned") } if len(peers) == 0 { t.Fatal("Could not find new torrent peers.") } for _, peer := range peers { t.Logf("peer found: %v", nettools.BinaryToDottedPort(peer)) } } }
// Requires Internet access and can be flaky if the server or the internet is // slow. func TestDHTLarge(t *testing.T) { node := startDHTNode(t) realDHTNodes := []string{ "1.a.magnets.im", } for _, addr := range realDHTNodes { ip, err := net.LookupHost(addr) if err != nil { t.Error(err) continue } node.AddNode(ip[0] + ":6881") } // Test that we can reach at least one node. success := false var ( reachable int v expvar.Var err error ) for i := 0; i < 10; i++ { v = expvar.Get("totalReachableNodes") reachable, err = strconv.Atoi(v.String()) if err != nil { t.Errorf("totalReachableNodes conversion to int failed: %v", err) continue } if reachable > 0 { t.Logf("Contacted %d DHT nodes.", reachable) success = true break } time.Sleep(time.Second) } if !success { t.Fatal("No external DHT node could be contacted.") } // Test that we can find peers for a known torrent in a timely fashion. // // Torrent from: http://www.clearbits.net/torrents/244-time-management-for-anarchists-1 infoHash := InfoHash("\xb4\x62\xc0\xa8\xbc\xef\x1c\xe5\xbb\x56\xb9\xfd\xb8\xcf\x37\xff\xd0\x2f\x5f\x59") go node.PeersRequest(string(infoHash), true) timeout := make(chan bool, 1) go func() { time.Sleep(10 * time.Second) timeout <- true }() var infoHashPeers map[InfoHash][]string select { case infoHashPeers = <-node.PeersRequestResults: t.Logf("Found %d peers.", len(infoHashPeers[infoHash])) case <-timeout: t.Fatal("Could not find new peers: timed out") } for ih, peers := range infoHashPeers { if infoHash != ih { t.Fatal("Unexpected infohash returned") } if len(peers) == 0 { t.Fatal("Could not find new torrent peers.") } for _, peer := range peers { t.Logf("peer found: %v", nettools.BinaryToDottedPort(peer)) } } t.Logf("=== Stats ===") t.Logf("totalReachableNodes: %v", totalReachableNodes) t.Logf("totalDupes: %v", totalDupes) t.Logf("totalPeers: %v", totalPeers) t.Logf("totalSentGetPeers: %v", totalSentGetPeers) }