| // Copyright 2014 Google Inc. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package profile |
| |
| import ( |
| "bytes" |
| "testing" |
| |
| "github.com/google/pprof/internal/proftest" |
| ) |
| |
| var testM = []*Mapping{ |
| { |
| ID: 1, |
| Start: 1, |
| Limit: 10, |
| Offset: 0, |
| File: "file1", |
| BuildID: "buildid1", |
| HasFunctions: true, |
| HasFilenames: true, |
| HasLineNumbers: true, |
| HasInlineFrames: true, |
| }, |
| { |
| ID: 2, |
| Start: 10, |
| Limit: 30, |
| Offset: 9, |
| File: "file1", |
| BuildID: "buildid2", |
| HasFunctions: true, |
| HasFilenames: true, |
| HasLineNumbers: true, |
| HasInlineFrames: true, |
| }, |
| } |
| |
| var testF = []*Function{ |
| {ID: 1, Name: "func1", SystemName: "func1", Filename: "file1"}, |
| {ID: 2, Name: "func2", SystemName: "func2", Filename: "file1"}, |
| {ID: 3, Name: "func3", SystemName: "func3", Filename: "file2"}, |
| {ID: 4, Name: "func4", SystemName: "func4", Filename: "file3"}, |
| {ID: 5, Name: "func5", SystemName: "func5", Filename: "file4"}, |
| } |
| |
| var testL = []*Location{ |
| { |
| ID: 1, |
| Address: 1, |
| Mapping: testM[0], |
| Line: []Line{ |
| { |
| Function: testF[0], |
| Line: 2, |
| }, |
| { |
| Function: testF[1], |
| Line: 2222222, |
| }, |
| }, |
| }, |
| { |
| ID: 2, |
| Mapping: testM[1], |
| Address: 11, |
| Line: []Line{ |
| { |
| Function: testF[2], |
| Line: 2, |
| }, |
| }, |
| }, |
| { |
| ID: 3, |
| Mapping: testM[1], |
| Address: 12, |
| }, |
| { |
| ID: 4, |
| Mapping: testM[1], |
| Address: 12, |
| Line: []Line{ |
| { |
| Function: testF[4], |
| Line: 6, |
| }, |
| { |
| Function: testF[4], |
| Line: 6, |
| }, |
| }, |
| IsFolded: true, |
| }, |
| } |
| |
| var all = &Profile{ |
| PeriodType: &ValueType{Type: "cpu", Unit: "milliseconds"}, |
| Period: 10, |
| DurationNanos: 10e9, |
| SampleType: []*ValueType{ |
| {Type: "cpu", Unit: "cycles"}, |
| {Type: "object", Unit: "count"}, |
| }, |
| Sample: []*Sample{ |
| { |
| Location: []*Location{testL[0], testL[1], testL[2], testL[1], testL[1]}, |
| Label: map[string][]string{ |
| "key1": {"value1"}, |
| "key2": {"value2"}, |
| }, |
| Value: []int64{10, 20}, |
| }, |
| { |
| Location: []*Location{testL[1], testL[2], testL[0], testL[1]}, |
| Value: []int64{30, 40}, |
| Label: map[string][]string{ |
| "key1": {"value1"}, |
| "key2": {"value2"}, |
| }, |
| NumLabel: map[string][]int64{ |
| "key1": {1, 2}, |
| "key2": {3, 4}, |
| "bytes": {3, 4}, |
| "requests": {1, 1, 3, 4, 5}, |
| "alignment": {3, 4}, |
| }, |
| NumUnit: map[string][]string{ |
| "requests": {"", "", "seconds", "", "s"}, |
| "alignment": {"kilobytes", "kilobytes"}, |
| }, |
| }, |
| }, |
| Function: testF, |
| Mapping: testM, |
| Location: testL, |
| Comments: []string{"Comment 1", "Comment 2"}, |
| } |
| |
| func TestMarshalUnmarshal(t *testing.T) { |
| // Write the profile, parse it, and ensure they're equal. |
| var buf bytes.Buffer |
| all.Write(&buf) |
| all2, err := Parse(&buf) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| js1 := proftest.EncodeJSON(&all) |
| js2 := proftest.EncodeJSON(&all2) |
| if string(js1) != string(js2) { |
| t.Errorf("profiles differ") |
| d, err := proftest.Diff(js1, js2) |
| if err != nil { |
| t.Fatal(err) |
| } |
| t.Error("\n" + string(d)) |
| } |
| } |