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
,