github.com/likebike/go--@v0.0.0-20190911215757-0bd925d16e96/go/src/runtime/callers_test.go (about)

     1  // Copyright 2016 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  	"runtime"
     9  	"strings"
    10  	"testing"
    11  )
    12  
    13  func f1(pan bool) []uintptr {
    14  	return f2(pan) // line 14
    15  }
    16  
    17  func f2(pan bool) []uintptr {
    18  	return f3(pan) // line 18
    19  }
    20  
    21  func f3(pan bool) []uintptr {
    22  	if pan {
    23  		panic("f3") // line 23
    24  	}
    25  	ret := make([]uintptr, 20)
    26  	return ret[:runtime.Callers(0, ret)] // line 26
    27  }
    28  
    29  func testCallers(t *testing.T, pcs []uintptr, pan bool) {
    30  	m := make(map[string]int, len(pcs))
    31  	frames := runtime.CallersFrames(pcs)
    32  	for {
    33  		frame, more := frames.Next()
    34  		if frame.Function != "" {
    35  			m[frame.Function] = frame.Line
    36  		}
    37  		if !more {
    38  			break
    39  		}
    40  	}
    41  
    42  	var seen []string
    43  	for k := range m {
    44  		seen = append(seen, k)
    45  	}
    46  	t.Logf("functions seen: %s", strings.Join(seen, " "))
    47  
    48  	var f3Line int
    49  	if pan {
    50  		f3Line = 23
    51  	} else {
    52  		f3Line = 26
    53  	}
    54  	want := []struct {
    55  		name string
    56  		line int
    57  	}{
    58  		{"f1", 14},
    59  		{"f2", 18},
    60  		{"f3", f3Line},
    61  	}
    62  	for _, w := range want {
    63  		if got := m["runtime_test."+w.name]; got != w.line {
    64  			t.Errorf("%s is line %d, want %d", w.name, got, w.line)
    65  		}
    66  	}
    67  }
    68  
    69  func TestCallers(t *testing.T) {
    70  	testCallers(t, f1(false), false)
    71  }
    72  
    73  func TestCallersPanic(t *testing.T) {
    74  	defer func() {
    75  		if r := recover(); r == nil {
    76  			t.Fatal("did not panic")
    77  		}
    78  		pcs := make([]uintptr, 20)
    79  		pcs = pcs[:runtime.Callers(0, pcs)]
    80  		testCallers(t, pcs, true)
    81  	}()
    82  	f1(true)
    83  }