1
2
3
4
5 package cmerge_test
6
7 import (
8 "fmt"
9 "internal/coverage"
10 "internal/coverage/cmerge"
11 "testing"
12 )
13
14 func TestClash(t *testing.T) {
15 m := &cmerge.Merger{}
16 err := m.SetModeAndGranularity("mdf1.data", coverage.CtrModeSet, coverage.CtrGranularityPerBlock)
17 if err != nil {
18 t.Fatalf("unexpected clash: %v", err)
19 }
20 err = m.SetModeAndGranularity("mdf1.data", coverage.CtrModeSet, coverage.CtrGranularityPerBlock)
21 if err != nil {
22 t.Fatalf("unexpected clash: %v", err)
23 }
24 err = m.SetModeAndGranularity("mdf1.data", coverage.CtrModeCount, coverage.CtrGranularityPerBlock)
25 if err == nil {
26 t.Fatalf("expected mode clash, not found")
27 }
28 err = m.SetModeAndGranularity("mdf1.data", coverage.CtrModeSet, coverage.CtrGranularityPerFunc)
29 if err == nil {
30 t.Fatalf("expected granularity clash, not found")
31 }
32 m.SetModeMergePolicy(cmerge.ModeMergeRelaxed)
33 err = m.SetModeAndGranularity("mdf1.data", coverage.CtrModeCount, coverage.CtrGranularityPerBlock)
34 if err != nil {
35 t.Fatalf("unexpected clash: %v", err)
36 }
37 err = m.SetModeAndGranularity("mdf1.data", coverage.CtrModeSet, coverage.CtrGranularityPerBlock)
38 if err != nil {
39 t.Fatalf("unexpected clash: %v", err)
40 }
41 err = m.SetModeAndGranularity("mdf1.data", coverage.CtrModeAtomic, coverage.CtrGranularityPerBlock)
42 if err != nil {
43 t.Fatalf("unexpected clash: %v", err)
44 }
45 m.ResetModeAndGranularity()
46 err = m.SetModeAndGranularity("mdf1.data", coverage.CtrModeCount, coverage.CtrGranularityPerFunc)
47 if err != nil {
48 t.Fatalf("unexpected clash after reset: %v", err)
49 }
50 }
51
52 func TestBasic(t *testing.T) {
53 scenarios := []struct {
54 cmode coverage.CounterMode
55 cgran coverage.CounterGranularity
56 src, dst, res []uint32
57 iters int
58 merr bool
59 overflow bool
60 }{
61 {
62 cmode: coverage.CtrModeSet,
63 cgran: coverage.CtrGranularityPerBlock,
64 src: []uint32{1, 0, 1},
65 dst: []uint32{1, 1, 0},
66 res: []uint32{1, 1, 1},
67 iters: 2,
68 overflow: false,
69 },
70 {
71 cmode: coverage.CtrModeCount,
72 cgran: coverage.CtrGranularityPerBlock,
73 src: []uint32{1, 0, 3},
74 dst: []uint32{5, 7, 0},
75 res: []uint32{6, 7, 3},
76 iters: 1,
77 overflow: false,
78 },
79 {
80 cmode: coverage.CtrModeCount,
81 cgran: coverage.CtrGranularityPerBlock,
82 src: []uint32{4294967200, 0, 3},
83 dst: []uint32{4294967001, 7, 0},
84 res: []uint32{4294967295, 7, 3},
85 iters: 1,
86 overflow: true,
87 },
88 }
89
90 for k, scenario := range scenarios {
91 var err error
92 var ovf bool
93 m := &cmerge.Merger{}
94 mdf := fmt.Sprintf("file%d", k)
95 err = m.SetModeAndGranularity(mdf, scenario.cmode, scenario.cgran)
96 if err != nil {
97 t.Fatalf("case %d SetModeAndGranularity failed: %v", k, err)
98 }
99 for i := 0; i < scenario.iters; i++ {
100 err, ovf = m.MergeCounters(scenario.dst, scenario.src)
101 if ovf != scenario.overflow {
102 t.Fatalf("case %d overflow mismatch: got %v want %v", k, ovf, scenario.overflow)
103 }
104 if !scenario.merr && err != nil {
105 t.Fatalf("case %d unexpected err %v", k, err)
106 }
107 if scenario.merr && err == nil {
108 t.Fatalf("case %d expected err, not received", k)
109 }
110 for i := range scenario.dst {
111 if scenario.dst[i] != scenario.res[i] {
112 t.Fatalf("case %d: bad merge at %d got %d want %d",
113 k, i, scenario.dst[i], scenario.res[i])
114 }
115 }
116 }
117 }
118 }
119
View as plain text