func TestCancelRequestOptimized(t *testing.T) { r, w := io.Pipe() c := &connection{ PeerMaxRequests: 1, peerPieces: func() bitmap.Bitmap { var bm bitmap.Bitmap bm.Set(1, true) return bm }(), rw: struct { io.Reader io.Writer }{ Writer: w, }, conn: new(net.TCPConn), // For the locks t: &Torrent{cl: &Client{}}, } assert.Len(t, c.Requests, 0) c.Request(newRequest(1, 2, 3)) require.Len(t, c.Requests, 1) // Posting this message should removing the pending Request. require.True(t, c.Cancel(newRequest(1, 2, 3))) assert.Len(t, c.Requests, 0) // Check that write optimization filters out the Request, due to the // Cancel. We should have received an Interested, due to the initial // request, and then keep-alives until we close the connection. go c.writer(0) b := make([]byte, 9) n, err := io.ReadFull(r, b) require.NoError(t, err) require.EqualValues(t, len(b), n) require.EqualValues(t, "\x00\x00\x00\x01\x02"+"\x00\x00\x00\x00", string(b)) time.Sleep(time.Millisecond) c.mu().Lock() c.Close() c.mu().Unlock() w.Close() b, err = ioutil.ReadAll(r) require.NoError(t, err) // A single keep-alive will have gone through, as writer would be stuck // trying to flush it, and then promptly close. require.EqualValues(t, "\x00\x00\x00\x00", string(b)) }
func TestCancelRequestOptimized(t *testing.T) { c := &connection{ PeerMaxRequests: 1, peerPieces: func() bitmap.Bitmap { var bm bitmap.Bitmap bm.Set(1, true) return bm }(), post: make(chan peer_protocol.Message), writeCh: make(chan []byte), } assert.Len(t, c.Requests, 0) // Keepalive timeout of 0 works because I'm just that good. go c.writeOptimizer(0 * time.Millisecond) c.Request(newRequest(1, 2, 3)) if len(c.Requests) != 1 { t.Fatal("request was not posted") } // Posting this message should removing the pending Request. if !c.Cancel(newRequest(1, 2, 3)) { t.Fatal("request was not found") } // Check that the write optimization has filtered out the Request message. for _, b := range []string{ // The initial request triggers an Interested message. "\x00\x00\x00\x01\x02", // Let a keep-alive through to verify there were no pending messages. "\x00\x00\x00\x00", } { bb := string(<-c.writeCh) if b != bb { t.Fatalf("received message %q is not expected: %q", bb, b) } } close(c.post) // Drain the write channel until it closes. for b := range c.writeCh { bs := string(b) if bs != "\x00\x00\x00\x00" { t.Fatal("got unexpected non-keepalive") } } }