xref: /aosp_15_r20/external/icing/icing/file/version-util_test.cc (revision 8b6cd535a057e39b3b86660c4aa06c99747c2136)
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