1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // The runstress tool stresses the runtime.
7 // It runs forever and should never fail. It tries to stress the garbage collector,
8 // maps, channels, the network, and everything else provided by the runtime.
27 v = flag.Bool("v", false, "verbose")
28 doMaps = flag.Bool("maps", true, "stress maps")
29 doExec = flag.Bool("exec", true, "stress exec")
30 doChan = flag.Bool("chan", true, "stress channels")
31 doNet = flag.Bool("net", true, "stress networking")
32 doParseGo = flag.Bool("parsego", true, "stress parsing Go (generates garbage)")
35 func Println(a ...interface{}) {
41 func dialStress(a net.Addr) {
43 d := net.Dialer{Timeout: time.Duration(rand.Intn(1e9))}
44 c, err := d.Dial("tcp", a.String())
48 time.Sleep(time.Duration(rand.Intn(500)) * time.Millisecond)
50 Println("closed dial")
53 // Don't run out of ephermeral ports too quickly:
54 time.Sleep(250 * time.Millisecond)
59 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
60 size, _ := strconv.Atoi(r.FormValue("size"))
61 w.Write(make([]byte, size))
63 go dialStress(ts.Listener.Addr())
65 size := rand.Intn(128 << 10)
66 res, err := http.Get(fmt.Sprintf("%s/?size=%d", ts.URL, size))
68 log.Fatalf("stressNet: http Get error: %v", err)
70 if res.StatusCode != 200 {
71 log.Fatalf("stressNet: Status code = %d", res.StatusCode)
73 n, err := io.Copy(ioutil.Discard, res.Body)
75 log.Fatalf("stressNet: io.Copy: %v", err)
78 log.Fatalf("stressNet: copied = %d; want %d", n, size)
81 Println("did http", size)
87 wantOutput := fmt.Sprintf("output-%d", rand.Intn(1e9))
88 cmd := exec.Command("/bin/sh", "-c", fmt.Sprintf("echo %s; exit %d", wantOutput, exit))
89 out, err := cmd.CombinedOutput()
92 log.Fatal("stressExec: unexpected exec success")
97 log.Fatalf("stressExec: exec failure: %v: %s", err, out)
100 if string(out) != wantOutput {
101 log.Fatalf("stressExec: exec output = %q; want %q", out, wantOutput)
107 gate := make(chan bool, 10) // max execs at once
117 func ringf(in <-chan int, out chan<- int, donec chan bool) {
133 func threadRing(bufsize int) {
135 donec := make(chan bool)
136 one := make(chan int, bufsize) // will be input to thread 1
137 var in, out chan int = nil, one
138 for i := 1; i <= N-1; i++ {
139 in, out = out, make(chan int, bufsize)
140 go ringf(in, out, donec)
142 go ringf(out, one, donec)
145 Println("did threadring of", bufsize)
148 func stressChannels() {
157 for want, f := range map[*bool]func(){
161 doChan: stressChannels,
162 doParseGo: stressParseGo,