Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(320)

Side by Side Diff: chrome/browser/extensions/extension_storage_monitor_browsertest.cc

Issue 221933013: Show a notification when an ephemeral app consumes excessive disk space (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@webkit_storage_monitor
Patch Set: Addressed review comments Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 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 <set>
6
7 #include "base/run_loop.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "chrome/browser/extensions/extension_browsertest.h"
10 #include "chrome/browser/extensions/extension_storage_monitor.h"
11 #include "chrome/browser/extensions/extension_test_message_listener.h"
12 #include "chrome/browser/ui/extensions/application_launch.h"
13 #include "content/public/test/test_utils.h"
14 #include "extensions/browser/extension_prefs.h"
15 #include "ui/message_center/message_center.h"
16 #include "ui/message_center/message_center_observer.h"
17
18 namespace extensions {
19
20 namespace {
21
22 const int kInitialUsageThreshold = 500;
23
24 const char kWriteDataApp[] = "storage_monitor/write_data";
25
26 class NotificationObserver : public message_center::MessageCenterObserver {
27 public:
28 explicit NotificationObserver(const std::string& target_notification)
29 : message_center_(message_center::MessageCenter::Get()),
30 target_notification_id_(target_notification),
31 waiting_(false) {
32 message_center_->AddObserver(this);
33 }
34
35 virtual ~NotificationObserver() {
36 message_center_->RemoveObserver(this);
37 }
38
39 bool HasReceivedNotification() const {
40 return received_notifications_.find(target_notification_id_) !=
41 received_notifications_.end();
42 }
43
44 // Runs the message loop and returns true if a notification is received.
45 // Immediately returns true if a notification has already been received.
46 bool WaitForNotification() {
47 if (HasReceivedNotification())
48 return true;
49
50 waiting_ = true;
51 content::RunMessageLoop();
52 waiting_ = false;
53 return HasReceivedNotification();
54 }
55
56 private:
57 // MessageCenterObserver implementation:
58 virtual void OnNotificationAdded(
59 const std::string& notification_id) OVERRIDE {
60 received_notifications_.insert(notification_id);
61
62 if (waiting_ && HasReceivedNotification())
63 base::MessageLoopForUI::current()->Quit();
64 }
65
66 message_center::MessageCenter* message_center_;
67 std::set<std::string> received_notifications_;
68 std::string target_notification_id_;
69 bool waiting_;
70 };
71
72 } // namespace
73
74 class ExtensionStorageMonitorTest : public ExtensionBrowserTest {
75 protected:
76 void InitStorageMonitor() {
77 ExtensionStorageMonitor* monitor = ExtensionStorageMonitor::Get(profile());
78 ASSERT_TRUE(monitor);
79
80 // Override thresholds so that we don't have to write a huge amount of data
81 // to trigger notifications in these tests.
82 monitor->enable_for_all_extensions_ = true;
83 monitor->initial_extension_threshold_ = kInitialUsageThreshold;
84
85 // To ensure storage events are dispatched from QuotaManager immediately.
86 monitor->observer_rate_ = 0;
87 }
88
89 const Extension* InitWriteDataApp() {
90 InitStorageMonitor();
91
92 base::FilePath path = test_data_dir_.AppendASCII(kWriteDataApp);
93 const Extension* extension = InstallExtension(path, 1);
94 EXPECT_TRUE(extension);
95 return extension;
96 }
97
98 std::string GetNotificationId(const std::string& extension_id) {
99 return ExtensionStorageMonitor::Get(profile())->
100 GetNotificationId(extension_id);
101 }
102
103 void WriteBytesExpectingNotification(const Extension* extension,
104 int num_bytes) {
105 WriteBytes(extension, num_bytes, true);
106 }
107
108 void WriteBytesNotExpectingNotification(const Extension* extension,
109 int num_bytes) {
110 WriteBytes(extension, num_bytes, false);
111 }
112
113 private:
114 // Write a number of bytes to persistent storage.
115 void WriteBytes(const Extension* extension,
116 int num_bytes,
117 bool expected_notification) {
118 ExtensionTestMessageListener launched_listener("launched", true);
119 ExtensionTestMessageListener write_complete_listener(
120 "write_complete", false);
121 NotificationObserver notification_observer(
122 GetNotificationId(extension->id()));
123
124 OpenApplication(AppLaunchParams(
125 profile(), extension, LAUNCH_CONTAINER_NONE, NEW_WINDOW));
126 ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
127
128 // Instruct the app to write |num_bytes| of data.
129 launched_listener.Reply(base::IntToString(num_bytes));
130 ASSERT_TRUE(write_complete_listener.WaitUntilSatisfied());
131
132 if (expected_notification) {
133 EXPECT_TRUE(notification_observer.WaitForNotification());
134 } else {
135 base::RunLoop().RunUntilIdle();
136 EXPECT_FALSE(notification_observer.HasReceivedNotification());
137 }
138 }
139 };
140
141 // Control - No notifications should be shown if usage remains under the
142 // threshold.
143 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, UnderThreshold) {
144 const Extension* extension = InitWriteDataApp();
145 ASSERT_TRUE(extension);
146 WriteBytesNotExpectingNotification(extension, 1);
147 }
148
149 // Ensure a notification is shown when usage reaches the first threshold.
150 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, ExceedInitialThreshold) {
151 const Extension* extension = InitWriteDataApp();
152 ASSERT_TRUE(extension);
153 WriteBytesExpectingNotification(extension, kInitialUsageThreshold);
154 }
155
156 // Ensure a notification is shown when usage immediately exceeds double the
157 // first threshold.
158 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, DoubleInitialThreshold) {
159 const Extension* extension = InitWriteDataApp();
160 ASSERT_TRUE(extension);
161 WriteBytesExpectingNotification(extension, kInitialUsageThreshold*2);
162 }
163
164 // Ensure that notifications are not fired if the next threshold has not been
165 // reached.
166 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, ThrottleNotifications) {
167 const Extension* extension = InitWriteDataApp();
168 ASSERT_TRUE(extension);
169
170 // Exceed the first threshold.
171 WriteBytesExpectingNotification(extension, kInitialUsageThreshold);
172
173 // Stay within the next threshold.
174 WriteBytesNotExpectingNotification(extension, 1);
175 }
176
177 // Verify that notifications are disabled when the user clicks the action button
178 // in the notification.
179 IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, UserDisabledNotifications) {
180 const Extension* extension = InitWriteDataApp();
181 ASSERT_TRUE(extension);
182 WriteBytesExpectingNotification(extension, kInitialUsageThreshold);
183
184 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
185 ASSERT_TRUE(prefs);
186 EXPECT_TRUE(prefs->IsStorageNotificationEnabled(extension->id()));
187
188 // Fake clicking the notification button.
189 message_center::MessageCenter::Get()->ClickOnNotificationButton(
190 GetNotificationId(extension->id()),
191 ExtensionStorageMonitor::BUTTON_DISABLE_NOTIFICATION);
192
193 EXPECT_FALSE(prefs->IsStorageNotificationEnabled(extension->id()));
194
195 // Expect to receive no further notifications when usage continues to
196 // increase.
197 int64 next_threshold = prefs->GetNextStorageThreshold(extension->id());
198 int64 next_data_size = next_threshold - kInitialUsageThreshold;
199 ASSERT_GE(next_data_size, 0);
200
201 WriteBytesNotExpectingNotification(extension, next_data_size);
202 }
203
204 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698