ckitagawa | ac78736 | 2019-10-01 19:13:47 | [diff] [blame] | 1 | // Copyright 2019 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "components/paint_preview/browser/file_manager.h" |
| 6 | |
ckitagawa | 353e3b3 | 2020-02-27 16:15:56 | [diff] [blame] | 7 | #include <memory> |
| 8 | |
ckitagawa | ac78736 | 2019-10-01 19:13:47 | [diff] [blame] | 9 | #include "base/files/file.h" |
| 10 | #include "base/files/file_path.h" |
| 11 | #include "base/files/file_util.h" |
| 12 | #include "base/files/scoped_temp_dir.h" |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 13 | #include "base/memory/ref_counted.h" |
| 14 | #include "base/run_loop.h" |
| 15 | #include "base/test/task_environment.h" |
| 16 | #include "base/threading/sequenced_task_runner_handle.h" |
| 17 | #include "base/updateable_sequenced_task_runner.h" |
ckitagawa | 353e3b3 | 2020-02-27 16:15:56 | [diff] [blame] | 18 | #include "components/paint_preview/common/proto/paint_preview.pb.h" |
| 19 | #include "components/paint_preview/common/test_utils.h" |
ckitagawa | ac78736 | 2019-10-01 19:13:47 | [diff] [blame] | 20 | #include "testing/gtest/include/gtest/gtest.h" |
ckitagawa | 8bc893a | 2020-02-27 15:24:46 | [diff] [blame] | 21 | #include "url/gurl.h" |
ckitagawa | ac78736 | 2019-10-01 19:13:47 | [diff] [blame] | 22 | |
| 23 | namespace paint_preview { |
| 24 | |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 25 | class FileManagerTest : public ::testing::Test { |
| 26 | public: |
| 27 | FileManagerTest() = default; |
| 28 | ~FileManagerTest() override = default; |
| 29 | |
| 30 | void SetUp() override { |
| 31 | EXPECT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 32 | secondary_runner_ = base::ThreadPool::CreateUpdateableSequencedTaskRunner( |
| 33 | {base::MayBlock(), base::TaskPriority::BEST_EFFORT, |
| 34 | base::TaskShutdownBehavior::BLOCK_SHUTDOWN, |
| 35 | base::ThreadPolicy::MUST_USE_FOREGROUND}); |
| 36 | } |
| 37 | |
| 38 | const base::FilePath& Dir() const { return temp_dir.GetPath(); } |
| 39 | |
| 40 | scoped_refptr<base::SequencedTaskRunner> MainTaskRunner() { |
| 41 | return base::SequencedTaskRunnerHandle::Get(); |
| 42 | } |
| 43 | |
| 44 | scoped_refptr<base::UpdateableSequencedTaskRunner> SecondaryTaskRunner() { |
| 45 | return secondary_runner_; |
| 46 | } |
| 47 | |
| 48 | void RunUntilIdle() { task_environment_.RunUntilIdle(); } |
| 49 | |
| 50 | private: |
| 51 | scoped_refptr<base::UpdateableSequencedTaskRunner> secondary_runner_; |
ckitagawa | ac78736 | 2019-10-01 19:13:47 | [diff] [blame] | 52 | base::ScopedTempDir temp_dir; |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 53 | base::test::TaskEnvironment task_environment_; |
| 54 | }; |
ckitagawa | ac78736 | 2019-10-01 19:13:47 | [diff] [blame] | 55 | |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 56 | TEST_F(FileManagerTest, TestStats) { |
| 57 | auto manager = base::MakeRefCounted<FileManager>(Dir(), MainTaskRunner()); |
| 58 | auto valid_key = manager->CreateKey(GURL("https://www.chromium.org")); |
| 59 | auto missing_key = manager->CreateKey(GURL("https://www.muimorhc.org")); |
| 60 | base::FilePath out = manager->CreateOrGetDirectory(valid_key, false) |
| 61 | .value_or(base::FilePath()); |
| 62 | EXPECT_FALSE(out.empty()); |
| 63 | EXPECT_TRUE(manager->DirectoryExists(valid_key)); |
| 64 | EXPECT_FALSE(manager->DirectoryExists(missing_key)); |
ckitagawa | ac78736 | 2019-10-01 19:13:47 | [diff] [blame] | 65 | |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 66 | EXPECT_FALSE(manager->GetInfo(missing_key).has_value()); |
| 67 | EXPECT_TRUE(manager->GetInfo(valid_key).has_value()); |
ckitagawa | ac78736 | 2019-10-01 19:13:47 | [diff] [blame] | 68 | |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 69 | base::FilePath file_path = out.AppendASCII("test"); |
| 70 | std::string test_str = "Hello World!"; |
| 71 | EXPECT_EQ(static_cast<int>(test_str.length()), |
| 72 | base::WriteFile(file_path, test_str.data(), test_str.length())); |
| 73 | |
| 74 | EXPECT_EQ(manager->GetSizeOfArtifacts(valid_key), test_str.length()); |
ckitagawa | ac78736 | 2019-10-01 19:13:47 | [diff] [blame] | 75 | } |
| 76 | |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 77 | TEST_F(FileManagerTest, TestCreateOrGetDirectory) { |
| 78 | auto manager = |
| 79 | base::MakeRefCounted<FileManager>(Dir(), SecondaryTaskRunner()); |
ckitagawa | 07b4aa5 | 2019-11-06 23:03:58 | [diff] [blame] | 80 | |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 81 | auto key = manager->CreateKey(1U); |
| 82 | base::RunLoop loop; |
| 83 | manager->GetTaskRunner()->PostTask( |
| 84 | FROM_HERE, |
| 85 | base::BindOnce( |
| 86 | [](base::OnceClosure quit, scoped_refptr<FileManager> manager, |
| 87 | const DirectoryKey& key) { |
| 88 | // Create a new directory. |
| 89 | base::FilePath directory = manager->CreateOrGetDirectory(key, false) |
| 90 | .value_or(base::FilePath()); |
| 91 | EXPECT_FALSE(directory.empty()); |
| 92 | base::FilePath test_file = directory.AppendASCII("test"); |
| 93 | std::string test_str = "Hello World!"; |
| 94 | EXPECT_EQ( |
| 95 | static_cast<int>(test_str.length()), |
| 96 | base::WriteFile(test_file, test_str.data(), test_str.length())); |
ckitagawa | 07b4aa5 | 2019-11-06 23:03:58 | [diff] [blame] | 97 | |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 98 | // Open an existing directory and don't clear. |
| 99 | base::FilePath existing_directory = |
| 100 | manager->CreateOrGetDirectory(key, false) |
| 101 | .value_or(base::FilePath()); |
| 102 | EXPECT_FALSE(directory.empty()); |
| 103 | EXPECT_EQ(existing_directory, directory); |
| 104 | EXPECT_TRUE(base::PathExists(test_file)); |
ckitagawa | 07b4aa5 | 2019-11-06 23:03:58 | [diff] [blame] | 105 | |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 106 | // Open an existing directory and clear. |
| 107 | base::FilePath cleared_existing_directory = |
| 108 | manager->CreateOrGetDirectory(key, true).value_or( |
| 109 | base::FilePath()); |
| 110 | EXPECT_FALSE(directory.empty()); |
| 111 | EXPECT_EQ(cleared_existing_directory, directory); |
| 112 | EXPECT_FALSE(base::PathExists(test_file)); |
| 113 | std::move(quit).Run(); |
| 114 | }, |
| 115 | loop.QuitClosure(), manager, key)); |
| 116 | loop.Run(); |
| 117 | } |
| 118 | |
| 119 | TEST_F(FileManagerTest, TestCompression) { |
| 120 | auto manager = base::MakeRefCounted<FileManager>(Dir(), MainTaskRunner()); |
| 121 | auto key = manager->CreateKey(1U); |
| 122 | base::FilePath directory = |
| 123 | manager->CreateOrGetDirectory(key, false).value_or(base::FilePath()); |
| 124 | EXPECT_FALSE(directory.empty()); |
ckitagawa | 07b4aa5 | 2019-11-06 23:03:58 | [diff] [blame] | 125 | // A file needs to exist for compression to work. |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 126 | base::FilePath test_file = directory.AppendASCII("test"); |
| 127 | std::string test_str = "Hello World!"; |
| 128 | EXPECT_EQ(static_cast<int>(test_str.length()), |
| 129 | base::WriteFile(test_file, test_str.data(), test_str.length())); |
| 130 | EXPECT_TRUE(base::PathExists(test_file)); |
| 131 | base::FilePath test_file_empty = directory.AppendASCII("foo.txt"); |
ckitagawa | 07b4aa5 | 2019-11-06 23:03:58 | [diff] [blame] | 132 | { |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 133 | base::File file(test_file_empty, |
ckitagawa | 07b4aa5 | 2019-11-06 23:03:58 | [diff] [blame] | 134 | base::File::FLAG_CREATE | base::File::FLAG_WRITE); |
| 135 | } |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 136 | EXPECT_TRUE(base::PathExists(test_file_empty)); |
ckitagawa | 07b4aa5 | 2019-11-06 23:03:58 | [diff] [blame] | 137 | |
| 138 | // Compress. |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 139 | base::FilePath zip_path = directory.AddExtensionASCII(".zip"); |
| 140 | EXPECT_TRUE(manager->CompressDirectory(key)); |
| 141 | EXPECT_GT(manager->GetSizeOfArtifacts(key), 0U); |
| 142 | EXPECT_FALSE(base::PathExists(directory)); |
| 143 | EXPECT_FALSE(base::PathExists(test_file)); |
| 144 | EXPECT_FALSE(base::PathExists(test_file_empty)); |
ckitagawa | 07b4aa5 | 2019-11-06 23:03:58 | [diff] [blame] | 145 | EXPECT_TRUE(base::PathExists(zip_path)); |
ckitagawa | 07b4aa5 | 2019-11-06 23:03:58 | [diff] [blame] | 146 | |
| 147 | // Open a compressed file. |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 148 | base::FilePath existing_directory = |
| 149 | manager->CreateOrGetDirectory(key, false).value_or(base::FilePath()); |
| 150 | EXPECT_FALSE(existing_directory.empty()); |
| 151 | EXPECT_EQ(existing_directory, directory); |
| 152 | EXPECT_TRUE(base::PathExists(directory)); |
| 153 | EXPECT_TRUE(base::PathExists(test_file)); |
| 154 | EXPECT_TRUE(base::PathExists(test_file_empty)); |
ckitagawa | 07b4aa5 | 2019-11-06 23:03:58 | [diff] [blame] | 155 | EXPECT_FALSE(base::PathExists(zip_path)); |
| 156 | } |
| 157 | |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 158 | TEST_F(FileManagerTest, TestCompressDirectoryFail) { |
| 159 | auto manager = base::MakeRefCounted<FileManager>(Dir(), MainTaskRunner()); |
| 160 | auto key = manager->CreateKey(GURL("https://www.chromium.org")); |
ckitagawa | 07b4aa5 | 2019-11-06 23:03:58 | [diff] [blame] | 161 | |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 162 | base::FilePath new_directory = |
| 163 | manager->CreateOrGetDirectory(key, true).value_or(base::FilePath()); |
ckitagawa | 07b4aa5 | 2019-11-06 23:03:58 | [diff] [blame] | 164 | EXPECT_FALSE(new_directory.empty()); |
ckitagawa | 07b4aa5 | 2019-11-06 23:03:58 | [diff] [blame] | 165 | |
| 166 | // Compression fails without valid contents. |
| 167 | base::FilePath zip_path = new_directory.AddExtensionASCII(".zip"); |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 168 | EXPECT_FALSE(manager->CompressDirectory(key)); |
ckitagawa | 07b4aa5 | 2019-11-06 23:03:58 | [diff] [blame] | 169 | EXPECT_TRUE(base::PathExists(new_directory)); |
| 170 | EXPECT_FALSE(base::PathExists(zip_path)); |
ckitagawa | ac78736 | 2019-10-01 19:13:47 | [diff] [blame] | 171 | } |
| 172 | |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 173 | TEST_F(FileManagerTest, TestDeleteArtifactsFor) { |
| 174 | auto manager = |
| 175 | base::MakeRefCounted<FileManager>(Dir(), SecondaryTaskRunner()); |
ckitagawa | 07b4aa5 | 2019-11-06 23:03:58 | [diff] [blame] | 176 | |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 177 | manager->GetTaskRunner()->PostTask( |
| 178 | FROM_HERE, |
| 179 | base::BindOnce( |
| 180 | [](scoped_refptr<FileManager> manager) { |
| 181 | auto cr_key = manager->CreateKey(GURL("https://www.chromium.org")); |
| 182 | base::FilePath cr_directory = |
| 183 | manager->CreateOrGetDirectory(cr_key, true) |
| 184 | .value_or(base::FilePath()); |
| 185 | EXPECT_FALSE(cr_directory.empty()); |
ckitagawa | 07b4aa5 | 2019-11-06 23:03:58 | [diff] [blame] | 186 | |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 187 | auto w3_key = manager->CreateKey(GURL("https://www.w3.org")); |
| 188 | base::FilePath w3_directory = |
| 189 | manager->CreateOrGetDirectory(w3_key, true) |
| 190 | .value_or(base::FilePath()); |
| 191 | EXPECT_FALSE(w3_directory.empty()); |
ckitagawa | 07b4aa5 | 2019-11-06 23:03:58 | [diff] [blame] | 192 | |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 193 | manager->DeleteArtifacts(cr_key); |
| 194 | EXPECT_FALSE(base::PathExists(cr_directory)); |
| 195 | EXPECT_TRUE(base::PathExists(w3_directory)); |
ckitagawa | 07b4aa5 | 2019-11-06 23:03:58 | [diff] [blame] | 196 | |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 197 | base::FilePath new_cr_directory = |
| 198 | manager->CreateOrGetDirectory(cr_key, true) |
| 199 | .value_or(base::FilePath()); |
| 200 | EXPECT_EQ(cr_directory, new_cr_directory); |
ckitagawa | 07b4aa5 | 2019-11-06 23:03:58 | [diff] [blame] | 201 | |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 202 | manager->DeleteArtifacts( |
| 203 | std::vector<DirectoryKey>({cr_key, w3_key})); |
| 204 | EXPECT_FALSE(base::PathExists(new_cr_directory)); |
| 205 | EXPECT_FALSE(base::PathExists(w3_directory)); |
| 206 | }, |
| 207 | manager)); |
| 208 | RunUntilIdle(); |
ckitagawa | ac78736 | 2019-10-01 19:13:47 | [diff] [blame] | 209 | } |
| 210 | |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 211 | TEST_F(FileManagerTest, TestDeleteAll) { |
ckitagawa | ac78736 | 2019-10-01 19:13:47 | [diff] [blame] | 212 | base::ScopedTempDir temp_dir; |
| 213 | ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 214 | auto manager = |
| 215 | base::MakeRefCounted<FileManager>(temp_dir.GetPath(), MainTaskRunner()); |
| 216 | |
| 217 | auto cr_key = manager->CreateKey(GURL("https://www.chromium.org")); |
| 218 | base::FilePath cr_directory = |
| 219 | manager->CreateOrGetDirectory(cr_key, true).value_or(base::FilePath()); |
ckitagawa | ac78736 | 2019-10-01 19:13:47 | [diff] [blame] | 220 | EXPECT_FALSE(cr_directory.empty()); |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 221 | |
| 222 | auto w3_key = manager->CreateKey(GURL("https://www.w3.org")); |
| 223 | base::FilePath w3_directory = |
| 224 | manager->CreateOrGetDirectory(w3_key, true).value_or(base::FilePath()); |
ckitagawa | ac78736 | 2019-10-01 19:13:47 | [diff] [blame] | 225 | EXPECT_FALSE(w3_directory.empty()); |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 226 | |
| 227 | manager->DeleteAll(); |
ckitagawa | ac78736 | 2019-10-01 19:13:47 | [diff] [blame] | 228 | EXPECT_FALSE(base::PathExists(cr_directory)); |
| 229 | EXPECT_FALSE(base::PathExists(w3_directory)); |
| 230 | } |
| 231 | |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 232 | TEST_F(FileManagerTest, HandleProto) { |
ckitagawa | 353e3b3 | 2020-02-27 16:15:56 | [diff] [blame] | 233 | base::ScopedTempDir temp_dir; |
| 234 | ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 235 | auto manager = |
| 236 | base::MakeRefCounted<FileManager>(temp_dir.GetPath(), MainTaskRunner()); |
| 237 | auto key = manager->CreateKey(1U); |
| 238 | base::FilePath path = |
| 239 | manager->CreateOrGetDirectory(key, true).value_or(base::FilePath()); |
| 240 | EXPECT_FALSE(path.empty()); |
ckitagawa | 353e3b3 | 2020-02-27 16:15:56 | [diff] [blame] | 241 | |
| 242 | PaintPreviewProto original_proto; |
| 243 | auto* root_frame = original_proto.mutable_root_frame(); |
| 244 | root_frame->set_embedding_token_low(0); |
| 245 | root_frame->set_embedding_token_high(0); |
| 246 | root_frame->set_is_main_frame(true); |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 247 | root_frame->set_file_path("0.skp"); |
ckitagawa | 353e3b3 | 2020-02-27 16:15:56 | [diff] [blame] | 248 | auto* metadata = original_proto.mutable_metadata(); |
| 249 | metadata->set_url(GURL("www.chromium.org").spec()); |
| 250 | |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 251 | EXPECT_TRUE(manager->SerializePaintPreviewProto(key, original_proto, false)); |
ckitagawa | 353e3b3 | 2020-02-27 16:15:56 | [diff] [blame] | 252 | EXPECT_TRUE(base::PathExists(path.AppendASCII("proto.pb"))); |
ckitagawa | 5c880614 | 2020-03-06 16:12:01 | [diff] [blame^] | 253 | auto out_proto = manager->DeserializePaintPreviewProto(key); |
| 254 | EXPECT_NE(out_proto, nullptr); |
| 255 | EXPECT_THAT(*out_proto, EqualsProto(original_proto)); |
| 256 | } |
| 257 | |
| 258 | TEST_F(FileManagerTest, HandleProtoCompressed) { |
| 259 | base::ScopedTempDir temp_dir; |
| 260 | ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 261 | auto manager = |
| 262 | base::MakeRefCounted<FileManager>(temp_dir.GetPath(), MainTaskRunner()); |
| 263 | auto key = manager->CreateKey(1U); |
| 264 | base::FilePath path = |
| 265 | manager->CreateOrGetDirectory(key, true).value_or(base::FilePath()); |
| 266 | EXPECT_FALSE(path.empty()); |
| 267 | |
| 268 | PaintPreviewProto original_proto; |
| 269 | auto* root_frame = original_proto.mutable_root_frame(); |
| 270 | root_frame->set_embedding_token_low(0); |
| 271 | root_frame->set_embedding_token_high(0); |
| 272 | root_frame->set_is_main_frame(true); |
| 273 | root_frame->set_file_path("0.skp"); |
| 274 | auto* metadata = original_proto.mutable_metadata(); |
| 275 | metadata->set_url(GURL("www.chromium.org").spec()); |
| 276 | |
| 277 | EXPECT_TRUE(manager->SerializePaintPreviewProto(key, original_proto, true)); |
| 278 | EXPECT_TRUE(base::PathExists(path.AddExtensionASCII(".zip"))); |
| 279 | auto out_proto = manager->DeserializePaintPreviewProto(key); |
| 280 | EXPECT_NE(out_proto, nullptr); |
| 281 | EXPECT_THAT(*out_proto, EqualsProto(original_proto)); |
ckitagawa | 353e3b3 | 2020-02-27 16:15:56 | [diff] [blame] | 282 | } |
| 283 | |
ckitagawa | ac78736 | 2019-10-01 19:13:47 | [diff] [blame] | 284 | } // namespace paint_preview |