mirror of
https://github.com/akvorado/akvorado.git
synced 2025-12-11 22:14:02 +01:00
Instead of computing the same time the call site, use an intermediate structure with lazily-evaluated functions.
122 lines
2.9 KiB
Go
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()
|
|
}
|
|
})
|
|
}
|