github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/src/runtime/runtime_test.go (about)

     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.
     4  
     5  package runtime_test
     6  
     7  import (
     8  	"io"
     9  	. "runtime"
    10  	"runtime/debug"
    11  	"testing"
    12  	"unsafe"
    13  )
    14  
    15  func init() {
    16  	// We're testing the runtime, so make tracebacks show things
    17  	// in the runtime. This only raises the level, so it won't
    18  	// override GOTRACEBACK=crash from the user.
    19  	SetTracebackEnv("system")
    20  }
    21  
    22  var errf error
    23  
    24  func errfn() error {
    25  	return errf
    26  }
    27  
    28  func errfn1() error {
    29  	return io.EOF
    30  }
    31  
    32  func BenchmarkIfaceCmp100(b *testing.B) {
    33  	for i := 0; i < b.N; i++ {
    34  		for j := 0; j < 100; j++ {
    35  			if errfn() == io.EOF {
    36  				b.Fatal("bad comparison")
    37  			}
    38  		}
    39  	}
    40  }
    41  
    42  func BenchmarkIfaceCmpNil100(b *testing.B) {
    43  	for i := 0; i < b.N; i++ {
    44  		for j := 0; j < 100; j++ {
    45  			if errfn1() == nil {
    46  				b.Fatal("bad comparison")
    47  			}
    48  		}
    49  	}
    50  }
    51  
    52  func BenchmarkDefer(b *testing.B) {
    53  	for i := 0; i < b.N; i++ {
    54  		defer1()
    55  	}
    56  }
    57  
    58  func defer1() {
    59  	defer func(x, y, z int) {
    60  		if recover() != nil || x != 1 || y != 2 || z != 3 {
    61  			panic("bad recover")
    62  		}
    63  	}(1, 2, 3)
    64  	return
    65  }
    66  
    67  func BenchmarkDefer10(b *testing.B) {
    68  	for i := 0; i < b.N/10; i++ {
    69  		defer2()
    70  	}
    71  }
    72  
    73  func defer2() {
    74  	for i := 0; i < 10; i++ {
    75  		defer func(x, y, z int) {
    76  			if recover() != nil || x != 1 || y != 2 || z != 3 {
    77  				panic("bad recover")
    78  			}
    79  		}(1, 2, 3)
    80  	}
    81  }
    82  
    83  func BenchmarkDeferMany(b *testing.B) {
    84  	for i := 0; i < b.N; i++ {
    85  		defer func(x, y, z int) {
    86  			if recover() != nil || x != 1 || y != 2 || z != 3 {
    87  				panic("bad recover")
    88  			}
    89  		}(1, 2, 3)
    90  	}
    91  }
    92  
    93  // golang.org/issue/7063
    94  func TestStopCPUProfilingWithProfilerOff(t *testing.T) {
    95  	SetCPUProfileRate(0)
    96  }
    97  
    98  // Addresses to test for faulting behavior.
    99  // This is less a test of SetPanicOnFault and more a check that
   100  // the operating system and the runtime can process these faults
   101  // correctly. That is, we're indirectly testing that without SetPanicOnFault
   102  // these would manage to turn into ordinary crashes.
   103  // Note that these are truncated on 32-bit systems, so the bottom 32 bits
   104  // of the larger addresses must themselves be invalid addresses.
   105  // We might get unlucky and the OS might have mapped one of these
   106  // addresses, but probably not: they're all in the first page, very high
   107  // addresses that normally an OS would reserve for itself, or malformed
   108  // addresses. Even so, we might have to remove one or two on different
   109  // systems. We will see.
   110  
   111  var faultAddrs = []uint64{
   112  	// low addresses
   113  	0,
   114  	1,
   115  	0xfff,
   116  	// high (kernel) addresses
   117  	// or else malformed.
   118  	0xffffffffffffffff,
   119  	0xfffffffffffff001,
   120  	0xffffffffffff0001,
   121  	0xfffffffffff00001,
   122  	0xffffffffff000001,
   123  	0xfffffffff0000001,
   124  	0xffffffff00000001,
   125  	0xfffffff000000001,
   126  	0xffffff0000000001,
   127  	0xfffff00000000001,
   128  	0xffff000000000001,
   129  	0xfff0000000000001,
   130  	0xff00000000000001,
   131  	0xf000000000000001,
   132  	0x8000000000000001,
   133  }
   134  
   135  func TestSetPanicOnFault(t *testing.T) {
   136  	old := debug.SetPanicOnFault(true)
   137  	defer debug.SetPanicOnFault(old)
   138  
   139  	nfault := 0
   140  	for _, addr := range faultAddrs {
   141  		testSetPanicOnFault(t, uintptr(addr), &nfault)
   142  	}
   143  	if nfault == 0 {
   144  		t.Fatalf("none of the addresses faulted")
   145  	}
   146  }
   147  
   148  func testSetPanicOnFault(t *testing.T, addr uintptr, nfault *int) {
   149  	if GOOS == "nacl" {
   150  		t.Skip("nacl doesn't seem to fault on high addresses")
   151  	}
   152  
   153  	defer func() {
   154  		if err := recover(); err != nil {
   155  			*nfault++
   156  		}
   157  	}()
   158  
   159  	// The read should fault, except that sometimes we hit
   160  	// addresses that have had C or kernel pages mapped there
   161  	// readable by user code. So just log the content.
   162  	// If no addresses fault, we'll fail the test.
   163  	v := *(*byte)(unsafe.Pointer(addr))
   164  	t.Logf("addr %#x: %#x\n", addr, v)
   165  }
   166  
   167  func eqstring_generic(s1, s2 string) bool {
   168  	if len(s1) != len(s2) {
   169  		return false
   170  	}
   171  	// optimization in assembly versions:
   172  	// if s1.str == s2.str { return true }
   173  	for i := 0; i < len(s1); i++ {
   174  		if s1[i] != s2[i] {
   175  			return false
   176  		}
   177  	}
   178  	return true
   179  }
   180  
   181  func TestEqString(t *testing.T) {
   182  	// This isn't really an exhaustive test of eqstring, it's
   183  	// just a convenient way of documenting (via eqstring_generic)
   184  	// what eqstring does.
   185  	s := []string{
   186  		"",
   187  		"a",
   188  		"c",
   189  		"aaa",
   190  		"ccc",
   191  		"cccc"[:3], // same contents, different string
   192  		"1234567890",
   193  	}
   194  	for _, s1 := range s {
   195  		for _, s2 := range s {
   196  			x := s1 == s2
   197  			y := eqstring_generic(s1, s2)
   198  			if x != y {
   199  				t.Errorf(`eqstring("%s","%s") = %t, want %t`, s1, s2, x, y)
   200  			}
   201  		}
   202  	}
   203  }
   204  
   205  func TestTrailingZero(t *testing.T) {
   206  	// make sure we add padding for structs with trailing zero-sized fields
   207  	type T1 struct {
   208  		n int32
   209  		z [0]byte
   210  	}
   211  	if unsafe.Sizeof(T1{}) != 8 {
   212  		t.Errorf("sizeof(%#v)==%d, want 8", T1{}, unsafe.Sizeof(T1{}))
   213  	}
   214  	type T2 struct {
   215  		n int64
   216  		z struct{}
   217  	}
   218  	if unsafe.Sizeof(T2{}) != 8+unsafe.Sizeof(Uintreg(0)) {
   219  		t.Errorf("sizeof(%#v)==%d, want %d", T2{}, unsafe.Sizeof(T2{}), 8+unsafe.Sizeof(Uintreg(0)))
   220  	}
   221  	type T3 struct {
   222  		n byte
   223  		z [4]struct{}
   224  	}
   225  	if unsafe.Sizeof(T3{}) != 2 {
   226  		t.Errorf("sizeof(%#v)==%d, want 2", T3{}, unsafe.Sizeof(T3{}))
   227  	}
   228  	// make sure padding can double for both zerosize and alignment
   229  	type T4 struct {
   230  		a int32
   231  		b int16
   232  		c int8
   233  		z struct{}
   234  	}
   235  	if unsafe.Sizeof(T4{}) != 8 {
   236  		t.Errorf("sizeof(%#v)==%d, want 8", T4{}, unsafe.Sizeof(T4{}))
   237  	}
   238  	// make sure we don't pad a zero-sized thing
   239  	type T5 struct {
   240  	}
   241  	if unsafe.Sizeof(T5{}) != 0 {
   242  		t.Errorf("sizeof(%#v)==%d, want 0", T5{}, unsafe.Sizeof(T5{}))
   243  	}
   244  }
   245  
   246  func TestBadOpen(t *testing.T) {
   247  	if GOOS == "windows" || GOOS == "nacl" {
   248  		t.Skip("skipping OS that doesn't have open/read/write/close")
   249  	}
   250  	// make sure we get the correct error code if open fails. Same for
   251  	// read/write/close on the resulting -1 fd. See issue 10052.
   252  	nonfile := []byte("/notreallyafile")
   253  	fd := Open(&nonfile[0], 0, 0)
   254  	if fd != -1 {
   255  		t.Errorf("open(\"%s\")=%d, want -1", string(nonfile), fd)
   256  	}
   257  	var buf [32]byte
   258  	r := Read(-1, unsafe.Pointer(&buf[0]), int32(len(buf)))
   259  	if r != -1 {
   260  		t.Errorf("read()=%d, want -1", r)
   261  	}
   262  	w := Write(^uintptr(0), unsafe.Pointer(&buf[0]), int32(len(buf)))
   263  	if w != -1 {
   264  		t.Errorf("write()=%d, want -1", w)
   265  	}
   266  	c := Close(-1)
   267  	if c != -1 {
   268  		t.Errorf("close()=%d, want -1", c)
   269  	}
   270  }
   271  
   272  func TestAppendGrowth(t *testing.T) {
   273  	var x []int64
   274  	check := func(want int) {
   275  		if cap(x) != want {
   276  			t.Errorf("len=%d, cap=%d, want cap=%d", len(x), cap(x), want)
   277  		}
   278  	}
   279  
   280  	check(0)
   281  	want := 1
   282  	for i := 1; i <= 100; i++ {
   283  		x = append(x, 1)
   284  		check(want)
   285  		if i&(i-1) == 0 {
   286  			want = 2 * i
   287  		}
   288  	}
   289  }
   290  
   291  var One = []int64{1}
   292  
   293  func TestAppendSliceGrowth(t *testing.T) {
   294  	var x []int64
   295  	check := func(want int) {
   296  		if cap(x) != want {
   297  			t.Errorf("len=%d, cap=%d, want cap=%d", len(x), cap(x), want)
   298  		}
   299  	}
   300  
   301  	check(0)
   302  	want := 1
   303  	for i := 1; i <= 100; i++ {
   304  		x = append(x, One...)
   305  		check(want)
   306  		if i&(i-1) == 0 {
   307  			want = 2 * i
   308  		}
   309  	}
   310  }
   311  
   312  func TestGoroutineProfileTrivial(t *testing.T) {
   313  	// Calling GoroutineProfile twice in a row should find the same number of goroutines,
   314  	// but it's possible there are goroutines just about to exit, so we might end up
   315  	// with fewer in the second call. Try a few times; it should converge once those
   316  	// zombies are gone.
   317  	for i := 0; ; i++ {
   318  		n1, ok := GoroutineProfile(nil) // should fail, there's at least 1 goroutine
   319  		if n1 < 1 || ok {
   320  			t.Fatalf("GoroutineProfile(nil) = %d, %v, want >0, false", n1, ok)
   321  		}
   322  		n2, ok := GoroutineProfile(make([]StackRecord, n1))
   323  		if n2 == n1 && ok {
   324  			break
   325  		}
   326  		t.Logf("GoroutineProfile(%d) = %d, %v, want %d, true", n1, n2, ok, n1)
   327  		if i >= 10 {
   328  			t.Fatalf("GoroutineProfile not converging")
   329  		}
   330  	}
   331  }