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

Side by Side Diff: chrome/browser/background_application_list_model_unittest.cc

Issue 6525056: Add unit tests for BackgroundApplicationListModel (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Tweaking whitespace and comments. Assigned bug number for TODO. Created 9 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/background_application_list_model.h ('k') | chrome/chrome_tests.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 // TODO(rickcam): Bug 73183: Add unit tests for image loading
6
7 #include <algorithm>
8 #include <cstdlib>
9 #include <map>
10 #include <set>
11 #include <vector>
12
13 #include "chrome/browser/background_application_list_model.h"
14
15 #include "base/command_line.h"
16 #include "base/file_path.h"
17 #include "base/file_util.h"
18 #include "base/message_loop.h"
19 #include "base/scoped_ptr.h"
20 #include "base/stl_util-inl.h"
21 #include "chrome/browser/browser_thread.h"
22 #include "chrome/browser/extensions/extension_service.h"
23 #include "chrome/common/extensions/extension.h"
24 #include "chrome/common/notification_registrar.h"
25 #include "chrome/common/notification_service.h"
26 #include "chrome/common/notification_type.h"
27 #include "chrome/test/testing_profile.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29
30 // This value is used to seed the PRNG at the beginning of a sequence of
31 // operations to produce a repeatable sequence.
32 #define RANDOM_SEED (0x33F7A7A7)
33
34 // For ExtensionService interface when it requires a path that is not used.
35 FilePath bogus_file_path() {
36 #if defined(OS_WIN)
37 return FilePath(FILE_PATH_LITERAL("c:\\foo"));
Andrew T Wilson (Slow) 2011/02/16 18:45:46 To avoid having platform-dependent code here, can
The wrong rickcam account 2011/02/16 22:39:20 It must be absolute to avoid "Check failed: path.I
38 #elif defined(OS_POSIX)
39 return FilePath(FILE_PATH_LITERAL("/foo"));
40 #endif
41 }
42
43 class BackgroundApplicationListModelTest : public testing::Test {
44 public:
45 BackgroundApplicationListModelTest();
46 ~BackgroundApplicationListModelTest();
47
48 virtual void InitializeEmptyExtensionService();
49
50 protected:
51 scoped_ptr<Profile> profile_;
52 scoped_refptr<ExtensionService> service_;
53 MessageLoop loop_;
54 BrowserThread ui_thread_;
55 };
56
57 // The message loop may be used in tests which require it to be an IO loop.
58 BackgroundApplicationListModelTest::BackgroundApplicationListModelTest()
59 : loop_(MessageLoop::TYPE_IO),
60 ui_thread_(BrowserThread::UI, &loop_) {
61 }
62
63 BackgroundApplicationListModelTest::~BackgroundApplicationListModelTest() {
64 // Drop reference to ExtensionService and TestingProfile, so that they can be
65 // destroyed while BrowserThreads and MessageLoop are still around. They
66 // are used in the destruction process.
67 service_ = NULL;
68 profile_.reset(NULL);
69 MessageLoop::current()->RunAllPending();
70 }
71
72 // This is modeled on a similar routine in ExtensionServiceTestBase.
73 void BackgroundApplicationListModelTest::InitializeEmptyExtensionService() {
74 TestingProfile* profile = new TestingProfile();
75 profile_.reset(profile);
76 service_ = profile->CreateExtensionService(
77 CommandLine::ForCurrentProcess(),
78 bogus_file_path());
79 service_->set_extensions_enabled(true);
80 service_->set_show_extensions_prompts(false);
81 service_->OnLoadedInstalledExtensions(); /* Sends EXTENSIONS_READY */
82 }
83
84 // Returns a barebones test Extension object with the specified |name|. The
85 // returned extension will include background permission iff
86 // |background_permission| is true.
87 static scoped_refptr<Extension> CreateExtension(const std::string& name,
88 bool background_permission) {
89 DictionaryValue manifest;
90 manifest.SetString(extension_manifest_keys::kVersion, "1.0.0.0");
91 manifest.SetString(extension_manifest_keys::kName, name);
92 if (background_permission) {
93 ListValue* permissions = new ListValue();
94 manifest.Set(extension_manifest_keys::kPermissions, permissions);
95 permissions->Append(Value::CreateStringValue("background"));
96 }
97 std::string error;
98 scoped_refptr<Extension> extension = Extension::Create(
99 bogus_file_path().AppendASCII(name), Extension::INVALID, manifest, false,
100 &error);
101 EXPECT_TRUE(extension) << error;
Andrew T Wilson (Slow) 2011/02/16 18:45:46 Use an ASSERT here rather than EXPECT since you wa
The wrong rickcam account 2011/02/16 22:39:20 As discussed with you, I'm going to leave the code
102 return extension;
103 }
104
105 // With minimal test logic, verifies behavior over an explicit set of
106 // extensions, of which some are Background Apps and others are not.
107 TEST_F(BackgroundApplicationListModelTest, LoadExplicitExtensions) {
108 InitializeEmptyExtensionService();
109 ExtensionService* service = profile_->GetExtensionService();
110 ASSERT_TRUE(service);
111 ASSERT_TRUE(service->is_ready());
112 ASSERT_TRUE(service->extensions());
113 ASSERT_TRUE(service->extensions()->empty());
114 scoped_ptr<BackgroundApplicationListModel> model(
115 new BackgroundApplicationListModel(profile_.get()));
116 ASSERT_FALSE(model->size());
Andrew T Wilson (Slow) 2011/02/16 18:45:46 It's more readable and generates better error outp
The wrong rickcam account 2011/02/16 22:39:20 Done, but with 0U as size() returns an unsigned in
117
118 scoped_refptr<Extension> ext1 = CreateExtension("alpha", false);
119 scoped_refptr<Extension> ext2 = CreateExtension("bravo", false);
120 scoped_refptr<Extension> ext3 = CreateExtension("charlie", false);
121 scoped_refptr<Extension> bgapp1 = CreateExtension("delta", true);
122 scoped_refptr<Extension> bgapp2 = CreateExtension("echo", true);
123 ASSERT_TRUE(service->extensions());
124 ASSERT_FALSE(service->extensions()->size());
125 ASSERT_TRUE(model->size() == 0);
Andrew T Wilson (Slow) 2011/02/16 18:45:46 Use ASSERT_EQ here and elsewhere in the routine wh
The wrong rickcam account 2011/02/16 22:39:20 Done.
126 // Add alternating Extensions and Background Apps
127 ASSERT_FALSE(BackgroundApplicationListModel::IsBackgroundApp(*ext1));
128 service->AddExtension(ext1);
129 ASSERT_TRUE(service->extensions()->size() == 1);
130 ASSERT_TRUE(model->size() == 0);
131 ASSERT_TRUE(BackgroundApplicationListModel::IsBackgroundApp(*bgapp1));
132 service->AddExtension(bgapp1);
133 ASSERT_TRUE(service->extensions()->size() == 2);
134 ASSERT_TRUE(model->size() == 1);
135 ASSERT_FALSE(BackgroundApplicationListModel::IsBackgroundApp(*ext2));
136 service->AddExtension(ext2);
137 ASSERT_TRUE(service->extensions()->size() == 3);
138 ASSERT_TRUE(model->size() == 1);
139 ASSERT_TRUE(BackgroundApplicationListModel::IsBackgroundApp(*bgapp2));
140 service->AddExtension(bgapp2);
141 ASSERT_TRUE(service->extensions()->size() == 4);
142 ASSERT_TRUE(model->size() == 2);
143 ASSERT_FALSE(BackgroundApplicationListModel::IsBackgroundApp(*ext3));
144 service->AddExtension(ext3);
145 ASSERT_TRUE(service->extensions()->size() == 5);
146 ASSERT_TRUE(model->size() == 2);
147 // Remove in FIFO order.
148 ASSERT_FALSE(BackgroundApplicationListModel::IsBackgroundApp(*ext1));
149 service->UninstallExtension(ext1->id(), false);
150 ASSERT_TRUE(service->extensions()->size() == 4);
151 ASSERT_TRUE(model->size() == 2);
152 ASSERT_TRUE(BackgroundApplicationListModel::IsBackgroundApp(*bgapp1));
153 service->UninstallExtension(bgapp1->id(), false);
154 ASSERT_TRUE(service->extensions()->size() == 3);
155 ASSERT_TRUE(model->size() == 1);
156 ASSERT_FALSE(BackgroundApplicationListModel::IsBackgroundApp(*ext2));
157 service->UninstallExtension(ext2->id(), false);
158 ASSERT_TRUE(service->extensions()->size() == 2);
159 ASSERT_TRUE(model->size() == 1);
160 ASSERT_TRUE(BackgroundApplicationListModel::IsBackgroundApp(*bgapp2));
161 service->UninstallExtension(bgapp2->id(), false);
162 ASSERT_TRUE(service->extensions()->size() == 1);
163 ASSERT_TRUE(model->size() == 0);
164 ASSERT_FALSE(BackgroundApplicationListModel::IsBackgroundApp(*ext3));
165 service->UninstallExtension(ext3->id(), false);
166 ASSERT_TRUE(service->extensions()->size() == 0);
167 ASSERT_TRUE(model->size() == 0);
168 }
169
170 typedef std::map<std::string,scoped_refptr<Extension> > ExtensionTable;
Andrew T Wilson (Slow) 2011/02/16 18:45:46 Do you really need a map here? I don't think you a
The wrong rickcam account 2011/02/16 22:39:20 Done.
171
172 namespace {
173 std::string
174 GenerateRandomExtensionName() {
Andrew T Wilson (Slow) 2011/02/16 18:45:46 put return type and function name on same line.
The wrong rickcam account 2011/02/16 22:39:20 Done. FWIW, this is leftover from previous style
175 static const char VALID[] = "ABCDEFGHIHJKMNOPabcdefghihjkmnop0123456789 ";
Andrew T Wilson (Slow) 2011/02/16 18:45:46 Should you put some non-ascii chars in here (unico
The wrong rickcam account 2011/02/16 22:39:20 No, but I need to change this! Your question made
176 static const unsigned int VALID_COUNT = sizeof(VALID) - 1;
177 static const unsigned int MINIMUM_NAME_LENGTH = 10;
178 static const unsigned int MAXIMUM_NAME_LENGTH = 30;
179
180 unsigned int length = MINIMUM_NAME_LENGTH +
181 random() % (MAXIMUM_NAME_LENGTH - MINIMUM_NAME_LENGTH);
182 char* characters = new char[length];
183 for (unsigned int index = 0; index < length; ++index)
184 characters[index] = VALID[random() % VALID_COUNT];
185 return std::string(characters, length);
186 }
187 }
188
189 // Verifies behavior with a pseudo-randomly generated set of actions: Adding and
190 // removing extensions, of which some are Background Apps and others are not.
191 TEST_F(BackgroundApplicationListModelTest, LoadRandomExtension) {
192 InitializeEmptyExtensionService();
193 ExtensionService* service = profile_->GetExtensionService();
194 ASSERT_TRUE(service);
195 ASSERT_TRUE(service->is_ready());
196 ASSERT_TRUE(service->extensions());
197 ASSERT_TRUE(service->extensions()->empty());
198 scoped_ptr<BackgroundApplicationListModel> model(
199 new BackgroundApplicationListModel(profile_.get()));
200 ASSERT_FALSE(model->size());
201
202 static const unsigned int iterations = 500;
Andrew T Wilson (Slow) 2011/02/16 18:45:46 nit: I think the style for contstants is of the fo
The wrong rickcam account 2011/02/16 22:39:20 Done.
203 ExtensionTable extensions;
204 unsigned int count = 0;
205 unsigned int expected = 0;
206 srandom(RANDOM_SEED);
207 for (unsigned int index = 0; index < iterations; ++index) {
208 // Randomly select: Add Extension (25%), Add Bg App (25%), Remove (50%)
209 switch (random() % 4) {
210 case 0: {
211 // Add a non-Background-App extension
212 std::string name = GenerateRandomExtensionName();
213 scoped_refptr<Extension> extension = CreateExtension(name, false);
214 ASSERT_FALSE(
215 BackgroundApplicationListModel::IsBackgroundApp(*extension));
216 std::string id = extension->id();
217 extensions[id] = extension;
218 ++count;
219 ASSERT_TRUE(extensions.size() == count);
220 service->AddExtension(extension);
221 ASSERT_TRUE(service->extensions()->size() == count);
222 ASSERT_TRUE(model->size() == expected);
223 break;
224 }
225 case 1: {
226 // Add a Background App
227 std::string name = GenerateRandomExtensionName();
228 scoped_refptr<Extension> extension = CreateExtension(name, true);
229 ASSERT_TRUE(
230 BackgroundApplicationListModel::IsBackgroundApp(*extension));
231 std::string id = extension->id();
232 extensions[id] = extension;
233 ++expected;
234 ++count;
235 ASSERT_TRUE(extensions.size() == count);
236 service->AddExtension(extension);
237 ASSERT_TRUE(service->extensions()->size() == count);
Andrew T Wilson (Slow) 2011/02/16 18:45:46 I suspect you could combine case 0: and case 1: an
The wrong rickcam account 2011/02/16 22:39:20 It got a little funkier than that, but I've redone
238 ASSERT_TRUE(model->size() == expected);
239 break;
240 }
241 case 2: // Intentional fall through
242 case 3: {
243 // Maybe remove an extension.
244 ExtensionTable::iterator cursor = extensions.begin();
245 if (cursor == extensions.end()) {
246 // Nothing to remove. Just verify accounting.
247 ASSERT_TRUE(count == 0);
248 ASSERT_TRUE(expected == 0);
249 ASSERT_TRUE(service->extensions()->size() == 0);
250 ASSERT_TRUE(model->size() == 0);
251 } else {
252 // Randomly select an extension
253 if (extensions.size() > 1) {
254 unsigned int offset = random() % (extensions.size() - 1);
255 for (unsigned int index = 0; index < offset; ++index)
256 ++cursor;
257 }
258 scoped_refptr<Extension> extension = cursor->second.get();
259 std::string id = extension->id();
260 if (BackgroundApplicationListModel::IsBackgroundApp(*extension))
261 --expected;
262 extensions.erase(cursor);
263 --count;
264 ASSERT_TRUE(extensions.size() == count);
265 service->UninstallExtension(extension->id(), false);
266 ASSERT_TRUE(service->extensions()->size() == count);
267 ASSERT_TRUE(model->size() == expected);
268 }
269 break;
270 }
271 default:
272 NOTREACHED();
273 break;
274 }
275 }
276 }
OLDNEW
« no previous file with comments | « chrome/browser/background_application_list_model.h ('k') | chrome/chrome_tests.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698