1*288bf522SAndroid Build Coastguard Worker #include <gtest/gtest.h>
2*288bf522SAndroid Build Coastguard Worker #include <stdio.h>
3*288bf522SAndroid Build Coastguard Worker
4*288bf522SAndroid Build Coastguard Worker #include <meminspect.h>
5*288bf522SAndroid Build Coastguard Worker
6*288bf522SAndroid Build Coastguard Worker using namespace std;
7*288bf522SAndroid Build Coastguard Worker
8*288bf522SAndroid Build Coastguard Worker /**
9*288bf522SAndroid Build Coastguard Worker * This test is meant to be ran by directly pushing the test binary
10*288bf522SAndroid Build Coastguard Worker * into the device as using atest will not provide sufficient privileges
11*288bf522SAndroid Build Coastguard Worker * to execute drop_caches command.
12*288bf522SAndroid Build Coastguard Worker */
TEST(meminspect_test,inspect_matches_resident)13*288bf522SAndroid Build Coastguard Worker TEST(meminspect_test, inspect_matches_resident) {
14*288bf522SAndroid Build Coastguard Worker // Create test file
15*288bf522SAndroid Build Coastguard Worker string test_file = "/data/local/tmp/meminspect_test";
16*288bf522SAndroid Build Coastguard Worker // If for any reason a test file already existed from a previous test, remove it.
17*288bf522SAndroid Build Coastguard Worker remove(test_file.c_str());
18*288bf522SAndroid Build Coastguard Worker
19*288bf522SAndroid Build Coastguard Worker int test_file_fd = open(test_file.c_str(), O_RDWR | O_CREAT, "w");
20*288bf522SAndroid Build Coastguard Worker unsigned int page_size = sysconf(_SC_PAGESIZE);
21*288bf522SAndroid Build Coastguard Worker if (test_file_fd == -1) {
22*288bf522SAndroid Build Coastguard Worker ADD_FAILURE() << "Failed to open test file for writing. errno: " << std::strerror(errno);
23*288bf522SAndroid Build Coastguard Worker close(test_file_fd);
24*288bf522SAndroid Build Coastguard Worker remove(test_file.c_str());
25*288bf522SAndroid Build Coastguard Worker return;
26*288bf522SAndroid Build Coastguard Worker }
27*288bf522SAndroid Build Coastguard Worker
28*288bf522SAndroid Build Coastguard Worker uint8_t* page_data = new uint8_t[page_size];
29*288bf522SAndroid Build Coastguard Worker for (unsigned int i = 0; i < page_size; ++i) {
30*288bf522SAndroid Build Coastguard Worker page_data[i] = i + 1;
31*288bf522SAndroid Build Coastguard Worker }
32*288bf522SAndroid Build Coastguard Worker int pages_to_write = 100;
33*288bf522SAndroid Build Coastguard Worker for (int page = 0; page < pages_to_write; ++page) {
34*288bf522SAndroid Build Coastguard Worker write(test_file_fd, page_data, page_size);
35*288bf522SAndroid Build Coastguard Worker }
36*288bf522SAndroid Build Coastguard Worker // fsync to ensure the data is flushed to disk.
37*288bf522SAndroid Build Coastguard Worker if (fsync(test_file_fd) == -1) {
38*288bf522SAndroid Build Coastguard Worker ADD_FAILURE() << "fsync failed errno: " << std::strerror(errno);
39*288bf522SAndroid Build Coastguard Worker close(test_file_fd);
40*288bf522SAndroid Build Coastguard Worker remove(test_file.c_str());
41*288bf522SAndroid Build Coastguard Worker return;
42*288bf522SAndroid Build Coastguard Worker }
43*288bf522SAndroid Build Coastguard Worker close(test_file_fd);
44*288bf522SAndroid Build Coastguard Worker
45*288bf522SAndroid Build Coastguard Worker // Drop the pagecache to ensure we do not have memory due to it staying there after write.
46*288bf522SAndroid Build Coastguard Worker int drop_cache_fd = open("/proc/sys/vm/drop_caches", O_WRONLY);
47*288bf522SAndroid Build Coastguard Worker if (drop_cache_fd == -1) {
48*288bf522SAndroid Build Coastguard Worker ADD_FAILURE() << "failed opening drop caches fd errno: " << std::strerror(errno);
49*288bf522SAndroid Build Coastguard Worker close(test_file_fd);
50*288bf522SAndroid Build Coastguard Worker remove(test_file.c_str());
51*288bf522SAndroid Build Coastguard Worker return;
52*288bf522SAndroid Build Coastguard Worker }
53*288bf522SAndroid Build Coastguard Worker write(drop_cache_fd, "3", 1);
54*288bf522SAndroid Build Coastguard Worker fsync(drop_cache_fd);
55*288bf522SAndroid Build Coastguard Worker close(drop_cache_fd);
56*288bf522SAndroid Build Coastguard Worker
57*288bf522SAndroid Build Coastguard Worker // Open file and page in some memory
58*288bf522SAndroid Build Coastguard Worker test_file_fd = open(test_file.c_str(), O_RDONLY, "r");
59*288bf522SAndroid Build Coastguard Worker if (test_file_fd == -1) {
60*288bf522SAndroid Build Coastguard Worker ADD_FAILURE() << "Failed to open test file for reading after creation. errno: "
61*288bf522SAndroid Build Coastguard Worker << std::strerror(errno);
62*288bf522SAndroid Build Coastguard Worker close(test_file_fd);
63*288bf522SAndroid Build Coastguard Worker remove(test_file.c_str());
64*288bf522SAndroid Build Coastguard Worker return;
65*288bf522SAndroid Build Coastguard Worker }
66*288bf522SAndroid Build Coastguard Worker
67*288bf522SAndroid Build Coastguard Worker char* base_address = (char*)mmap(0, page_size * pages_to_write, PROT_READ, MAP_SHARED,
68*288bf522SAndroid Build Coastguard Worker test_file_fd, /*offset*/ 0);
69*288bf522SAndroid Build Coastguard Worker if (base_address == (char*)-1) {
70*288bf522SAndroid Build Coastguard Worker ADD_FAILURE() << "Failed to mmap file for reading after creation. errno: "
71*288bf522SAndroid Build Coastguard Worker << std::strerror(errno);
72*288bf522SAndroid Build Coastguard Worker close(test_file_fd);
73*288bf522SAndroid Build Coastguard Worker remove(test_file.c_str());
74*288bf522SAndroid Build Coastguard Worker return;
75*288bf522SAndroid Build Coastguard Worker }
76*288bf522SAndroid Build Coastguard Worker
77*288bf522SAndroid Build Coastguard Worker VmaRangeGroup vmas_resident;
78*288bf522SAndroid Build Coastguard Worker int res = probe_resident_memory(test_file, vmas_resident, 1);
79*288bf522SAndroid Build Coastguard Worker EXPECT_TRUE(res == 0);
80*288bf522SAndroid Build Coastguard Worker
81*288bf522SAndroid Build Coastguard Worker // Probing the file without reading anything yields no resident memory
82*288bf522SAndroid Build Coastguard Worker EXPECT_TRUE(vmas_resident.ranges.empty());
83*288bf522SAndroid Build Coastguard Worker
84*288bf522SAndroid Build Coastguard Worker // Clear our to start fresh for next probe.
85*288bf522SAndroid Build Coastguard Worker vmas_resident = VmaRangeGroup();
86*288bf522SAndroid Build Coastguard Worker
87*288bf522SAndroid Build Coastguard Worker int pages_to_read = 1;
88*288bf522SAndroid Build Coastguard Worker char* read_data = new char[pages_to_read];
89*288bf522SAndroid Build Coastguard Worker for (int page = 0; page < pages_to_read; ++page) {
90*288bf522SAndroid Build Coastguard Worker // Read 1 byte from each page to page it in.
91*288bf522SAndroid Build Coastguard Worker read_data[page] = base_address[page * page_size];
92*288bf522SAndroid Build Coastguard Worker }
93*288bf522SAndroid Build Coastguard Worker res = probe_resident_memory(test_file, vmas_resident, 1);
94*288bf522SAndroid Build Coastguard Worker EXPECT_TRUE(res == 0);
95*288bf522SAndroid Build Coastguard Worker
96*288bf522SAndroid Build Coastguard Worker // The amount of memory paged in is outside our control, but we should have some.
97*288bf522SAndroid Build Coastguard Worker uint64_t resident_total_size = vmas_resident.compute_total_size();
98*288bf522SAndroid Build Coastguard Worker EXPECT_TRUE(resident_total_size > 0);
99*288bf522SAndroid Build Coastguard Worker EXPECT_TRUE(vmas_resident.ranges.size() == 1);
100*288bf522SAndroid Build Coastguard Worker EXPECT_TRUE(vmas_resident.ranges[0].offset == 0);
101*288bf522SAndroid Build Coastguard Worker EXPECT_TRUE((uint64_t)vmas_resident.ranges[0].length == resident_total_size);
102*288bf522SAndroid Build Coastguard Worker
103*288bf522SAndroid Build Coastguard Worker close(test_file_fd);
104*288bf522SAndroid Build Coastguard Worker remove(test_file.c_str());
105*288bf522SAndroid Build Coastguard Worker }
106*288bf522SAndroid Build Coastguard Worker
TEST(meminspect_test,custom_probe_coverage_matches_with_probe)107*288bf522SAndroid Build Coastguard Worker TEST(meminspect_test, custom_probe_coverage_matches_with_probe) {
108*288bf522SAndroid Build Coastguard Worker ZipMemInspector inspector("");
109*288bf522SAndroid Build Coastguard Worker VmaRangeGroup* probe = new VmaRangeGroup();
110*288bf522SAndroid Build Coastguard Worker probe->ranges.push_back(VmaRange(0, 500));
111*288bf522SAndroid Build Coastguard Worker probe->ranges.push_back(VmaRange(700, 100));
112*288bf522SAndroid Build Coastguard Worker probe->ranges.push_back(VmaRange(1000, 500));
113*288bf522SAndroid Build Coastguard Worker probe->ranges.push_back(VmaRange(2000, 100));
114*288bf522SAndroid Build Coastguard Worker // Probed Resident Memory Offset ranges:
115*288bf522SAndroid Build Coastguard Worker // [0,500],[700,800],[1000,1500],[2000,2100]
116*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(probe->compute_total_size(), (unsigned long long)1200);
117*288bf522SAndroid Build Coastguard Worker inspector.set_existing_probe(probe);
118*288bf522SAndroid Build Coastguard Worker
119*288bf522SAndroid Build Coastguard Worker // Emulate reading some files from the zip to compute their coverages
120*288bf522SAndroid Build Coastguard Worker // fake1 memory offset ranges [100,300]
121*288bf522SAndroid Build Coastguard Worker ZipEntryInfo info;
122*288bf522SAndroid Build Coastguard Worker info.name = "fake1";
123*288bf522SAndroid Build Coastguard Worker info.offset_in_zip = 100;
124*288bf522SAndroid Build Coastguard Worker info.file_size_bytes = 200;
125*288bf522SAndroid Build Coastguard Worker inspector.add_file_info(info);
126*288bf522SAndroid Build Coastguard Worker
127*288bf522SAndroid Build Coastguard Worker // fake2 memory offset ranges [600,1200]
128*288bf522SAndroid Build Coastguard Worker ZipEntryInfo info2;
129*288bf522SAndroid Build Coastguard Worker info2.name = "fake2";
130*288bf522SAndroid Build Coastguard Worker info2.offset_in_zip = 600;
131*288bf522SAndroid Build Coastguard Worker info2.file_size_bytes = 600;
132*288bf522SAndroid Build Coastguard Worker inspector.add_file_info(info2);
133*288bf522SAndroid Build Coastguard Worker
134*288bf522SAndroid Build Coastguard Worker inspector.compute_per_file_coverage();
135*288bf522SAndroid Build Coastguard Worker std::vector<ZipEntryCoverage> coverages = inspector.get_file_coverages();
136*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages.size(), (size_t)2);
137*288bf522SAndroid Build Coastguard Worker
138*288bf522SAndroid Build Coastguard Worker // Result coverage for fake1 should be: [100,300]
139*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].coverage.ranges[0].offset, (uint32_t)100);
140*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].coverage.ranges[0].length, (uint32_t)200);
141*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].coverage.compute_total_size(), (unsigned long long)200);
142*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].info.name, "fake1");
143*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].info.offset_in_zip, (uint32_t)100);
144*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].info.file_size_bytes, (uint32_t)200);
145*288bf522SAndroid Build Coastguard Worker
146*288bf522SAndroid Build Coastguard Worker // coverage coverage for fake2 should be: [700,800] and [1000,1200]
147*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].coverage.ranges[0].offset, (uint32_t)700);
148*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].coverage.ranges[0].length, (uint32_t)100);
149*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].coverage.ranges[1].offset, (uint32_t)1000);
150*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].coverage.ranges[1].length, (uint32_t)200);
151*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].coverage.compute_total_size(), (unsigned long long)300); // 100 +
152*288bf522SAndroid Build Coastguard Worker // 200
153*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].info.name, "fake2");
154*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].info.offset_in_zip, (uint32_t)600);
155*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].info.file_size_bytes, (uint32_t)600);
156*288bf522SAndroid Build Coastguard Worker }
157*288bf522SAndroid Build Coastguard Worker
TEST(meminspect_test,whole_file_coverage_against_probe)158*288bf522SAndroid Build Coastguard Worker TEST(meminspect_test, whole_file_coverage_against_probe) {
159*288bf522SAndroid Build Coastguard Worker ZipMemInspector inspector("");
160*288bf522SAndroid Build Coastguard Worker
161*288bf522SAndroid Build Coastguard Worker // Emulate reading some files from the zip to compute their coverages
162*288bf522SAndroid Build Coastguard Worker // fake1 memory offset ranges [100,300]
163*288bf522SAndroid Build Coastguard Worker ZipEntryInfo info;
164*288bf522SAndroid Build Coastguard Worker info.name = "fake1";
165*288bf522SAndroid Build Coastguard Worker info.offset_in_zip = 100;
166*288bf522SAndroid Build Coastguard Worker info.file_size_bytes = 200;
167*288bf522SAndroid Build Coastguard Worker inspector.add_file_info(info);
168*288bf522SAndroid Build Coastguard Worker
169*288bf522SAndroid Build Coastguard Worker // fake2 memory offset ranges [600,1200]
170*288bf522SAndroid Build Coastguard Worker ZipEntryInfo info2;
171*288bf522SAndroid Build Coastguard Worker info2.name = "fake2";
172*288bf522SAndroid Build Coastguard Worker info2.offset_in_zip = 600;
173*288bf522SAndroid Build Coastguard Worker info2.file_size_bytes = 600;
174*288bf522SAndroid Build Coastguard Worker inspector.add_file_info(info2);
175*288bf522SAndroid Build Coastguard Worker
176*288bf522SAndroid Build Coastguard Worker inspector.compute_per_file_coverage();
177*288bf522SAndroid Build Coastguard Worker std::vector<ZipEntryCoverage> coverages = inspector.get_file_coverages();
178*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages.size(), (size_t)2);
179*288bf522SAndroid Build Coastguard Worker
180*288bf522SAndroid Build Coastguard Worker // Check that coverage matches entire file sizes
181*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].coverage.ranges[0].offset, (uint32_t)100);
182*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].coverage.ranges[0].length, (uint32_t)200);
183*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].coverage.compute_total_size(), (unsigned long long)200);
184*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].info.name, "fake1");
185*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].info.offset_in_zip, (uint32_t)100);
186*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].info.file_size_bytes, (uint32_t)200);
187*288bf522SAndroid Build Coastguard Worker
188*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].coverage.ranges[0].offset, (uint32_t)600);
189*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].coverage.ranges[0].length, (uint32_t)600);
190*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].coverage.compute_total_size(), (unsigned long long)600);
191*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].info.name, "fake2");
192*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].info.offset_in_zip, (uint32_t)600);
193*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].info.file_size_bytes, (uint32_t)600);
194*288bf522SAndroid Build Coastguard Worker }
195*288bf522SAndroid Build Coastguard Worker
TEST(meminspect_test,file_multiple_ranges_matches_probe)196*288bf522SAndroid Build Coastguard Worker TEST(meminspect_test, file_multiple_ranges_matches_probe) {
197*288bf522SAndroid Build Coastguard Worker VmaRangeGroup probe;
198*288bf522SAndroid Build Coastguard Worker probe.ranges.push_back(VmaRange(0, 500));
199*288bf522SAndroid Build Coastguard Worker probe.ranges.push_back(VmaRange(700, 100));
200*288bf522SAndroid Build Coastguard Worker probe.ranges.push_back(VmaRange(1000, 500));
201*288bf522SAndroid Build Coastguard Worker probe.ranges.push_back(VmaRange(2000, 100));
202*288bf522SAndroid Build Coastguard Worker // Probed Resident Memory Offset ranges:
203*288bf522SAndroid Build Coastguard Worker // [0,500],[700,800],[1000,1500],[2000,2100]
204*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(probe.compute_total_size(), (unsigned long long)1200);
205*288bf522SAndroid Build Coastguard Worker
206*288bf522SAndroid Build Coastguard Worker std::vector<ZipEntryCoverage> desired_coverages;
207*288bf522SAndroid Build Coastguard Worker
208*288bf522SAndroid Build Coastguard Worker // fake1 file resides between [100,1100]
209*288bf522SAndroid Build Coastguard Worker // desired ranges are [100,200],[400,710],[820,850]
210*288bf522SAndroid Build Coastguard Worker ZipEntryCoverage file1_mem;
211*288bf522SAndroid Build Coastguard Worker file1_mem.info.name = "fake1";
212*288bf522SAndroid Build Coastguard Worker file1_mem.info.offset_in_zip = 100;
213*288bf522SAndroid Build Coastguard Worker file1_mem.info.file_size_bytes = 1000;
214*288bf522SAndroid Build Coastguard Worker file1_mem.coverage.ranges.push_back(VmaRange(100, 100));
215*288bf522SAndroid Build Coastguard Worker file1_mem.coverage.ranges.push_back(VmaRange(400, 310));
216*288bf522SAndroid Build Coastguard Worker file1_mem.coverage.ranges.push_back(VmaRange(820, 30));
217*288bf522SAndroid Build Coastguard Worker desired_coverages.push_back(file1_mem);
218*288bf522SAndroid Build Coastguard Worker
219*288bf522SAndroid Build Coastguard Worker // fake2 memory offset ranges [1300,2100]
220*288bf522SAndroid Build Coastguard Worker // desired ranges are [1400,1500],[1600,1650],[1800,2050]
221*288bf522SAndroid Build Coastguard Worker ZipEntryCoverage file2_mem;
222*288bf522SAndroid Build Coastguard Worker file2_mem.info.name = "fake2";
223*288bf522SAndroid Build Coastguard Worker file2_mem.info.offset_in_zip = 1300;
224*288bf522SAndroid Build Coastguard Worker file2_mem.info.file_size_bytes = 750;
225*288bf522SAndroid Build Coastguard Worker file2_mem.coverage.ranges.push_back(VmaRange(1400, 100));
226*288bf522SAndroid Build Coastguard Worker file2_mem.coverage.ranges.push_back(VmaRange(1600, 50));
227*288bf522SAndroid Build Coastguard Worker file2_mem.coverage.ranges.push_back(VmaRange(1800, 250));
228*288bf522SAndroid Build Coastguard Worker desired_coverages.push_back(file2_mem);
229*288bf522SAndroid Build Coastguard Worker
230*288bf522SAndroid Build Coastguard Worker std::vector<ZipEntryCoverage> coverages =
231*288bf522SAndroid Build Coastguard Worker ZipMemInspector::compute_coverage(desired_coverages, &probe);
232*288bf522SAndroid Build Coastguard Worker
233*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages.size(), (size_t)2);
234*288bf522SAndroid Build Coastguard Worker
235*288bf522SAndroid Build Coastguard Worker // Result coverage for fake1 should be: [100,200],[400,500],[700,710]
236*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].coverage.ranges[0].offset, (uint32_t)100);
237*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].coverage.ranges[0].length, (uint32_t)100);
238*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].coverage.ranges[1].offset, (uint32_t)400);
239*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].coverage.ranges[1].length, (uint32_t)100);
240*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].coverage.ranges[2].offset, (uint32_t)700);
241*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].coverage.ranges[2].length, (uint32_t)10);
242*288bf522SAndroid Build Coastguard Worker
243*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].coverage.compute_total_size(), (unsigned long long)210);
244*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].info.name, "fake1");
245*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].info.offset_in_zip, (uint32_t)100);
246*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[0].info.file_size_bytes, (uint32_t)1000);
247*288bf522SAndroid Build Coastguard Worker
248*288bf522SAndroid Build Coastguard Worker // coverage coverage for fake2 should be: [1400,1500],[2000,2050]
249*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].coverage.ranges[0].offset, (uint32_t)1400);
250*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].coverage.ranges[0].length, (uint32_t)100);
251*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].coverage.ranges[1].offset, (uint32_t)2000);
252*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].coverage.ranges[1].length, (uint32_t)50);
253*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].coverage.compute_total_size(), (unsigned long long)150);
254*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].info.name, "fake2");
255*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].info.offset_in_zip, (uint32_t)1300);
256*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(coverages[1].info.file_size_bytes, (uint32_t)750);
257*288bf522SAndroid Build Coastguard Worker }
258*288bf522SAndroid Build Coastguard Worker
TEST(meminspect_test,range_alignment_and_merge_matches)259*288bf522SAndroid Build Coastguard Worker TEST(meminspect_test, range_alignment_and_merge_matches) {
260*288bf522SAndroid Build Coastguard Worker ZipMemInspector inspector("");
261*288bf522SAndroid Build Coastguard Worker VmaRangeGroup* probe = new VmaRangeGroup();
262*288bf522SAndroid Build Coastguard Worker probe->ranges.push_back(VmaRange(0, 500));
263*288bf522SAndroid Build Coastguard Worker probe->ranges.push_back(VmaRange(700, 100));
264*288bf522SAndroid Build Coastguard Worker int page_size = 4096;
265*288bf522SAndroid Build Coastguard Worker
266*288bf522SAndroid Build Coastguard Worker // Probed Resident Memory Offset ranges:
267*288bf522SAndroid Build Coastguard Worker // [0,500],[700,800]
268*288bf522SAndroid Build Coastguard Worker inspector.set_existing_probe(probe);
269*288bf522SAndroid Build Coastguard Worker
270*288bf522SAndroid Build Coastguard Worker // When we page align, we should end up with [0,500],[0,800]
271*288bf522SAndroid Build Coastguard Worker align_ranges(probe->ranges, page_size);
272*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(probe->ranges[0].offset, (uint32_t)0);
273*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(probe->ranges[0].length, (uint32_t)500);
274*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(probe->ranges[1].offset, (uint32_t)0);
275*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(probe->ranges[1].length, (uint32_t)800);
276*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(probe->ranges.size(), (uint32_t)2);
277*288bf522SAndroid Build Coastguard Worker
278*288bf522SAndroid Build Coastguard Worker // Because we have overlapping ranges, a union-merge should
279*288bf522SAndroid Build Coastguard Worker // skip duplication of intersections and end up with [0,800]
280*288bf522SAndroid Build Coastguard Worker std::vector<VmaRange> merged = merge_ranges(probe->ranges);
281*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(merged[0].offset, (uint32_t)0);
282*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(merged[0].length, (uint32_t)800);
283*288bf522SAndroid Build Coastguard Worker EXPECT_EQ(merged.size(), (uint32_t)1);
284*288bf522SAndroid Build Coastguard Worker }