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