* builtins.def (BUILT_IN_SETJMP): Revert latest change.
[official-gcc.git] / libgo / go / runtime / runtime_test.go
blobb8f6ac2aed4c1b845abcbf92add1de39e58124e0
1 // Copyright 2012 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 package runtime_test
7 import (
8 "io"
9 . "runtime"
10 "runtime/debug"
11 "strings"
12 "testing"
13 "unsafe"
16 func init() {
17 // We're testing the runtime, so make tracebacks show things
18 // in the runtime. This only raises the level, so it won't
19 // override GOTRACEBACK=crash from the user.
20 SetTracebackEnv("system")
23 var errf error
25 func errfn() error {
26 return errf
29 func errfn1() error {
30 return io.EOF
33 func BenchmarkIfaceCmp100(b *testing.B) {
34 for i := 0; i < b.N; i++ {
35 for j := 0; j < 100; j++ {
36 if errfn() == io.EOF {
37 b.Fatal("bad comparison")
43 func BenchmarkIfaceCmpNil100(b *testing.B) {
44 for i := 0; i < b.N; i++ {
45 for j := 0; j < 100; j++ {
46 if errfn1() == nil {
47 b.Fatal("bad comparison")
53 var efaceCmp1 interface{}
54 var efaceCmp2 interface{}
56 func BenchmarkEfaceCmpDiff(b *testing.B) {
57 x := 5
58 efaceCmp1 = &x
59 y := 6
60 efaceCmp2 = &y
61 for i := 0; i < b.N; i++ {
62 for j := 0; j < 100; j++ {
63 if efaceCmp1 == efaceCmp2 {
64 b.Fatal("bad comparison")
70 func BenchmarkDefer(b *testing.B) {
71 for i := 0; i < b.N; i++ {
72 defer1()
76 func defer1() {
77 defer func(x, y, z int) {
78 if recover() != nil || x != 1 || y != 2 || z != 3 {
79 panic("bad recover")
81 }(1, 2, 3)
84 func BenchmarkDefer10(b *testing.B) {
85 for i := 0; i < b.N/10; i++ {
86 defer2()
90 func defer2() {
91 for i := 0; i < 10; i++ {
92 defer func(x, y, z int) {
93 if recover() != nil || x != 1 || y != 2 || z != 3 {
94 panic("bad recover")
96 }(1, 2, 3)
100 func BenchmarkDeferMany(b *testing.B) {
101 for i := 0; i < b.N; i++ {
102 defer func(x, y, z int) {
103 if recover() != nil || x != 1 || y != 2 || z != 3 {
104 panic("bad recover")
106 }(1, 2, 3)
110 // golang.org/issue/7063
111 func TestStopCPUProfilingWithProfilerOff(t *testing.T) {
112 SetCPUProfileRate(0)
115 // Addresses to test for faulting behavior.
116 // This is less a test of SetPanicOnFault and more a check that
117 // the operating system and the runtime can process these faults
118 // correctly. That is, we're indirectly testing that without SetPanicOnFault
119 // these would manage to turn into ordinary crashes.
120 // Note that these are truncated on 32-bit systems, so the bottom 32 bits
121 // of the larger addresses must themselves be invalid addresses.
122 // We might get unlucky and the OS might have mapped one of these
123 // addresses, but probably not: they're all in the first page, very high
124 // addresses that normally an OS would reserve for itself, or malformed
125 // addresses. Even so, we might have to remove one or two on different
126 // systems. We will see.
128 var faultAddrs = []uint64{
129 // low addresses
132 0xfff,
133 // high (kernel) addresses
134 // or else malformed.
135 0xffffffffffffffff,
136 0xfffffffffffff001,
137 0xffffffffffff0001,
138 0xfffffffffff00001,
139 0xffffffffff000001,
140 0xfffffffff0000001,
141 0xffffffff00000001,
142 0xfffffff000000001,
143 0xffffff0000000001,
144 0xfffff00000000001,
145 0xffff000000000001,
146 0xfff0000000000001,
147 0xff00000000000001,
148 0xf000000000000001,
149 0x8000000000000001,
152 func TestSetPanicOnFault(t *testing.T) {
153 old := debug.SetPanicOnFault(true)
154 defer debug.SetPanicOnFault(old)
156 nfault := 0
157 for _, addr := range faultAddrs {
158 testSetPanicOnFault(t, uintptr(addr), &nfault)
160 if nfault == 0 {
161 t.Fatalf("none of the addresses faulted")
165 func testSetPanicOnFault(t *testing.T, addr uintptr, nfault *int) {
166 if GOOS == "nacl" {
167 t.Skip("nacl doesn't seem to fault on high addresses")
170 defer func() {
171 if err := recover(); err != nil {
172 *nfault++
176 // The read should fault, except that sometimes we hit
177 // addresses that have had C or kernel pages mapped there
178 // readable by user code. So just log the content.
179 // If no addresses fault, we'll fail the test.
180 v := *(*byte)(unsafe.Pointer(addr))
181 t.Logf("addr %#x: %#x\n", addr, v)
184 func eqstring_generic(s1, s2 string) bool {
185 if len(s1) != len(s2) {
186 return false
188 // optimization in assembly versions:
189 // if s1.str == s2.str { return true }
190 for i := 0; i < len(s1); i++ {
191 if s1[i] != s2[i] {
192 return false
195 return true
198 func TestEqString(t *testing.T) {
199 // This isn't really an exhaustive test of eqstring, it's
200 // just a convenient way of documenting (via eqstring_generic)
201 // what eqstring does.
202 s := []string{
204 "a",
205 "c",
206 "aaa",
207 "ccc",
208 "cccc"[:3], // same contents, different string
209 "1234567890",
211 for _, s1 := range s {
212 for _, s2 := range s {
213 x := s1 == s2
214 y := eqstring_generic(s1, s2)
215 if x != y {
216 t.Errorf(`eqstring("%s","%s") = %t, want %t`, s1, s2, x, y)
223 func TestTrailingZero(t *testing.T) {
224 // make sure we add padding for structs with trailing zero-sized fields
225 type T1 struct {
226 n int32
227 z [0]byte
229 if unsafe.Sizeof(T1{}) != 8 {
230 t.Errorf("sizeof(%#v)==%d, want 8", T1{}, unsafe.Sizeof(T1{}))
232 type T2 struct {
233 n int64
234 z struct{}
236 if unsafe.Sizeof(T2{}) != 8+unsafe.Sizeof(Uintreg(0)) {
237 t.Errorf("sizeof(%#v)==%d, want %d", T2{}, unsafe.Sizeof(T2{}), 8+unsafe.Sizeof(Uintreg(0)))
239 type T3 struct {
240 n byte
241 z [4]struct{}
243 if unsafe.Sizeof(T3{}) != 2 {
244 t.Errorf("sizeof(%#v)==%d, want 2", T3{}, unsafe.Sizeof(T3{}))
246 // make sure padding can double for both zerosize and alignment
247 type T4 struct {
248 a int32
249 b int16
250 c int8
251 z struct{}
253 if unsafe.Sizeof(T4{}) != 8 {
254 t.Errorf("sizeof(%#v)==%d, want 8", T4{}, unsafe.Sizeof(T4{}))
256 // make sure we don't pad a zero-sized thing
257 type T5 struct {
259 if unsafe.Sizeof(T5{}) != 0 {
260 t.Errorf("sizeof(%#v)==%d, want 0", T5{}, unsafe.Sizeof(T5{}))
265 func TestBadOpen(t *testing.T) {
266 if GOOS == "windows" || GOOS == "nacl" {
267 t.Skip("skipping OS that doesn't have open/read/write/close")
269 // make sure we get the correct error code if open fails. Same for
270 // read/write/close on the resulting -1 fd. See issue 10052.
271 nonfile := []byte("/notreallyafile")
272 fd := Open(&nonfile[0], 0, 0)
273 if fd != -1 {
274 t.Errorf("open(\"%s\")=%d, want -1", string(nonfile), fd)
276 var buf [32]byte
277 r := Read(-1, unsafe.Pointer(&buf[0]), int32(len(buf)))
278 if r != -1 {
279 t.Errorf("read()=%d, want -1", r)
281 w := Write(^uintptr(0), unsafe.Pointer(&buf[0]), int32(len(buf)))
282 if w != -1 {
283 t.Errorf("write()=%d, want -1", w)
285 c := Close(-1)
286 if c != -1 {
287 t.Errorf("close()=%d, want -1", c)
291 func TestAppendGrowth(t *testing.T) {
292 var x []int64
293 check := func(want int) {
294 if cap(x) != want {
295 t.Errorf("len=%d, cap=%d, want cap=%d", len(x), cap(x), want)
299 check(0)
300 want := 1
301 for i := 1; i <= 100; i++ {
302 x = append(x, 1)
303 check(want)
304 if i&(i-1) == 0 {
305 want = 2 * i
310 var One = []int64{1}
312 func TestAppendSliceGrowth(t *testing.T) {
313 var x []int64
314 check := func(want int) {
315 if cap(x) != want {
316 t.Errorf("len=%d, cap=%d, want cap=%d", len(x), cap(x), want)
320 check(0)
321 want := 1
322 for i := 1; i <= 100; i++ {
323 x = append(x, One...)
324 check(want)
325 if i&(i-1) == 0 {
326 want = 2 * i
331 func TestGoroutineProfileTrivial(t *testing.T) {
332 // Calling GoroutineProfile twice in a row should find the same number of goroutines,
333 // but it's possible there are goroutines just about to exit, so we might end up
334 // with fewer in the second call. Try a few times; it should converge once those
335 // zombies are gone.
336 for i := 0; ; i++ {
337 n1, ok := GoroutineProfile(nil) // should fail, there's at least 1 goroutine
338 if n1 < 1 || ok {
339 t.Fatalf("GoroutineProfile(nil) = %d, %v, want >0, false", n1, ok)
341 n2, ok := GoroutineProfile(make([]StackRecord, n1))
342 if n2 == n1 && ok {
343 break
345 t.Logf("GoroutineProfile(%d) = %d, %v, want %d, true", n1, n2, ok, n1)
346 if i >= 10 {
347 t.Fatalf("GoroutineProfile not converging")
352 func TestVersion(t *testing.T) {
353 // Test that version does not contain \r or \n.
354 vers := Version()
355 if strings.Contains(vers, "\r") || strings.Contains(vers, "\n") {
356 t.Fatalf("cr/nl in version: %q", vers)