blob: 76eec130afab69cc96504f170d403f69b1ea34ca [file] [log] [blame]
shafikc3f62672019-08-30 11:15:48 +01001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specic language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "RedactionInfoTest"
18
19#include <gtest/gtest.h>
20
21#include <memory>
Narayan Kamath11700c02020-10-06 09:15:34 +010022#include <ostream>
shafikc3f62672019-08-30 11:15:48 +010023#include <vector>
24
25#include "libfuse_jni/RedactionInfo.h"
26
27using namespace mediaprovider::fuse;
28
29using std::unique_ptr;
30using std::vector;
31
Narayan Kamath11700c02020-10-06 09:15:34 +010032std::ostream& operator<<(std::ostream& os, const ReadRange& rr) {
33 os << "{ " << rr.start << ", " << rr.size << ", " << rr.is_redaction << " }";
34 return os;
shafikc3f62672019-08-30 11:15:48 +010035}
36
shafikc3f62672019-08-30 11:15:48 +010037TEST(RedactionInfoTest, testNoRedactionRanges) {
38 RedactionInfo info(0, nullptr);
39 EXPECT_EQ(0, info.size());
40 EXPECT_EQ(false, info.isRedactionNeeded());
Zim2e5ad882020-01-13 14:11:19 +000041
Narayan Kamath11700c02020-10-06 09:15:34 +010042 std::vector<ReadRange> out;
43 info.getReadRanges(0, std::numeric_limits<size_t>::max(), &out);
44 EXPECT_EQ(0, out.size());
shafikc3f62672019-08-30 11:15:48 +010045}
46
Narayan Kamath11700c02020-10-06 09:15:34 +010047// Test the case where there is 1 redaction range.
shafikc3f62672019-08-30 11:15:48 +010048TEST(RedactionInfoTest, testSingleRedactionRange) {
Zim2e5ad882020-01-13 14:11:19 +000049 off64_t ranges[2] = {
50 1,
51 10,
52 };
Narayan Kamath11700c02020-10-06 09:15:34 +010053
shafikc3f62672019-08-30 11:15:48 +010054 RedactionInfo info(1, ranges);
55 EXPECT_EQ(1, info.size());
56 EXPECT_EQ(true, info.isRedactionNeeded());
Narayan Kamath11700c02020-10-06 09:15:34 +010057
shafikc3f62672019-08-30 11:15:48 +010058 // Overlapping ranges
Narayan Kamath11700c02020-10-06 09:15:34 +010059 std::vector<ReadRange> out;
60 info.getReadRanges(0, 1000, &out); // read offsets [0, 1000)
61 EXPECT_EQ(3, out.size());
62 EXPECT_EQ(ReadRange(0, 1, false), out[0]);
63 EXPECT_EQ(ReadRange(1, 9, true), out[1]);
64 EXPECT_EQ(ReadRange(10, 990, false), out[2]);
shafikc3f62672019-08-30 11:15:48 +010065
Narayan Kamath11700c02020-10-06 09:15:34 +010066 out.clear();
67 info.getReadRanges(0, 5, &out); // read offsets [0, 5)
68 EXPECT_EQ(2, out.size());
69 EXPECT_EQ(ReadRange(0, 1, false), out[0]); // offsets: [0, 1) len = 1
70 EXPECT_EQ(ReadRange(1, 4, true), out[1]); // offsets: [1, 5) len = 4
shafikc3f62672019-08-30 11:15:48 +010071
Narayan Kamath11700c02020-10-06 09:15:34 +010072 out.clear();
73 info.getReadRanges(1, 10, &out); // read offsets [1, 11)
74 EXPECT_EQ(2, out.size());
75 EXPECT_EQ(ReadRange(1, 9, true), out[0]); // offsets: [1, 10) len = 9
76 EXPECT_EQ(ReadRange(10, 1, false), out[1]); // offsets: [10, 11) len = 1
shafikc3f62672019-08-30 11:15:48 +010077
Narayan Kamath11700c02020-10-06 09:15:34 +010078 // Read ranges that start or end with the boundary of the redacted area.
79 out.clear();
80 info.getReadRanges(5, 5, &out); // read offsets [5, 10)
81 EXPECT_EQ(1, out.size());
82 EXPECT_EQ(ReadRange(5, 5, true), out[0]); // offsets: [5, 10) len = 5
shafikc3f62672019-08-30 11:15:48 +010083
Narayan Kamath11700c02020-10-06 09:15:34 +010084 out.clear();
85 info.getReadRanges(1, 5, &out); // read offsets [1, 6)
86 EXPECT_EQ(1, out.size());
87 EXPECT_EQ(ReadRange(1, 5, true), out[0]); // offsets: [1, 6) len = 5
shafikc3f62672019-08-30 11:15:48 +010088
Narayan Kamath11700c02020-10-06 09:15:34 +010089 // Read ranges adjoining the redacted area.
90 out.clear();
91 info.getReadRanges(10, 10, &out); // read offsets [10, 20)
92 EXPECT_EQ(0, out.size());
shafikc3f62672019-08-30 11:15:48 +010093
Narayan Kamath11700c02020-10-06 09:15:34 +010094 out.clear();
95 info.getReadRanges(0, 1, &out); // read offsets [0, 1)
96 EXPECT_EQ(0, out.size());
97
98 // Read Range outside the redacted area.
99 out.clear();
100 info.getReadRanges(200, 10, &out); // read offsets [200, 210)
101 EXPECT_EQ(0, out.size());
shafikc3f62672019-08-30 11:15:48 +0100102}
103
Narayan Kamath11700c02020-10-06 09:15:34 +0100104// Multiple redaction ranges within a given area.
shafikc3f62672019-08-30 11:15:48 +0100105TEST(RedactionInfoTest, testSortedAndNonOverlappingRedactionRanges) {
Narayan Kamath11700c02020-10-06 09:15:34 +0100106 // [10, 20), [30, 40), [40, 50)
107 off64_t ranges[4] = {10, 20, 30, 40};
108
109 RedactionInfo info = RedactionInfo(2, ranges);
110 EXPECT_EQ(2, info.size());
111 EXPECT_EQ(true, info.isRedactionNeeded());
112
113 std::vector<ReadRange> out;
114 info.getReadRanges(0, 40, &out); // read offsets [0, 40)
115 EXPECT_EQ(4, out.size());
116 EXPECT_EQ(ReadRange(0, 10, false), out[0]); // offsets: [0, 10) len = 10
117 EXPECT_EQ(ReadRange(10, 10, true), out[1]); // offsets: [10, 20) len = 10
118 EXPECT_EQ(ReadRange(20, 10, false), out[2]); // offsets: [20, 30) len = 10
119 EXPECT_EQ(ReadRange(30, 10, true), out[3]); // offsets [30, 40) len = 10
120
121 // Read request straddling two ranges.
122 out.clear();
123 info.getReadRanges(5, 30, &out); // read offsets [5, 35)
124 EXPECT_EQ(4, out.size());
125 EXPECT_EQ(ReadRange(5, 5, false), out[0]); // offsets: [5, 10) len = 5
126 EXPECT_EQ(ReadRange(10, 10, true), out[1]); // offsets: [10, 20) len = 10
127 EXPECT_EQ(ReadRange(20, 10, false), out[2]); // offsets: [20, 30) len = 10
128 EXPECT_EQ(ReadRange(30, 5, true), out[3]); // offsets [30, 35) len = 5
129
130 // Read request overlapping first range only.
131 out.clear();
132 info.getReadRanges(5, 10, &out); // read offsets [5, 15)
133 EXPECT_EQ(2, out.size());
134 EXPECT_EQ(ReadRange(5, 5, false), out[0]); // offsets: [5, 10) len = 5
135 EXPECT_EQ(ReadRange(10, 5, true), out[1]); // offsets: [10, 15) len = 5
136
137 // Read request overlapping last range only.
138 out.clear();
139 info.getReadRanges(35, 10, &out); // read offsets [35, 45)
140 EXPECT_EQ(2, out.size());
141 EXPECT_EQ(ReadRange(35, 5, true), out[0]); // offsets: [35, 40) len = 5
142 EXPECT_EQ(ReadRange(40, 5, false), out[1]); // offsets: [40, 45) len = 5
143
144 // Read request overlapping no ranges.
145 out.clear();
146 info.getReadRanges(0, 10, &out); // read offsets [0, 10)
147 EXPECT_EQ(0, out.size());
148 out.clear();
Sahana Rao8a1db672020-10-25 00:00:11 +0100149 info.getReadRanges(21, 5, &out); // read offsets [21, 26)
Hyoungho Choi446de542020-10-22 23:07:57 +0900150 EXPECT_EQ(0, out.size());
151 out.clear();
Narayan Kamath11700c02020-10-06 09:15:34 +0100152 info.getReadRanges(40, 10, &out); // read offsets [40, 50)
153 EXPECT_EQ(0, out.size());
154}
155
Sahana Rao8a1db672020-10-25 00:00:11 +0100156// Multiple redaction ranges overlapping with read range.
157TEST(RedactionInfoTest, testReadRangeOverlappingWithRedactionRanges) {
158 // [10, 20), [30, 40)
159 off64_t ranges[4] = {10, 20, 30, 40};
160
161 RedactionInfo info = RedactionInfo(2, ranges);
162 EXPECT_EQ(2, info.size());
163 EXPECT_EQ(true, info.isRedactionNeeded());
164
165 std::vector<ReadRange> out;
166 // Read request overlaps with end of the ranges.
167 info.getReadRanges(20, 20, &out); // read offsets [20, 40)
168 EXPECT_EQ(2, out.size());
169 EXPECT_EQ(ReadRange(20, 10, false), out[0]); // offsets: [20, 30) len = 10
170 EXPECT_EQ(ReadRange(30, 10, true), out[1]); // offsets: [30, 40) len = 10
171
172 // Read request overlapping with start of the ranges
173 out.clear();
174 info.getReadRanges(10, 20, &out); // read offsets [10, 30)
175 EXPECT_EQ(2, out.size());
176 EXPECT_EQ(ReadRange(10, 10, true), out[0]); // offsets: [10, 20) len = 10
177 EXPECT_EQ(ReadRange(20, 10, false), out[1]); // offsets: [20, 30) len = 10
178
179 // Read request overlaps with start of one and end of other range.
180 out.clear();
181 info.getReadRanges(10, 30, &out); // read offsets [10, 40)
182 EXPECT_EQ(3, out.size());
183 EXPECT_EQ(ReadRange(10, 10, true), out[0]); // offsets: [10, 20) len = 10
184 EXPECT_EQ(ReadRange(20, 10, false), out[1]); // offsets: [20, 30) len = 10
185 EXPECT_EQ(ReadRange(30, 10, true), out[2]); // offsets: [30, 40) len = 10
186
187 // Read request overlaps with end of one and start of other range.
188 out.clear();
189 info.getReadRanges(20, 10, &out); // read offsets [20, 30)
190 EXPECT_EQ(0, out.size());
191}
192
Narayan Kamath11700c02020-10-06 09:15:34 +0100193TEST(RedactionInfoTest, testRedactionRangesSorted) {
194 off64_t ranges[6] = {30, 40, 50, 60, 10, 20};
shafikc3f62672019-08-30 11:15:48 +0100195
196 RedactionInfo info = RedactionInfo(3, ranges);
197 EXPECT_EQ(3, info.size());
198 EXPECT_EQ(true, info.isRedactionNeeded());
199
Narayan Kamath11700c02020-10-06 09:15:34 +0100200 std::vector<ReadRange> out;
201 info.getReadRanges(0, 60, &out); // read offsets [0, 60)
202 EXPECT_EQ(6, out.size());
203 EXPECT_EQ(ReadRange(0, 10, false), out[0]); // offsets: [0, 10) len = 10
204 EXPECT_EQ(ReadRange(10, 10, true), out[1]); // offsets: [10, 20) len = 10
205 EXPECT_EQ(ReadRange(20, 10, false), out[2]); // offsets: [20, 30) len = 10
206 EXPECT_EQ(ReadRange(30, 10, true), out[3]); // offsets [30, 40) len = 10
207 EXPECT_EQ(ReadRange(40, 10, false), out[4]); // offsets [40, 50) len = 10
208 EXPECT_EQ(ReadRange(50, 10, true), out[5]); // offsets [50, 60) len = 10
shafikc3f62672019-08-30 11:15:48 +0100209
Narayan Kamath11700c02020-10-06 09:15:34 +0100210 // Read request overlapping first range only.
211 out.clear();
212 info.getReadRanges(5, 10, &out); // read offsets [5, 15)
213 EXPECT_EQ(2, out.size());
214 EXPECT_EQ(ReadRange(5, 5, false), out[0]); // offsets: [5, 10) len = 5
215 EXPECT_EQ(ReadRange(10, 5, true), out[1]); // offsets: [10, 15) len = 5
shafikc3f62672019-08-30 11:15:48 +0100216
Narayan Kamath11700c02020-10-06 09:15:34 +0100217 // Read request overlapping last range only.
218 out.clear();
219 info.getReadRanges(55, 10, &out); // read offsets [55, 65)
220 EXPECT_EQ(2, out.size());
221 EXPECT_EQ(ReadRange(55, 5, true), out[0]); // offsets: [55, 60) len = 5
222 EXPECT_EQ(ReadRange(60, 5, false), out[1]); // offsets: [60, 65) len = 5
223
224 // Read request overlapping no ranges.
225 out.clear();
226 info.getReadRanges(0, 10, &out); // read offsets [0, 10)
227 EXPECT_EQ(0, out.size());
228 out.clear();
229 info.getReadRanges(60, 10, &out); // read offsets [60, 70)
230 EXPECT_EQ(0, out.size());
shafikc3f62672019-08-30 11:15:48 +0100231}
232
Narayan Kamath11700c02020-10-06 09:15:34 +0100233// Test that the ranges are both sorted and merged
shafikc3f62672019-08-30 11:15:48 +0100234TEST(RedactionInfoTest, testSortAndMergeRedactionRanges) {
Narayan Kamath11700c02020-10-06 09:15:34 +0100235 // Ranges are: [10, 20), [25, 40), [50, 60)
236 off64_t ranges[8] = {30, 40, 10, 20, 25, 30, 50, 60};
shafikc3f62672019-08-30 11:15:48 +0100237
238 RedactionInfo info = RedactionInfo(4, ranges);
239 EXPECT_EQ(3, info.size());
240 EXPECT_EQ(true, info.isRedactionNeeded());
241
Narayan Kamath11700c02020-10-06 09:15:34 +0100242 std::vector<ReadRange> out;
243 info.getReadRanges(0, 60, &out); // read offsets [0, 60)
244 EXPECT_EQ(6, out.size());
245 EXPECT_EQ(ReadRange(0, 10, false), out[0]); // offsets: [0, 10) len = 10
246 EXPECT_EQ(ReadRange(10, 10, true), out[1]); // offsets: [10, 20) len = 10
247 EXPECT_EQ(ReadRange(20, 5, false), out[2]); // offsets: [20, 25) len = 5
248 EXPECT_EQ(ReadRange(25, 15, true), out[3]); // offsets [25, 40) len = 15
249 EXPECT_EQ(ReadRange(40, 10, false), out[4]); // offsets [40, 50) len = 10
250 EXPECT_EQ(ReadRange(50, 10, true), out[5]); // offsets [50, 60) len = 10
shafikc3f62672019-08-30 11:15:48 +0100251}
252
Narayan Kamath11700c02020-10-06 09:15:34 +0100253// Test that the ranges are both sorted and merged when there's an overlap.
254//
255// TODO: Can this ever happen ? Will we ever be in a state where we need to
256// redact exif attributes that have overlapping ranges ?
257TEST(RedactionInfoTest, testSortAndMergeRedactionRanges_overlap) {
258 // Ranges are: [10, 20), [25, 40), [50, 60)
259 off64_t ranges[8] = {30, 40, 10, 20, 25, 34, 50, 60};
shafikc3f62672019-08-30 11:15:48 +0100260
Narayan Kamath11700c02020-10-06 09:15:34 +0100261 RedactionInfo info = RedactionInfo(4, ranges);
262 EXPECT_EQ(3, info.size());
shafikc3f62672019-08-30 11:15:48 +0100263 EXPECT_EQ(true, info.isRedactionNeeded());
264
Narayan Kamath11700c02020-10-06 09:15:34 +0100265 std::vector<ReadRange> out;
266 info.getReadRanges(0, 60, &out); // read offsets [0, 60)
267 EXPECT_EQ(6, out.size());
268 EXPECT_EQ(ReadRange(0, 10, false), out[0]); // offsets: [0, 10) len = 10
269 EXPECT_EQ(ReadRange(10, 10, true), out[1]); // offsets: [10, 20) len = 10
270 EXPECT_EQ(ReadRange(20, 5, false), out[2]); // offsets: [20, 25) len = 5
271 EXPECT_EQ(ReadRange(25, 15, true), out[3]); // offsets [25, 40) len = 15
272 EXPECT_EQ(ReadRange(40, 10, false), out[4]); // offsets [40, 50) len = 10
273 EXPECT_EQ(ReadRange(50, 10, true), out[5]); // offsets [50, 60) len = 10
shafikc3f62672019-08-30 11:15:48 +0100274}
275
Narayan Kamath11700c02020-10-06 09:15:34 +0100276// WARNING: The tests below assume that merging of ranges happen during
277// object construction (which is asserted by the check on |info.size()|.
278// Therefore, we don't write redundant tests for boundary conditions that
279// we've covered above. If this ever changes, these tests need to be expanded.
280TEST(RedactionInfoTest, testMergeAllRangesIntoSingleRange) {
281 // Ranges are: [8, 24)
282 off64_t ranges[8] = {10, 20, 8, 14, 14, 24, 12, 16};
shafikc3f62672019-08-30 11:15:48 +0100283
Narayan Kamath11700c02020-10-06 09:15:34 +0100284 RedactionInfo info = RedactionInfo(4, ranges);
shafikc3f62672019-08-30 11:15:48 +0100285 EXPECT_EQ(1, info.size());
286 EXPECT_EQ(true, info.isRedactionNeeded());
287
Narayan Kamath11700c02020-10-06 09:15:34 +0100288 std::vector<ReadRange> out;
289 info.getReadRanges(0, 30, &out); // read offsets [0, 30)
290 EXPECT_EQ(3, out.size());
291 EXPECT_EQ(ReadRange(0, 8, false), out[0]); // offsets: [0, 8) len = 8
292 EXPECT_EQ(ReadRange(8, 16, true), out[1]); // offsets: [8, 24) len = 16
293 EXPECT_EQ(ReadRange(24, 6, false), out[2]); // offsets: [24, 30) len = 6
shafikc3f62672019-08-30 11:15:48 +0100294
Narayan Kamath11700c02020-10-06 09:15:34 +0100295 // Ranges are: [85, 100)
296 off64_t ranges2[10] = {90, 95, 95, 100, 85, 91, 92, 94, 99, 100};
297 info = RedactionInfo(5, ranges2);
298 EXPECT_EQ(1, info.size());
299 EXPECT_EQ(true, info.isRedactionNeeded());
shafikc3f62672019-08-30 11:15:48 +0100300
Narayan Kamath11700c02020-10-06 09:15:34 +0100301 out.clear();
302 info.getReadRanges(80, 30, &out); // read offsets [80, 110)
303 EXPECT_EQ(3, out.size());
304 EXPECT_EQ(ReadRange(80, 5, false), out[0]); // offsets: [80, 85) len = 5
305 EXPECT_EQ(ReadRange(85, 15, true), out[1]); // offsets: [85, 100) len = 15
306 EXPECT_EQ(ReadRange(100, 10, false), out[2]); // offsets: [100, 110) len = 10
shafikc3f62672019-08-30 11:15:48 +0100307}
308
Narayan Kamath11700c02020-10-06 09:15:34 +0100309TEST(RedactionInfoTest, testMergeMultipleRanges) {
310 // Ranges are: [10, 30), [60, 80)
311 off64_t ranges[8] = {20, 30, 10, 20, 70, 80, 60, 70};
shafikc3f62672019-08-30 11:15:48 +0100312
Narayan Kamath11700c02020-10-06 09:15:34 +0100313 RedactionInfo info = RedactionInfo(4, ranges);
314 EXPECT_EQ(2, info.size());
shafikc3f62672019-08-30 11:15:48 +0100315 EXPECT_EQ(true, info.isRedactionNeeded());
316
Narayan Kamath11700c02020-10-06 09:15:34 +0100317 std::vector<ReadRange> out;
318 info.getReadRanges(0, 100, &out); // read offsets [0, 100)
319 EXPECT_EQ(5, out.size());
320 EXPECT_EQ(ReadRange(0, 10, false), out[0]); // offsets: [0, 10) len = 10
321 EXPECT_EQ(ReadRange(10, 20, true), out[1]); // offsets: [10, 30) len = 20
322 EXPECT_EQ(ReadRange(30, 30, false), out[2]); // offsets: [30, 60) len = 30
323 EXPECT_EQ(ReadRange(60, 20, true), out[3]); // offsets [60, 80) len = 20
324 EXPECT_EQ(ReadRange(80, 20, false), out[4]); // offsets [80, 100) len = 20
shafikc3f62672019-08-30 11:15:48 +0100325}
Sahana Rao8a1db672020-10-25 00:00:11 +0100326
327// Redaction ranges of size zero.
328TEST(RedactionInfoTest, testRedactionRangesZeroSize) {
329 // [10, 20), [30, 40)
330 off64_t ranges[6] = {10, 20, 30, 40, 25, 25};
331
332 RedactionInfo info = RedactionInfo(3, ranges);
333 EXPECT_EQ(2, info.size());
334 EXPECT_EQ(true, info.isRedactionNeeded());
335
336 // Normal read request, should skip range with zero size
337 std::vector<ReadRange> out;
338 info.getReadRanges(0, 40, &out); // read offsets [0, 40)
339 EXPECT_EQ(4, out.size());
340 EXPECT_EQ(ReadRange(0, 10, false), out[0]); // offsets: [0, 10) len = 10
341 EXPECT_EQ(ReadRange(10, 10, true), out[1]); // offsets: [10, 20) len = 10
342 EXPECT_EQ(ReadRange(20, 10, false), out[2]); // offsets: [20, 30) len = 10
343 EXPECT_EQ(ReadRange(30, 10, true), out[3]); // offsets [30, 40) len = 10
344
345 // Read request starting at offset overlapping with zero size range.
346 out.clear();
347 info.getReadRanges(25, 10, &out); // read offsets [25, 35)
348 EXPECT_EQ(2, out.size());
349 EXPECT_EQ(ReadRange(25, 5, false), out[0]); // offsets: [25, 30) len = 5
350 EXPECT_EQ(ReadRange(30, 5, true), out[1]); // offsets [30, 35) len = 5
351
352 // 1 byte read request starting at offset overlapping with zero size range.
353 out.clear();
354 info.getReadRanges(25, 1, &out); // read offsets [25, 26)
355 EXPECT_EQ(0, out.size());
356
357 // Read request ending at offset overlapping with zero size range.
358 out.clear();
359 info.getReadRanges(0, 25, &out); // read offsets [0, 25)
360 EXPECT_EQ(3, out.size());
361 EXPECT_EQ(ReadRange(0, 10, false), out[0]); // offsets: [0, 10) len = 10
362 EXPECT_EQ(ReadRange(10, 10, true), out[1]); // offsets: [10, 20) len = 10
363 EXPECT_EQ(ReadRange(20, 5, false), out[2]); // offsets: [20, 25) len = 10
364
365 // Read request that includes only zero size range
366 out.clear();
367 info.getReadRanges(20, 10, &out); // read offsets [20, 27)
368 EXPECT_EQ(0, out.size());
369}
370
371// Single redaction range with zero size
372TEST(RedactionInfoTest, testSingleRedactionRangesZeroSize) {
373 off64_t ranges[2] = {10, 10};
374
375 RedactionInfo info = RedactionInfo(1, ranges);
376 EXPECT_EQ(0, info.size());
377 EXPECT_EQ(false, info.isRedactionNeeded());
378
379 // Normal read request, should skip range with zero size
380 std::vector<ReadRange> out;
381 info.getReadRanges(0, 40, &out); // read offsets [0, 40)
382 EXPECT_EQ(0, out.size());
383}