1 // Copyright (C) 2021 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/destructible-file.h"
16
17 #include "gmock/gmock.h"
18 #include "gtest/gtest.h"
19 #include "icing/file/filesystem.h"
20 #include "icing/testing/tmp-directory.h"
21
22 namespace icing {
23 namespace lib {
24
25 namespace {
26
TEST(DestructibleFileTest,DeletesFileProperly)27 TEST(DestructibleFileTest, DeletesFileProperly) {
28 Filesystem filesystem;
29 std::string filepath1 = GetTestTempDir() + "/file1";
30
31 {
32 // 1. Create the file
33 ScopedFd sfd(filesystem.OpenForWrite(filepath1.c_str()));
34 ASSERT_TRUE(sfd.is_valid());
35 int i = 127;
36 ASSERT_TRUE(filesystem.Write(sfd.get(), &i, sizeof(i)));
37 }
38
39 {
40 // 2. Open with a Destructible file.
41 DestructibleFile destructible(filepath1, &filesystem);
42 ASSERT_TRUE(destructible.is_valid());
43 }
44
45 // 3. Ensure that the file doesn't exist.
46 EXPECT_FALSE(filesystem.FileExists(filepath1.c_str()));
47 }
48
TEST(DestructibleFileTest,MoveAssignDeletesFileProperly)49 TEST(DestructibleFileTest, MoveAssignDeletesFileProperly) {
50 Filesystem filesystem;
51 std::string filepath1 = GetTestTempDir() + "/file1";
52 std::string filepath2 = GetTestTempDir() + "/file2";
53
54 // 1. Create file1
55 DestructibleFile destructible1(filepath1, &filesystem);
56 ASSERT_TRUE(destructible1.is_valid());
57 int i = 127;
58 ASSERT_TRUE(filesystem.Write(destructible1.get_fd(), &i, sizeof(i)));
59
60 {
61 // 2. Create file2
62 DestructibleFile destructible2(filepath2, &filesystem);
63 ASSERT_TRUE(destructible2.is_valid());
64 i = 458;
65 ASSERT_TRUE(filesystem.Write(destructible2.get_fd(), &i, sizeof(i)));
66
67 // Move assign destructible2 into destructible1
68 destructible1 = std::move(destructible2);
69 }
70
71 // 3. file1 shouldn't exist because it was destroyed when destructible1 was
72 // move assigned to.
73 EXPECT_FALSE(filesystem.FileExists(filepath1.c_str()));
74
75 // 4. file2 should still exist because it moved into destructible1 from
76 // destructible2.
77 EXPECT_TRUE(filesystem.FileExists(filepath2.c_str()));
78 }
79
TEST(DestructibleFileTest,MoveConstructionDeletesFileProperly)80 TEST(DestructibleFileTest, MoveConstructionDeletesFileProperly) {
81 Filesystem filesystem;
82 std::string filepath1 = GetTestTempDir() + "/file1";
83
84 // 1. Create destructible1, it'll be reconstructed soon anyways.
85 std::unique_ptr<DestructibleFile> destructible1;
86 {
87 // 2. Create file1
88 DestructibleFile destructible2(filepath1, &filesystem);
89 ASSERT_TRUE(destructible2.is_valid());
90 int i = 458;
91 ASSERT_TRUE(filesystem.Write(destructible2.get_fd(), &i, sizeof(i)));
92
93 // Move construct destructible1 from destructible2
94 destructible1 =
95 std::make_unique<DestructibleFile>(std::move(destructible2));
96 }
97
98 // 3. file1 should still exist because it moved into destructible1 from
99 // destructible2.
100 ASSERT_TRUE(destructible1->is_valid());
101 EXPECT_TRUE(filesystem.FileExists(filepath1.c_str()));
102
103 {
104 // 4. Move construct destructible3 from destructible1
105 DestructibleFile destructible3(std::move(*destructible1));
106 ASSERT_TRUE(destructible3.is_valid());
107 }
108
109 // 5. file1 shouldn't exist because it was destroyed when destructible3 was
110 // destroyed.
111 EXPECT_FALSE(filesystem.FileExists(filepath1.c_str()));
112 }
113
114 } // namespace
115
116 } // namespace lib
117 } // namespace icing
118