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  }