Create embedded-5_0-branch branch for development on ARM embedded cores.
[official-gcc.git] / embedded-5_0-branch / gcc / testsuite / go.test / test / stress / runstress.go
blob76ab2a8b4faf918ccf6474e88be145c760b594e7
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.
6 //
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.
9 package main
11 import (
12 "flag"
13 "fmt"
14 "io"
15 "io/ioutil"
16 "log"
17 "math/rand"
18 "net"
19 "net/http"
20 "net/http/httptest"
21 "os/exec"
22 "strconv"
23 "time"
26 var (
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{}) {
36 if *v {
37 log.Println(a...)
41 func dialStress(a net.Addr) {
42 for {
43 d := net.Dialer{Timeout: time.Duration(rand.Intn(1e9))}
44 c, err := d.Dial("tcp", a.String())
45 if err == nil {
46 Println("did dial")
47 go func() {
48 time.Sleep(time.Duration(rand.Intn(500)) * time.Millisecond)
49 c.Close()
50 Println("closed dial")
51 }()
53 // Don't run out of ephermeral ports too quickly:
54 time.Sleep(250 * time.Millisecond)
58 func stressNet() {
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))
62 }))
63 go dialStress(ts.Listener.Addr())
64 for {
65 size := rand.Intn(128 << 10)
66 res, err := http.Get(fmt.Sprintf("%s/?size=%d", ts.URL, size))
67 if err != nil {
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)
74 if err != nil {
75 log.Fatalf("stressNet: io.Copy: %v", err)
77 if n != int64(size) {
78 log.Fatalf("stressNet: copied = %d; want %d", n, size)
80 res.Body.Close()
81 Println("did http", size)
85 func doAnExec() {
86 exit := rand.Intn(2)
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()
90 if exit == 1 {
91 if err == nil {
92 log.Fatal("stressExec: unexpected exec success")
94 return
96 if err != nil {
97 log.Fatalf("stressExec: exec failure: %v: %s", err, out)
99 wantOutput += "\n"
100 if string(out) != wantOutput {
101 log.Fatalf("stressExec: exec output = %q; want %q", out, wantOutput)
103 Println("did exec")
106 func stressExec() {
107 gate := make(chan bool, 10) // max execs at once
108 for {
109 gate <- true
110 go func() {
111 doAnExec()
112 <-gate
117 func ringf(in <-chan int, out chan<- int, donec chan bool) {
118 for {
119 var n int
120 select {
121 case <-donec:
122 return
123 case n = <-in:
125 if n == 0 {
126 close(donec)
127 return
129 out <- n - 1
133 func threadRing(bufsize int) {
134 const N = 100
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)
143 one <- N
144 <-donec
145 Println("did threadring of", bufsize)
148 func stressChannels() {
149 for {
150 threadRing(0)
151 threadRing(1)
155 func main() {
156 flag.Parse()
157 for want, f := range map[*bool]func(){
158 doMaps: stressMaps,
159 doNet: stressNet,
160 doExec: stressExec,
161 doChan: stressChannels,
162 doParseGo: stressParseGo,
164 if *want {
165 go f()
168 select {}