github.com/grafana/pyroscope@v1.18.0/pkg/model/flamegraph_diff_test.go (about) 1 package model 2 3 import ( 4 "math" 5 "testing" 6 7 "github.com/stretchr/testify/assert" 8 ) 9 10 func Test_Diff_Tree(t *testing.T) { 11 tr := newTree([]stacktraces{ 12 {locations: []string{"b", "a"}, value: 1}, 13 {locations: []string{"c", "a"}, value: 2}, 14 }) 15 16 tr2 := newTree([]stacktraces{ 17 {locations: []string{"b", "a"}, value: 4}, 18 {locations: []string{"c", "a"}, value: 8}, 19 }) 20 21 res, err := NewFlamegraphDiff(tr, tr2, 1024) 22 assert.NoError(t, err) 23 assert.Equal(t, []string{"total", "a", "c", "b"}, res.Names) 24 assert.Equal(t, int64(8), res.MaxSelf) 25 assert.Equal(t, int64(15), res.Total) 26 27 assert.Equal(t, 3, len(res.Levels)) 28 assert.Equal(t, []int64{0, 3, 0, 0, 12, 0, 0}, res.Levels[0].Values) 29 assert.Equal(t, []int64{0, 3, 0, 0, 12, 0, 1}, res.Levels[1].Values) 30 assert.Equal(t, []int64{0, 1, 1, 0, 4, 4, 3, 0, 2, 2, 0, 8, 8, 2}, res.Levels[2].Values) 31 } 32 33 func Test_Diff_Tree_With_Different_Structure(t *testing.T) { 34 tr := newTree([]stacktraces{ 35 {locations: []string{"b", "a"}, value: 1}, 36 {locations: []string{"c", "a"}, value: 2}, 37 {locations: []string{"e", "a"}, value: 3}, 38 }) 39 40 tr2 := newTree([]stacktraces{ 41 {locations: []string{"b", "a"}, value: 4}, 42 {locations: []string{"d", "a"}, value: 8}, 43 {locations: []string{"e", "a"}, value: 12}, 44 }) 45 46 res, err := NewFlamegraphDiff(tr, tr2, 1024) 47 assert.NoError(t, err) 48 assert.Equal(t, []string{"total", "a", "e", "d", "c", "b"}, res.Names) 49 assert.Equal(t, int64(12), res.MaxSelf) 50 assert.Equal(t, int64(30), res.Total) 51 52 assert.Equal(t, 3, len(res.Levels)) 53 assert.Equal(t, []int64{0, 6, 0, 0, 24, 0, 0}, res.Levels[0].Values) 54 assert.Equal(t, []int64{0, 6, 0, 0, 24, 0, 1}, res.Levels[1].Values) 55 assert.Equal(t, []int64{ 56 0, 1, 1, 0, 4, 4, 5, // e 57 0, 2, 2, 0, 0, 0, 4, // d 58 0, 0, 0, 0, 8, 8, 3, // c 59 0, 3, 3, 0, 12, 12, 2, // b 60 }, res.Levels[2].Values) 61 } 62 63 func Test_Diff_Tree_With_MaxNodes(t *testing.T) { 64 tr := newTree([]stacktraces{ 65 {locations: []string{"b", "a"}, value: 1}, 66 {locations: []string{"c", "a"}, value: 2}, 67 }) 68 69 tr2 := newTree([]stacktraces{ 70 {locations: []string{"b", "a"}, value: 4}, 71 {locations: []string{"c", "a"}, value: 8}, 72 }) 73 74 t.Run("max nodes less than the tree size", func(t *testing.T) { 75 res, err := NewFlamegraphDiff(tr, tr2, 2) 76 assert.NoError(t, err) 77 assert.Equal(t, []string{"total", "a", "other"}, res.Names) 78 assert.Equal(t, int64(12), res.MaxSelf) 79 assert.Equal(t, int64(15), res.Total) 80 }) 81 82 t.Run("max nodes greater than the tree size", func(t *testing.T) { 83 res, err := NewFlamegraphDiff(tr, tr2, math.MaxInt64) 84 assert.NoError(t, err) 85 assert.Equal(t, []string{"total", "a", "c", "b"}, res.Names) 86 assert.Equal(t, int64(8), res.MaxSelf) 87 assert.Equal(t, int64(15), res.Total) 88 }) 89 90 t.Run("negative max nodes", func(t *testing.T) { 91 res, err := NewFlamegraphDiff(tr, tr2, -1) 92 assert.NoError(t, err) 93 assert.Equal(t, []string{"total", "a", "c", "b"}, res.Names) 94 assert.Equal(t, int64(8), res.MaxSelf) 95 assert.Equal(t, int64(15), res.Total) 96 }) 97 } 98 99 func Test_Diff_Tree_With_NegativeNodes(t *testing.T) { 100 tr := newTree([]stacktraces{ 101 {locations: []string{"b", "a"}, value: 1}, 102 {locations: []string{"c", "a"}, value: -2}, 103 }) 104 105 tr2 := newTree([]stacktraces{ 106 {locations: []string{"b", "a"}, value: 4}, 107 {locations: []string{"c", "a"}, value: -8}, 108 }) 109 110 _, err := NewFlamegraphDiff(tr, tr2, 1024) 111 assert.Error(t, err) 112 } 113 114 func Test_Diff_No_Common_Root(t *testing.T) { 115 tr := newTree([]stacktraces{ 116 {locations: []string{"b", "a"}, value: 1}, 117 }) 118 119 tr2 := newTree([]stacktraces{ 120 {locations: []string{"c", "a", "b", "k"}, value: 8}, 121 }) 122 123 _, err := NewFlamegraphDiff(tr, tr2, 1024) 124 assert.NoError(t, err) 125 }