func TestGoroutineCounts(t *testing.T) { if runtime.GOOS == "openbsd" { testenv.SkipFlaky(t, 15156) } c := make(chan int) for i := 0; i < 100; i++ { if i%10 == 0 { go func1(c) continue } if i%2 == 0 { go func2(c) continue } go func3(c) } time.Sleep(10 * time.Millisecond) // let goroutines block on channel var prof bytes.Buffer Lookup("goroutine").WriteTo(&prof, 1) parseProfile(t, prof, func(p *ProfileTest) { if len(p.Sample) < 4 { t.Errorf("few samples, got %v", len(p.Sample)) } if p.Sample[0].Value[0] != 50 || p.Sample[1].Value[0] != 40 || p.Sample[2].Value[0] != 10 || p.Sample[3].Value[0] != 1 { t.Errorf("expected sorted goroutine counts:\n 50, 40, 10, 1\ngot:\n", p.Sample[0].Value[0], p.Sample[1].Value[0], p.Sample[2].Value[0], p.Sample[3].Value[0]) } }) close(c) time.Sleep(10 * time.Millisecond) // let goroutines exit }
func TestGoroutineCounts(t *testing.T) { if runtime.GOOS == "openbsd" { testenv.SkipFlaky(t, 15156) } c := make(chan int) for i := 0; i < 100; i++ { if i%10 == 0 { go func1(c) continue } if i%2 == 0 { go func2(c) continue } go func3(c) } time.Sleep(10 * time.Millisecond) // let goroutines block on channel var w bytes.Buffer Lookup("goroutine").WriteTo(&w, 1) prof := w.String() if !containsInOrder(prof, "\n50 @ ", "\n40 @", "\n10 @", "\n1 @") { t.Errorf("expected sorted goroutine counts:\n%s", prof) } close(c) time.Sleep(10 * time.Millisecond) // let goroutines exit }
// TestGdbBacktrace tests that gdb can unwind the stack correctly // using only the DWARF debug info. func TestGdbBacktrace(t *testing.T) { t.Parallel() checkGdbEnvironment(t) checkGdbVersion(t) if runtime.GOOS == "netbsd" { testenv.SkipFlaky(t, 15603) } dir, err := ioutil.TempDir("", "go-build") if err != nil { t.Fatalf("failed to create temp directory: %v", err) } defer os.RemoveAll(dir) // Build the source code. src := filepath.Join(dir, "main.go") err = ioutil.WriteFile(src, []byte(backtraceSource), 0644) if err != nil { t.Fatalf("failed to create file: %v", err) } cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", "a.exe") cmd.Dir = dir out, err := testEnv(cmd).CombinedOutput() if err != nil { t.Fatalf("building source %v\n%s", err, out) } // Execute gdb commands. args := []string{"-nx", "-batch", "-ex", "set startup-with-shell off", "-ex", "break main.eee", "-ex", "run", "-ex", "backtrace", "-ex", "continue", filepath.Join(dir, "a.exe"), } got, _ := exec.Command("gdb", args...).CombinedOutput() // Check that the backtrace matches the source code. bt := []string{ "eee", "ddd", "ccc", "bbb", "aaa", "main", } for i, name := range bt { s := fmt.Sprintf("#%v.*main\\.%v", i, name) re := regexp.MustCompile(s) if found := re.Find(got) != nil; !found { t.Errorf("could not find '%v' in backtrace", s) t.Fatalf("gdb output:\n%v", string(got)) } } }
func TestDialerDualStack(t *testing.T) { // This test is known to be flaky. Don't frighten regular // users about it; only fail on the build dashboard. if testenv.Builder() == "" { testenv.SkipFlaky(t, 13324) } if !supportsIPv4 || !supportsIPv6 { t.Skip("both IPv4 and IPv6 are required") } closedPortDelay, expectClosedPortDelay := dialClosedPort() if closedPortDelay > expectClosedPortDelay { t.Errorf("got %v; want <= %v", closedPortDelay, expectClosedPortDelay) } origTestHookLookupIP := testHookLookupIP defer func() { testHookLookupIP = origTestHookLookupIP }() testHookLookupIP = lookupLocalhost handler := func(dss *dualStackServer, ln Listener) { for { c, err := ln.Accept() if err != nil { return } c.Close() } } var timeout = 150*time.Millisecond + closedPortDelay for _, dualstack := range []bool{false, true} { dss, err := newDualStackServer() if err != nil { t.Fatal(err) } defer dss.teardown() if err := dss.buildup(handler); err != nil { t.Fatal(err) } d := &Dialer{DualStack: dualstack, Timeout: timeout} for range dss.lns { c, err := d.Dial("tcp", JoinHostPort("localhost", dss.port)) if err != nil { t.Error(err) continue } switch addr := c.LocalAddr().(*TCPAddr); { case addr.IP.To4() != nil: dss.teardownNetwork("tcp4") case addr.IP.To16() != nil && addr.IP.To4() == nil: dss.teardownNetwork("tcp6") } c.Close() } } }
func TestAcceptTimeout(t *testing.T) { testenv.SkipFlaky(t, 17948) t.Parallel() switch runtime.GOOS { case "plan9": t.Skipf("not supported on %s", runtime.GOOS) } ln, err := newLocalListener("tcp") if err != nil { t.Fatal(err) } defer ln.Close() var wg sync.WaitGroup for i, tt := range acceptTimeoutTests { if tt.timeout < 0 { wg.Add(1) go func() { defer wg.Done() d := Dialer{Timeout: 100 * time.Millisecond} c, err := d.Dial(ln.Addr().Network(), ln.Addr().String()) if err != nil { t.Error(err) return } c.Close() }() } if err := ln.(*TCPListener).SetDeadline(time.Now().Add(tt.timeout)); err != nil { t.Fatalf("$%d: %v", i, err) } for j, xerr := range tt.xerrs { for { c, err := ln.Accept() if xerr != nil { if perr := parseAcceptError(err); perr != nil { t.Errorf("#%d/%d: %v", i, j, perr) } if nerr, ok := err.(Error); !ok || !nerr.Timeout() { t.Fatalf("#%d/%d: %v", i, j, err) } } if err == nil { c.Close() time.Sleep(10 * time.Millisecond) continue } break } } } wg.Wait() }
func TestReadUnixgramWithUnnamedSocket(t *testing.T) { if !testableNetwork("unixgram") { t.Skip("unixgram test") } if runtime.GOOS == "openbsd" { testenv.SkipFlaky(t, 15157) } addr := testUnixAddr() la, err := ResolveUnixAddr("unixgram", addr) if err != nil { t.Fatal(err) } c, err := ListenUnixgram("unixgram", la) if err != nil { t.Fatal(err) } defer func() { c.Close() os.Remove(addr) }() off := make(chan bool) data := [5]byte{1, 2, 3, 4, 5} go func() { defer func() { off <- true }() s, err := syscall.Socket(syscall.AF_UNIX, syscall.SOCK_DGRAM, 0) if err != nil { t.Error(err) return } defer syscall.Close(s) rsa := &syscall.SockaddrUnix{Name: addr} if err := syscall.Sendto(s, data[:], 0, rsa); err != nil { t.Error(err) return } }() <-off b := make([]byte, 64) c.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) n, from, err := c.ReadFrom(b) if err != nil { t.Fatal(err) } if from != nil { t.Fatalf("unexpected peer address: %v", from) } if !bytes.Equal(b[:n], data[:]) { t.Fatalf("got %v; want %v", b[:n], data[:]) } }
func TestGoroutineCounts(t *testing.T) { if runtime.GOOS == "openbsd" { testenv.SkipFlaky(t, 15156) } c := make(chan int) for i := 0; i < 100; i++ { if i%10 == 0 { go func1(c) continue } if i%2 == 0 { go func2(c) continue } go func3(c) } time.Sleep(10 * time.Millisecond) // let goroutines block on channel var w bytes.Buffer goroutineProf := Lookup("goroutine") // Check debug profile goroutineProf.WriteTo(&w, 1) prof := w.String() if !containsInOrder(prof, "\n50 @ ", "\n40 @", "\n10 @", "\n1 @") { t.Errorf("expected sorted goroutine counts:\n%s", prof) } // Check proto profile w.Reset() goroutineProf.WriteTo(&w, 0) p, err := profile.Parse(&w) if err != nil { t.Errorf("error parsing protobuf profile: %v", err) } if err := p.CheckValid(); err != nil { t.Errorf("protobuf profile is invalid: %v", err) } if !containsCounts(p, []int64{50, 40, 10, 1}) { t.Errorf("expected count profile to contain goroutines with counts %v, got %v", []int64{50, 40, 10, 1}, p) } close(c) time.Sleep(10 * time.Millisecond) // let goroutines exit }
func TestDialTimeoutMaxDuration(t *testing.T) { if runtime.GOOS == "openbsd" { testenv.SkipFlaky(t, 15157) } ln, err := newLocalListener("tcp") if err != nil { t.Fatal(err) } defer ln.Close() for i, tt := range dialTimeoutMaxDurationTests { ch := make(chan error) max := time.NewTimer(250 * time.Millisecond) defer max.Stop() go func() { d := Dialer{Timeout: tt.timeout} if tt.delta != 0 { d.Deadline = time.Now().Add(tt.delta) } c, err := d.Dial(ln.Addr().Network(), ln.Addr().String()) if err == nil { c.Close() } ch <- err }() select { case <-max.C: t.Fatalf("#%d: Dial didn't return in an expected time", i) case err := <-ch: if perr := parseDialError(err); perr != nil { t.Error(perr) } if err != nil { t.Errorf("#%d: %v", i, err) } } } }
func TestCgoCallbackGC(t *testing.T) { switch runtime.GOOS { case "plan9", "windows": t.Skipf("no pthreads on %s", runtime.GOOS) case "freebsd": testenv.SkipFlaky(t, 16396) } if testing.Short() { switch { case runtime.GOOS == "dragonfly": t.Skip("see golang.org/issue/11990") case runtime.GOOS == "linux" && runtime.GOARCH == "arm": t.Skip("too slow for arm builders") case runtime.GOOS == "linux" && (runtime.GOARCH == "mips64" || runtime.GOARCH == "mips64le"): t.Skip("too slow for mips64x builders") } } got := runTestProg(t, "testprogcgo", "CgoCallbackGC") want := "OK\n" if got != want { t.Fatalf("expected %q, but got:\n%s", want, got) } }
func TestDialTimeoutFDLeak(t *testing.T) { switch runtime.GOOS { case "plan9": t.Skipf("%s does not have full support of socktest", runtime.GOOS) case "openbsd": testenv.SkipFlaky(t, 15157) } const T = 100 * time.Millisecond switch runtime.GOOS { case "plan9", "windows": origTestHookDialChannel := testHookDialChannel testHookDialChannel = func() { time.Sleep(2 * T) } defer func() { testHookDialChannel = origTestHookDialChannel }() if runtime.GOOS == "plan9" { break } fallthrough default: sw.Set(socktest.FilterConnect, func(so *socktest.Status) (socktest.AfterFilter, error) { time.Sleep(2 * T) return nil, errTimeout }) defer sw.Set(socktest.FilterConnect, nil) } // Avoid tracking open-close jitterbugs between netFD and // socket that leads to confusion of information inside // socktest.Switch. // It may happen when the Dial call bumps against TCP // simultaneous open. See selfConnect in tcpsock_posix.go. defer func() { sw.Set(socktest.FilterClose, nil) }() var mu sync.Mutex var attempts int sw.Set(socktest.FilterClose, func(so *socktest.Status) (socktest.AfterFilter, error) { mu.Lock() attempts++ mu.Unlock() return nil, nil }) const N = 100 var wg sync.WaitGroup wg.Add(N) for i := 0; i < N; i++ { go func() { defer wg.Done() // This dial never starts to send any SYN // segment because of above socket filter and // test hook. c, err := DialTimeout("tcp", "127.0.0.1:0", T) if err == nil { t.Errorf("unexpectedly established: tcp:%s->%s", c.LocalAddr(), c.RemoteAddr()) c.Close() } }() } wg.Wait() if attempts < N { t.Errorf("got %d; want >= %d", attempts, N) } }