File: fallback_copy_in_foreign_file_unittest.cc

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (142 lines) | stat: -rw-r--r-- 5,492 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ash/fileapi/fallback_copy_in_foreign_file.h"

#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/strings/strcat.h"
#include "base/test/task_environment.h"
#include "base/test/test_future.h"
#include "storage/browser/file_system/external_mount_points.h"
#include "storage/browser/file_system/file_system_operation_runner.h"
#include "storage/browser/test/mock_quota_manager.h"
#include "storage/browser/test/mock_quota_manager_proxy.h"
#include "storage/browser/test/mock_special_storage_policy.h"
#include "storage/browser/test/test_file_system_context.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/cleanup/cleanup.h"

namespace ash {

class FallbackCopyInForeignFileTest : public testing::Test,
                                      public testing::WithParamInterface<bool> {
 public:
  static int CountFilesInDirectory(const base::FilePath& dir_path) {
    int count = 0;
    static constexpr bool recursive = false;
    base::FileEnumerator e(dir_path, recursive, base::FileEnumerator::FILES);
    while (!e.Next().empty()) {
      count++;
    }
    return count;
  }

  bool dest_file_already_exists() const { return GetParam(); }

  static std::string DescribeParams(
      const testing::TestParamInfo<ParamType>& info) {
    return info.param ? "DestFileAlreadyExists" : "DestFileDoesNotExist";
  }

 protected:
  void SetUp() override {
    ASSERT_TRUE(fs_context_temp_dir_.CreateUniqueTempDir());

    static constexpr bool is_incognito = false;
    scoped_refptr<storage::MockQuotaManager> quota_manager =
        base::MakeRefCounted<storage::MockQuotaManager>(
            is_incognito, fs_context_temp_dir_.GetPath(),
            base::SingleThreadTaskRunner::GetCurrentDefault(),
            base::MakeRefCounted<storage::MockSpecialStoragePolicy>());

    scoped_refptr<storage::MockQuotaManagerProxy> quota_manager_proxy =
        base::MakeRefCounted<storage::MockQuotaManagerProxy>(
            quota_manager.get(),
            base::SingleThreadTaskRunner::GetCurrentDefault());

    fs_context_ = CreateFileSystemContextForTesting(
        quota_manager_proxy, fs_context_temp_dir_.GetPath());
    ASSERT_NE(fs_context_.get(), nullptr);
  }

  base::test::TaskEnvironment task_environment_;

  base::ScopedTempDir fs_context_temp_dir_;
  scoped_refptr<storage::FileSystemContext> fs_context_;
};

TEST_P(FallbackCopyInForeignFileTest, Basic) {
  // Create a source temporary directory and a poem file within it.
  base::ScopedTempDir src_temp_dir;
  ASSERT_TRUE(src_temp_dir.CreateUniqueTempDir());
  base::FilePath src_file_path =
      src_temp_dir.GetPath().Append(FILE_PATH_LITERAL("src_poem.txt"));
  std::string poem("The frumious Bandersnatch!\n");
  ASSERT_TRUE(base::WriteFile(src_file_path, poem));

  // Create a destination temporary directory. If dest_file_already_exists()
  // then also create an existing file in that dest_temp_dir. It should be
  // overwritten (by being renamed and then deleted) by
  // FallbackCopyInForeignFile.
  base::ScopedTempDir dest_temp_dir;
  ASSERT_TRUE(dest_temp_dir.CreateUniqueTempDir());
  base::FilePath dest_file_path =
      dest_temp_dir.GetPath().Append(FILE_PATH_LITERAL("dest_poem.txt"));
  if (dest_file_already_exists()) {
    std::string occupied("The dest_file_path already exists.\n");
    ASSERT_TRUE(base::WriteFile(dest_file_path, occupied));
    ASSERT_EQ(CountFilesInDirectory(dest_temp_dir.GetPath()), 1);
  } else {
    ASSERT_EQ(CountFilesInDirectory(dest_temp_dir.GetPath()), 0);
  }

  // Register the mount point (and unregister at end-of-scope).
  static constexpr char mount_name[] = "FallbackCopyInForeignFileTest.Basic";
  EXPECT_TRUE(
      storage::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
          mount_name, storage::kFileSystemTypeLocal,
          storage::FileSystemMountOption(), dest_temp_dir.GetPath()));
  absl::Cleanup mount_points_unregisterer = [] {
    EXPECT_TRUE(
        storage::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
            mount_name));
  };

  // Call FallbackCopyInForeignFile.
  {
    storage::FileSystemURL dest_url = fs_context_->CrackURLInFirstPartyContext(
        GURL(base::StrCat({"filesystem:https://example.com/external/",
                           mount_name, "/dest_poem.txt"})));

    base::test::TestFuture<base::File::Error> future;

    FallbackCopyInForeignFile(
        *fs_context_->GetAsyncFileUtil(dest_url.type()),
        std::make_unique<storage::FileSystemOperationContext>(
            fs_context_.get()),
        src_file_path, dest_url, future.GetCallback());

    EXPECT_EQ(future.Get(), base::File::FILE_OK);
  }

  // Check the destination file's contents.
  {
    std::string dest_contents;
    base::ReadFileToString(dest_file_path, &dest_contents);
    EXPECT_EQ(poem, dest_contents);
  }

  // The destination temporary directory should contain exactly one file,
  // regardless of dest_file_already_exists().
  ASSERT_EQ(CountFilesInDirectory(dest_temp_dir.GetPath()), 1);
}

INSTANTIATE_TEST_SUITE_P(,
                         FallbackCopyInForeignFileTest,
                         testing::Bool(),
                         &FallbackCopyInForeignFileTest::DescribeParams);

}  // namespace ash