]> Sergey Matveev's repositories - btrtrc.git/blob - tracker/udp/udp_test.go
More Windows test fixes
[btrtrc.git] / tracker / udp / udp_test.go
1 package udp
2
3 import (
4         "bytes"
5         "context"
6         "crypto/rand"
7         "encoding/binary"
8         "io"
9         "net"
10         "sync"
11         "testing"
12         "time"
13
14         "github.com/anacrolix/dht/v2/krpc"
15         _ "github.com/anacrolix/envpprof"
16         "github.com/anacrolix/missinggo/v2/iter"
17         qt "github.com/frankban/quicktest"
18         "github.com/stretchr/testify/require"
19 )
20
21 // Ensure net.IPs are stored big-endian, to match the way they're read from
22 // the wire.
23 func TestNetIPv4Bytes(t *testing.T) {
24         ip := net.IP([]byte{127, 0, 0, 1})
25         if ip.String() != "127.0.0.1" {
26                 t.FailNow()
27         }
28         if string(ip) != "\x7f\x00\x00\x01" {
29                 t.Fatal([]byte(ip))
30         }
31 }
32
33 func TestMarshalAnnounceResponse(t *testing.T) {
34         peers := krpc.CompactIPv4NodeAddrs{
35                 {[]byte{127, 0, 0, 1}, 2},
36                 {[]byte{255, 0, 0, 3}, 4},
37         }
38         b, err := peers.MarshalBinary()
39         require.NoError(t, err)
40         require.EqualValues(t,
41                 "\x7f\x00\x00\x01\x00\x02\xff\x00\x00\x03\x00\x04",
42                 b)
43         require.EqualValues(t, 12, binary.Size(AnnounceResponseHeader{}))
44 }
45
46 // Failure to write an entire packet to UDP is expected to given an error.
47 func TestLongWriteUDP(t *testing.T) {
48         t.Parallel()
49         l, err := net.ListenUDP("udp4", nil)
50         require.NoError(t, err)
51         defer l.Close()
52         c, err := net.DialUDP("udp", nil, l.LocalAddr().(*net.UDPAddr))
53         if err != nil {
54                 t.Fatal(err)
55         }
56         defer c.Close()
57         for msgLen := 1; ; msgLen *= 2 {
58                 n, err := c.Write(make([]byte, msgLen))
59                 if err != nil {
60                         if isErrMessageTooLong(err) {
61                                 return
62                         }
63                         t.Fatalf("expected message too long error: %v", err)
64                 }
65                 if n < msgLen {
66                         t.FailNow()
67                 }
68         }
69 }
70
71 func TestShortBinaryRead(t *testing.T) {
72         var data ResponseHeader
73         err := binary.Read(bytes.NewBufferString("\x00\x00\x00\x01"), binary.BigEndian, &data)
74         if err != io.ErrUnexpectedEOF {
75                 t.FailNow()
76         }
77 }
78
79 func TestConvertInt16ToInt(t *testing.T) {
80         i := 50000
81         if int(uint16(int16(i))) != 50000 {
82                 t.FailNow()
83         }
84 }
85
86 func TestConnClientLogDispatchUnknownTransactionId(t *testing.T) {
87         const network = "udp"
88         cc, err := NewConnClient(NewConnClientOpts{
89                 Network: network,
90         })
91         c := qt.New(t)
92         c.Assert(err, qt.IsNil)
93         defer cc.Close()
94         pc, err := net.ListenPacket(network, ":0")
95         c.Assert(err, qt.IsNil)
96         defer pc.Close()
97         ccAddr := *cc.LocalAddr().(*net.UDPAddr)
98         ccAddr.IP = net.IPv6loopback
99         _, err = pc.WriteTo(make([]byte, 30), &ccAddr)
100         c.Assert(err, qt.IsNil)
101 }
102
103 func TestConnectionIdMismatch(t *testing.T) {
104         t.Skip("Server host returns consistent connection ID in limited tests and so isn't effective.")
105         cl, err := NewConnClient(NewConnClientOpts{
106                 // This host seems to return `Connection ID missmatch.\x00` every 2 minutes or so under
107                 // heavy use.
108                 Host: "tracker.torrent.eu.org:451",
109                 //Host:    "tracker.opentrackr.org:1337",
110                 Network: "udp",
111         })
112         c := qt.New(t)
113         c.Assert(err, qt.IsNil)
114         defer cl.Close()
115         ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
116         defer cancel()
117         // Force every request to use a different connection ID. It's racey, but we want to get a
118         // different ID issued before a request can be sent with an old ID.
119         cl.Client.shouldReconnectOverride = func() bool { return true }
120         started := time.Now()
121         var wg sync.WaitGroup
122         for range iter.N(2) {
123                 ar := AnnounceRequest{
124                         NumWant: -1,
125                         Event:   2,
126                 }
127                 rand.Read(ar.InfoHash[:])
128                 rand.Read(ar.PeerId[:])
129                 //spew.Dump(ar)
130                 wg.Add(1)
131                 go func() {
132                         defer wg.Done()
133                         _, _, err := cl.Announce(ctx, ar, Options{})
134                         // I'm looking for `error response: "Connection ID missmatch.\x00"`.
135                         t.Logf("announce error after %v: %v", time.Since(started), err)
136                 }()
137         }
138         wg.Wait()
139 }