1 // Copyright (C) 2023 Google LLC
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
15 #include "icing/file/version-util.h"
16
17 #include <cstdint>
18 #include <memory>
19 #include <optional>
20 #include <string>
21 #include <unordered_set>
22 #include <utility>
23
24 #include "gmock/gmock.h"
25 #include "gtest/gtest.h"
26 #include "icing/file/filesystem.h"
27 #include "icing/file/posting_list/flash-index-storage-header.h"
28 #include "icing/portable/equals-proto.h"
29 #include "icing/proto/initialize.pb.h"
30 #include "icing/testing/common-matchers.h"
31 #include "icing/testing/tmp-directory.h"
32
33 namespace icing {
34 namespace lib {
35 namespace version_util {
36
37 namespace {
38
39 using ::testing::Eq;
40 using ::testing::IsEmpty;
41 using ::testing::IsFalse;
42 using ::testing::IsTrue;
43
MakeTestVersionProto(const VersionInfo & version_info,const std::unordered_set<IcingSearchEngineFeatureInfoProto::FlaggedFeatureType> & features_set)44 IcingSearchEngineVersionProto MakeTestVersionProto(
45 const VersionInfo& version_info,
46 const std::unordered_set<
47 IcingSearchEngineFeatureInfoProto::FlaggedFeatureType>& features_set) {
48 IcingSearchEngineVersionProto version_proto;
49 version_proto.set_version(version_info.version);
50 version_proto.set_max_version(version_info.max_version);
51
52 auto* enabled_features = version_proto.mutable_enabled_features();
53 for (const auto& feature : features_set) {
54 enabled_features->Add(GetFeatureInfoProto(feature));
55 }
56 return version_proto;
57 }
58
59 struct VersionUtilReadVersionTestParam {
60 std::optional<VersionInfo> existing_v1_version_info;
61 std::optional<VersionInfo> existing_v2_version_info;
62 std::optional<int> existing_flash_index_magic;
63 VersionInfo expected_version_info;
64
VersionUtilReadVersionTestParamicing::lib::version_util::__anon761a82ec0111::VersionUtilReadVersionTestParam65 explicit VersionUtilReadVersionTestParam(
66 std::optional<VersionInfo> existing_v1_version_info_in,
67 std::optional<VersionInfo> existing_v2_version_info_in,
68 std::optional<int> existing_flash_index_magic_in,
69 VersionInfo expected_version_info_in)
70 : existing_v1_version_info(std::move(existing_v1_version_info_in)),
71 existing_v2_version_info(std::move(existing_v2_version_info_in)),
72 existing_flash_index_magic(std::move(existing_flash_index_magic_in)),
73 expected_version_info(std::move(expected_version_info_in)) {}
74 };
75
76 class VersionUtilReadVersionTest
77 : public ::testing::TestWithParam<VersionUtilReadVersionTestParam> {
78 protected:
SetUp()79 void SetUp() override {
80 base_dir_ = GetTestTempDir() + "/version_util_test";
81 index_path_ = base_dir_ + "/index";
82
83 ASSERT_TRUE(filesystem_.CreateDirectoryRecursively(base_dir_.c_str()));
84 }
85
TearDown()86 void TearDown() override {
87 ASSERT_TRUE(filesystem_.DeleteDirectoryRecursively(base_dir_.c_str()));
88 }
89
filesystem() const90 const Filesystem& filesystem() const { return filesystem_; }
91
92 Filesystem filesystem_;
93 std::string base_dir_;
94 std::string index_path_;
95 };
96
TEST_P(VersionUtilReadVersionTest,ReadVersion)97 TEST_P(VersionUtilReadVersionTest, ReadVersion) {
98 const VersionUtilReadVersionTestParam& param = GetParam();
99 IcingSearchEngineVersionProto dummy_version_proto;
100
101 if (param.existing_v1_version_info.has_value()) {
102 ICING_ASSERT_OK(WriteV1Version(filesystem_, base_dir_,
103 param.existing_v1_version_info.value()));
104 }
105 if (param.existing_v2_version_info.has_value()) {
106 dummy_version_proto = MakeTestVersionProto(
107 param.existing_v2_version_info.value(),
108 {IcingSearchEngineFeatureInfoProto::FEATURE_HAS_PROPERTY_OPERATOR,
109 IcingSearchEngineFeatureInfoProto::UNKNOWN});
110 ICING_ASSERT_OK(WriteV2Version(
111 filesystem_, base_dir_,
112 std::make_unique<IcingSearchEngineVersionProto>(dummy_version_proto)));
113 }
114
115 // Prepare flash index file.
116 if (param.existing_flash_index_magic.has_value()) {
117 HeaderBlock header_block(&filesystem_, /*block_size=*/4096);
118 header_block.header()->magic = param.existing_flash_index_magic.value();
119
120 std::string main_index_dir = index_path_ + "/idx/main";
121 ASSERT_TRUE(filesystem_.CreateDirectoryRecursively(main_index_dir.c_str()));
122 std::string flash_index_file_path = main_index_dir + "/main_index";
123
124 ScopedFd sfd(filesystem_.OpenForWrite(flash_index_file_path.c_str()));
125 ASSERT_TRUE(sfd.is_valid());
126 ASSERT_TRUE(header_block.Write(sfd.get()));
127 }
128
129 ICING_ASSERT_OK_AND_ASSIGN(IcingSearchEngineVersionProto version_proto,
130 ReadVersion(filesystem_, base_dir_, index_path_));
131 if (param.existing_v2_version_info.has_value() &&
132 param.expected_version_info.version ==
133 param.existing_v2_version_info.value().version) {
134 EXPECT_THAT(version_proto,
135 portable_equals_proto::EqualsProto(dummy_version_proto));
136 } else {
137 // We're returning the version from v1 version file, or an invalid version.
138 // version_proto.enabled_features should be empty in this case.
139 EXPECT_THAT(version_proto.version(),
140 Eq(param.expected_version_info.version));
141 EXPECT_THAT(version_proto.max_version(),
142 Eq(param.expected_version_info.max_version));
143 EXPECT_THAT(version_proto.enabled_features(), IsEmpty());
144 }
145 }
146
147 INSTANTIATE_TEST_SUITE_P(
148 VersionUtilReadVersionTest, VersionUtilReadVersionTest,
149 testing::Values(
150 // - Version file doesn't exist
151 // - Flash index doesn't exist
152 // - Result: version -1, max_version -1 (invalid)
153 VersionUtilReadVersionTestParam(
154 /*existing_v1_version_info_in=*/std::nullopt,
155 /*existing_v2_version_info_in=*/std::nullopt,
156 /*existing_flash_index_magic_in=*/std::nullopt,
157 /*expected_version_info_in=*/
158 VersionInfo(/*version_in=*/-1, /*max_version=*/-1)),
159
160 // - Version file doesn't exist
161 // - Flash index exists with version 0 magic
162 // - Result: version 0, max_version 0
163 VersionUtilReadVersionTestParam(
164 /*existing_v1_version_info_in=*/std::nullopt,
165 /*existing_v2_version_info_in=*/std::nullopt,
166 /*existing_flash_index_magic_in=*/
167 std::make_optional<int>(kVersionZeroFlashIndexMagic),
168 /*expected_version_info_in=*/
169 VersionInfo(/*version_in=*/0, /*max_version=*/0)),
170
171 // - Version file doesn't exist
172 // - Flash index exists with non version 0 magic
173 // - Result: version -1, max_version -1 (invalid)
174 VersionUtilReadVersionTestParam(
175 /*existing_v1_version_info_in=*/std::nullopt,
176 /*existing_v2_version_info_in=*/std::nullopt,
177 /*existing_flash_index_magic_in=*/
178 std::make_optional<int>(kVersionZeroFlashIndexMagic + 1),
179 /*expected_version_info_in=*/
180 VersionInfo(/*version_in=*/-1, /*max_version=*/-1)),
181
182 // - Version file v1 exists
183 // - Flash index doesn't exist
184 // - Result: version -1, max_version 1 (invalid)
185 VersionUtilReadVersionTestParam(
186 /*existing_v1_version_info_in=*/std::make_optional<VersionInfo>(
187 /*version_in=*/1, /*max_version=*/1),
188 /*existing_v2_version_info_in=*/std::nullopt,
189 /*existing_flash_index_magic_in=*/std::nullopt,
190 /*expected_version_info_in=*/
191 VersionInfo(/*version_in=*/-1, /*max_version=*/1)),
192
193 // - Version file v1 exists: version 1, max_version 1
194 // - Flash index exists with version 0 magic
195 // - Result: version 0, max_version 1
196 VersionUtilReadVersionTestParam(
197 /*existing_v1_version_info_in=*/std::make_optional<VersionInfo>(
198 /*version_in=*/1, /*max_version=*/1),
199 /*existing_v2_version_info_in=*/std::nullopt,
200 /*existing_flash_index_magic_in=*/
201 std::make_optional<int>(kVersionZeroFlashIndexMagic),
202 /*expected_version_info_in=*/
203 VersionInfo(/*version_in=*/0, /*max_version=*/1)),
204
205 // - Version file v1 exists: version 2, max_version 3
206 // - Flash index exists with version 0 magic
207 // - Result: version 0, max_version 3
208 VersionUtilReadVersionTestParam(
209 /*existing_v1_version_info_in=*/std::make_optional<VersionInfo>(
210 /*version_in=*/2, /*max_version=*/3),
211 /*existing_v2_version_info_in=*/std::nullopt,
212 /*existing_flash_index_magic_in=*/
213 std::make_optional<int>(kVersionZeroFlashIndexMagic),
214 /*expected_version_info_in=*/
215 VersionInfo(/*version_in=*/0, /*max_version=*/3)),
216
217 // - Version file v1 exists: version 1, max_version 1
218 // - Flash index exists with non version 0 magic
219 // - Result: version 1, max_version 1
220 VersionUtilReadVersionTestParam(
221 /*existing_v1_version_info_in=*/std::make_optional<VersionInfo>(
222 /*version_in=*/1, /*max_version=*/1),
223 /*existing_v2_version_info_in=*/std::nullopt,
224 /*existing_flash_index_magic_in=*/
225 std::make_optional<int>(kVersionZeroFlashIndexMagic + 1),
226 /*expected_version_info_in=*/
227 VersionInfo(/*version_in=*/1, /*max_version=*/1)),
228
229 // - Version file v1 exists: version 2, max_version 3
230 // - Flash index exists with non version 0 magic
231 // - Result: version 2, max_version 3
232 VersionUtilReadVersionTestParam(
233 /*existing_v1_version_info_in=*/std::make_optional<VersionInfo>(
234 /*version_in=*/2, /*max_version=*/3),
235 /*existing_v2_version_info_in=*/std::nullopt,
236 /*existing_flash_index_magic_in=*/
237 std::make_optional<int>(kVersionZeroFlashIndexMagic + 1),
238 /*expected_version_info_in=*/
239 VersionInfo(/*version_in=*/2, /*max_version=*/3)),
240
241 // - Version file v1 exists: version 2, max_version 4
242 // - Version file v2 exists: version 4, max_version 4
243 // - Flash index exists with non version 0 magic
244 // - Result: version -1, max_version 4
245 VersionUtilReadVersionTestParam(
246 /*existing_v1_version_info_in=*/std::make_optional<VersionInfo>(
247 /*version_in=*/2, /*max_version=*/4),
248 /*existing_v2_version_info_in=*/
249 std::make_optional<VersionInfo>(
250 /*version_in=*/4, /*max_version=*/4),
251 /*existing_flash_index_magic_in=*/
252 std::make_optional<int>(kVersionZeroFlashIndexMagic + 1),
253 /*expected_version_info_in=*/
254 VersionInfo(/*version_in=*/-1, /*max_version=*/4)),
255
256 // - Version file v1 exists: version 4, max_version 4
257 // - Version file v2 exists: version 4, max_version 4
258 // - Flash index exists with version 0 magic
259 // - Result: version -1, max_version 4
260 VersionUtilReadVersionTestParam(
261 /*existing_v1_version_info_in=*/std::make_optional<VersionInfo>(
262 /*version_in=*/4, /*max_version=*/4),
263 /*existing_v2_version_info_in=*/
264 std::make_optional<VersionInfo>(
265 /*version_in=*/4, /*max_version=*/4),
266 /*existing_flash_index_magic_in=*/
267 std::make_optional<int>(kVersionZeroFlashIndexMagic),
268 /*expected_version_info_in=*/
269 VersionInfo(/*version_in=*/-1, /*max_version=*/4)),
270
271 // - Version file v1 exists: version 4, max_version 4
272 // - Version file v2 exists: version 4, max_version 4
273 // - Flash index exists with non version 0 magic
274 // - Result: version 4, max_version 4
275 VersionUtilReadVersionTestParam(
276 /*existing_v1_version_info_in=*/std::make_optional<VersionInfo>(
277 /*version_in=*/4, /*max_version=*/4),
278 /*existing_v2_version_info_in=*/
279 std::make_optional<VersionInfo>(
280 /*version_in=*/4, /*max_version=*/4),
281 /*existing_flash_index_magic_in=*/
282 std::make_optional<int>(kVersionZeroFlashIndexMagic + 1),
283 /*expected_version_info_in=*/
284 VersionInfo(/*version_in=*/4, /*max_version=*/4)),
285
286 // - Version file v1 exists: version 4, max_version 4
287 // - Version file v2 does not exist
288 // - Flash index exists with non version 0 magic
289 // - Result: version -1, max_version 4
290 VersionUtilReadVersionTestParam(
291 /*existing_v1_version_info_in=*/std::make_optional<VersionInfo>(
292 /*version_in=*/4, /*max_version=*/4),
293 /*existing_v2_version_info_in=*/std::nullopt,
294 /*existing_flash_index_magic_in=*/
295 std::make_optional<int>(kVersionZeroFlashIndexMagic + 1),
296 /*expected_version_info_in=*/
297 VersionInfo(/*version_in=*/-1, /*max_version=*/4)),
298
299 // - Version file v1 does not exist
300 // - Version file v2 exists: version 4, max_version 4
301 // - Flash index exists with non version 0 magic
302 // - Result: version -1, max_version -1
303 VersionUtilReadVersionTestParam(
304 /*existing_v1_version_info_in=*/std::nullopt,
305 /*existing_v2_version_info_in=*/
306 std::make_optional<VersionInfo>(
307 /*version_in=*/4, /*max_version=*/4),
308 /*existing_flash_index_magic_in=*/
309 std::make_optional<int>(kVersionZeroFlashIndexMagic + 1),
310 /*expected_version_info_in=*/
311 VersionInfo(/*version_in=*/-1, /*max_version=*/-1)),
312
313 // - Version file v1 doesn't exist
314 // - Version file v2 exists: version 4, max_version 4
315 // - Flash index doesn't exist
316 // - Result: version -1, max_version -1 (invalid since flash index
317 // doesn't exist)
318 VersionUtilReadVersionTestParam(
319 /*existing_v1_version_info_in=*/std::nullopt,
320 /*existing_v2_version_info_in=*/
321 std::make_optional<VersionInfo>(
322 /*version_in=*/4, /*max_version=*/4),
323 /*existing_flash_index_magic_in=*/std::nullopt,
324 /*expected_version_info_in=*/
325 VersionInfo(/*version_in=*/-1, /*max_version=*/-1))));
326
327 struct VersionUtilStateChangeTestParam {
328 VersionInfo existing_version_info;
329 int32_t curr_version;
330 StateChange expected_state_change;
331
VersionUtilStateChangeTestParamicing::lib::version_util::__anon761a82ec0111::VersionUtilStateChangeTestParam332 explicit VersionUtilStateChangeTestParam(VersionInfo existing_version_info_in,
333 int32_t curr_version_in,
334 StateChange expected_state_change_in)
335 : existing_version_info(std::move(existing_version_info_in)),
336 curr_version(curr_version_in),
337 expected_state_change(expected_state_change_in) {}
338 };
339
340 class VersionUtilStateChangeTest
341 : public ::testing::TestWithParam<VersionUtilStateChangeTestParam> {};
342
TEST_P(VersionUtilStateChangeTest,GetVersionStateChange)343 TEST_P(VersionUtilStateChangeTest, GetVersionStateChange) {
344 const VersionUtilStateChangeTestParam& param = GetParam();
345
346 EXPECT_THAT(
347 GetVersionStateChange(param.existing_version_info, param.curr_version),
348 Eq(param.expected_state_change));
349 }
350
351 INSTANTIATE_TEST_SUITE_P(
352 VersionUtilStateChangeTest, VersionUtilStateChangeTest,
353 testing::Values(
354 // - version -1, max_version -1 (invalid)
355 // - Current version = 1
356 // - Result: undetermined
357 VersionUtilStateChangeTestParam(
358 /*existing_version_info_in=*/VersionInfo(-1, -1),
359 /*curr_version_in=*/1,
360 /*expected_state_change_in=*/StateChange::kUndetermined),
361
362 // - version -1, max_version 1 (invalid)
363 // - Current version = 1
364 // - Result: undetermined
365 VersionUtilStateChangeTestParam(
366 /*existing_version_info_in=*/VersionInfo(-1, 1),
367 /*curr_version_in=*/1,
368 /*expected_state_change_in=*/StateChange::kUndetermined),
369
370 // - version -1, max_version -1 (invalid)
371 // - Current version = 2
372 // - Result: undetermined
373 VersionUtilStateChangeTestParam(
374 /*existing_version_info_in=*/VersionInfo(-1, -1),
375 /*curr_version_in=*/2,
376 /*expected_state_change_in=*/StateChange::kUndetermined),
377
378 // - version -1, max_version 1 (invalid)
379 // - Current version = 2
380 // - Result: undetermined
381 VersionUtilStateChangeTestParam(
382 /*existing_version_info_in=*/VersionInfo(-1, 1),
383 /*curr_version_in=*/2,
384 /*expected_state_change_in=*/StateChange::kUndetermined),
385
386 // - version 0, max_version 0
387 // - Current version = 1
388 // - Result: version 0 upgrade
389 VersionUtilStateChangeTestParam(
390 /*existing_version_info_in=*/VersionInfo(0, 0),
391 /*curr_version_in=*/1,
392 /*expected_state_change_in=*/StateChange::kVersionZeroUpgrade),
393
394 // - version 0, max_version 1
395 // - Current version = 1
396 // - Result: version 0 roll forward
397 VersionUtilStateChangeTestParam(
398 /*existing_version_info_in=*/VersionInfo(0, 1),
399 /*curr_version_in=*/1,
400 /*expected_state_change_in=*/StateChange::kVersionZeroRollForward),
401
402 // - version 0, max_version 2
403 // - Current version = 1
404 // - Result: version 0 roll forward
405 VersionUtilStateChangeTestParam(
406 /*existing_version_info_in=*/VersionInfo(0, 2),
407 /*curr_version_in=*/1,
408 /*expected_state_change_in=*/StateChange::kVersionZeroRollForward),
409
410 // - version 0, max_version 0
411 // - Current version = 2
412 // - Result: version 0 upgrade
413 VersionUtilStateChangeTestParam(
414 /*existing_version_info_in=*/VersionInfo(0, 0),
415 /*curr_version_in=*/2,
416 /*expected_state_change_in=*/StateChange::kVersionZeroUpgrade),
417
418 // - version 0, max_version 1
419 // - Current version = 2
420 // - Result: version 0 upgrade
421 VersionUtilStateChangeTestParam(
422 /*existing_version_info_in=*/VersionInfo(0, 1),
423 /*curr_version_in=*/2,
424 /*expected_state_change_in=*/StateChange::kVersionZeroRollForward),
425
426 // - version 0, max_version 2
427 // - Current version = 2
428 // - Result: version 0 roll forward
429 VersionUtilStateChangeTestParam(
430 /*existing_version_info_in=*/VersionInfo(0, 2),
431 /*curr_version_in=*/2,
432 /*expected_state_change_in=*/StateChange::kVersionZeroRollForward),
433
434 // - version 1, max_version 1
435 // - Current version = 1
436 // - Result: compatible
437 VersionUtilStateChangeTestParam(
438 /*existing_version_info_in=*/VersionInfo(1, 1),
439 /*curr_version_in=*/1,
440 /*expected_state_change_in=*/StateChange::kCompatible),
441
442 // - version 1, max_version 2
443 // - Current version = 1
444 // - Result: compatible
445 VersionUtilStateChangeTestParam(
446 /*existing_version_info_in=*/VersionInfo(1, 2),
447 /*curr_version_in=*/1,
448 /*expected_state_change_in=*/StateChange::kCompatible),
449
450 // - version 2, max_version 2
451 // - Current version = 1
452 // - Result: roll back
453 VersionUtilStateChangeTestParam(
454 /*existing_version_info_in=*/VersionInfo(2, 2),
455 /*curr_version_in=*/1,
456 /*expected_state_change_in=*/StateChange::kRollBack),
457
458 // - version 2, max_version 3
459 // - Current version = 1
460 // - Result: roll back
461 VersionUtilStateChangeTestParam(
462 /*existing_version_info_in=*/VersionInfo(2, 3),
463 /*curr_version_in=*/1,
464 /*expected_state_change_in=*/StateChange::kRollBack),
465
466 // - version 1, max_version 1
467 // - Current version = 2
468 // - Result: upgrade
469 VersionUtilStateChangeTestParam(
470 /*existing_version_info_in=*/VersionInfo(1, 1),
471 /*curr_version_in=*/2,
472 /*expected_state_change_in=*/StateChange::kUpgrade),
473
474 // - version 1, max_version 2
475 // - Current version = 2
476 // - Result: roll forward
477 VersionUtilStateChangeTestParam(
478 /*existing_version_info_in=*/VersionInfo(1, 2),
479 /*curr_version_in=*/2,
480 /*expected_state_change_in=*/StateChange::kRollForward),
481
482 // - version 1, max_version 2
483 // - Current version = 3
484 // - Result: roll forward
485 VersionUtilStateChangeTestParam(
486 /*existing_version_info_in=*/VersionInfo(1, 2),
487 /*curr_version_in=*/3,
488 /*expected_state_change_in=*/StateChange::kRollForward),
489
490 // - version 1, max_version 3
491 // - Current version = 2
492 // - Result: roll forward
493 VersionUtilStateChangeTestParam(
494 /*existing_version_info_in=*/VersionInfo(1, 3),
495 /*curr_version_in=*/2,
496 /*expected_state_change_in=*/StateChange::kRollForward),
497
498 // - version 2, max_version 2
499 // - Current version = 2
500 // - Result: compatible
501 VersionUtilStateChangeTestParam(
502 /*existing_version_info_in=*/VersionInfo(2, 2),
503 /*curr_version_in=*/2,
504 /*expected_state_change_in=*/StateChange::kCompatible),
505
506 // - version 2, max_version 3
507 // - Current version = 2
508 // - Result: compatible
509 VersionUtilStateChangeTestParam(
510 /*existing_version_info_in=*/VersionInfo(2, 3),
511 /*curr_version_in=*/2,
512 /*expected_state_change_in=*/StateChange::kCompatible),
513
514 // - version 3, max_version 3
515 // - Current version = 2
516 // - Result: rollback
517 VersionUtilStateChangeTestParam(
518 /*existing_version_info_in=*/VersionInfo(3, 3),
519 /*curr_version_in=*/2,
520 /*expected_state_change_in=*/StateChange::kRollBack),
521
522 // - version 3, max_version 4
523 // - Current version = 2
524 // - Result: rollback
525 VersionUtilStateChangeTestParam(
526 /*existing_version_info_in=*/VersionInfo(3, 4),
527 /*curr_version_in=*/2,
528 /*expected_state_change_in=*/StateChange::kRollBack),
529
530 // - version 3, max_version 3
531 // - Current version = 4
532 // - Result: upgrade
533 VersionUtilStateChangeTestParam(
534 /*existing_version_info_in=*/VersionInfo(3, 3),
535 /*curr_version_in=*/4,
536 /*expected_state_change_in=*/StateChange::kUpgrade),
537
538 // - version 4, max_version 4
539 // - Current version = 3
540 // - Result: rollback
541 VersionUtilStateChangeTestParam(
542 /*existing_version_info_in=*/VersionInfo(4, 4),
543 /*curr_version_in=*/3,
544 /*expected_state_change_in=*/StateChange::kRollBack),
545
546 // - version 4, max_version 5
547 // - Current version = 4
548 // - Result: compatible
549 VersionUtilStateChangeTestParam(
550 /*existing_version_info_in=*/VersionInfo(4, 5),
551 /*curr_version_in=*/4,
552 /*expected_state_change_in=*/StateChange::kCompatible),
553
554 // - version 3, max_version 4
555 // - Current version = 5
556 // - Result: rollforward
557 VersionUtilStateChangeTestParam(
558 /*existing_version_info_in=*/VersionInfo(3, 4),
559 /*curr_version_in=*/5,
560 /*expected_state_change_in=*/StateChange::kRollForward),
561
562 // - version 3, max_version 3
563 // - Current version = 5
564 // - Result: upgrade
565 VersionUtilStateChangeTestParam(
566 /*existing_version_info_in=*/VersionInfo(3, 3),
567 /*curr_version_in=*/5,
568 /*expected_state_change_in=*/StateChange::kUpgrade),
569
570 // - version 4, max_version 5
571 // - Current version = 5
572 // - Result: rollforward
573 VersionUtilStateChangeTestParam(
574 /*existing_version_info_in=*/VersionInfo(4, 5),
575 /*curr_version_in=*/5,
576 /*expected_state_change_in=*/StateChange::kRollForward)));
577
578 struct VersionUtilDerivedFilesRebuildTestParam {
579 int32_t existing_version;
580 int32_t max_version;
581 std::unordered_set<IcingSearchEngineFeatureInfoProto::FlaggedFeatureType>
582 existing_enabled_features;
583 int32_t curr_version;
584 std::unordered_set<IcingSearchEngineFeatureInfoProto::FlaggedFeatureType>
585 curr_enabled_features;
586 DerivedFilesRebuildResult expected_derived_files_rebuild_result;
587
VersionUtilDerivedFilesRebuildTestParamicing::lib::version_util::__anon761a82ec0111::VersionUtilDerivedFilesRebuildTestParam588 explicit VersionUtilDerivedFilesRebuildTestParam(
589 int32_t existing_version_in, int32_t max_version_in,
590 std::unordered_set<IcingSearchEngineFeatureInfoProto::FlaggedFeatureType>
591 existing_enabled_features_in,
592 int32_t curr_version_in,
593 std::unordered_set<IcingSearchEngineFeatureInfoProto::FlaggedFeatureType>
594 curr_enabled_features_in,
595 DerivedFilesRebuildResult expected_derived_files_rebuild_result_in)
596 : existing_version(existing_version_in),
597 max_version(max_version_in),
598 existing_enabled_features(std::move(existing_enabled_features_in)),
599 curr_version(curr_version_in),
600 curr_enabled_features(std::move(curr_enabled_features_in)),
601 expected_derived_files_rebuild_result(
602 std::move(expected_derived_files_rebuild_result_in)) {}
603 };
604
605 class VersionUtilDerivedFilesRebuildTest
606 : public ::testing::TestWithParam<VersionUtilDerivedFilesRebuildTestParam> {
607 };
608
TEST_P(VersionUtilDerivedFilesRebuildTest,CalculateRequiredDerivedFilesRebuild)609 TEST_P(VersionUtilDerivedFilesRebuildTest,
610 CalculateRequiredDerivedFilesRebuild) {
611 const VersionUtilDerivedFilesRebuildTestParam& param = GetParam();
612
613 EXPECT_THAT(CalculateRequiredDerivedFilesRebuild(
614 /*prev_version_proto=*/MakeTestVersionProto(
615 VersionInfo(param.existing_version, param.max_version),
616 param.existing_enabled_features),
617 /*curr_version_proto=*/
618 MakeTestVersionProto(
619 VersionInfo(param.curr_version, param.max_version),
620 param.curr_enabled_features)),
621 Eq(param.expected_derived_files_rebuild_result));
622 }
623
624 INSTANTIATE_TEST_SUITE_P(
625 VersionUtilDerivedFilesRebuildTest, VersionUtilDerivedFilesRebuildTest,
626 testing::Values(
627 // - Existing version -1, max_version -1 (invalid)
628 // - Existing enabled features = {}
629 // - Current version = 4
630 // - Current enabled features = {}
631 //
632 // - Result: rebuild everything
633 VersionUtilDerivedFilesRebuildTestParam(
634 /*existing_version_in=*/-1, /*max_version_in=*/-1,
635 /*existing_enabled_features_in=*/{}, /*curr_version_in=*/4,
636 /*curr_enabled_features_in=*/{},
637 /*expected_derived_files_rebuild_result_in=*/
638 DerivedFilesRebuildResult(
639 /*needs_document_store_derived_files_rebuild_in=*/true,
640 /*needs_schema_store_derived_files_rebuild_in=*/true,
641 /*needs_term_index_rebuild_in=*/true,
642 /*needs_integer_index_rebuild_in=*/true,
643 /*needs_qualified_id_join_index_rebuild_in=*/true,
644 /*needs_embedding_index_rebuild_in=*/true)),
645
646 // - Existing version -1, max_version 2 (invalid)
647 // - Existing enabled features = {}
648 // - Current version = 4
649 // - Current enabled features = {}
650 //
651 // - Result: rebuild everything
652 VersionUtilDerivedFilesRebuildTestParam(
653 /*existing_version_in=*/-1, /*max_version_in=*/-1,
654 /*existing_enabled_features_in=*/{}, /*curr_version_in=*/4,
655 /*curr_enabled_features_in=*/{},
656 /*expected_derived_files_rebuild_result_in=*/
657 DerivedFilesRebuildResult(
658 /*needs_document_store_derived_files_rebuild_in=*/true,
659 /*needs_schema_store_derived_files_rebuild_in=*/true,
660 /*needs_term_index_rebuild_in=*/true,
661 /*needs_integer_index_rebuild_in=*/true,
662 /*needs_qualified_id_join_index_rebuild_in=*/true,
663 /*needs_embedding_index_rebuild_in=*/true)),
664
665 // - Existing version 3, max_version 3 (pre v2 version check)
666 // - Existing enabled features = {}
667 // - Current version = 4
668 // - Current enabled features = {}
669 //
670 // - Result: don't rebuild anything
671 VersionUtilDerivedFilesRebuildTestParam(
672 /*existing_version_in=*/3, /*max_version_in=*/3,
673 /*existing_enabled_features_in=*/{}, /*curr_version_in=*/4,
674 /*curr_enabled_features_in=*/{},
675 /*expected_derived_files_rebuild_result_in=*/
676 DerivedFilesRebuildResult(
677 /*needs_document_store_derived_files_rebuild_in=*/false,
678 /*needs_schema_store_derived_files_rebuild_in=*/false,
679 /*needs_term_index_rebuild_in=*/false,
680 /*needs_integer_index_rebuild_in=*/false,
681 /*needs_qualified_id_join_index_rebuild_in=*/false,
682 /*needs_embedding_index_rebuild_in=*/false)),
683
684 // - Existing version 3, max_version 3 (pre v2 version check)
685 // - Existing enabled features = {}
686 // - Current version = 4
687 // - Current enabled features = {FEATURE_HAS_PROPERTY_OPERATOR}
688 //
689 // - Result: rebuild term index
690 VersionUtilDerivedFilesRebuildTestParam(
691 /*existing_version_in=*/3, /*max_version_in=*/3,
692 /*existing_enabled_features_in=*/{}, /*curr_version_in=*/4,
693 /*curr_enabled_features_in=*/
694 {IcingSearchEngineFeatureInfoProto::FEATURE_HAS_PROPERTY_OPERATOR},
695 /*expected_derived_files_rebuild_result_in=*/
696 DerivedFilesRebuildResult(
697 /*needs_document_store_derived_files_rebuild_in=*/false,
698 /*needs_schema_store_derived_files_rebuild_in=*/false,
699 /*needs_term_index_rebuild_in=*/true,
700 /*needs_integer_index_rebuild_in=*/false,
701 /*needs_qualified_id_join_index_rebuild_in=*/false,
702 /*needs_embedding_index_rebuild_in=*/false)),
703
704 // - Existing version 3, max_version 3 (pre v2 version check)
705 // - Existing enabled features = {}
706 // - Current version = 4
707 // - Current enabled features = {FEATURE_EMBEDDING_INDEX}
708 //
709 // - Result: rebuild embedding index
710 VersionUtilDerivedFilesRebuildTestParam(
711 /*existing_version_in=*/3, /*max_version_in=*/3,
712 /*existing_enabled_features_in=*/{}, /*curr_version_in=*/4,
713 /*curr_enabled_features_in=*/
714 {IcingSearchEngineFeatureInfoProto::FEATURE_EMBEDDING_INDEX},
715 /*expected_derived_files_rebuild_result_in=*/
716 DerivedFilesRebuildResult(
717 /*needs_document_store_derived_files_rebuild_in=*/false,
718 /*needs_schema_store_derived_files_rebuild_in=*/false,
719 /*needs_term_index_rebuild_in=*/false,
720 /*needs_integer_index_rebuild_in=*/false,
721 /*needs_qualified_id_join_index_rebuild_in=*/false,
722 /*needs_embedding_index_rebuild_in=*/true)),
723
724 // - Existing version 4, max_version 4
725 // - Existing enabled features = {}
726 // - Current version = 4
727 // - Current enabled features = {}
728 //
729 // - Result: don't rebuild anything
730 VersionUtilDerivedFilesRebuildTestParam(
731 /*existing_version_in=*/4, /*max_version_in=*/4,
732 /*existing_enabled_features_in=*/{}, /*curr_version_in=*/4,
733 /*curr_enabled_features_in=*/{},
734 /*expected_derived_files_rebuild_result_in=*/
735 DerivedFilesRebuildResult(
736 /*needs_document_store_derived_files_rebuild_in=*/false,
737 /*needs_schema_store_derived_files_rebuild_in=*/false,
738 /*needs_term_index_rebuild_in=*/false,
739 /*needs_integer_index_rebuild_in=*/false,
740 /*needs_qualified_id_join_index_rebuild_in=*/false,
741 /*needs_embedding_index_rebuild_in=*/false)),
742
743 // - Existing version 4, max_version 4
744 // - Existing enabled features = {}
745 // - Current version = 5
746 // - Current enabled features = {}
747 //
748 // - Result: 4 -> 5 upgrade -- don't rebuild anything
749 VersionUtilDerivedFilesRebuildTestParam(
750 /*existing_version_in=*/4, /*max_version_in=*/4,
751 /*existing_enabled_features_in=*/{}, /*curr_version_in=*/5,
752 /*curr_enabled_features_in=*/{},
753 /*expected_derived_files_rebuild_result_in=*/
754 DerivedFilesRebuildResult(
755 /*needs_document_store_derived_files_rebuild_in=*/false,
756 /*needs_schema_store_derived_files_rebuild_in=*/false,
757 /*needs_term_index_rebuild_in=*/false,
758 /*needs_integer_index_rebuild_in=*/false,
759 /*needs_qualified_id_join_index_rebuild_in=*/false,
760 /*needs_embedding_index_rebuild_in=*/false)),
761
762 // - Existing version 4, max_version 5
763 // - Existing enabled features = {}
764 // - Current version = 5
765 // - Current enabled features = {}
766 //
767 // - Result: Rollforward -- rebuild everything
768 VersionUtilDerivedFilesRebuildTestParam(
769 /*existing_version_in=*/4, /*max_version_in=*/5,
770 /*existing_enabled_features_in=*/{}, /*curr_version_in=*/5,
771 /*curr_enabled_features_in=*/{},
772 /*expected_derived_files_rebuild_result_in=*/
773 DerivedFilesRebuildResult(
774 /*needs_document_store_derived_files_rebuild_in=*/true,
775 /*needs_schema_store_derived_files_rebuild_in=*/true,
776 /*needs_term_index_rebuild_in=*/true,
777 /*needs_integer_index_rebuild_in=*/true,
778 /*needs_qualified_id_join_index_rebuild_in=*/true,
779 /*needs_embedding_index_rebuild_in=*/true)),
780
781 // - Existing version 5, max_version 5
782 // - Existing enabled features = {}
783 // - Current version = 4
784 // - Current enabled features = {}
785 //
786 // - Result: Rollback -- rebuild everything
787 VersionUtilDerivedFilesRebuildTestParam(
788 /*existing_version_in=*/5, /*max_version_in=*/5,
789 /*existing_enabled_features_in=*/{}, /*curr_version_in=*/4,
790 /*curr_enabled_features_in=*/{},
791 /*expected_derived_files_rebuild_result_in=*/
792 DerivedFilesRebuildResult(
793 /*needs_document_store_derived_files_rebuild_in=*/true,
794 /*needs_schema_store_derived_files_rebuild_in=*/true,
795 /*needs_term_index_rebuild_in=*/true,
796 /*needs_integer_index_rebuild_in=*/true,
797 /*needs_qualified_id_join_index_rebuild_in=*/true,
798 /*needs_embedding_index_rebuild_in=*/true)),
799
800 // - Existing version 4, max_version 4
801 // - Existing enabled features = {}
802 // - Current version = 4
803 // - Current enabled features = {FEATURE_HAS_PROPERTY_OPERATOR}
804 //
805 // - Result: rebuild term index
806 VersionUtilDerivedFilesRebuildTestParam(
807 /*existing_version_in=*/4, /*max_version_in=*/4,
808 /*existing_enabled_features_in=*/{}, /*curr_version_in=*/4,
809 /*curr_enabled_features_in=*/
810 {IcingSearchEngineFeatureInfoProto::FEATURE_HAS_PROPERTY_OPERATOR},
811 /*expected_derived_files_rebuild_result_in=*/
812 DerivedFilesRebuildResult(
813 /*needs_document_store_derived_files_rebuild_in=*/false,
814 /*needs_schema_store_derived_files_rebuild_in=*/false,
815 /*needs_term_index_rebuild_in=*/true,
816 /*needs_integer_index_rebuild_in=*/false,
817 /*needs_qualified_id_join_index_rebuild_in=*/false,
818 /*needs_embedding_index_rebuild_in=*/false)),
819
820 // - Existing version 4, max_version 4
821 // - Existing enabled features = {}
822 // - Current version = 4
823 // - Current enabled features = {FEATURE_EMBEDDING_INDEX}
824 //
825 // - Result: rebuild embedding index
826 VersionUtilDerivedFilesRebuildTestParam(
827 /*existing_version_in=*/4, /*max_version_in=*/4,
828 /*existing_enabled_features_in=*/{}, /*curr_version_in=*/4,
829 /*curr_enabled_features_in=*/
830 {IcingSearchEngineFeatureInfoProto::FEATURE_EMBEDDING_INDEX},
831 /*expected_derived_files_rebuild_result_in=*/
832 DerivedFilesRebuildResult(
833 /*needs_document_store_derived_files_rebuild_in=*/false,
834 /*needs_schema_store_derived_files_rebuild_in=*/false,
835 /*needs_term_index_rebuild_in=*/false,
836 /*needs_integer_index_rebuild_in=*/false,
837 /*needs_qualified_id_join_index_rebuild_in=*/false,
838 /*needs_embedding_index_rebuild_in=*/true)),
839
840 // - Existing version 4, max_version 4
841 // - Existing enabled features = {}
842 // - Current version = 4
843 // - Current enabled features = {FEATURE_EMBEDDING_INDEX,
844 // FEATURE_EMBEDDING_QUANTIZATION}
845 //
846 // - Result: rebuild embedding index
847 VersionUtilDerivedFilesRebuildTestParam(
848 /*existing_version_in=*/4, /*max_version_in=*/4,
849 /*existing_enabled_features_in=*/{}, /*curr_version_in=*/4,
850 /*curr_enabled_features_in=*/
851 {IcingSearchEngineFeatureInfoProto::FEATURE_EMBEDDING_INDEX,
852 IcingSearchEngineFeatureInfoProto::FEATURE_EMBEDDING_QUANTIZATION},
853 /*expected_derived_files_rebuild_result_in=*/
854 DerivedFilesRebuildResult(
855 /*needs_document_store_derived_files_rebuild_in=*/false,
856 /*needs_schema_store_derived_files_rebuild_in=*/false,
857 /*needs_term_index_rebuild_in=*/false,
858 /*needs_integer_index_rebuild_in=*/false,
859 /*needs_qualified_id_join_index_rebuild_in=*/false,
860 /*needs_embedding_index_rebuild_in=*/true)),
861
862 // - Existing version 4, max_version 4
863 // - Existing enabled features = {FEATURE_EMBEDDING_INDEX}
864 // - Current version = 4
865 // - Current enabled features = {FEATURE_EMBEDDING_INDEX,
866 // FEATURE_EMBEDDING_QUANTIZATION}
867 //
868 // - Result: rebuild embedding index
869 VersionUtilDerivedFilesRebuildTestParam(
870 /*existing_version_in=*/4, /*max_version_in=*/4,
871 /*existing_enabled_features_in=*/
872 {IcingSearchEngineFeatureInfoProto::FEATURE_EMBEDDING_INDEX},
873 /*curr_version_in=*/4,
874 /*curr_enabled_features_in=*/
875 {IcingSearchEngineFeatureInfoProto::FEATURE_EMBEDDING_INDEX,
876 IcingSearchEngineFeatureInfoProto::FEATURE_EMBEDDING_QUANTIZATION},
877 /*expected_derived_files_rebuild_result_in=*/
878 DerivedFilesRebuildResult(
879 /*needs_document_store_derived_files_rebuild_in=*/false,
880 /*needs_schema_store_derived_files_rebuild_in=*/false,
881 /*needs_term_index_rebuild_in=*/false,
882 /*needs_integer_index_rebuild_in=*/false,
883 /*needs_qualified_id_join_index_rebuild_in=*/false,
884 /*needs_embedding_index_rebuild_in=*/true)),
885
886 // - Existing version 4, max_version 4
887 // - Existing enabled features = {FEATURE_HAS_PROPERTY_OPERATOR}
888 // - Current version = 4
889 // - Current enabled features = {}
890 //
891 // - Result: rebuild term index
892 VersionUtilDerivedFilesRebuildTestParam(
893 /*existing_version_in=*/4, /*max_version_in=*/4,
894 /*existing_enabled_features_in=*/
895 {IcingSearchEngineFeatureInfoProto::FEATURE_HAS_PROPERTY_OPERATOR},
896 /*curr_version_in=*/4, /*curr_enabled_features_in=*/{},
897 /*expected_derived_files_rebuild_result_in=*/
898 DerivedFilesRebuildResult(
899 /*needs_document_store_derived_files_rebuild_in=*/false,
900 /*needs_schema_store_derived_files_rebuild_in=*/false,
901 /*needs_term_index_rebuild_in=*/true,
902 /*needs_integer_index_rebuild_in=*/false,
903 /*needs_qualified_id_join_index_rebuild_in=*/false,
904 /*needs_embedding_index_rebuild_in=*/false)),
905
906 // - Existing version 4, max_version 4
907 // - Existing enabled features = {FEATURE_EMBEDDING_INDEX}
908 // - Current version = 4
909 // - Current enabled features = {}
910 //
911 // - Result: rebuild embedding index
912 VersionUtilDerivedFilesRebuildTestParam(
913 /*existing_version_in=*/4, /*max_version_in=*/4,
914 /*existing_enabled_features_in=*/
915 {IcingSearchEngineFeatureInfoProto::FEATURE_EMBEDDING_INDEX},
916 /*curr_version_in=*/4, /*curr_enabled_features_in=*/{},
917 /*expected_derived_files_rebuild_result_in=*/
918 DerivedFilesRebuildResult(
919 /*needs_document_store_derived_files_rebuild_in=*/false,
920 /*needs_schema_store_derived_files_rebuild_in=*/false,
921 /*needs_term_index_rebuild_in=*/false,
922 /*needs_integer_index_rebuild_in=*/false,
923 /*needs_qualified_id_join_index_rebuild_in=*/false,
924 /*needs_embedding_index_rebuild_in=*/true)),
925
926 // - Existing version 4, max_version 4
927 // - Existing enabled features = {FEATURE_EMBEDDING_INDEX,
928 // FEATURE_EMBEDDING_QUANTIZATION}
929 // - Current version = 4
930 // - Current enabled features = {}
931 //
932 // - Result: rebuild embedding index
933 VersionUtilDerivedFilesRebuildTestParam(
934 /*existing_version_in=*/4, /*max_version_in=*/4,
935 /*existing_enabled_features_in=*/
936 {IcingSearchEngineFeatureInfoProto::FEATURE_EMBEDDING_INDEX,
937 IcingSearchEngineFeatureInfoProto::FEATURE_EMBEDDING_QUANTIZATION},
938 /*curr_version_in=*/4, /*curr_enabled_features_in=*/{},
939 /*expected_derived_files_rebuild_result_in=*/
940 DerivedFilesRebuildResult(
941 /*needs_document_store_derived_files_rebuild_in=*/false,
942 /*needs_schema_store_derived_files_rebuild_in=*/false,
943 /*needs_term_index_rebuild_in=*/false,
944 /*needs_integer_index_rebuild_in=*/false,
945 /*needs_qualified_id_join_index_rebuild_in=*/false,
946 /*needs_embedding_index_rebuild_in=*/true)),
947
948 // - Existing version 4, max_version 4
949 // - Existing enabled features = {FEATURE_EMBEDDING_INDEX,
950 // FEATURE_EMBEDDING_QUANTIZATION}
951 // - Current version = 4
952 // - Current enabled features = {FEATURE_EMBEDDING_INDEX}
953 //
954 // - Result: rebuild embedding index
955 VersionUtilDerivedFilesRebuildTestParam(
956 /*existing_version_in=*/4, /*max_version_in=*/4,
957 /*existing_enabled_features_in=*/
958 {IcingSearchEngineFeatureInfoProto::FEATURE_EMBEDDING_INDEX,
959 IcingSearchEngineFeatureInfoProto::FEATURE_EMBEDDING_QUANTIZATION},
960 /*curr_version_in=*/4, /*curr_enabled_features_in=*/
961 {IcingSearchEngineFeatureInfoProto::FEATURE_EMBEDDING_INDEX},
962 /*expected_derived_files_rebuild_result_in=*/
963 DerivedFilesRebuildResult(
964 /*needs_document_store_derived_files_rebuild_in=*/false,
965 /*needs_schema_store_derived_files_rebuild_in=*/false,
966 /*needs_term_index_rebuild_in=*/false,
967 /*needs_integer_index_rebuild_in=*/false,
968 /*needs_qualified_id_join_index_rebuild_in=*/false,
969 /*needs_embedding_index_rebuild_in=*/true)),
970
971 // - Existing version 4, max_version 4
972 // - Existing enabled features = {UNKNOWN}
973 // - Current version = 4
974 // - Current enabled features = {FEATURE_HAS_PROPERTY_OPERATOR}
975 //
976 // - Result: rebuild everything
977 VersionUtilDerivedFilesRebuildTestParam(
978 /*existing_version_in=*/4, /*max_version_in=*/4,
979 /*existing_enabled_features_in=*/
980 {IcingSearchEngineFeatureInfoProto::UNKNOWN}, /*curr_version_in=*/4,
981 /*curr_enabled_features_in=*/
982 {IcingSearchEngineFeatureInfoProto::FEATURE_HAS_PROPERTY_OPERATOR},
983 /*expected_derived_files_rebuild_result_in=*/
984 DerivedFilesRebuildResult(
985 /*needs_document_store_derived_files_rebuild_in=*/true,
986 /*needs_schema_store_derived_files_rebuild_in=*/true,
987 /*needs_term_index_rebuild_in=*/true,
988 /*needs_integer_index_rebuild_in=*/true,
989 /*needs_qualified_id_join_index_rebuild_in=*/true,
990 /*needs_embedding_index_rebuild_in=*/true)),
991
992 // - Existing version 5, max_version 5
993 // - Existing enabled features = {}
994 // - Current version = 5
995 // - Current enabled features = {FEATURE_HAS_PROPERTY_OPERATOR}
996 //
997 // - Result: rebuild term index
998 VersionUtilDerivedFilesRebuildTestParam(
999 /*existing_version_in=*/5, /*max_version_in=*/5,
1000 /*existing_enabled_features_in=*/{}, /*curr_version_in=*/5,
1001 /*curr_enabled_features_in=*/
1002 {IcingSearchEngineFeatureInfoProto::FEATURE_HAS_PROPERTY_OPERATOR},
1003 /*expected_derived_files_rebuild_result_in=*/
1004 DerivedFilesRebuildResult(
1005 /*needs_document_store_derived_files_rebuild_in=*/false,
1006 /*needs_schema_store_derived_files_rebuild_in=*/false,
1007 /*needs_term_index_rebuild_in=*/true,
1008 /*needs_integer_index_rebuild_in=*/false,
1009 /*needs_qualified_id_join_index_rebuild_in=*/false,
1010 /*needs_embedding_index_rebuild_in=*/false)),
1011
1012 // - Existing version 5, max_version 5
1013 // - Existing enabled features = {}
1014 // - Current version = 5
1015 // - Current enabled features = {FEATURE_SCHEMA_DATABASE}
1016 //
1017 // - Result: no rebuild
1018 VersionUtilDerivedFilesRebuildTestParam(
1019 /*existing_version_in=*/5, /*max_version_in=*/5,
1020 /*existing_enabled_features_in=*/{},
1021 /*curr_version_in=*/5, /*curr_enabled_features_in=*/
1022 {IcingSearchEngineFeatureInfoProto::FEATURE_SCHEMA_DATABASE},
1023 /*expected_derived_files_rebuild_result_in=*/
1024 DerivedFilesRebuildResult(
1025 /*needs_document_store_derived_files_rebuild_in=*/false,
1026 /*needs_schema_store_derived_files_rebuild_in=*/false,
1027 /*needs_term_index_rebuild_in=*/false,
1028 /*needs_integer_index_rebuild_in=*/false,
1029 /*needs_qualified_id_join_index_rebuild_in=*/false,
1030 /*needs_embedding_index_rebuild_in=*/false)),
1031
1032 // - Existing version 5, max_version 5
1033 // - Existing enabled features = {}
1034 // - Current version = 5
1035 // - Current enabled features =
1036 // {FEATURE_QUALIFIED_ID_JOIN_INDEX_V3_AND_DELETE_PROPAGATE_FROM}
1037 //
1038 // - Result: rebuild qualified id join index
1039 VersionUtilDerivedFilesRebuildTestParam(
1040 /*existing_version_in=*/5, /*max_version_in=*/5,
1041 /*existing_enabled_features_in=*/{},
1042 /*curr_version_in=*/5, /*curr_enabled_features_in=*/
1043 {IcingSearchEngineFeatureInfoProto::
1044 FEATURE_QUALIFIED_ID_JOIN_INDEX_V3_AND_DELETE_PROPAGATE_FROM},
1045 /*expected_derived_files_rebuild_result_in=*/
1046 DerivedFilesRebuildResult(
1047 /*needs_document_store_derived_files_rebuild_in=*/false,
1048 /*needs_schema_store_derived_files_rebuild_in=*/false,
1049 /*needs_term_index_rebuild_in=*/false,
1050 /*needs_integer_index_rebuild_in=*/false,
1051 /*needs_qualified_id_join_index_rebuild_in=*/true,
1052 /*needs_embedding_index_rebuild_in=*/false)),
1053
1054 // - Existing version 5, max_version 5
1055 // - Existing enabled features =
1056 // {FEATURE_QUALIFIED_ID_JOIN_INDEX_V3_AND_DELETE_PROPAGATE_FROM}
1057 // - Current version = 5
1058 // - Current enabled features = {}
1059 //
1060 // - Result: rebuild qualified id join index
1061 VersionUtilDerivedFilesRebuildTestParam(
1062 /*existing_version_in=*/5, /*max_version_in=*/5,
1063 /*existing_enabled_features_in=*/
1064 {IcingSearchEngineFeatureInfoProto::
1065 FEATURE_QUALIFIED_ID_JOIN_INDEX_V3_AND_DELETE_PROPAGATE_FROM},
1066 /*curr_version_in=*/5, /*curr_enabled_features_in=*/{},
1067 /*expected_derived_files_rebuild_result_in=*/
1068 DerivedFilesRebuildResult(
1069 /*needs_document_store_derived_files_rebuild_in=*/false,
1070 /*needs_schema_store_derived_files_rebuild_in=*/false,
1071 /*needs_term_index_rebuild_in=*/false,
1072 /*needs_integer_index_rebuild_in=*/false,
1073 /*needs_qualified_id_join_index_rebuild_in=*/true,
1074 /*needs_embedding_index_rebuild_in=*/false))));
1075
TEST(VersionUtilTest,ShouldRebuildDerivedFilesUndeterminedVersion)1076 TEST(VersionUtilTest, ShouldRebuildDerivedFilesUndeterminedVersion) {
1077 EXPECT_THAT(
1078 ShouldRebuildDerivedFiles(VersionInfo(-1, -1), /*curr_version=*/1),
1079 IsTrue());
1080 EXPECT_THAT(
1081 ShouldRebuildDerivedFiles(VersionInfo(-1, -1), /*curr_version=*/2),
1082 IsTrue());
1083 }
1084
TEST(VersionUtilTest,ShouldRebuildDerivedFilesVersionZeroUpgrade)1085 TEST(VersionUtilTest, ShouldRebuildDerivedFilesVersionZeroUpgrade) {
1086 // 0 -> 1
1087 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(0, 0), /*curr_version=*/1),
1088 IsTrue());
1089
1090 // 0 -> 2
1091 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(0, 0), /*curr_version=*/2),
1092 IsTrue());
1093 }
1094
TEST(VersionUtilTest,ShouldRebuildDerivedFilesVersionZeroRollForward)1095 TEST(VersionUtilTest, ShouldRebuildDerivedFilesVersionZeroRollForward) {
1096 // (1 -> 0), 0 -> 1
1097 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(0, 1), /*curr_version=*/1),
1098 IsTrue());
1099
1100 // (1 -> 0), 0 -> 2
1101 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(0, 1), /*curr_version=*/2),
1102 IsTrue());
1103
1104 // (2 -> 0), 0 -> 1
1105 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(0, 2), /*curr_version=*/1),
1106 IsTrue());
1107
1108 // (5 -> 0), 0 -> 5
1109 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(0, 5), /*curr_version=*/5),
1110 IsTrue());
1111 }
1112
TEST(VersionUtilTest,ShouldRebuildDerivedFilesRollBack)1113 TEST(VersionUtilTest, ShouldRebuildDerivedFilesRollBack) {
1114 // 2 -> 1
1115 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(2, 2), /*curr_version=*/1),
1116 IsTrue());
1117
1118 // 3 -> 1
1119 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(3, 3), /*curr_version=*/1),
1120 IsTrue());
1121
1122 // (3 -> 2), 2 -> 1
1123 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(2, 3), /*curr_version=*/1),
1124 IsTrue());
1125
1126 // (5 -> 4), 4 -> 3
1127 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(4, 5), /*curr_version=*/3),
1128 IsTrue());
1129 }
1130
TEST(VersionUtilTest,ShouldRebuildDerivedFilesRollForward)1131 TEST(VersionUtilTest, ShouldRebuildDerivedFilesRollForward) {
1132 // (2 -> 1), 1 -> 2
1133 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(1, 2), /*curr_version=*/2),
1134 IsTrue());
1135
1136 // (2 -> 1), 1 -> 3
1137 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(1, 2), /*curr_version=*/3),
1138 IsTrue());
1139
1140 // (3 -> 1), 1 -> 2
1141 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(1, 3), /*curr_version=*/2),
1142 IsTrue());
1143
1144 // (5 -> 4), 4 -> 5
1145 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(4, 5), /*curr_version=*/5),
1146 IsTrue());
1147 }
1148
TEST(VersionUtilTest,ShouldRebuildDerivedFilesCompatible)1149 TEST(VersionUtilTest, ShouldRebuildDerivedFilesCompatible) {
1150 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(2, 2), /*curr_version=*/2),
1151 IsFalse());
1152
1153 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(2, 3), /*curr_version=*/2),
1154 IsFalse());
1155 }
1156
TEST(VersionUtilTest,Upgrade)1157 TEST(VersionUtilTest, Upgrade) {
1158 // Unlike other state changes, upgrade depends on the actual "encoded path".
1159
1160 // kVersionOne -> kVersionTwo
1161 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(kVersionOne, kVersionOne),
1162 /*curr_version=*/kVersionTwo),
1163 IsFalse());
1164
1165 // kVersionTwo -> kVersionThree
1166 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(kVersionTwo, kVersionTwo),
1167 /*curr_version=*/kVersionThree),
1168 IsFalse());
1169
1170 // kVersionOne -> kVersionThree.
1171 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(kVersionOne, kVersionOne),
1172 /*curr_version=*/kVersionThree),
1173 IsFalse());
1174
1175 // kVersionThree -> kVersionFour.
1176 EXPECT_THAT(
1177 ShouldRebuildDerivedFiles(VersionInfo(kVersionThree, kVersionThree),
1178 /*curr_version=*/kVersionFour),
1179 IsFalse());
1180
1181 // kVersionTwo -> kVersionFour
1182 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(kVersionTwo, kVersionTwo),
1183 /*curr_version=*/kVersionFour),
1184 IsFalse());
1185
1186 // kVersionOne -> kVersionFour.
1187 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(kVersionOne, kVersionOne),
1188 /*curr_version=*/kVersionFour),
1189 IsFalse());
1190
1191 // kVersionFour -> kVersionFive.
1192 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(kVersionFour, kVersionFour),
1193 /*curr_version=*/kVersionFive),
1194 IsFalse());
1195
1196 // kVersionThree -> kVersionFive.
1197 EXPECT_THAT(
1198 ShouldRebuildDerivedFiles(VersionInfo(kVersionThree, kVersionThree),
1199 /*curr_version=*/kVersionFive),
1200 IsFalse());
1201
1202 // kVersionTwo -> kVersionFour
1203 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(kVersionTwo, kVersionTwo),
1204 /*curr_version=*/kVersionFive),
1205 IsFalse());
1206
1207 // kVersionOne -> kVersionFour.
1208 EXPECT_THAT(ShouldRebuildDerivedFiles(VersionInfo(kVersionOne, kVersionOne),
1209 /*curr_version=*/kVersionFive),
1210 IsFalse());
1211 }
1212
TEST(VersionUtilTest,GetFeatureDerivedFilesRebuildResult_unknown)1213 TEST(VersionUtilTest, GetFeatureDerivedFilesRebuildResult_unknown) {
1214 EXPECT_THAT(GetFeatureDerivedFilesRebuildResult(
1215 IcingSearchEngineFeatureInfoProto::UNKNOWN),
1216 Eq(DerivedFilesRebuildResult(
1217 /*needs_document_store_derived_files_rebuild_in=*/true,
1218 /*needs_schema_store_derived_files_rebuild_in=*/true,
1219 /*needs_term_index_rebuild_in=*/true,
1220 /*needs_integer_index_rebuild_in=*/true,
1221 /*needs_qualified_id_join_index_rebuild_in=*/true,
1222 /*needs_embedding_index_rebuild_in=*/true)));
1223 }
1224
TEST(VersionUtilTest,GetFeatureDerivedFilesRebuildResult_featureHasPropertyOperator)1225 TEST(VersionUtilTest,
1226 GetFeatureDerivedFilesRebuildResult_featureHasPropertyOperator) {
1227 EXPECT_THAT(
1228 GetFeatureDerivedFilesRebuildResult(
1229 IcingSearchEngineFeatureInfoProto::FEATURE_HAS_PROPERTY_OPERATOR),
1230 Eq(DerivedFilesRebuildResult(
1231 /*needs_document_store_derived_files_rebuild_in=*/false,
1232 /*needs_schema_store_derived_files_rebuild_in=*/false,
1233 /*needs_term_index_rebuild_in=*/true,
1234 /*needs_integer_index_rebuild_in=*/false,
1235 /*needs_qualified_id_join_index_rebuild_in=*/false,
1236 /*needs_embedding_index_rebuild_in=*/false)));
1237 }
1238
TEST(VersionUtilTest,GetFeatureDerivedFilesRebuildResult_featureEmbeddingIndex)1239 TEST(VersionUtilTest,
1240 GetFeatureDerivedFilesRebuildResult_featureEmbeddingIndex) {
1241 EXPECT_THAT(GetFeatureDerivedFilesRebuildResult(
1242 IcingSearchEngineFeatureInfoProto::FEATURE_EMBEDDING_INDEX),
1243 Eq(DerivedFilesRebuildResult(
1244 /*needs_document_store_derived_files_rebuild_in=*/false,
1245 /*needs_schema_store_derived_files_rebuild_in=*/false,
1246 /*needs_term_index_rebuild_in=*/false,
1247 /*needs_integer_index_rebuild_in=*/false,
1248 /*needs_qualified_id_join_index_rebuild_in=*/false,
1249 /*needs_embedding_index_rebuild_in=*/true)));
1250 }
1251
TEST(VersionUtilTest,GetFeatureDerivedFilesRebuildResult_featureEmbeddingQuantization)1252 TEST(VersionUtilTest,
1253 GetFeatureDerivedFilesRebuildResult_featureEmbeddingQuantization) {
1254 EXPECT_THAT(
1255 GetFeatureDerivedFilesRebuildResult(
1256 IcingSearchEngineFeatureInfoProto::FEATURE_EMBEDDING_QUANTIZATION),
1257 Eq(DerivedFilesRebuildResult(
1258 /*needs_document_store_derived_files_rebuild_in=*/false,
1259 /*needs_schema_store_derived_files_rebuild_in=*/false,
1260 /*needs_term_index_rebuild_in=*/false,
1261 /*needs_integer_index_rebuild_in=*/false,
1262 /*needs_qualified_id_join_index_rebuild_in=*/false,
1263 /*needs_embedding_index_rebuild_in=*/true)));
1264 }
1265
TEST(VersionUtilTest,GetFeatureDerivedFilesRebuildResult_featureSchemaDatabase)1266 TEST(VersionUtilTest,
1267 GetFeatureDerivedFilesRebuildResult_featureSchemaDatabase) {
1268 EXPECT_THAT(GetFeatureDerivedFilesRebuildResult(
1269 IcingSearchEngineFeatureInfoProto::FEATURE_SCHEMA_DATABASE),
1270 Eq(DerivedFilesRebuildResult(
1271 /*needs_document_store_derived_files_rebuild_in=*/false,
1272 /*needs_schema_store_derived_files_rebuild_in=*/false,
1273 /*needs_term_index_rebuild_in=*/false,
1274 /*needs_integer_index_rebuild_in=*/false,
1275 /*needs_qualified_id_join_index_rebuild_in=*/false,
1276 /*needs_embedding_index_rebuild_in=*/false)));
1277 }
1278
TEST(VersionUtilTest,GetFeatureDerivedFilesRebuildResult_featureQualifiedIdJoinIndexV3AndDeletePropagateFrom)1279 TEST(
1280 VersionUtilTest,
1281 GetFeatureDerivedFilesRebuildResult_featureQualifiedIdJoinIndexV3AndDeletePropagateFrom) {
1282 EXPECT_THAT(
1283 GetFeatureDerivedFilesRebuildResult(
1284 IcingSearchEngineFeatureInfoProto::
1285 FEATURE_QUALIFIED_ID_JOIN_INDEX_V3_AND_DELETE_PROPAGATE_FROM),
1286 Eq(DerivedFilesRebuildResult(
1287 /*needs_document_store_derived_files_rebuild_in=*/false,
1288 /*needs_schema_store_derived_files_rebuild_in=*/false,
1289 /*needs_term_index_rebuild_in=*/false,
1290 /*needs_integer_index_rebuild_in=*/false,
1291 /*needs_qualified_id_join_index_rebuild_in=*/true,
1292 /*needs_embedding_index_rebuild_in=*/false)));
1293 }
1294
TEST(VersionUtilTest,SchemaDatabaseMigrationRequired)1295 TEST(VersionUtilTest, SchemaDatabaseMigrationRequired) {
1296 // Migration is required if the previous version is less than the version at
1297 // which the database field is introduced.
1298 IcingSearchEngineVersionProto previous_version_proto;
1299 previous_version_proto.set_version(kSchemaDatabaseVersion - 1);
1300 previous_version_proto.set_max_version(kSchemaDatabaseVersion - 1);
1301 previous_version_proto.add_enabled_features()->set_feature_type(
1302 IcingSearchEngineFeatureInfoProto::FEATURE_SCHEMA_DATABASE);
1303 EXPECT_TRUE(SchemaDatabaseMigrationRequired(previous_version_proto));
1304
1305 // Migration is required if the schema database feature was not enabled in the
1306 // previous version.
1307 previous_version_proto.set_version(kSchemaDatabaseVersion);
1308 previous_version_proto.set_max_version(kSchemaDatabaseVersion);
1309 previous_version_proto.mutable_enabled_features()->Clear();
1310 // Add a feature that is not the schema database feature.
1311 previous_version_proto.add_enabled_features()->set_feature_type(
1312 IcingSearchEngineFeatureInfoProto::FEATURE_HAS_PROPERTY_OPERATOR);
1313 EXPECT_TRUE(SchemaDatabaseMigrationRequired(previous_version_proto));
1314
1315 previous_version_proto.set_version(kSchemaDatabaseVersion + 1);
1316 previous_version_proto.set_max_version(kSchemaDatabaseVersion + 1);
1317 previous_version_proto.mutable_enabled_features()->Clear();
1318 EXPECT_TRUE(SchemaDatabaseMigrationRequired(previous_version_proto));
1319 }
1320
TEST(VersionUtilTest,SchemaDatabaseMigrationNotRequired)1321 TEST(VersionUtilTest, SchemaDatabaseMigrationNotRequired) {
1322 // Migration is not required if previous version is >= the version at which
1323 // the schema database is introduced and the schema database feature was
1324 // enabled in the previous version.
1325 IcingSearchEngineVersionProto previous_version_proto;
1326 previous_version_proto.set_version(kSchemaDatabaseVersion);
1327 previous_version_proto.set_max_version(kSchemaDatabaseVersion);
1328 previous_version_proto.add_enabled_features()->set_feature_type(
1329 IcingSearchEngineFeatureInfoProto::FEATURE_SCHEMA_DATABASE);
1330 EXPECT_FALSE(SchemaDatabaseMigrationRequired(previous_version_proto));
1331
1332 previous_version_proto.set_version(kSchemaDatabaseVersion + 1);
1333 previous_version_proto.set_max_version(kSchemaDatabaseVersion + 1);
1334 previous_version_proto.add_enabled_features()->set_feature_type(
1335 IcingSearchEngineFeatureInfoProto::FEATURE_SCHEMA_DATABASE);
1336 EXPECT_FALSE(SchemaDatabaseMigrationRequired(previous_version_proto));
1337 }
1338
1339 class VersionUtilFeatureProtoTest
1340 : public ::testing::TestWithParam<
1341 IcingSearchEngineFeatureInfoProto::FlaggedFeatureType> {};
1342
TEST_P(VersionUtilFeatureProtoTest,GetFeatureInfoProto)1343 TEST_P(VersionUtilFeatureProtoTest, GetFeatureInfoProto) {
1344 IcingSearchEngineFeatureInfoProto::FlaggedFeatureType feature_type =
1345 GetParam();
1346 DerivedFilesRebuildResult rebuild_result =
1347 GetFeatureDerivedFilesRebuildResult(feature_type);
1348
1349 IcingSearchEngineFeatureInfoProto feature_info =
1350 GetFeatureInfoProto(feature_type);
1351 EXPECT_THAT(feature_info.feature_type(), Eq(feature_type));
1352
1353 EXPECT_THAT(feature_info.needs_document_store_rebuild(),
1354 Eq(rebuild_result.needs_document_store_derived_files_rebuild));
1355 EXPECT_THAT(feature_info.needs_schema_store_rebuild(),
1356 Eq(rebuild_result.needs_schema_store_derived_files_rebuild));
1357 EXPECT_THAT(feature_info.needs_term_index_rebuild(),
1358 Eq(rebuild_result.needs_term_index_rebuild));
1359 EXPECT_THAT(feature_info.needs_integer_index_rebuild(),
1360 Eq(rebuild_result.needs_integer_index_rebuild));
1361 EXPECT_THAT(feature_info.needs_qualified_id_join_index_rebuild(),
1362 Eq(rebuild_result.needs_qualified_id_join_index_rebuild));
1363 EXPECT_THAT(feature_info.needs_embedding_index_rebuild(),
1364 Eq(rebuild_result.needs_embedding_index_rebuild));
1365 }
1366
1367 INSTANTIATE_TEST_SUITE_P(
1368 VersionUtilFeatureProtoTest, VersionUtilFeatureProtoTest,
1369 testing::Values(
1370 IcingSearchEngineFeatureInfoProto::UNKNOWN,
1371 IcingSearchEngineFeatureInfoProto::FEATURE_HAS_PROPERTY_OPERATOR,
1372 IcingSearchEngineFeatureInfoProto::FEATURE_SCORABLE_PROPERTIES,
1373 IcingSearchEngineFeatureInfoProto::FEATURE_EMBEDDING_INDEX,
1374 IcingSearchEngineFeatureInfoProto::FEATURE_EMBEDDING_QUANTIZATION,
1375 IcingSearchEngineFeatureInfoProto::FEATURE_SCHEMA_DATABASE,
1376 IcingSearchEngineFeatureInfoProto::
1377 FEATURE_QUALIFIED_ID_JOIN_INDEX_V3_AND_DELETE_PROPAGATE_FROM));
1378
1379 } // namespace
1380
1381 } // namespace version_util
1382 } // namespace lib
1383 } // namespace icing
1384