github.com/Laisky/zap@v1.27.0/internal/stacktrace/stack_test.go (about) 1 // Copyright (c) 2023 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package stacktrace 22 23 import ( 24 "bytes" 25 "strings" 26 "testing" 27 28 "github.com/stretchr/testify/assert" 29 "github.com/stretchr/testify/require" 30 ) 31 32 func TestTake(t *testing.T) { 33 trace := Take(0) 34 lines := strings.Split(trace, "\n") 35 require.NotEmpty(t, lines, "Expected stacktrace to have at least one frame.") 36 assert.Contains( 37 t, 38 lines[0], 39 "github.com/Laisky/zap/internal/stacktrace.TestTake", 40 "Expected stacktrace to start with the test.", 41 ) 42 } 43 44 func TestTakeWithSkip(t *testing.T) { 45 trace := Take(1) 46 lines := strings.Split(trace, "\n") 47 require.NotEmpty(t, lines, "Expected stacktrace to have at least one frame.") 48 assert.Contains( 49 t, 50 lines[0], 51 "testing.", 52 "Expected stacktrace to start with the test runner (skipping our own frame).", 53 ) 54 } 55 56 func TestTakeWithSkipInnerFunc(t *testing.T) { 57 var trace string 58 func() { 59 trace = Take(2) 60 }() 61 lines := strings.Split(trace, "\n") 62 require.NotEmpty(t, lines, "Expected stacktrace to have at least one frame.") 63 assert.Contains( 64 t, 65 lines[0], 66 "testing.", 67 "Expected stacktrace to start with the test function (skipping the test function).", 68 ) 69 } 70 71 func TestTakeDeepStack(t *testing.T) { 72 const ( 73 N = 500 74 withStackDepthName = "github.com/Laisky/zap/internal/stacktrace.withStackDepth" 75 ) 76 withStackDepth(N, func() { 77 trace := Take(0) 78 for found := 0; found < N; found++ { 79 i := strings.Index(trace, withStackDepthName) 80 if i < 0 { 81 t.Fatalf(`expected %v occurrences of %q, found %d`, 82 N, withStackDepthName, found) 83 } 84 trace = trace[i+len(withStackDepthName):] 85 } 86 }) 87 } 88 89 func BenchmarkTake(b *testing.B) { 90 for i := 0; i < b.N; i++ { 91 Take(0) 92 } 93 } 94 95 func withStackDepth(depth int, f func()) { 96 var recurse func(rune) rune 97 recurse = func(r rune) rune { 98 if r > 0 { 99 bytes.Map(recurse, []byte(string([]rune{r - 1}))) 100 } else { 101 f() 102 } 103 return 0 104 } 105 recurse(rune(depth)) 106 }