File: profile_browsertest_android.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (147 lines) | stat: -rw-r--r-- 5,334 bytes parent folder | download | duplicates (7)
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
143
144
145
146
147
// Copyright 2012 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/profiles/profile.h"

#include <stddef.h>

#include <memory>

#include "base/check_op.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_path_watcher.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/run_loop.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/thread_pool.h"
#include "chrome/browser/ui/android/tab_model/tab_model.h"
#include "chrome/browser/ui/android/tab_model/tab_model_list.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/test/base/android/android_browser_test.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

class ProfileDeleteMediaBrowserTest : public AndroidBrowserTest {
 protected:
  void SetUp() override {
    // This needs to happen before AndroidBrowserTest::SetUp(), since that
    // invokes deletion. Luckily on Android chrome::GetUserCacheDirectory()
    // doesn't actually look at its input. (This would be cleaner as a PRE_
    // test, but that doesn't appear to be supported here).
    chrome::GetUserCacheDirectory(base::FilePath(), &cache_base_);
    base::FilePath media_cache_path =
        cache_base_.Append(chrome::kMediaCacheDirname);

    base::ScopedAllowBlockingForTesting allow_blocking;
    EXPECT_TRUE(base::CreateDirectory(media_cache_path));
    std::string data = "foo";
    base::WriteFile(media_cache_path.AppendASCII("foo"), data);

    AndroidBrowserTest::SetUp();
  }

  base::FilePath cache_base_;
};

namespace {

// Watches for the destruction of the specified path (Which, in the tests that
// use it, is typically a directory), and expects the parent directory not to be
// deleted.
//
// The public methods are called on the UI thread, the private ones called on a
// separate SequencedTaskRunner.
class FileDestructionWatcher {
 public:
  explicit FileDestructionWatcher(const base::FilePath& watched_file_path)
      : watched_file_path_(watched_file_path) {
    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  }

  FileDestructionWatcher(const FileDestructionWatcher&) = delete;
  FileDestructionWatcher& operator=(const FileDestructionWatcher&) = delete;

  void WaitForDestruction() {
    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
    DCHECK(!watcher_);
    base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()})
        ->PostTask(FROM_HERE,
                   base::BindOnce(&FileDestructionWatcher::StartWatchingPath,
                                  base::Unretained(this)));
    run_loop_.Run();
    // The watcher should be destroyed before quitting the run loop, once the
    // file has been destroyed.
    DCHECK(!watcher_);

    // Double check that the file was destroyed, and that the parent directory
    // was not.
    base::ScopedAllowBlockingForTesting allow_blocking;
    EXPECT_FALSE(base::PathExists(watched_file_path_));
    EXPECT_TRUE(base::PathExists(watched_file_path_.DirName()));
  }

 private:
  void StartWatchingPath() {
    DCHECK(!watcher_);
    watcher_ = std::make_unique<base::FilePathWatcher>();
    // Start watching before checking if the file exists, as the file could be
    // destroyed between the existence check and when we start watching, if the
    // order were reversed.
    EXPECT_TRUE(watcher_->Watch(
        watched_file_path_, base::FilePathWatcher::Type::kNonRecursive,
        base::BindRepeating(&FileDestructionWatcher::OnPathChanged,
                            base::Unretained(this))));
    CheckIfPathExists();
  }

  void OnPathChanged(const base::FilePath& path, bool error) {
    EXPECT_EQ(watched_file_path_, path);
    EXPECT_FALSE(error);
    CheckIfPathExists();
  }

  // Checks if the path exists, and if so, destroys the watcher and quits
  // |run_loop_|.
  void CheckIfPathExists() {
    if (!base::PathExists(watched_file_path_)) {
      watcher_.reset();
      run_loop_.Quit();
      return;
    }
  }

  base::RunLoop run_loop_;
  const base::FilePath watched_file_path_;

  // Created and destroyed off of the UI thread, on the sequence used to watch
  // for changes.
  std::unique_ptr<base::FilePathWatcher> watcher_;
};

}  // namespace

IN_PROC_BROWSER_TEST_F(ProfileDeleteMediaBrowserTest, DeleteMediaCache) {
  // Make sure the legacy media cache directory (created in SetUp) gets deleted
  // properly.
  base::FilePath cache_base;
  chrome::GetUserCacheDirectory(
      TabModelList::models()[0]->GetProfile()->GetPath(), &cache_base);

  // |cache_base_| computation in SetUp() makes assumptions on implementation
  // details to be able to run that early, so verify its result is sane.
  EXPECT_EQ(cache_base, cache_base_);
  base::FilePath media_cache_path =
      cache_base.Append(chrome::kMediaCacheDirname);

  base::ScopedAllowBlockingForTesting allow_blocking;
  FileDestructionWatcher destruction_watcher(media_cache_path);
  destruction_watcher.WaitForDestruction();
}