xref: /aosp_15_r20/external/icing/icing/legacy/index/icing-array-storage_test.cc (revision 8b6cd535a057e39b3b86660c4aa06c99747c2136)
1 // Copyright (C) 2024 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/legacy/index/icing-array-storage.h"
16 
17 #include <cstdint>
18 #include <string>
19 
20 #include "gmock/gmock.h"
21 #include "gtest/gtest.h"
22 #include "icing/legacy/index/icing-filesystem.h"
23 #include "icing/testing/tmp-directory.h"
24 #include "icing/util/crc32.h"
25 
26 namespace icing {
27 namespace lib {
28 
29 namespace {
30 
31 using testing::Eq;
32 
33 class IcingArrayStorageTest : public ::testing::Test {
34  protected:
SetUp()35   void SetUp() override {
36     array_files_dir_ = GetTestTempDir() + "/array_files";
37     filesystem_.CreateDirectoryRecursively(array_files_dir_.c_str());
38     array_file_ = array_files_dir_ + "/array_file";
39   }
40 
TearDown()41   void TearDown() override {
42     filesystem_.DeleteDirectoryRecursively(array_files_dir_.c_str());
43   }
44 
45   IcingFilesystem filesystem_;
46   std::string array_files_dir_;
47   std::string array_file_;
48 };
49 
TEST_F(IcingArrayStorageTest,UpdateCrcNoCrcPtr)50 TEST_F(IcingArrayStorageTest, UpdateCrcNoCrcPtr) {
51   IcingArrayStorage storage(filesystem_);
52   IcingScopedFd sfd(filesystem_.OpenForWrite(array_file_.c_str()));
53   ASSERT_TRUE(sfd.is_valid());
54   ASSERT_TRUE(storage.Init(sfd.get(), /*fd_offset=*/0, /*map_shared=*/true,
55                            /*elt_size=*/sizeof(uint32_t), /*num_elts=*/0,
56                            /*max_num_elts=*/1000, /*crc_ptr=*/nullptr,
57                            /*init_crc=*/false));
58 
59   // Initial Crc should be 0.
60   EXPECT_THAT(storage.GetCrc(), Eq(Crc32()));
61   EXPECT_THAT(storage.UpdateCrc(), Eq(Crc32()));
62   EXPECT_THAT(storage.GetCrc(), Eq(Crc32()));
63 
64   uint32_t* val = storage.GetMutableMem<uint32_t>(0, 1);
65   *val = 5;
66 
67   // Because there is no crc_ptr, the crc should remain 0 even though we have
68   // added content.
69   EXPECT_THAT(storage.GetCrc(), Eq(Crc32()));
70   EXPECT_THAT(storage.UpdateCrc(), Eq(Crc32()));
71   EXPECT_THAT(storage.GetCrc(), Eq(Crc32()));
72 }
73 
TEST_F(IcingArrayStorageTest,UpdateCrc)74 TEST_F(IcingArrayStorageTest, UpdateCrc) {
75   IcingArrayStorage storage(filesystem_);
76   uint32_t crc = 0;
77   IcingScopedFd sfd(filesystem_.OpenForWrite(array_file_.c_str()));
78   ASSERT_TRUE(sfd.is_valid());
79   ASSERT_TRUE(storage.Init(sfd.get(), /*fd_offset=*/0, /*map_shared=*/true,
80                            /*elt_size=*/sizeof(uint32_t), /*num_elts=*/0,
81                            /*max_num_elts=*/1000, &crc, /*init_crc=*/false));
82 
83   // Initial Crc should be 0.
84   EXPECT_THAT(storage.GetCrc(), Eq(Crc32()));
85   EXPECT_THAT(storage.UpdateCrc(), Eq(Crc32()));
86   EXPECT_THAT(storage.GetCrc(), Eq(Crc32()));
87 
88   uint32_t* val = storage.GetMutableMem<uint32_t>(0, 1);
89   *val = 5;
90 
91   EXPECT_THAT(storage.GetCrc(), Eq(Crc32(937357362)));
92   EXPECT_THAT(storage.UpdateCrc(), Eq(Crc32(937357362)));
93   EXPECT_THAT(storage.GetCrc(), Eq(Crc32(937357362)));
94 }
95 
TEST_F(IcingArrayStorageTest,GetCrcDoesNotUpdateHeader)96 TEST_F(IcingArrayStorageTest, GetCrcDoesNotUpdateHeader) {
97   uint32_t crc = 0;
98   IcingScopedFd sfd(filesystem_.OpenForWrite(array_file_.c_str()));
99   ASSERT_TRUE(sfd.is_valid());
100 
101   {
102     IcingArrayStorage storage_one(filesystem_);
103     ASSERT_TRUE(
104         storage_one.Init(sfd.get(), /*fd_offset=*/0, /*map_shared=*/true,
105                          /*elt_size=*/sizeof(uint32_t), /*num_elts=*/0,
106                          /*max_num_elts=*/1000, &crc, /*init_crc=*/false));
107 
108     // Initial Crc should be 0.
109     EXPECT_THAT(storage_one.GetCrc(), Eq(Crc32()));
110     EXPECT_THAT(storage_one.UpdateCrc(), Eq(Crc32()));
111     EXPECT_THAT(storage_one.GetCrc(), Eq(Crc32()));
112 
113     uint32_t* val = storage_one.GetMutableMem<uint32_t>(0, 1);
114     *val = 5;
115 
116     EXPECT_THAT(storage_one.GetCrc(), Eq(Crc32(937357362)));
117     EXPECT_THAT(crc, Eq(0));
118   }
119 
120   {
121     IcingArrayStorage storage_two(filesystem_);
122     // Init should fail because the updated checksum was never written to crc.
123     ASSERT_FALSE(
124         storage_two.Init(sfd.get(), /*fd_offset=*/0, /*map_shared=*/true,
125                          /*elt_size=*/sizeof(uint32_t), /*num_elts=*/1,
126                          /*max_num_elts=*/1000, &crc, /*init_crc=*/false));
127   }
128 }
129 
TEST_F(IcingArrayStorageTest,UpdateCrcDoesUpdateHeader)130 TEST_F(IcingArrayStorageTest, UpdateCrcDoesUpdateHeader) {
131   uint32_t crc = 0;
132   IcingScopedFd sfd(filesystem_.OpenForWrite(array_file_.c_str()));
133   ASSERT_TRUE(sfd.is_valid());
134 
135   {
136     IcingArrayStorage storage_one(filesystem_);
137     ASSERT_TRUE(
138         storage_one.Init(sfd.get(), /*fd_offset=*/0, /*map_shared=*/true,
139                          /*elt_size=*/sizeof(uint32_t), /*num_elts=*/0,
140                          /*max_num_elts=*/1000, &crc, /*init_crc=*/false));
141 
142     // Initial Crc should be 0.
143     EXPECT_THAT(storage_one.GetCrc(), Eq(Crc32()));
144     EXPECT_THAT(storage_one.UpdateCrc(), Eq(Crc32()));
145     EXPECT_THAT(storage_one.GetCrc(), Eq(Crc32()));
146 
147     uint32_t* val = storage_one.GetMutableMem<uint32_t>(0, 1);
148     *val = 5;
149 
150     EXPECT_THAT(storage_one.GetCrc(), Eq(Crc32(937357362)));
151     EXPECT_THAT(storage_one.UpdateCrc(), Eq(Crc32(937357362)));
152     EXPECT_THAT(storage_one.GetCrc(), Eq(Crc32(937357362)));
153     EXPECT_THAT(crc, Eq(937357362));
154   }
155 
156   {
157     IcingArrayStorage storage_two(filesystem_);
158     // Init should fail because the updated checksum was never written to crc.
159     ASSERT_TRUE(
160         storage_two.Init(sfd.get(), /*fd_offset=*/0, /*map_shared=*/true,
161                          /*elt_size=*/sizeof(uint32_t), /*num_elts=*/1,
162                          /*max_num_elts=*/1000, &crc, /*init_crc=*/false));
163     EXPECT_THAT(storage_two.GetCrc().Get(), Eq(937357362));
164   }
165 }
166 
167 }  // namespace
168 
169 }  // namespace lib
170 }  // namespace icing