Two-pass parser resolves forward cfn= references; all cost lines (including call edges) are accumulated as inclusive costs per function. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
81 lines
1.8 KiB
Go
81 lines
1.8 KiB
Go
package cachegrind_test
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"forge.lclr.dev/AI/xdebug-mcp/internal/cachegrind"
|
|
)
|
|
|
|
const simpleFixture = `version: 1
|
|
creator: test
|
|
cmd: index.php
|
|
part: 1
|
|
positions: line
|
|
|
|
events: Time_(10ns) Memory_(bytes)
|
|
|
|
fl=(1) index.php
|
|
fn=(1) main
|
|
1 2000 1000
|
|
cfl=(1)
|
|
cfn=(2)
|
|
calls=1 0 0
|
|
2 1500 700
|
|
|
|
fl=(1)
|
|
fn=(2) query
|
|
10 1500 700
|
|
cfl=(1)
|
|
cfn=(3)
|
|
calls=2 0 0
|
|
15 500 200
|
|
|
|
fl=(1)
|
|
fn=(3) connect
|
|
20 250 100
|
|
`
|
|
|
|
func TestParseSimple(t *testing.T) {
|
|
p, err := cachegrind.Parse(strings.NewReader(simpleFixture))
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "index.php", p.Cmd)
|
|
assert.Equal(t, []string{"Time_(10ns)", "Memory_(bytes)"}, p.Events)
|
|
assert.Len(t, p.Functions, 3)
|
|
|
|
main := p.ByName["main"]
|
|
require.Len(t, main, 1)
|
|
// main costs: self (2000,1000) + call to query (1500,700) = (3500,1700)
|
|
assert.Equal(t, []int64{3500, 1700}, main[0].Costs)
|
|
assert.Len(t, main[0].Calls, 1)
|
|
assert.Equal(t, int64(1), main[0].Calls[0].Count)
|
|
assert.Equal(t, "query", main[0].Calls[0].Callee.Name)
|
|
|
|
query := p.ByName["query"]
|
|
require.Len(t, query, 1)
|
|
assert.Equal(t, []int64{2000, 900}, query[0].Costs)
|
|
assert.Len(t, query[0].CalledBy, 1)
|
|
assert.Len(t, query[0].Calls, 1)
|
|
assert.Equal(t, int64(2), query[0].Calls[0].Count)
|
|
|
|
connect := p.ByName["connect"]
|
|
require.Len(t, connect, 1)
|
|
assert.Equal(t, []int64{250, 100}, connect[0].Costs)
|
|
assert.Empty(t, connect[0].Calls)
|
|
assert.Len(t, connect[0].CalledBy, 1)
|
|
}
|
|
|
|
func TestParseFile_gzip(t *testing.T) {
|
|
path := "/home/leclere/Uppler/apps/uppler1/docker/tmp/xdebug/cachegrind.out.45.gz"
|
|
p, err := cachegrind.ParseFile(path)
|
|
if err != nil {
|
|
t.Skipf("real file unavailable: %v", err)
|
|
}
|
|
assert.NotEmpty(t, p.Events)
|
|
assert.NotEmpty(t, p.Functions)
|
|
assert.NotEmpty(t, p.Cmd)
|
|
}
|