|
@@ -217,7 +217,7 @@ var cpuL = []*Location{
|
217
|
217
|
},
|
218
|
218
|
}
|
219
|
219
|
|
220
|
|
-var testProfile = &Profile{
|
|
220
|
+var testProfile1 = &Profile{
|
221
|
221
|
PeriodType: &ValueType{Type: "cpu", Unit: "milliseconds"},
|
222
|
222
|
Period: 1,
|
223
|
223
|
DurationNanos: 10e9,
|
|
@@ -272,6 +272,83 @@ var testProfile = &Profile{
|
272
|
272
|
Mapping: cpuM,
|
273
|
273
|
}
|
274
|
274
|
|
|
275
|
+var testProfile2 = &Profile{
|
|
276
|
+ PeriodType: &ValueType{Type: "cpu", Unit: "milliseconds"},
|
|
277
|
+ Period: 1,
|
|
278
|
+ DurationNanos: 10e9,
|
|
279
|
+ SampleType: []*ValueType{
|
|
280
|
+ {Type: "samples", Unit: "count"},
|
|
281
|
+ {Type: "cpu", Unit: "milliseconds"},
|
|
282
|
+ },
|
|
283
|
+ Sample: []*Sample{
|
|
284
|
+ {
|
|
285
|
+ Location: []*Location{cpuL[0]},
|
|
286
|
+ Value: []int64{70, 1000},
|
|
287
|
+ Label: map[string][]string{
|
|
288
|
+ "key1": {"tag1"},
|
|
289
|
+ "key2": {"tag1"},
|
|
290
|
+ },
|
|
291
|
+ },
|
|
292
|
+ {
|
|
293
|
+ Location: []*Location{cpuL[1], cpuL[0]},
|
|
294
|
+ Value: []int64{60, 100},
|
|
295
|
+ Label: map[string][]string{
|
|
296
|
+ "key1": {"tag2"},
|
|
297
|
+ "key3": {"tag2"},
|
|
298
|
+ },
|
|
299
|
+ },
|
|
300
|
+ {
|
|
301
|
+ Location: []*Location{cpuL[2], cpuL[0]},
|
|
302
|
+ Value: []int64{50, 10},
|
|
303
|
+ Label: map[string][]string{
|
|
304
|
+ "key1": {"tag3"},
|
|
305
|
+ "key2": {"tag2"},
|
|
306
|
+ },
|
|
307
|
+ },
|
|
308
|
+ {
|
|
309
|
+ Location: []*Location{cpuL[3], cpuL[0]},
|
|
310
|
+ Value: []int64{40, 10000},
|
|
311
|
+ Label: map[string][]string{
|
|
312
|
+ "key1": {"tag4"},
|
|
313
|
+ "key2": {"tag1"},
|
|
314
|
+ },
|
|
315
|
+ },
|
|
316
|
+ {
|
|
317
|
+ Location: []*Location{cpuL[4], cpuL[0]},
|
|
318
|
+ Value: []int64{1, 1},
|
|
319
|
+ Label: map[string][]string{
|
|
320
|
+ "key1": {"tag4"},
|
|
321
|
+ "key2": {"tag1"},
|
|
322
|
+ },
|
|
323
|
+ },
|
|
324
|
+ },
|
|
325
|
+ Location: cpuL,
|
|
326
|
+ Function: cpuF,
|
|
327
|
+ Mapping: cpuM,
|
|
328
|
+}
|
|
329
|
+
|
|
330
|
+var testProfile3 = &Profile{
|
|
331
|
+ PeriodType: &ValueType{Type: "cpu", Unit: "milliseconds"},
|
|
332
|
+ Period: 1,
|
|
333
|
+ DurationNanos: 10e9,
|
|
334
|
+ SampleType: []*ValueType{
|
|
335
|
+ {Type: "samples", Unit: "count"},
|
|
336
|
+ },
|
|
337
|
+ Sample: []*Sample{
|
|
338
|
+ {
|
|
339
|
+ Location: []*Location{cpuL[0]},
|
|
340
|
+ Value: []int64{1000},
|
|
341
|
+ Label: map[string][]string{
|
|
342
|
+ "key1": {"tag1"},
|
|
343
|
+ "key2": {"tag1"},
|
|
344
|
+ },
|
|
345
|
+ },
|
|
346
|
+ },
|
|
347
|
+ Location: cpuL,
|
|
348
|
+ Function: cpuF,
|
|
349
|
+ Mapping: cpuM,
|
|
350
|
+}
|
|
351
|
+
|
275
|
352
|
var aggTests = map[string]aggTest{
|
276
|
353
|
"precise": {true, true, true, true, 5},
|
277
|
354
|
"fileline": {false, true, true, true, 4},
|
|
@@ -287,7 +364,7 @@ type aggTest struct {
|
287
|
364
|
const totalSamples = int64(11111)
|
288
|
365
|
|
289
|
366
|
func TestAggregation(t *testing.T) {
|
290
|
|
- prof := testProfile.Copy()
|
|
367
|
+ prof := testProfile1.Copy()
|
291
|
368
|
for _, resolution := range []string{"precise", "fileline", "inline_function", "function"} {
|
292
|
369
|
a := aggTests[resolution]
|
293
|
370
|
if !a.precise {
|
|
@@ -362,7 +439,7 @@ func checkAggregation(prof *Profile, a *aggTest) error {
|
362
|
439
|
|
363
|
440
|
// Test merge leaves the main binary in place.
|
364
|
441
|
func TestMergeMain(t *testing.T) {
|
365
|
|
- prof := testProfile.Copy()
|
|
442
|
+ prof := testProfile1.Copy()
|
366
|
443
|
p1, err := Merge([]*Profile{prof})
|
367
|
444
|
if err != nil {
|
368
|
445
|
t.Fatalf("merge error: %v", err)
|
|
@@ -377,7 +454,7 @@ func TestMerge(t *testing.T) {
|
377
|
454
|
// -2. Should end up with an empty profile (all samples for a
|
378
|
455
|
// location should add up to 0).
|
379
|
456
|
|
380
|
|
- prof := testProfile.Copy()
|
|
457
|
+ prof := testProfile1.Copy()
|
381
|
458
|
p1, err := Merge([]*Profile{prof, prof})
|
382
|
459
|
if err != nil {
|
383
|
460
|
t.Errorf("merge error: %v", err)
|
|
@@ -409,7 +486,7 @@ func TestMergeAll(t *testing.T) {
|
409
|
486
|
// Aggregate 10 copies of the profile.
|
410
|
487
|
profs := make([]*Profile, 10)
|
411
|
488
|
for i := 0; i < 10; i++ {
|
412
|
|
- profs[i] = testProfile.Copy()
|
|
489
|
+ profs[i] = testProfile1.Copy()
|
413
|
490
|
}
|
414
|
491
|
prof, err := Merge(profs)
|
415
|
492
|
if err != nil {
|
|
@@ -420,7 +497,7 @@ func TestMergeAll(t *testing.T) {
|
420
|
497
|
tb := locationHash(s)
|
421
|
498
|
samples[tb] = samples[tb] + s.Value[0]
|
422
|
499
|
}
|
423
|
|
- for _, s := range testProfile.Sample {
|
|
500
|
+ for _, s := range testProfile1.Sample {
|
424
|
501
|
tb := locationHash(s)
|
425
|
502
|
if samples[tb] != s.Value[0]*10 {
|
426
|
503
|
t.Errorf("merge got wrong value at %s : %d instead of %d", tb, samples[tb], s.Value[0]*10)
|
|
@@ -428,6 +505,83 @@ func TestMergeAll(t *testing.T) {
|
428
|
505
|
}
|
429
|
506
|
}
|
430
|
507
|
|
|
508
|
+func TestNormalizeBySameProfile(t *testing.T) {
|
|
509
|
+ pb := testProfile1.Copy()
|
|
510
|
+ p := testProfile1.Copy()
|
|
511
|
+
|
|
512
|
+ if err := p.Normalize(pb); err != nil {
|
|
513
|
+ t.Fatal(err)
|
|
514
|
+ }
|
|
515
|
+
|
|
516
|
+ for i, s := range p.Sample {
|
|
517
|
+ for j, v := range s.Value {
|
|
518
|
+ expectedSampleValue := testProfile1.Sample[i].Value[j]
|
|
519
|
+ if v != expectedSampleValue {
|
|
520
|
+ t.Errorf("For sample %d, value %d want %d got %d", i, j, expectedSampleValue, v)
|
|
521
|
+ }
|
|
522
|
+ }
|
|
523
|
+ }
|
|
524
|
+}
|
|
525
|
+
|
|
526
|
+func TestNormalizeByDifferentProfile(t *testing.T) {
|
|
527
|
+ p := testProfile1.Copy()
|
|
528
|
+ pb := testProfile2.Copy()
|
|
529
|
+
|
|
530
|
+ if err := p.Normalize(pb); err != nil {
|
|
531
|
+ t.Fatal(err)
|
|
532
|
+ }
|
|
533
|
+
|
|
534
|
+ expectedSampleValues := [][]int64{
|
|
535
|
+ {19, 1000},
|
|
536
|
+ {1, 100},
|
|
537
|
+ {0, 10},
|
|
538
|
+ {198, 10000},
|
|
539
|
+ {0, 1},
|
|
540
|
+ }
|
|
541
|
+
|
|
542
|
+ for i, s := range p.Sample {
|
|
543
|
+ for j, v := range s.Value {
|
|
544
|
+ if v != expectedSampleValues[i][j] {
|
|
545
|
+ t.Errorf("For sample %d, value %d want %d got %d", i, j, expectedSampleValues[i][j], v)
|
|
546
|
+ }
|
|
547
|
+ }
|
|
548
|
+ }
|
|
549
|
+}
|
|
550
|
+
|
|
551
|
+func TestNormalizeByMultipleOfSameProfile(t *testing.T) {
|
|
552
|
+ pb := testProfile1.Copy()
|
|
553
|
+ for i, s := range pb.Sample {
|
|
554
|
+ for j, v := range s.Value {
|
|
555
|
+ pb.Sample[i].Value[j] = 10 * v
|
|
556
|
+ }
|
|
557
|
+ }
|
|
558
|
+
|
|
559
|
+ p := testProfile1.Copy()
|
|
560
|
+
|
|
561
|
+ err := p.Normalize(pb)
|
|
562
|
+ if err != nil {
|
|
563
|
+ t.Fatal(err)
|
|
564
|
+ }
|
|
565
|
+
|
|
566
|
+ for i, s := range p.Sample {
|
|
567
|
+ for j, v := range s.Value {
|
|
568
|
+ expectedSampleValue := 10 * testProfile1.Sample[i].Value[j]
|
|
569
|
+ if v != expectedSampleValue {
|
|
570
|
+ t.Errorf("For sample %d, value %d, want %d got %d", i, j, expectedSampleValue, v)
|
|
571
|
+ }
|
|
572
|
+ }
|
|
573
|
+ }
|
|
574
|
+}
|
|
575
|
+
|
|
576
|
+func TestNormalizeIncompatibleProfiles(t *testing.T) {
|
|
577
|
+ p := testProfile1.Copy()
|
|
578
|
+ pb := testProfile3.Copy()
|
|
579
|
+
|
|
580
|
+ if err := p.Normalize(pb); err == nil {
|
|
581
|
+ t.Errorf("Expected an error")
|
|
582
|
+ }
|
|
583
|
+}
|
|
584
|
+
|
431
|
585
|
func TestFilter(t *testing.T) {
|
432
|
586
|
// Perform several forms of filtering on the test profile.
|
433
|
587
|
|
|
@@ -442,7 +596,7 @@ func TestFilter(t *testing.T) {
|
442
|
596
|
{nil, regexp.MustCompile("foo.c"), nil, nil, true, true, false, false},
|
443
|
597
|
{nil, nil, regexp.MustCompile("lib.so"), nil, true, false, true, false},
|
444
|
598
|
} {
|
445
|
|
- prof := *testProfile.Copy()
|
|
599
|
+ prof := *testProfile1.Copy()
|
446
|
600
|
gf, gi, gh, gnh := prof.FilterSamplesByName(tc.focus, tc.ignore, tc.hide, tc.show)
|
447
|
601
|
if gf != tc.fm {
|
448
|
602
|
t.Errorf("Filter #%d, got fm=%v, want %v", tx, gf, tc.fm)
|
|
@@ -488,7 +642,7 @@ func TestTagFilter(t *testing.T) {
|
488
|
642
|
{regexp.MustCompile("key1"), nil, true, false, 1},
|
489
|
643
|
{nil, regexp.MustCompile("key[12]"), true, true, 1},
|
490
|
644
|
} {
|
491
|
|
- prof := testProfile.Copy()
|
|
645
|
+ prof := testProfile1.Copy()
|
492
|
646
|
gim, gem := prof.FilterTagsByName(tc.include, tc.exclude)
|
493
|
647
|
if gim != tc.im {
|
494
|
648
|
t.Errorf("Filter #%d, got include match=%v, want %v", tx, gim, tc.im)
|
|
@@ -514,8 +668,8 @@ func locationHash(s *Sample) string {
|
514
|
668
|
}
|
515
|
669
|
|
516
|
670
|
func TestSetMain(t *testing.T) {
|
517
|
|
- testProfile.massageMappings()
|
518
|
|
- if testProfile.Mapping[0].File != mainBinary {
|
519
|
|
- t.Errorf("got %s for main", testProfile.Mapping[0].File)
|
|
671
|
+ testProfile1.massageMappings()
|
|
672
|
+ if testProfile1.Mapping[0].File != mainBinary {
|
|
673
|
+ t.Errorf("got %s for main", testProfile1.Mapping[0].File)
|
520
|
674
|
}
|
521
|
675
|
}
|