Files
akvorado/common/reporter/stack/root_test.go
Vincent Bernat 7c7821bddc
Some checks failed
CI / 🤖 Check dependabot status (push) Has been cancelled
CI / 🐧 Test on Linux (${{ github.ref_type == 'tag' }}, misc) (push) Has been cancelled
CI / 🐧 Test on Linux (coverage) (push) Has been cancelled
CI / 🐧 Test on Linux (regular) (push) Has been cancelled
CI / ❄️ Build on Nix (push) Has been cancelled
CI / 🍏 Build and test on macOS (push) Has been cancelled
CI / 🧪 End-to-end testing (push) Has been cancelled
CI / 🔍 Upload code coverage (push) Has been cancelled
CI / 🔬 Test only Go (push) Has been cancelled
CI / 🔬 Test only JS (${{ needs.dependabot.outputs.package-ecosystem }}, 20) (push) Has been cancelled
CI / 🔬 Test only JS (${{ needs.dependabot.outputs.package-ecosystem }}, 22) (push) Has been cancelled
CI / 🔬 Test only JS (${{ needs.dependabot.outputs.package-ecosystem }}, 24) (push) Has been cancelled
CI / ⚖️ Check licenses (push) Has been cancelled
CI / 🐋 Build Docker images (push) Has been cancelled
CI / 🐋 Tag Docker images (push) Has been cancelled
CI / 🚀 Publish release (push) Has been cancelled
common/reporter: optimize stack trace walking when logging
Instead of computing the same time the call site, use an intermediate
structure with lazily-evaluated functions.
2025-11-05 15:17:32 +01:00

122 lines
2.9 KiB
Go

// SPDX-FileCopyrightText: 2022 Free Mobile
// SPDX-License-Identifier: AGPL-3.0-only
package stack_test
import (
"strings"
"testing"
"akvorado/common/helpers"
"akvorado/common/reporter/stack"
)
func TestSourceFile(t *testing.T) {
callers := stack.Callers()
got := []string{}
for _, caller := range callers[:len(callers)-1] {
// Extract source file without line number
sourceFile := caller.Info().SourceFile()
if idx := strings.LastIndex(sourceFile, ":"); idx != -1 {
sourceFile = sourceFile[:idx]
}
got = append(got, sourceFile)
}
expected := []string{
"akvorado/common/reporter/stack/root_test.go",
"testing/testing.go",
}
if diff := helpers.Diff(got, expected); diff != "" {
t.Fatalf("SourceFile() (-got, +want):\n%s", diff)
}
}
func TestFunctionName(t *testing.T) {
callers := stack.Callers()
got := []string{}
for _, caller := range callers[:len(callers)-1] {
got = append(got, caller.Info().FunctionName())
}
expected := []string{
"akvorado/common/reporter/stack_test.TestFunctionName",
"testing.tRunner",
}
if diff := helpers.Diff(got, expected); diff != "" {
t.Fatalf("FunctionName() (-got, +want):\n%s", diff)
}
}
func TestModuleName(t *testing.T) {
got := strings.Split(stack.ModuleName, "/")
expected := []string{"akvorado"}
if diff := helpers.Diff(got, expected); diff != "" {
t.Errorf("moduleName:\n%s", diff)
}
}
func TestInfo(t *testing.T) {
callers := stack.Callers()
if len(callers) == 0 {
t.Fatal("Callers() empty")
}
caller := callers[0]
info := caller.Info()
// Verify basic properties
functionName := info.FunctionName()
if !strings.HasSuffix(functionName, ".TestInfo") {
t.Errorf("FunctionName() should end with .TestInfo, got %q", functionName)
}
fileName := info.FileName()
if !strings.HasSuffix(fileName, "/root_test.go") {
t.Errorf("FileName() should end with /root_test.go, got %q", fileName)
}
sourceFile := info.SourceFile()
if !strings.HasSuffix(sourceFile, "akvorado/common/reporter/stack/root_test.go:58") {
t.Errorf("SourceFile() should have complete path, got %q", sourceFile)
}
}
func BenchmarkCallInfo(b *testing.B) {
callers := stack.Callers()
if len(callers) == 0 {
b.Fatal("no callers")
}
caller := callers[0]
b.Run("Info() all fields", func(b *testing.B) {
for b.Loop() {
info := caller.Info()
_ = info.FunctionName()
_ = info.FileName()
_ = info.SourceFile()
}
})
b.Run("Info() function name", func(b *testing.B) {
for b.Loop() {
info := caller.Info()
_ = info.FunctionName()
}
})
b.Run("Info() function and filename", func(b *testing.B) {
// Simulates frames that match but we skip SourceFile computation
for b.Loop() {
info := caller.Info()
_ = info.FunctionName()
_ = info.FileName()
}
})
b.Run("Info() separate", func(b *testing.B) {
for b.Loop() {
_ = caller.Info().FunctionName()
_ = caller.Info().FileName()
_ = caller.Info().SourceFile()
}
})
}