blob: 7ea70ffdc73bbd9942cc2c804a9031943e2b67a0 [file] [log] [blame]
package bloaty
import (
"strconv"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestParseBloatyOutput_EmptyBloatyOutput_Error(t *testing.T) {
_, err := ParseTSVOutput("")
require.Error(t, err)
assert.Contains(t, err.Error(), "empty input")
}
func TestParseBloatyOutput_NotTSV_Error(t *testing.T) {
bloatyOutput := `compileunits,symbols,vmsize,filesize
../../dm/DMSrcSink.cpp,DM::CodecSrc::draw(),7307,7382
`
_, err := ParseTSVOutput(bloatyOutput)
require.Error(t, err)
assert.Contains(t, err.Error(), "on line 1: unrecognized header format; must be: \"compileunits\\tsymbols\\tvmsize\\tfilesize\"")
}
func TestParseBloatyOutput_WrongColumns_Error(t *testing.T) {
bloatyOutput := `compileunits filesize
../../dm/DMSrcSink.cpp 7382
`
_, err := ParseTSVOutput(bloatyOutput)
require.Error(t, err)
assert.Contains(t, err.Error(), "on line 1: unrecognized header format; must be: \"compileunits\\tsymbols\\tvmsize\\tfilesize\"")
}
// sampleBloatyOutput is a valid Bloaty output that exercises the following logic:
//
// - Enforcement of unique symbol names (see the repeated symbols).
// - Special handling of third_party paths (see the third_party compile units).
var sampleBloatyOutput = `compileunits symbols vmsize filesize
../../third_party/externals/harfbuzz/src/hb-ot-font.cc (anonymous namespace)::TLSCurrentObjects::Get()::objects 0 13
../../third_party/externals/harfbuzz/src/hb-subset.cc [section .debug_info] 0 4213071
../../dm/DMSrcSink.cpp (anonymous namespace)::TLSCurrentObjects::Get()::objects 0 14
../../dm/DMSrcSink.cpp DM::CodecSrc::draw() 7307 7382
../../src/sksl/SkSLCompiler.cpp (anonymous namespace)::TLSCurrentObjects::Get()::objects 0 16
../../../../../../skia/third_party/externals/libwebp/src/enc/vp8l_enc.c EncodeStreamHook 7656 7656
[section .rodata] [section .rodata] 10425940 10425940
[section .rodata] propsVectorsTrie_index 62456 62456
[section .text] png_create_read_struct_2 75 75
[section .eh_frame] png_create_read_struct_2 32 32
[section .eh_frame_hdr] png_create_read_struct_2 8 8
`
func TestParseBloatyOutput_Success(t *testing.T) {
items, err := ParseTSVOutput(sampleBloatyOutput)
require.NoError(t, err)
assert.Equal(t, []OutputItem{
{
CompileUnit: "third_party/externals/harfbuzz/src/hb-ot-font.cc",
Symbol: "(anonymous namespace)::TLSCurrentObjects::Get()::objects",
VirtualMemorySize: 0,
FileSize: 13,
},
{
CompileUnit: "third_party/externals/harfbuzz/src/hb-subset.cc",
Symbol: "[section .debug_info]",
VirtualMemorySize: 0,
FileSize: 4213071,
},
{
CompileUnit: "dm/DMSrcSink.cpp",
Symbol: "(anonymous namespace)::TLSCurrentObjects::Get()::objects",
VirtualMemorySize: 0,
FileSize: 14,
},
{
CompileUnit: "dm/DMSrcSink.cpp",
Symbol: "DM::CodecSrc::draw()",
VirtualMemorySize: 7307,
FileSize: 7382,
},
{
CompileUnit: "src/sksl/SkSLCompiler.cpp",
Symbol: "(anonymous namespace)::TLSCurrentObjects::Get()::objects",
VirtualMemorySize: 0,
FileSize: 16,
},
{
CompileUnit: "third_party/externals/libwebp/src/enc/vp8l_enc.c",
Symbol: "EncodeStreamHook",
VirtualMemorySize: 7656,
FileSize: 7656,
},
{
CompileUnit: "[section .rodata]",
Symbol: "UNKNOWN [section .rodata]",
VirtualMemorySize: 10425940,
FileSize: 10425940,
},
{
CompileUnit: "[section .rodata]",
Symbol: "propsVectorsTrie_index [section .rodata]",
VirtualMemorySize: 62456,
FileSize: 62456,
},
{
CompileUnit: "[section .text]",
Symbol: "png_create_read_struct_2 [section .text]",
VirtualMemorySize: 75,
FileSize: 75,
},
{
CompileUnit: "[section .eh_frame]",
Symbol: "png_create_read_struct_2 [section .eh_frame]",
VirtualMemorySize: 32,
FileSize: 32,
},
{
CompileUnit: "[section .eh_frame_hdr]",
Symbol: "png_create_read_struct_2 [section .eh_frame_hdr]",
VirtualMemorySize: 8,
FileSize: 8,
},
},
items)
}
func TestGenTreeMapDataTable_AllRowsCreatedInSpecifiedOrder(t *testing.T) {
items, err := ParseTSVOutput(sampleBloatyOutput)
require.NoError(t, err)
rows := GenTreeMapDataTableRows(items, 200)
assert.Equal(t, []TreeMapDataTableRow{
{
Name: "ROOT",
Parent: "",
Size: 0,
},
{
Name: "[section .eh_frame]",
Parent: "ROOT",
Size: 0,
},
{
Parent: "[section .eh_frame]",
Name: "png_create_read_struct_2 [section .eh_frame]",
Size: 32,
},
{
Name: "[section .eh_frame_hdr]",
Parent: "ROOT",
Size: 0,
},
{
Parent: "[section .eh_frame_hdr]",
Name: "png_create_read_struct_2 [section .eh_frame_hdr]",
Size: 8,
},
{
Name: "[section .rodata]",
Parent: "ROOT",
Size: 0,
},
{
Name: "UNKNOWN [section .rodata]",
Parent: "[section .rodata]",
Size: 10425940,
},
{
Parent: "[section .rodata]",
Name: "propsVectorsTrie_index [section .rodata]",
Size: 62456,
},
{
Name: "[section .text]",
Parent: "ROOT",
Size: 0,
},
{
Parent: "[section .text]",
Name: "png_create_read_struct_2 [section .text]",
Size: 75,
},
{
Name: "dm",
Parent: "ROOT",
Size: 0,
},
{
Name: "dm/DMSrcSink.cpp",
Parent: "dm",
Size: 0,
},
{
Name: "DM::CodecSrc::draw()",
Parent: "dm/DMSrcSink.cpp",
Size: 7382,
},
{
Name: "(anonymous namespace)::TLSCurrentObjects::Get()::objects",
Parent: "dm/DMSrcSink.cpp",
Size: 14,
},
{
Name: "src",
Parent: "ROOT",
Size: 0,
},
{
Name: "src/sksl",
Parent: "src",
Size: 0,
},
{
Name: "src/sksl/SkSLCompiler.cpp",
Parent: "src/sksl",
Size: 0,
},
{
Name: "(anonymous namespace)::TLSCurrentObjects::Get()::objects_1",
Parent: "src/sksl/SkSLCompiler.cpp",
Size: 16,
},
{
Name: "third_party",
Parent: "ROOT",
Size: 0,
},
{
Name: "third_party/externals",
Parent: "third_party",
Size: 0,
},
{
Name: "third_party/externals/harfbuzz",
Parent: "third_party/externals",
Size: 0,
},
{
Name: "third_party/externals/harfbuzz/src",
Parent: "third_party/externals/harfbuzz",
Size: 0,
},
{
Name: "third_party/externals/harfbuzz/src/hb-ot-font.cc",
Parent: "third_party/externals/harfbuzz/src",
Size: 0,
},
{
Name: "(anonymous namespace)::TLSCurrentObjects::Get()::objects_2",
Parent: "third_party/externals/harfbuzz/src/hb-ot-font.cc",
Size: 13,
},
{
Name: "third_party/externals/harfbuzz/src/hb-subset.cc",
Parent: "third_party/externals/harfbuzz/src",
Size: 0,
},
{
Name: "[section .debug_info]",
Parent: "third_party/externals/harfbuzz/src/hb-subset.cc",
Size: 4213071,
},
{
Name: "third_party/externals/libwebp",
Parent: "third_party/externals",
Size: 0,
},
{
Name: "third_party/externals/libwebp/src",
Parent: "third_party/externals/libwebp",
Size: 0,
},
{
Name: "third_party/externals/libwebp/src/enc",
Parent: "third_party/externals/libwebp/src",
Size: 0,
},
{
Name: "third_party/externals/libwebp/src/enc/vp8l_enc.c",
Parent: "third_party/externals/libwebp/src/enc",
Size: 0,
},
{
Name: "EncodeStreamHook",
Parent: "third_party/externals/libwebp/src/enc/vp8l_enc.c",
Size: 7656,
},
},
rows)
}
func TestGenTreeMapDataTable_GroupsSymbolsBeyondCutoff(t *testing.T) {
// Create 10 alpha items (of which the biggest 4 will be shown) and 2 beta items (all of which
// will be shown).
var items []OutputItem
for i := 1; i <= 10; i++ {
items = append(items, OutputItem{
CompileUnit: "alpha",
Symbol: "a" + strconv.Itoa(i),
FileSize: i,
})
}
for i := 1; i <= 2; i++ {
items = append(items, OutputItem{
CompileUnit: "beta",
Symbol: "b" + strconv.Itoa(i),
FileSize: i,
})
}
rows := GenTreeMapDataTableRows(items, 4)
assert.Equal(t, []TreeMapDataTableRow{
{
Name: "ROOT",
Parent: "",
Size: 0,
},
{
Name: "alpha",
Parent: "ROOT",
Size: 0,
},
{
Name: "a10",
Parent: "alpha",
Size: 10,
},
{
Name: "a9",
Parent: "alpha",
Size: 9,
},
{
Name: "a8",
Parent: "alpha",
Size: 8,
},
{
Name: "a7",
Parent: "alpha",
Size: 7,
},
{
Name: "beta",
Parent: "ROOT",
Size: 0,
},
{
Name: "b2",
Parent: "beta",
Size: 2,
},
{
Name: "b1",
Parent: "beta",
Size: 1,
},
// Overflow comes at the end
{
Name: "remainder (alpha)",
Parent: "alpha",
Size: 6 + 5 + 4 + 3 + 2 + 1,
},
}, rows)
}