func TestUTPPingPong(t *testing.T) { defer goroutineLeakCheck(t)() s, err := NewSocket("udp", "localhost:0") require.NoError(t, err) defer s.Close() pingerClosed := make(chan struct{}) go func() { defer close(pingerClosed) b, err := Dial(s.Addr().String()) require.NoError(t, err) defer b.Close() n, err := b.Write([]byte("ping")) require.NoError(t, err) require.EqualValues(t, 4, n) buf := make([]byte, 4) b.Read(buf) require.EqualValues(t, "pong", buf) log.Printf("got pong") }() a, err := s.Accept() require.NoError(t, err) defer a.Close() log.Printf("accepted %s", a) buf := make([]byte, 42) n, err := a.Read(buf) require.NoError(t, err) require.EqualValues(t, "ping", buf[:n]) log.Print("got ping") n, err = a.Write([]byte("pong")) require.NoError(t, err) require.Equal(t, 4, n) log.Print("waiting for pinger to close") <-pingerClosed }
// Check that peer sending FIN doesn't cause unread data to be dropped in a // receiver. func TestReadFinishedConn(t *testing.T) { a, b := connPair() defer a.Close() defer b.Close() mu.Lock() originalAPDC := artificialPacketDropChance artificialPacketDropChance = 1 mu.Unlock() n, err := a.Write([]byte("hello")) require.Equal(t, 5, n) require.NoError(t, err) n, err = a.Write([]byte("world")) require.Equal(t, 5, n) require.NoError(t, err) mu.Lock() artificialPacketDropChance = originalAPDC mu.Unlock() a.Close() all, err := ioutil.ReadAll(b) require.NoError(t, err) require.EqualValues(t, "helloworld", all) }
func TestUTPRawConn(t *testing.T) { l, err := NewSocket("udp", "") require.NoError(t, err) defer l.Close() go func() { for { _, err := l.Accept() if err != nil { break } } }() // Connect a UTP peer to see if the RawConn will still work. log.Print("dialing") utpPeer := func() net.Conn { s, _ := NewSocket("udp", "") defer s.Close() ret, err := s.Dial(fmt.Sprintf("localhost:%d", missinggo.AddrPort(l.Addr()))) require.NoError(t, err) return ret }() log.Print("dial returned") if err != nil { t.Fatalf("error dialing utp listener: %s", err) } defer utpPeer.Close() peer, err := net.ListenPacket("udp", ":0") if err != nil { t.Fatal(err) } defer peer.Close() msgsReceived := 0 const N = 5000 // How many messages to send. readerStopped := make(chan struct{}) // The reader goroutine. go func() { defer close(readerStopped) b := make([]byte, 500) for i := 0; i < N; i++ { n, _, err := l.ReadFrom(b) if err != nil { t.Fatalf("error reading from raw conn: %s", err) } msgsReceived++ var d int fmt.Sscan(string(b[:n]), &d) if d != i { log.Printf("got wrong number: expected %d, got %d", i, d) } } }() udpAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("localhost:%d", missinggo.AddrPort(l.Addr()))) if err != nil { t.Fatal(err) } for i := 0; i < N; i++ { _, err := peer.WriteTo([]byte(fmt.Sprintf("%d", i)), udpAddr) if err != nil { t.Fatal(err) } time.Sleep(time.Microsecond) } select { case <-readerStopped: case <-time.After(time.Second): t.Fatal("reader timed out") } if msgsReceived != N { t.Fatalf("messages received: %d", msgsReceived) } }
func TestCache(t *testing.T) { td, err := ioutil.TempDir("", "gotest") if err != nil { t.Fatal(err) } defer os.RemoveAll(td) c, err := NewCache(filepath.Join(td, "cache")) if err != nil { t.Fatal(err) } assert.EqualValues(t, 0, c.Info().Filled) c.WalkItems(func(i ItemInfo) {}) _, err = c.OpenFile("/", os.O_CREATE) assert.NotNil(t, err) _, err = c.OpenFile("", os.O_CREATE) assert.NotNil(t, err) c.WalkItems(func(i ItemInfo) {}) require.Equal(t, 0, c.Info().NumItems) _, err = c.OpenFile("notexist", 0) assert.True(t, os.IsNotExist(err), err) _, err = c.OpenFile("/notexist", 0) assert.True(t, os.IsNotExist(err), err) _, err = c.OpenFile("/dir/notexist", 0) assert.True(t, os.IsNotExist(err), err) f, err := c.OpenFile("dir/blah", os.O_CREATE) require.NoError(t, err) defer f.Close() c.WalkItems(func(i ItemInfo) {}) assert.True(t, missinggo.FilePathExists(filepath.Join(td, filepath.FromSlash("cache/dir/blah")))) assert.True(t, missinggo.FilePathExists(filepath.Join(td, filepath.FromSlash("cache/dir/")))) assert.Equal(t, 1, c.Info().NumItems) f.Remove() assert.False(t, missinggo.FilePathExists(filepath.Join(td, filepath.FromSlash("dir/blah")))) assert.False(t, missinggo.FilePathExists(filepath.Join(td, filepath.FromSlash("dir/")))) _, err = f.Read(nil) assert.NotEqual(t, io.EOF, err) a, err := c.OpenFile("/a", os.O_CREATE|os.O_WRONLY) defer a.Close() require.Nil(t, err) b, err := c.OpenFile("b", os.O_CREATE|os.O_WRONLY) defer b.Close() require.Nil(t, err) c.mu.Lock() assert.True(t, c.pathInfo("a").Accessed.Before(c.pathInfo("b").Accessed)) c.mu.Unlock() n, err := a.Write([]byte("hello")) assert.Nil(t, err) assert.EqualValues(t, 5, n) assert.EqualValues(t, 5, c.Info().Filled) assert.True(t, c.pathInfo("b").Accessed.Before(c.pathInfo("a").Accessed)) c.SetCapacity(5) n, err = a.Write([]byte(" world")) assert.NotNil(t, err) _, err = b.Write([]byte("boom!")) // "a" and "b" have been evicted. assert.NotNil(t, err) assert.EqualValues(t, 0, c.Info().Filled) assert.EqualValues(t, 0, c.Info().NumItems) _, err = a.Seek(0, os.SEEK_SET) assert.NotNil(t, err) }