mirror of
https://github.com/tailscale/tailscale.git
synced 2024-12-11 10:44:41 +00:00
e16cb523aa
The block-write and block-read tests are both flaky, because each assumes it can get a normal read/write completed within 10ms. This isn’t always true. We can’t increase the timeouts, because that slows down the test. However, we don’t need to issue a regular read/write for this test. The immediately preceding tests already test this code, using a far more generous timeout. Remove the extraneous read/write. This drops the failure rate from 1 per 20,000 to undetectable on my machine. While we’re here, fix a typo in a debug print statement. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
119 lines
2.8 KiB
Go
119 lines
2.8 KiB
Go
// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package nettest
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestPipeHello(t *testing.T) {
|
|
p := NewPipe("p1", 1<<16)
|
|
msg := "Hello, World!"
|
|
if n, err := p.Write([]byte(msg)); err != nil {
|
|
t.Fatal(err)
|
|
} else if n != len(msg) {
|
|
t.Errorf("p.Write(%q) n=%d, want %d", msg, n, len(msg))
|
|
}
|
|
b := make([]byte, len(msg))
|
|
if n, err := p.Read(b); err != nil {
|
|
t.Fatal(err)
|
|
} else if n != len(b) {
|
|
t.Errorf("p.Read(%q) n=%d, want %d", string(b[:n]), n, len(b))
|
|
}
|
|
if got := string(b); got != msg {
|
|
t.Errorf("p.Read: %q, want %q", got, msg)
|
|
}
|
|
}
|
|
|
|
func TestPipeTimeout(t *testing.T) {
|
|
t.Run("write", func(t *testing.T) {
|
|
p := NewPipe("p1", 1<<16)
|
|
p.SetWriteDeadline(time.Now().Add(-1 * time.Second))
|
|
n, err := p.Write([]byte{'h'})
|
|
if !errors.Is(err, os.ErrDeadlineExceeded) {
|
|
t.Errorf("missing write timeout got err: %v", err)
|
|
}
|
|
if n != 0 {
|
|
t.Errorf("n=%d on timeout", n)
|
|
}
|
|
})
|
|
t.Run("read", func(t *testing.T) {
|
|
p := NewPipe("p1", 1<<16)
|
|
p.Write([]byte{'h'})
|
|
|
|
p.SetReadDeadline(time.Now().Add(-1 * time.Second))
|
|
b := make([]byte, 1)
|
|
n, err := p.Read(b)
|
|
if !errors.Is(err, os.ErrDeadlineExceeded) {
|
|
t.Errorf("missing read timeout got err: %v", err)
|
|
}
|
|
if n != 0 {
|
|
t.Errorf("n=%d on timeout", n)
|
|
}
|
|
})
|
|
t.Run("block-write", func(t *testing.T) {
|
|
p := NewPipe("p1", 1<<16)
|
|
p.SetWriteDeadline(time.Now().Add(10 * time.Millisecond))
|
|
if err := p.Block(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := p.Write([]byte{'h'}); !errors.Is(err, os.ErrDeadlineExceeded) {
|
|
t.Fatalf("want write timeout got: %v", err)
|
|
}
|
|
})
|
|
t.Run("block-read", func(t *testing.T) {
|
|
p := NewPipe("p1", 1<<16)
|
|
p.Write([]byte{'h', 'i'})
|
|
p.SetReadDeadline(time.Now().Add(10 * time.Millisecond))
|
|
b := make([]byte, 1)
|
|
if err := p.Block(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := p.Read(b); !errors.Is(err, os.ErrDeadlineExceeded) {
|
|
t.Fatalf("want read timeout got: %v", err)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestLimit(t *testing.T) {
|
|
p := NewPipe("p1", 1)
|
|
errCh := make(chan error)
|
|
go func() {
|
|
n, err := p.Write([]byte{'a', 'b', 'c'})
|
|
if err != nil {
|
|
errCh <- err
|
|
} else if n != 3 {
|
|
errCh <- fmt.Errorf("p.Write n=%d, want 3", n)
|
|
} else {
|
|
errCh <- nil
|
|
}
|
|
}()
|
|
b := make([]byte, 3)
|
|
|
|
if n, err := p.Read(b); err != nil {
|
|
t.Fatal(err)
|
|
} else if n != 1 {
|
|
t.Errorf("Read(%q): n=%d want 1", string(b), n)
|
|
}
|
|
if n, err := p.Read(b); err != nil {
|
|
t.Fatal(err)
|
|
} else if n != 1 {
|
|
t.Errorf("Read(%q): n=%d want 1", string(b), n)
|
|
}
|
|
if n, err := p.Read(b); err != nil {
|
|
t.Fatal(err)
|
|
} else if n != 1 {
|
|
t.Errorf("Read(%q): n=%d want 1", string(b), n)
|
|
}
|
|
|
|
if err := <-errCh; err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|