github.com/xg0n/routine@v0.0.0-20240119033701-c364deb94aee/stack_test.go (about)

     1  package routine
     2  
     3  import (
     4  	"runtime"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  )
     9  
    10  func TestCaptureStackTrace(t *testing.T) {
    11  	stackTrace := captureStackTrace(0, 10)
    12  	assert.Greater(t, len(stackTrace), 2)
    13  	frame, _ := runtime.CallersFrames(stackTrace).Next()
    14  	assert.Equal(t, "github.com/xg0n/routine.TestCaptureStackTrace", frame.Function)
    15  	assert.Equal(t, 11, frame.Line)
    16  	//
    17  	stackTrace2 := captureStackSkip(1)
    18  	assert.Greater(t, len(stackTrace2), 2)
    19  	frame2, _ := runtime.CallersFrames(stackTrace2).Next()
    20  	assert.Equal(t, "github.com/xg0n/routine.TestCaptureStackTrace", frame2.Function)
    21  	assert.Equal(t, 17, frame2.Line)
    22  }
    23  
    24  func TestCaptureStackTrace_Deep(t *testing.T) {
    25  	stackTrace := captureStackDeep(20)
    26  	assert.Greater(t, len(stackTrace), 20)
    27  	frames := runtime.CallersFrames(stackTrace)
    28  	//
    29  	frame, more := frames.Next()
    30  	assert.True(t, more)
    31  	assert.Equal(t, "github.com/xg0n/routine.captureStackDeepRecursive", frame.Function)
    32  	assert.Equal(t, 93, frame.Line)
    33  	//
    34  	frame2, more2 := frames.Next()
    35  	assert.True(t, more2)
    36  	assert.Equal(t, "github.com/xg0n/routine.captureStackDeepRecursive", frame2.Function)
    37  	assert.Equal(t, 91, frame2.Line)
    38  }
    39  
    40  func TestCaptureStackTrace_Overflow(t *testing.T) {
    41  	stackTrace := captureStackDeep(200)
    42  	assert.Equal(t, 100, len(stackTrace))
    43  }
    44  
    45  func TestShowFrame(t *testing.T) {
    46  	assert.False(t, showFrame("make"))
    47  	assert.True(t, showFrame("strings.equal"))
    48  	assert.True(t, showFrame("strings.Equal"))
    49  	assert.False(t, showFrame("runtime.hello"))
    50  	assert.True(t, showFrame("runtime.Hello"))
    51  }
    52  
    53  func TestSkipFrame(t *testing.T) {
    54  	assert.False(t, skipFrame("runtime.a", true))
    55  	assert.False(t, skipFrame("runtime.gopanic", true))
    56  	assert.False(t, skipFrame("runtime.a", false))
    57  	assert.True(t, skipFrame("runtime.gopanic", false))
    58  }
    59  
    60  func TestIsExportedRuntime(t *testing.T) {
    61  	assert.False(t, isExportedRuntime(""))
    62  	assert.False(t, isExportedRuntime("runtime."))
    63  	assert.False(t, isExportedRuntime("hello_world"))
    64  	assert.False(t, isExportedRuntime("runtime._"))
    65  	assert.False(t, isExportedRuntime("runtime.a"))
    66  	assert.True(t, isExportedRuntime("runtime.Hello"))
    67  	assert.True(t, isExportedRuntime("runtime.Panic"))
    68  }
    69  
    70  func TestIsPanicRuntime(t *testing.T) {
    71  	assert.False(t, isPanicRuntime(""))
    72  	assert.False(t, isPanicRuntime("runtime."))
    73  	assert.False(t, isPanicRuntime("hello_world"))
    74  	assert.False(t, isPanicRuntime("runtime.a"))
    75  	assert.True(t, isPanicRuntime("runtime.goPanicIndex"))
    76  	assert.True(t, isPanicRuntime("runtime.gopanic"))
    77  	assert.True(t, isPanicRuntime("runtime.panicshift"))
    78  }
    79  
    80  func captureStackSkip(skip int) []uintptr {
    81  	return captureStackTrace(skip, 100)
    82  }
    83  
    84  func captureStackDeep(deep int) []uintptr {
    85  	return captureStackDeepRecursive(1, deep)
    86  }
    87  
    88  func captureStackDeepRecursive(cur int, deep int) []uintptr {
    89  	if cur < deep {
    90  		cur++
    91  		return captureStackDeepRecursive(cur, deep)
    92  	}
    93  	return captureStackTrace(0, 100)
    94  }