github.com/anacrolix/torrent@v1.61.0/client-tracker_test.go (about) 1 package torrent 2 3 import ( 4 "errors" 5 "net/http" 6 "net/http/httptest" 7 "os" 8 "strings" 9 "testing" 10 "time" 11 12 "github.com/gorilla/websocket" 13 "github.com/stretchr/testify/require" 14 15 "github.com/anacrolix/torrent/internal/testutil" 16 "github.com/anacrolix/torrent/tracker" 17 ) 18 19 func TestClientInvalidTracker(t *testing.T) { 20 timeout := time.NewTimer(3 * time.Second) 21 receivedStatusUpdate := make(chan bool) 22 gotTrackerDisconnectedEvt := false 23 cfg := TestingConfig(t) 24 cfg.DisableTrackers = false 25 cfg.Callbacks.StatusUpdated = append(cfg.Callbacks.StatusUpdated, func(e StatusUpdatedEvent) { 26 if e.Event == TrackerAnnounceError { 27 // ignore 28 return 29 } 30 if e.Event == TrackerDisconnected { 31 gotTrackerDisconnectedEvt = true 32 require.Equal(t, "ws://test.invalid:4242", e.Url) 33 require.Error(t, e.Error) 34 } 35 receivedStatusUpdate <- true 36 }) 37 38 cl, err := NewClient(cfg) 39 require.NoError(t, err) 40 defer cl.Close() 41 42 dir, mi := testutil.GreetingTestTorrent() 43 defer os.RemoveAll(dir) 44 45 mi.AnnounceList = [][]string{ 46 {"ws://test.invalid:4242"}, 47 } 48 49 to, err := cl.AddTorrent(mi) 50 require.NoError(t, err) 51 52 select { 53 case <-timeout.C: 54 case <-receivedStatusUpdate: 55 } 56 require.True(t, gotTrackerDisconnectedEvt) 57 to.Drop() 58 } 59 60 var upgrader = websocket.Upgrader{} 61 62 func testtracker(w http.ResponseWriter, r *http.Request) { 63 c, err := upgrader.Upgrade(w, r, nil) 64 if err != nil { 65 return 66 } 67 defer c.Close() 68 for { 69 _, _, err := c.ReadMessage() 70 if err != nil { 71 break 72 } 73 //err = c.WriteMessage(mt, message) 74 //if err != nil { 75 // break 76 //} 77 } 78 } 79 80 func TestClientValidTrackerConn(t *testing.T) { 81 s, trackerUrl := startTestTracker() 82 defer s.Close() 83 84 timeout := time.NewTimer(3 * time.Second) 85 receivedStatusUpdate := make(chan bool) 86 gotTrackerConnectedEvt := false 87 cfg := TestingConfig(t) 88 cfg.DisableTrackers = false 89 cfg.Callbacks.StatusUpdated = append(cfg.Callbacks.StatusUpdated, func(e StatusUpdatedEvent) { 90 if e.Event == TrackerConnected { 91 gotTrackerConnectedEvt = true 92 require.Equal(t, trackerUrl, e.Url) 93 require.NoError(t, e.Error) 94 } 95 receivedStatusUpdate <- true 96 }) 97 98 cl, err := NewClient(cfg) 99 require.NoError(t, err) 100 defer cl.Close() 101 102 dir, mi := testutil.GreetingTestTorrent() 103 defer os.RemoveAll(dir) 104 105 mi.AnnounceList = [][]string{ 106 {trackerUrl}, 107 } 108 109 to, err := cl.AddTorrent(mi) 110 require.NoError(t, err) 111 112 select { 113 case <-timeout.C: 114 case <-receivedStatusUpdate: 115 } 116 require.True(t, gotTrackerConnectedEvt) 117 to.Drop() 118 } 119 120 func TestClientAnnounceFailure(t *testing.T) { 121 s, trackerUrl := startTestTracker() 122 defer s.Close() 123 124 timeout := time.NewTimer(3 * time.Second) 125 receivedStatusUpdate := make(chan bool) 126 gotTrackerAnnounceErrorEvt := false 127 cfg := TestingConfig(t) 128 cfg.DisableTrackers = false 129 130 var to *Torrent 131 132 cfg.Callbacks.StatusUpdated = append(cfg.Callbacks.StatusUpdated, func(e StatusUpdatedEvent) { 133 if e.Event == TrackerConnected { 134 // ignore 135 return 136 } 137 if e.Event == TrackerAnnounceError { 138 gotTrackerAnnounceErrorEvt = true 139 require.Equal(t, trackerUrl, e.Url) 140 require.Equal(t, to.InfoHash().HexString(), e.InfoHash) 141 require.Error(t, e.Error) 142 require.Equal(t, "test error", e.Error.Error()) 143 } 144 receivedStatusUpdate <- true 145 }) 146 147 cl, err := NewClient(cfg) 148 require.NoError(t, err) 149 defer cl.Close() 150 151 cl.websocketTrackers.GetAnnounceRequest = func(event tracker.AnnounceEvent, infoHash [20]byte) (tracker.AnnounceRequest, error) { 152 return tracker.AnnounceRequest{}, errors.New("test error") 153 } 154 155 dir, mi := testutil.GreetingTestTorrent() 156 defer os.RemoveAll(dir) 157 158 mi.AnnounceList = [][]string{ 159 {trackerUrl}, 160 } 161 162 to, err = cl.AddTorrent(mi) 163 require.NoError(t, err) 164 165 select { 166 case <-timeout.C: 167 case <-receivedStatusUpdate: 168 } 169 require.True(t, gotTrackerAnnounceErrorEvt) 170 to.Drop() 171 } 172 173 func TestClientAnnounceSuccess(t *testing.T) { 174 s, trackerUrl := startTestTracker() 175 defer s.Close() 176 177 timeout := time.NewTimer(3 * time.Second) 178 receivedStatusUpdate := make(chan bool) 179 gotTrackerAnnounceSuccessfulEvt := false 180 cfg := TestingConfig(t) 181 cfg.DisableTrackers = false 182 183 var to *Torrent 184 185 cfg.Callbacks.StatusUpdated = append(cfg.Callbacks.StatusUpdated, func(e StatusUpdatedEvent) { 186 if e.Event == TrackerConnected { 187 // ignore 188 return 189 } 190 if e.Event == TrackerAnnounceSuccessful { 191 gotTrackerAnnounceSuccessfulEvt = true 192 require.Equal(t, trackerUrl, e.Url) 193 require.Equal(t, to.InfoHash().HexString(), e.InfoHash) 194 require.NoError(t, e.Error) 195 } 196 receivedStatusUpdate <- true 197 }) 198 199 cl, err := NewClient(cfg) 200 require.NoError(t, err) 201 defer cl.Close() 202 203 dir, mi := testutil.GreetingTestTorrent() 204 defer os.RemoveAll(dir) 205 206 mi.AnnounceList = [][]string{ 207 {trackerUrl}, 208 } 209 210 to, err = cl.AddTorrent(mi) 211 require.NoError(t, err) 212 213 select { 214 case <-timeout.C: 215 case <-receivedStatusUpdate: 216 } 217 require.True(t, gotTrackerAnnounceSuccessfulEvt) 218 to.Drop() 219 } 220 221 func startTestTracker() (*httptest.Server, string) { 222 s := httptest.NewServer(http.HandlerFunc(testtracker)) 223 trackerUrl := "ws" + strings.TrimPrefix(s.URL, "http") 224 return s, trackerUrl 225 }