xref: /aosp_15_r20/external/federated-compute/fcp/client/cache/temp_files_test.cc (revision 14675a029014e728ec732f129a32e299b2da0601)
1 /*
2  * Copyright 2022 Google LLC
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "fcp/client/cache/temp_files.h"
18 
19 #include <filesystem>
20 #include <fstream>
21 #include <functional>
22 #include <string>
23 #include <utility>
24 
25 #include "gmock/gmock.h"
26 #include "gtest/gtest.h"
27 #include "absl/status/statusor.h"
28 #include "fcp/client/test_helpers.h"
29 #include "fcp/testing/testing.h"
30 
31 namespace fcp {
32 namespace client {
33 namespace cache {
34 namespace {
35 
CountFilesInDir(const std::filesystem::path & dir)36 int CountFilesInDir(const std::filesystem::path& dir) {
37   int num_files = 0;
38   for ([[maybe_unused]] auto const& unused :
39        std::filesystem::directory_iterator{dir}) {
40     num_files++;
41   }
42   return num_files;
43 }
44 
45 class TempFilesTest : public testing::Test {
46  protected:
SetUp()47   void SetUp() override {
48     root_dir_ = testing::TempDir();
49     std::filesystem::path root_dir(root_dir_);
50     temp_file_dir_ =
51         root_dir / TempFiles::kParentDir / TempFiles::kTempFilesDir;
52   }
TearDown()53   void TearDown() override {
54     std::filesystem::remove_all(std::filesystem::path(root_dir_));
55   }
56 
57   testing::StrictMock<MockLogManager> log_manager_;
58   std::string root_dir_;
59   std::filesystem::path temp_file_dir_;
60 };
61 
TEST_F(TempFilesTest,FailToCreateParentDirectory)62 TEST_F(TempFilesTest, FailToCreateParentDirectory) {
63   ASSERT_THAT(TempFiles::Create("/proc/0", &log_manager_), IsCode(INTERNAL));
64 }
65 
TEST_F(TempFilesTest,InvalidRelativePath)66 TEST_F(TempFilesTest, InvalidRelativePath) {
67   ASSERT_THAT(TempFiles::Create("relative/cache", &log_manager_),
68               IsCode(INVALID_ARGUMENT));
69 }
70 
TEST_F(TempFilesTest,SuccessfulInitialization)71 TEST_F(TempFilesTest, SuccessfulInitialization) {
72   ASSERT_OK(TempFiles::Create(root_dir_, &log_manager_));
73 }
74 
TEST_F(TempFilesTest,CreateTempFile)75 TEST_F(TempFilesTest, CreateTempFile) {
76   auto temp_files = TempFiles::Create(root_dir_, &log_manager_);
77   ASSERT_OK(temp_files);
78   auto temp_file = (*temp_files)->CreateTempFile("stefan", ".cool");
79   ASSERT_OK(temp_file);
80 }
81 
TEST_F(TempFilesTest,CreateSomeTempFilesThenDeleteInDtor)82 TEST_F(TempFilesTest, CreateSomeTempFilesThenDeleteInDtor) {
83   auto temp_files = TempFiles::Create(root_dir_, &log_manager_);
84   ASSERT_OK(temp_files);
85   int num_temp_files = 4;
86   for (int i = 0; i < num_temp_files; i++) {
87     ASSERT_OK((*temp_files)->CreateTempFile("stefan", ".cool"));
88   }
89   ASSERT_EQ(num_temp_files, CountFilesInDir(temp_file_dir_));
90 
91   temp_files->reset();  // deleting temp_files should empty the directory.
92 
93   ASSERT_EQ(0, CountFilesInDir(temp_file_dir_));
94 }
95 
TEST_F(TempFilesTest,CreatingTempFilesDeletesExistingFiles)96 TEST_F(TempFilesTest, CreatingTempFilesDeletesExistingFiles) {
97   std::filesystem::path root_dir(root_dir_);
98 
99   ASSERT_TRUE(std::filesystem::create_directories(temp_file_dir_));
100 
101   int num_existing_temp_files = 10;
102   for (int i = 0; i < num_existing_temp_files; i++) {
103     std::filesystem::path temp_file_path =
104         temp_file_dir_ / absl::StrCat("temp", i);
105     std::ofstream{temp_file_path};
106   }
107   ASSERT_EQ(num_existing_temp_files, CountFilesInDir(temp_file_dir_));
108 
109   auto temp_files = TempFiles::Create(root_dir_, &log_manager_);
110   ASSERT_OK(temp_files);
111   ASSERT_EQ(0, CountFilesInDir(temp_file_dir_));
112 }
113 
TEST_F(TempFilesTest,FailToDeleteTempFilesLogs)114 TEST_F(TempFilesTest, FailToDeleteTempFilesLogs) {
115   // Create a temp file in the temp dir
116   auto temp_files = TempFiles::Create(root_dir_, &log_manager_);
117   ASSERT_OK(temp_files);
118   ASSERT_OK((*temp_files)->CreateTempFile("stefan", ".cool"));
119   ASSERT_OK((*temp_files)->CreateTempFile("stefan", ".cool"));
120   ASSERT_OK((*temp_files)->CreateTempFile("stefan", ".cool"));
121   ASSERT_EQ(3, CountFilesInDir(temp_file_dir_));
122 
123   // Delete the temp file dir and root dir, which should cause the dtor to fail
124   // because we deleted the directories out from underneath it.
125   std::filesystem::remove_all(std::filesystem::path(root_dir_));
126 
127   EXPECT_CALL(log_manager_,
128               LogDiag(ProdDiagCode::TEMP_FILES_NATIVE_FAILED_TO_DELETE));
129   temp_files->reset();
130 }
131 
132 }  // namespace
133 }  // namespace cache
134 }  // namespace client
135 }  // namespace fcp
136