1 // Copyright 2014 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package profile 16 17 import ( 18 "bytes" 19 "testing" 20 21 "github.com/google/pprof/internal/proftest" 22 ) 23 24 var testM = []*Mapping{ 25 { 26 ID: 1, 27 Start: 1, 28 Limit: 10, 29 Offset: 0, 30 File: "file1", 31 BuildID: "buildid1", 32 HasFunctions: true, 33 HasFilenames: true, 34 HasLineNumbers: true, 35 HasInlineFrames: true, 36 }, 37 { 38 ID: 2, 39 Start: 10, 40 Limit: 30, 41 Offset: 9, 42 File: "file1", 43 BuildID: "buildid2", 44 HasFunctions: true, 45 HasFilenames: true, 46 HasLineNumbers: true, 47 HasInlineFrames: true, 48 }, 49 } 50 51 var testF = []*Function{ 52 {ID: 1, Name: "func1", SystemName: "func1", Filename: "file1"}, 53 {ID: 2, Name: "func2", SystemName: "func2", Filename: "file1"}, 54 {ID: 3, Name: "func3", SystemName: "func3", Filename: "file2"}, 55 } 56 57 var testL = []*Location{ 58 { 59 ID: 1, 60 Address: 1, 61 Mapping: testM[0], 62 Line: []Line{ 63 { 64 Function: testF[0], 65 Line: 2, 66 }, 67 { 68 Function: testF[1], 69 Line: 2222222, 70 }, 71 }, 72 }, 73 { 74 ID: 2, 75 Mapping: testM[1], 76 Address: 11, 77 Line: []Line{ 78 { 79 Function: testF[2], 80 Line: 2, 81 }, 82 }, 83 }, 84 { 85 ID: 3, 86 Mapping: testM[1], 87 Address: 12, 88 }, 89 } 90 91 var all = &Profile{ 92 PeriodType: &ValueType{Type: "cpu", Unit: "milliseconds"}, 93 Period: 10, 94 DurationNanos: 10e9, 95 SampleType: []*ValueType{ 96 {Type: "cpu", Unit: "cycles"}, 97 {Type: "object", Unit: "count"}, 98 }, 99 Sample: []*Sample{ 100 { 101 Location: []*Location{testL[0], testL[1], testL[2], testL[1], testL[1]}, 102 Label: map[string][]string{ 103 "key1": {"value1"}, 104 "key2": {"value2"}, 105 }, 106 Value: []int64{10, 20}, 107 }, 108 { 109 Location: []*Location{testL[1], testL[2], testL[0], testL[1]}, 110 Value: []int64{30, 40}, 111 Label: map[string][]string{ 112 "key1": {"value1"}, 113 "key2": {"value2"}, 114 }, 115 NumLabel: map[string][]int64{ 116 "key1": {1, 2}, 117 "key2": {3, 4}, 118 "bytes": {3, 4}, 119 "requests": {1, 1, 3, 4, 5}, 120 "alignment": {3, 4}, 121 }, 122 NumUnit: map[string][]string{ 123 "requests": {"", "", "seconds", "", "s"}, 124 "alignment": {"kilobytes", "kilobytes"}, 125 }, 126 }, 127 }, 128 Function: testF, 129 Mapping: testM, 130 Location: testL, 131 Comments: []string{"Comment 1", "Comment 2"}, 132 } 133 134 func TestMarshalUnmarshal(t *testing.T) { 135 // Write the profile, parse it, and ensure they're equal. 136 buf := bytes.NewBuffer(nil) 137 all.Write(buf) 138 all2, err := Parse(buf) 139 if err != nil { 140 t.Fatal(err) 141 } 142 143 js1 := proftest.EncodeJSON(&all) 144 js2 := proftest.EncodeJSON(&all2) 145 if string(js1) != string(js2) { 146 t.Errorf("profiles differ") 147 d, err := proftest.Diff(js1, js2) 148 if err != nil { 149 t.Fatal(err) 150 } 151 t.Error("\n" + string(d)) 152 } 153 } 154