1// Copyright 2018 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
15package profile
16
17import (
18	"testing"
19)
20
21func TestMapMapping(t *testing.T) {
22	pm := &profileMerger{
23		p:            &Profile{},
24		mappings:     make(map[mappingKey]*Mapping),
25		mappingsByID: make(map[uint64]mapInfo),
26	}
27	for _, tc := range []struct {
28		desc       string
29		m1         Mapping
30		m2         Mapping
31		wantMerged bool
32	}{
33		{
34			desc: "same file name",
35			m1: Mapping{
36				ID:   1,
37				File: "test-file-1",
38			},
39			m2: Mapping{
40				ID:   2,
41				File: "test-file-1",
42			},
43			wantMerged: true,
44		},
45		{
46			desc: "same build ID",
47			m1: Mapping{
48				ID:      3,
49				BuildID: "test-build-id-1",
50			},
51			m2: Mapping{
52				ID:      4,
53				BuildID: "test-build-id-1",
54			},
55			wantMerged: true,
56		},
57		{
58			desc: "same fake mapping",
59			m1: Mapping{
60				ID: 5,
61			},
62			m2: Mapping{
63				ID: 6,
64			},
65			wantMerged: true,
66		},
67		{
68			desc: "different start",
69			m1: Mapping{
70				ID:      7,
71				Start:   0x1000,
72				Limit:   0x2000,
73				BuildID: "test-build-id-2",
74			},
75			m2: Mapping{
76				ID:      8,
77				Start:   0x3000,
78				Limit:   0x4000,
79				BuildID: "test-build-id-2",
80			},
81			wantMerged: true,
82		},
83		{
84			desc: "different file name",
85			m1: Mapping{
86				ID:   9,
87				File: "test-file-2",
88			},
89			m2: Mapping{
90				ID:   10,
91				File: "test-file-3",
92			},
93		},
94		{
95			desc: "different build id",
96			m1: Mapping{
97				ID:      11,
98				BuildID: "test-build-id-3",
99			},
100			m2: Mapping{
101				ID:      12,
102				BuildID: "test-build-id-4",
103			},
104		},
105		{
106			desc: "different size",
107			m1: Mapping{
108				ID:      13,
109				Start:   0x1000,
110				Limit:   0x3000,
111				BuildID: "test-build-id-5",
112			},
113			m2: Mapping{
114				ID:      14,
115				Start:   0x1000,
116				Limit:   0x5000,
117				BuildID: "test-build-id-5",
118			},
119		},
120		{
121			desc: "different offset",
122			m1: Mapping{
123				ID:      15,
124				Offset:  1,
125				BuildID: "test-build-id-6",
126			},
127			m2: Mapping{
128				ID:      16,
129				Offset:  2,
130				BuildID: "test-build-id-6",
131			},
132		},
133	} {
134		t.Run(tc.desc, func(t *testing.T) {
135			info1 := pm.mapMapping(&tc.m1)
136			info2 := pm.mapMapping(&tc.m2)
137			gotM1, gotM2 := *info1.m, *info2.m
138
139			wantM1 := tc.m1
140			wantM1.ID = gotM1.ID
141			if gotM1 != wantM1 {
142				t.Errorf("first mapping got %v, want %v", gotM1, wantM1)
143			}
144
145			if tc.wantMerged {
146				if gotM1 != gotM2 {
147					t.Errorf("first mapping got %v, second mapping got %v, want equal", gotM1, gotM2)
148				}
149				if info1.offset != 0 {
150					t.Errorf("first mapping info got offset %d, want 0", info1.offset)
151				}
152				if wantOffset := int64(tc.m1.Start) - int64(tc.m2.Start); wantOffset != info2.offset {
153					t.Errorf("second mapping info got offset %d, want %d", info2.offset, wantOffset)
154				}
155			} else {
156				if gotM1.ID == gotM2.ID {
157					t.Errorf("first mapping got %v, second mapping got %v, want different IDs", gotM1, gotM2)
158				}
159				wantM2 := tc.m2
160				wantM2.ID = gotM2.ID
161				if gotM2 != wantM2 {
162					t.Errorf("second mapping got %v, want %v", gotM2, wantM2)
163				}
164			}
165		})
166	}
167}
168