| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package bloaty |
| |
| import ( |
| "fmt" |
| "io/ioutil" |
| "testing" |
| ) |
| |
| const ( |
| ids = `0071116f87e52dab0c21bd1cabc590fab5b06348 /out/libc.so |
| 01885627175ee9996b08af6c64c95a6e30787269 /out/libpc-ps2.so |
| ` |
| ) |
| |
| func WriteTempIdsTxt() (string, error) { |
| idsPath, err := ioutil.TempFile("", "ids") |
| if err != nil { |
| return "", err |
| } |
| fmt.Fprintf(idsPath, ids) |
| idsPath.Close() |
| return idsPath.Name(), nil |
| } |
| |
| func TestGetFiles(t *testing.T) { |
| idsPath, errIds := WriteTempIdsTxt() |
| if errIds != nil { |
| t.Fatal(errIds) |
| } |
| |
| actual, errConfig := getFiles(idsPath) |
| if errConfig != nil { |
| t.Fatal(errConfig) |
| } |
| |
| expected := []string{"/out/libc.so", "/out/libpc-ps2.so"} |
| |
| if len(actual) != len(expected) { |
| t.Fatalf("In TestGenConfig, expected \n%s but got \n%s", expected, actual) |
| } |
| |
| for i, val := range expected { |
| if actual[i] != val { |
| t.Fatalf("In TestGenConfig, expected \n%s but got \n%s", expected, actual) |
| } |
| } |
| } |
| |
| func TestGetTopNFiles(t *testing.T) { |
| input := map[string]*Segment{ |
| "LOAD [R]": { |
| Files: map[string]*File{ |
| "file.c": { |
| TotalFilesz: 14, |
| Symbols: map[string]*Symbol{ |
| "ecm_bind": { |
| Name: "ecm_bind", |
| Vmsz: 14, |
| Filesz: 14, |
| Binaries: []string{"lib.so"}, |
| }, |
| }, |
| }, |
| "different.c": { |
| TotalFilesz: 5, |
| Symbols: map[string]*Symbol{ |
| "ecm_bind": { |
| Name: "ecm_bind", |
| Vmsz: 23, |
| Filesz: 5, |
| Binaries: []string{"lib.so"}, |
| }, |
| }, |
| }, |
| }, |
| }, |
| "LOAD [RX]": { |
| Files: map[string]*File{ |
| "other.c": { |
| TotalFilesz: 1, |
| Symbols: map[string]*Symbol{ |
| "ecm_bind": { |
| Name: "ecm_bind", |
| Vmsz: 1, |
| Filesz: 1, |
| Binaries: []string{"lib.so"}, |
| }, |
| }, |
| }, |
| "test.c": { |
| TotalFilesz: 4, |
| Symbols: map[string]*Symbol{ |
| "test": { |
| Name: "test", |
| Vmsz: 4, |
| Filesz: 4, |
| Binaries: []string{"lib.so"}, |
| }, |
| }, |
| }, |
| }, |
| }, |
| } |
| |
| fileSizes := map[string]uint64{ |
| "file.c": 14, |
| "different.c": 5, |
| "other.c": 1, |
| "test.c": 4, |
| } |
| |
| getTopN(fileSizes, 1, 0, &input) |
| if len(input) != 2 { |
| t.Fatalf("In TestGetTopN, len is wrong: \n%+v", input) |
| } |
| |
| if _, ok := input["LOAD [R]"]; !ok { |
| t.Fatalf("In TestGetTopN, missing LOAD [R]: \n%+v", input) |
| } |
| |
| if len(input["LOAD [R]"].Files) != 2 { |
| t.Fatalf("In TestGetTopN, len is wrong: \n%+v", input["LOAD [R]"].Files) |
| } |
| |
| if val, ok := input["LOAD [R]"].Files["file.c"]; !ok { |
| t.Fatalf("In TestGetTopN, missing file.c: \n%+v", input["LOAD [R]"].Files) |
| } else if val.TotalFilesz != 14 { |
| t.Fatalf("In TestGetTopN, filesz is wrong: \n%+v", val) |
| } |
| |
| if val, ok := input["LOAD [R]"].Files["all small files"]; !ok { |
| t.Fatalf("In TestGetTopN, missing all small files: \n%+v", input["LOAD [R]"].Files) |
| } else if val.TotalFilesz != 5 { |
| t.Fatalf("In TestGetTopN, filesz is wrong: \n%+v", val) |
| } |
| |
| if _, ok := input["LOAD [RX]"]; !ok { |
| t.Fatalf("In TestGetTopN, missing LOAD [RX]: \n%+v", input) |
| } |
| |
| if len(input["LOAD [RX]"].Files) != 1 { |
| t.Fatalf("In TestGetTopN, len is wrong: \n%+v", input["LOAD [R]"].Files) |
| } |
| |
| if val, ok := input["LOAD [RX]"].Files["all small files"]; !ok { |
| t.Fatalf("In TestGetTopN, missing all small files: \n%+v", input["LOAD [R]"].Files) |
| } else if val.TotalFilesz != 5 { |
| t.Fatalf("In TestGetTopN, filesz is wrong: \n%+v", val) |
| } |
| } |
| |
| func TestGetTopNSymbols(t *testing.T) { |
| input := map[string]*Segment{ |
| "LOAD [R]": { |
| Files: map[string]*File{ |
| "file.c": { |
| TotalFilesz: 14, |
| Symbols: map[string]*Symbol{ |
| "ecm_bind": { |
| Name: "ecm_bind", |
| Vmsz: 14, |
| Filesz: 14, |
| Binaries: []string{"lib.so"}, |
| }, |
| "test": { |
| Name: "test", |
| Vmsz: 23, |
| Filesz: 5, |
| Binaries: []string{"lib.so"}, |
| }, |
| "other": { |
| Name: "other", |
| Vmsz: 5, |
| Filesz: 5, |
| Binaries: []string{"lib.so"}, |
| }, |
| }, |
| }, |
| }, |
| }, |
| } |
| |
| fileSizes := map[string]uint64{ |
| "file.c": 14, |
| "different.c": 5, |
| "other.c": 1, |
| "test.c": 4, |
| } |
| |
| getTopN(fileSizes, 0, 1, &input) |
| if len(input) != 1 { |
| t.Fatalf("In TestGetTopNSymbols, len is wrong: \n%+v", input) |
| } |
| |
| if _, ok := input["LOAD [R]"]; !ok { |
| t.Fatalf("In TestGetTopNSymbols, missing LOAD [R]: \n%+v", input) |
| } |
| |
| if len(input["LOAD [R]"].Files) != 1 { |
| t.Fatalf("In TestGetTopNSymbols, len is wrong: \n%+v", input["LOAD [R]"].Files) |
| } |
| |
| if val, ok := input["LOAD [R]"].Files["file.c"]; !ok { |
| t.Fatalf("In TestGetTopNSymbols, missing file.c: \n%+v", input["LOAD [R]"].Files) |
| } else if val.TotalFilesz != 14 { |
| t.Fatalf("In TestGetTopNSymbols, filesz is wrong: \n%+v", val) |
| } |
| |
| if len(input["LOAD [R]"].Files["file.c"].Symbols) != 2 { |
| t.Fatalf("In TestGetTopNSymbols, len is wrong: \n%+v", input["LOAD [R]"].Files["file.c"].Symbols) |
| } |
| |
| if val, ok := input["LOAD [R]"].Files["file.c"].Symbols["ecm_bind"]; !ok { |
| t.Fatalf("In TestGetTopNSymbols, missing ecm_bind: \n%+v", input["LOAD [R]"].Files) |
| } else if val.Filesz != 14 { |
| t.Fatalf("In TestGetTopNSymbols, filesz is wrong: \n%+v", val) |
| } |
| |
| if val, ok := input["LOAD [R]"].Files["file.c"].Symbols["all small syms"]; !ok { |
| t.Fatalf("In TestGetTopNSymbols, missing ecm_bind: \n%+v", input["LOAD [R]"].Files["file.c"].Symbols["all small syms"]) |
| } else if val.Filesz != 10 { |
| t.Fatalf("In TestGetTopNSymbols, filesz is wrong: \n%+v", val) |
| } |
| } |
| |
| func TestAddRowToOutput(t *testing.T) { |
| rows := []row{ |
| {"ecm_bind", "other.c", "LOAD [RX]", 7, 7}, |
| {"test", "other.c", "LOAD [RX]", 12, 2}, |
| {"ecm_bind", "other.c", "LOAD [R]", 23, 5}, |
| {"ecm_bind", "file.c", "LOAD [R]", 3, 3}, |
| } |
| |
| actual := make(map[string]*Segment) |
| for _, row := range rows { |
| addRowToOutput(&row, row.File, actual) |
| } |
| |
| // {"ecm_bind", "other.c", "LOAD [RX]", 7, 7}, |
| if _, ok := actual["LOAD [RX]"]; !ok { |
| t.Fatalf("In TestAddRowToOutput, got \n%+v", actual) |
| } |
| if _, ok := actual["LOAD [RX]"].Files["other.c"]; !ok { |
| t.Fatalf("In TestAddRowToOutput, missing LOAD[RX] other.c") |
| } |
| if val, ok := actual["LOAD [RX]"].Files["other.c"].Symbols["ecm_bind"]; !ok { |
| t.Fatalf("In TestAddRowToOutput, missing LOAD[RX] other.c ecm_bind") |
| } else if val.Name != "ecm_bind" || val.Vmsz != 7 || val.Filesz != 7 { |
| t.Fatalf("In TestAddRowToOutput, got \n%+v", val) |
| } |
| |
| // {"test", "other.c", "LOAD [RX]", 12, 2}, |
| if val, ok := actual["LOAD [RX]"].Files["other.c"].Symbols["test"]; !ok { |
| t.Fatalf("In TestAddRowToOutput, missing LOAD[RX] other.c test") |
| } else if val.Name != "test" || val.Vmsz != 12 || val.Filesz != 2 { |
| t.Fatalf("In TestAddRowToOutput, got \n%+v", val) |
| } |
| |
| // {"ecm_bind", "other.c", "LOAD [R]", 23, 5}, |
| if _, ok := actual["LOAD [R]"]; !ok { |
| t.Fatalf("In TestAddRowToOutput, missing LOAD[R]") |
| } |
| if _, ok := actual["LOAD [R]"].Files["other.c"]; !ok { |
| t.Fatalf("In TestAddRowToOutput, missing LOAD[R]:other.c") |
| } |
| if val, ok := actual["LOAD [R]"].Files["other.c"].Symbols["ecm_bind"]; !ok { |
| t.Fatalf("In TestAddRowToOutput, missing LOAD[R] other.c ecm_bind") |
| } else if val.Name != "ecm_bind" || val.Vmsz != 23 || val.Filesz != 5 { |
| t.Fatalf("In TestAddRowToOutput, got \n%+v", val) |
| } |
| |
| // {"ecm_bind", "file.c", "LOAD [R]", 3, 3}, |
| if _, ok := actual["LOAD [R]"].Files["file.c"]; !ok { |
| t.Fatalf("In TestAddRowToOutput, missing LOAD[R] file.c") |
| } |
| if val, ok := actual["LOAD [R]"].Files["file.c"].Symbols["ecm_bind"]; !ok { |
| t.Fatalf("In TestAddRowToOutput, missing LOAD[R] file.c ecm_bind") |
| } else if val.Name != "ecm_bind" || val.Vmsz != 3 || val.Filesz != 3 { |
| t.Fatalf("In TestAddRowToOutput, got \n%+v", val) |
| } |
| } |