File size: 2,577 Bytes
e36aeda | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | // Copyright 2023 The Go 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 main
import (
"fmt"
"log"
"net"
"os"
"runtime"
"runtime/trace"
"sync"
"syscall"
"time"
)
func main() {
if err := trace.Start(os.Stdout); err != nil {
log.Fatal(err)
}
// checkExecutionTimes relies on this.
var wg sync.WaitGroup
wg.Add(2)
go cpu10(&wg)
go cpu20(&wg)
wg.Wait()
// checkHeapMetrics relies on this.
allocHog(25 * time.Millisecond)
// checkProcStartStop relies on this.
var wg2 sync.WaitGroup
for i := 0; i < runtime.GOMAXPROCS(0); i++ {
wg2.Add(1)
go func() {
defer wg2.Done()
cpuHog(50 * time.Millisecond)
}()
}
wg2.Wait()
// checkSyscalls relies on this.
done := make(chan error)
go blockingSyscall(50*time.Millisecond, done)
if err := <-done; err != nil {
log.Fatal(err)
}
// checkNetworkUnblock relies on this.
ln, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
log.Fatalf("listen failed: %v", err)
}
defer ln.Close()
go func() {
c, err := ln.Accept()
if err != nil {
return
}
time.Sleep(time.Millisecond)
var buf [1]byte
c.Write(buf[:])
c.Close()
}()
c, err := net.Dial("tcp", ln.Addr().String())
if err != nil {
log.Fatalf("dial failed: %v", err)
}
var tmp [1]byte
c.Read(tmp[:])
c.Close()
trace.Stop()
}
// blockingSyscall blocks the current goroutine for duration d in a syscall and
// sends a message to done when it is done or if the syscall failed.
func blockingSyscall(d time.Duration, done chan<- error) {
r, w, err := os.Pipe()
if err != nil {
done <- err
return
}
start := time.Now()
msg := []byte("hello")
time.AfterFunc(d, func() { w.Write(msg) })
_, err = syscall.Read(int(r.Fd()), make([]byte, len(msg)))
if err == nil && time.Since(start) < d {
err = fmt.Errorf("syscall returned too early: want=%s got=%s", d, time.Since(start))
}
done <- err
}
func cpu10(wg *sync.WaitGroup) {
defer wg.Done()
cpuHog(10 * time.Millisecond)
}
func cpu20(wg *sync.WaitGroup) {
defer wg.Done()
cpuHog(20 * time.Millisecond)
}
func cpuHog(dt time.Duration) {
start := time.Now()
for i := 0; ; i++ {
if i%1000 == 0 && time.Since(start) > dt {
return
}
}
}
func allocHog(dt time.Duration) {
start := time.Now()
var s [][]byte
for i := 0; ; i++ {
if i%1000 == 0 {
if time.Since(start) > dt {
return
}
// Take a break... this will generate a ton of events otherwise.
time.Sleep(50 * time.Microsecond)
}
s = append(s, make([]byte, 1024))
}
}
|