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

Side by Side Diff: chrome/browser/conflicts/module_database_win_unittest.cc

Issue 2576843002: [win] Create ModuleDatabase and ModuleEventSinkImpl. (Closed)
Patch Set: Rework OnProcessStarted. Created 4 years 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 2016 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 "chrome/browser/conflicts/module_database_win.h"
6
7 #include <algorithm>
8
9 #include "base/bind.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/threading/simple_thread.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace {
17
18 // A simple mechanism for running a single task on a separate thread.
19 class SingleTaskRunner : public base::SimpleThread {
20 public:
21 explicit SingleTaskRunner(const base::Closure& task)
22 : base::SimpleThread("SingleTaskRunner"), task_(task) {}
23
24 // Runs the provided task and exits.
25 void Run() override { task_.Run(); }
26
27 private:
28 base::Closure task_;
29 DISALLOW_COPY_AND_ASSIGN(SingleTaskRunner);
30 };
31
32 // Launches a thread and runs a single task on it.
33 void RunTask(const base::Closure& task) {
34 SingleTaskRunner task_runner(task);
35 task_runner.Start();
36 task_runner.Join();
37 }
38
39 const uint32_t kPid1 = 1234u;
40 const uint32_t kPid2 = 2345u;
41
42 const wchar_t kDll1[] = L"dummy.dll";
43 const wchar_t kDll2[] = L"foo.dll";
44
45 const size_t kSize1 = 100 * 4096;
46 const size_t kSize2 = 20 * 4096;
47
48 void* kGoodAddress1 = reinterpret_cast<void*>(0x04000000u);
49 void* kGoodAddress2 = reinterpret_cast<void*>(0x05000000u);
50
51 } // namespace
52
53 class TestModuleDatabase : ModuleDatabase {
54 public:
55 // Types.
56 using ModuleDatabase::ModuleId;
57 using ModuleDatabase::ModuleLoadAddresses;
58
59 // Constants.
60 using ModuleDatabase::kInvalidIndex;
61
62 // Functions.
63 using ModuleDatabase::FindLoadAddressIndexById;
64 using ModuleDatabase::FindLoadAddressIndexByAddress;
65 using ModuleDatabase::InsertLoadAddress;
66 using ModuleDatabase::RemoveLoadAddressById;
67 using ModuleDatabase::RemoveLoadAddressByIndex;
68 };
69
70 class ModuleDatabaseTest : public testing::Test {
71 protected:
72 ModuleDatabaseTest()
73 : dll1_(kDll1),
74 dll2_(kDll2),
75 message_loop_(new base::MessageLoop),
grt (UTC plus 2) 2016/12/20 11:11:34 MakeUnique?
chrisha 2016/12/20 19:46:24 How is that any shorter or better? I can see that
grt (UTC plus 2) 2016/12/20 21:09:53 With naked "new", I have to check the type of |mes
chrisha 2016/12/21 20:14:59 Okay, fair enough. Done.
76 module_database_(new ModuleDatabase(message_loop_->task_runner())) {}
77
78 void RunLoopUntilIdle() {
79 base::RunLoop run_loop;
grt (UTC plus 2) 2016/12/20 11:11:34 nit: base::RunLoop().RunUntilIdle();
chrisha 2016/12/20 19:46:24 Done.
80 run_loop.RunUntilIdle();
81 }
82
83 const ModuleDatabase::ModuleSet& modules() {
84 return module_database_->modules_;
85 }
86
87 const ModuleDatabase::ProcessSet& processes() {
88 return module_database_->processes_;
89 }
90
91 static uint32_t ProcessTypeToBit(content::ProcessType process_type) {
92 return ModuleDatabase::ProcessTypeToBit(process_type);
93 }
94
95 // Counts the occurrences of the given |module_id| in the given collection of
96 // |load_addresses|.
97 static size_t ModuleIdCount(
98 ModuleDatabase::ModuleId module_id,
99 const ModuleDatabase::ModuleLoadAddresses& load_addresses) {
100 size_t count = 0;
101 for (const auto& load_address : load_addresses) {
102 if (load_address.first == module_id)
103 ++count;
104 }
105 return count;
106 }
107
108 protected:
109 const base::FilePath dll1_;
110 const base::FilePath dll2_;
111
112 std::unique_ptr<base::MessageLoop> message_loop_;
113 std::unique_ptr<ModuleDatabase> module_database_;
114
115 private:
116 DISALLOW_COPY_AND_ASSIGN(ModuleDatabaseTest);
117 };
118
119 TEST_F(ModuleDatabaseTest, LoadAddressVectorOperations) {
120 using TMD = TestModuleDatabase;
121 TestModuleDatabase::ModuleLoadAddresses la;
122
123 // Finds should fail in an empty collection.
124 EXPECT_EQ(TMD::kInvalidIndex, TMD::FindLoadAddressIndexById(0, la));
125 EXPECT_EQ(TMD::kInvalidIndex, TMD::FindLoadAddressIndexById(0x04000000, la));
126
127 // A first insert should work. Don't start with ModuleId 0 so that later
128 // inserts can insert that module.
129 TMD::InsertLoadAddress(10, 0x04000000, &la);
130 EXPECT_EQ(1u, la.size());
131 EXPECT_EQ(10, la[0].first);
132 EXPECT_EQ(0x04000000u, la[0].second);
133
134 // Finds should work.
135 EXPECT_EQ(TMD::kInvalidIndex, TMD::FindLoadAddressIndexById(0, la));
136 EXPECT_EQ(TMD::kInvalidIndex, TMD::FindLoadAddressIndexById(0x03000000, la));
137 EXPECT_EQ(0, TMD::FindLoadAddressIndexById(10, la));
138 EXPECT_EQ(0, TMD::FindLoadAddressIndexByAddress(0x04000000, la));
139
140 // A second insert should work. This is the new max so should be at the end
141 // of the collection.
142 TMD::InsertLoadAddress(12, 0x06000000, &la);
143 EXPECT_EQ(2u, la.size());
144 EXPECT_EQ(10, la[0].first);
145 EXPECT_EQ(0x04000000u, la[0].second);
146 EXPECT_EQ(12, la[1].first);
147 EXPECT_EQ(0x06000000u, la[1].second);
148
149 // Finds should work.
150 EXPECT_EQ(TMD::kInvalidIndex, TMD::FindLoadAddressIndexById(0, la));
151 EXPECT_EQ(TMD::kInvalidIndex, TMD::FindLoadAddressIndexById(0x03000000, la));
152 EXPECT_EQ(0, TMD::FindLoadAddressIndexById(10, la));
153 EXPECT_EQ(0, TMD::FindLoadAddressIndexByAddress(0x04000000, la));
154 EXPECT_EQ(1, TMD::FindLoadAddressIndexById(12, la));
155 EXPECT_EQ(1, TMD::FindLoadAddressIndexByAddress(0x06000000, la));
156
157 // Another insert should work. This is not the new max, so a swap should
158 // happen to keep the maximum element at the end of the collection.
159 TMD::InsertLoadAddress(11, 0x05000000, &la);
160 EXPECT_EQ(3u, la.size());
161 EXPECT_EQ(10, la[0].first);
162 EXPECT_EQ(0x04000000u, la[0].second);
163 EXPECT_EQ(11, la[1].first);
164 EXPECT_EQ(0x05000000u, la[1].second);
165 EXPECT_EQ(12, la[2].first);
166 EXPECT_EQ(0x06000000u, la[2].second);
167
168 // An insert of an existing module should work, but simply overwrite the
169 // load address.
170 TMD::InsertLoadAddress(11, 0x0F000000, &la);
171 EXPECT_EQ(3u, la.size());
172 EXPECT_EQ(11, la[1].first);
173 EXPECT_EQ(0x0F000000u, la[1].second);
174 TMD::InsertLoadAddress(11, 0x05000000, &la);
175 EXPECT_EQ(3u, la.size());
176 EXPECT_EQ(11, la[1].first);
177 EXPECT_EQ(0x05000000u, la[1].second);
178
179 // Finds should work.
180 EXPECT_EQ(TMD::kInvalidIndex, TMD::FindLoadAddressIndexById(0, la));
181 EXPECT_EQ(TMD::kInvalidIndex, TMD::FindLoadAddressIndexById(0x03000000, la));
182 EXPECT_EQ(0, TMD::FindLoadAddressIndexById(10, la));
183 EXPECT_EQ(0, TMD::FindLoadAddressIndexByAddress(0x04000000, la));
184 EXPECT_EQ(1, TMD::FindLoadAddressIndexById(11, la));
185 EXPECT_EQ(1, TMD::FindLoadAddressIndexByAddress(0x05000000, la));
186 EXPECT_EQ(2, TMD::FindLoadAddressIndexById(12, la));
187 EXPECT_EQ(2, TMD::FindLoadAddressIndexByAddress(0x06000000, la));
188
189 // Do some inserts of lower modules IDs. This ensures that we'll have some
190 // higher module IDs in the vector before some lower modules IDs, for testing
191 // the deletion logic.
192 TMD::InsertLoadAddress(3, 0x07000000, &la);
193 TMD::InsertLoadAddress(4, 0x08000000, &la);
194 TMD::InsertLoadAddress(5, 0x09000000, &la);
195 EXPECT_EQ(6u, la.size());
196 EXPECT_EQ(10, la[0].first);
197 EXPECT_EQ(0x04000000u, la[0].second);
198 EXPECT_EQ(11, la[1].first);
199 EXPECT_EQ(0x05000000u, la[1].second);
200 EXPECT_EQ(3, la[2].first);
201 EXPECT_EQ(0x07000000u, la[2].second);
202 EXPECT_EQ(4, la[3].first);
203 EXPECT_EQ(0x08000000u, la[3].second);
204 EXPECT_EQ(5, la[4].first);
205 EXPECT_EQ(0x09000000u, la[4].second);
206 EXPECT_EQ(12, la[5].first);
207 EXPECT_EQ(0x06000000u, la[5].second);
208
209 // Remove an element that isn't in the second last position. The second last
210 // element should be swapped into its position, and the last element moved
211 // to the second last place.
212 TMD::RemoveLoadAddressByIndex(2, &la);
213 EXPECT_EQ(5u, la.size());
214 EXPECT_EQ(10, la[0].first);
215 EXPECT_EQ(0x04000000u, la[0].second);
216 EXPECT_EQ(11, la[1].first);
217 EXPECT_EQ(0x05000000u, la[1].second);
218 EXPECT_EQ(5, la[2].first);
219 EXPECT_EQ(0x09000000u, la[2].second);
220 EXPECT_EQ(4, la[3].first);
221 EXPECT_EQ(0x08000000u, la[3].second);
222 EXPECT_EQ(12, la[4].first);
223 EXPECT_EQ(0x06000000u, la[4].second);
224
225 // Remove the second last element. Only the last element should move.
226 TMD::RemoveLoadAddressByIndex(3, &la);
227 EXPECT_EQ(4u, la.size());
228 EXPECT_EQ(10, la[0].first);
229 EXPECT_EQ(0x04000000u, la[0].second);
230 EXPECT_EQ(11, la[1].first);
231 EXPECT_EQ(0x05000000u, la[1].second);
232 EXPECT_EQ(5, la[2].first);
233 EXPECT_EQ(0x09000000u, la[2].second);
234 EXPECT_EQ(12, la[3].first);
235 EXPECT_EQ(0x06000000u, la[3].second);
236
237 // Remove the last element. The new maximum should be found moved to the
238 // end.
239 TMD::RemoveLoadAddressByIndex(3, &la);
240 EXPECT_EQ(3u, la.size());
241 EXPECT_EQ(10, la[0].first);
242 EXPECT_EQ(0x04000000u, la[0].second);
243 EXPECT_EQ(5, la[1].first);
244 EXPECT_EQ(0x09000000u, la[1].second);
245 EXPECT_EQ(11, la[2].first);
246 EXPECT_EQ(0x05000000u, la[2].second);
247
248 // Remove the last element by ModuleId. The remaining modules should be
249 // swapped.
250 TMD::RemoveLoadAddressById(11, &la);
251 EXPECT_EQ(2u, la.size());
252 EXPECT_EQ(5, la[0].first);
253 EXPECT_EQ(0x09000000u, la[0].second);
254 EXPECT_EQ(10, la[1].first);
255 EXPECT_EQ(0x04000000u, la[1].second);
256
257 // Remove the first element by ModuleId.
258 TMD::RemoveLoadAddressById(5, &la);
259 EXPECT_EQ(1u, la.size());
260 EXPECT_EQ(10, la[0].first);
261 EXPECT_EQ(0x04000000u, la[0].second);
262
263 // Remove the only remaining element.
264 TMD::RemoveLoadAddressByIndex(0, &la);
265 EXPECT_TRUE(la.empty());
266 }
267
268 TEST_F(ModuleDatabaseTest, LoadAddressVectorStressTest) {
269 using TMD = TestModuleDatabase;
270 TestModuleDatabase::ModuleLoadAddresses la;
271
272 for (size_t n = 1; n < 200; ++n) {
273 // Will keep track of which elements have been inserted.
274 std::vector<bool> inserted(n);
275 size_t inserted_count = 0;
276
277 // Generate a shuffled list of IDs. This will be the insertion order.
278 // More insertions than elements will occur so that rewrites occur.,
279 std::vector<TMD::ModuleId> ids(11 * n / 10);
280 for (size_t i = 0; i < 11 * n / 10; ++i)
281 ids[i] = i % n;
282 std::random_shuffle(ids.begin(), ids.end());
283
284 // Do the insertions.
285 for (auto id : ids) {
286 if (!inserted[id]) {
287 inserted[id] = true;
288 ++inserted_count;
289 }
290
291 // Generate a load address. The load address bakes in the index so that
292 // searching by load address is easy.
293 uintptr_t load_address = static_cast<uintptr_t>(id) << 16;
294
295 // Do the insertion.
296 TMD::InsertLoadAddress(id, load_address, &la);
297 EXPECT_EQ(inserted_count, la.size());
298 }
299
300 // Validate that every element is there, via both search mechanisms.
301 for (size_t id = 0; id < n; ++id) {
302 uintptr_t load_address = static_cast<uintptr_t>(id) << 16;
303 int index1 = TMD::FindLoadAddressIndexById(id, la);
304 int index2 = TMD::FindLoadAddressIndexByAddress(load_address, la);
305 EXPECT_NE(TMD::kInvalidIndex, index1);
306 EXPECT_EQ(index1, index2);
307 }
308
309 // Generate the deletion order.
310 ids.resize(n);
311 for (size_t i = 0; i < ids.size(); ++i)
312 ids[i] = i;
313 std::random_shuffle(ids.begin(), ids.end());
314
315 // Do the deletions.
316 for (auto id : ids) {
317 --inserted_count;
318 TMD::RemoveLoadAddressById(id, &la);
319 EXPECT_EQ(inserted_count, la.size());
320 }
321 }
322 }
323
324 TEST_F(ModuleDatabaseTest, TasksAreBounced) {
325 // Run a task on the current thread. This should not be bounced, so no
326 // task should be scheduled on the task runner.
327 module_database_->OnProcessStarted(kPid1, content::PROCESS_TYPE_BROWSER);
328 EXPECT_TRUE(message_loop_->IsIdleForTesting());
329 module_database_->OnModuleEvent(
330 kPid1, ModuleWatcher::ModuleEvent(mojom::ModuleEventType::MODULE_LOADED,
331 dll1_, kGoodAddress1, kSize1));
332 EXPECT_TRUE(message_loop_->IsIdleForTesting());
333 module_database_->OnProcessEnded(kPid1);
334 EXPECT_TRUE(message_loop_->IsIdleForTesting());
335
336 // Indicate another process start on this thread. This call can't be
337 // bounced.
338 module_database_->OnProcessStarted(kPid2, content::PROCESS_TYPE_BROWSER);
339
340 // Run similar tasks on another thread. These should be bounced.
341 RunTask(base::Bind(
342 &ModuleDatabase::OnModuleEvent, base::Unretained(module_database_.get()),
343 kPid2, ModuleWatcher::ModuleEvent(mojom::ModuleEventType::MODULE_LOADED,
344 dll1_, kGoodAddress1, kSize1)));
345 EXPECT_FALSE(message_loop_->IsIdleForTesting());
346 RunLoopUntilIdle();
347
348 RunTask(base::Bind(&ModuleDatabase::OnProcessEnded,
349 base::Unretained(module_database_.get()), kPid2));
350 EXPECT_FALSE(message_loop_->IsIdleForTesting());
351 RunLoopUntilIdle();
352 }
353
354 TEST_F(ModuleDatabaseTest, EventsWithoutProcessIgnore) {
355 EXPECT_EQ(0u, modules().size());
356 EXPECT_EQ(0u, processes().size());
357
358 module_database_->OnModuleEvent(
359 kPid1,
360 ModuleWatcher::ModuleEvent(mojom::ModuleEventType::MODULE_ALREADY_LOADED,
361 dll1_, kGoodAddress1, kSize1));
362
363 EXPECT_EQ(0u, modules().size());
364 EXPECT_EQ(0u, processes().size());
365 }
366
367 TEST_F(ModuleDatabaseTest, OutOfOrderEventsHandled) {
368 EXPECT_EQ(0u, modules().size());
369 EXPECT_EQ(0u, processes().size());
370
371 // Start a process.
372 module_database_->OnProcessStarted(kPid1, content::PROCESS_TYPE_BROWSER);
373 EXPECT_EQ(0u, modules().size());
374 EXPECT_EQ(1u, processes().size());
375 auto p1 = processes().begin();
376 EXPECT_EQ(kPid1, p1->process_id);
377 EXPECT_EQ(content::PROCESS_TYPE_BROWSER, p1->process_type);
378 EXPECT_EQ(0u, p1->loaded_modules.size());
379 EXPECT_EQ(0u, p1->unloaded_modules.size());
380
381 // Indicate a module unload. This should create an unloaded module entry.
382 module_database_->OnModuleEvent(
383 kPid1, ModuleWatcher::ModuleEvent(mojom::ModuleEventType::MODULE_UNLOADED,
384 dll1_, kGoodAddress1, kSize1));
385 EXPECT_EQ(1u, modules().size());
386 EXPECT_EQ(1u, processes().size());
387 EXPECT_EQ(0u, p1->loaded_modules.size());
388 EXPECT_EQ(1u, p1->unloaded_modules.size());
389
390 // Now do a corresponding load. This should create a loaded module entry and
391 // erase the unloaded module entry.
392 module_database_->OnModuleEvent(
393 kPid1, ModuleWatcher::ModuleEvent(mojom::ModuleEventType::MODULE_LOADED,
394 dll1_, kGoodAddress1, kSize1));
395 EXPECT_EQ(1u, modules().size());
396 EXPECT_EQ(1u, processes().size());
397 EXPECT_EQ(1u, p1->loaded_modules.size());
398 EXPECT_EQ(0u, p1->unloaded_modules.size());
399 }
400
401 TEST_F(ModuleDatabaseTest, OutOfOrderUnloadIgnored) {
402 EXPECT_EQ(0u, modules().size());
403 EXPECT_EQ(0u, processes().size());
404
405 // Start a process.
406 module_database_->OnProcessStarted(kPid1, content::PROCESS_TYPE_BROWSER);
407 EXPECT_EQ(0u, modules().size());
408 EXPECT_EQ(1u, processes().size());
409 auto p1 = processes().begin();
410 EXPECT_EQ(kPid1, p1->process_id);
411 EXPECT_EQ(content::PROCESS_TYPE_BROWSER, p1->process_type);
412 EXPECT_EQ(0u, p1->loaded_modules.size());
413 EXPECT_EQ(0u, p1->unloaded_modules.size());
414
415 // Indicate a module unload using the alternative API for calls via IPC. This
416 // should do nothing.
417 module_database_->OnModuleEvent(
418 kPid1, ModuleWatcher::ModuleEvent(mojom::ModuleEventType::MODULE_UNLOADED,
419 dll1_, kGoodAddress1, kSize1));
420 EXPECT_EQ(1u, modules().size());
421 EXPECT_EQ(1u, processes().size());
422 EXPECT_EQ(0u, p1->loaded_modules.size());
423 EXPECT_EQ(1u, p1->unloaded_modules.size());
424 }
425
426 TEST_F(ModuleDatabaseTest, DatabaseIsConsistent) {
427 EXPECT_EQ(0u, modules().size());
428 EXPECT_EQ(0u, processes().size());
429
430 // Start a process.
431 module_database_->OnProcessStarted(kPid1, content::PROCESS_TYPE_BROWSER);
432 EXPECT_EQ(0u, modules().size());
433 EXPECT_EQ(1u, processes().size());
434 auto p1 = processes().begin();
435 EXPECT_EQ(kPid1, p1->process_id);
436 EXPECT_EQ(content::PROCESS_TYPE_BROWSER, p1->process_type);
437 EXPECT_EQ(0u, p1->loaded_modules.size());
438 EXPECT_EQ(0u, p1->unloaded_modules.size());
439
440 // Indicate an already loaded module.
441 module_database_->OnModuleEvent(
442 kPid1,
443 ModuleWatcher::ModuleEvent(mojom::ModuleEventType::MODULE_ALREADY_LOADED,
444 dll1_, kGoodAddress1, kSize1));
445 EXPECT_EQ(1u, modules().size());
446 EXPECT_EQ(1u, processes().size());
447
448 // Ensure that the process and module sets are up to date.
449 auto m1 = modules().begin();
450 EXPECT_EQ(dll1_, m1->module_path);
451 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER), m1->process_types);
452 EXPECT_EQ(kPid1, p1->process_id);
453 EXPECT_EQ(content::PROCESS_TYPE_BROWSER, p1->process_type);
454 EXPECT_EQ(1u, p1->loaded_modules.size());
455 EXPECT_EQ(0u, p1->unloaded_modules.size());
456 EXPECT_EQ(1u, ModuleIdCount(m1->module_id, p1->loaded_modules));
457
458 // Provide a redundant load message for that module.
459 module_database_->OnModuleEvent(
460 kPid1, ModuleWatcher::ModuleEvent(mojom::ModuleEventType::MODULE_LOADED,
461 dll1_, kGoodAddress1, kSize1));
462 EXPECT_EQ(1u, modules().size());
463 EXPECT_EQ(1u, processes().size());
464
465 // Ensure that the process and module sets haven't changed.
466 EXPECT_EQ(dll1_, m1->module_path);
467 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER), m1->process_types);
468 EXPECT_EQ(kPid1, p1->process_id);
469 EXPECT_EQ(content::PROCESS_TYPE_BROWSER, p1->process_type);
470 EXPECT_EQ(1u, p1->loaded_modules.size());
471 EXPECT_EQ(0u, p1->unloaded_modules.size());
472 EXPECT_EQ(1u, ModuleIdCount(m1->module_id, p1->loaded_modules));
473
474 // Load a second module into the process.
475 module_database_->OnModuleEvent(
476 kPid1, ModuleWatcher::ModuleEvent(mojom::ModuleEventType::MODULE_LOADED,
477 dll2_, kGoodAddress2, kSize2));
478 EXPECT_EQ(2u, modules().size());
479 EXPECT_EQ(1u, processes().size());
480
481 // Ensure that the process and module sets are up to date.
482 auto m2 = modules().rbegin();
483 EXPECT_EQ(dll2_, m2->module_path);
484 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER), m2->process_types);
485 EXPECT_EQ(kPid1, p1->process_id);
486 EXPECT_EQ(content::PROCESS_TYPE_BROWSER, p1->process_type);
487 EXPECT_EQ(2u, p1->loaded_modules.size());
488 EXPECT_EQ(0u, p1->unloaded_modules.size());
489 EXPECT_EQ(1u, ModuleIdCount(m1->module_id, p1->loaded_modules));
490 EXPECT_EQ(1u, ModuleIdCount(m2->module_id, p1->loaded_modules));
491
492 // Unload the second module.
493 module_database_->OnModuleEvent(
494 kPid1, ModuleWatcher::ModuleEvent(mojom::ModuleEventType::MODULE_UNLOADED,
495 dll2_, kGoodAddress2, kSize2));
496 EXPECT_EQ(2u, modules().size());
497 EXPECT_EQ(1u, processes().size());
498
499 // Ensure that the process and module sets are up to date.
500 EXPECT_EQ(dll2_, m2->module_path);
501 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER), m2->process_types);
502 EXPECT_EQ(kPid1, p1->process_id);
503 EXPECT_EQ(content::PROCESS_TYPE_BROWSER, p1->process_type);
504 EXPECT_EQ(1u, p1->loaded_modules.size());
505 EXPECT_EQ(1u, p1->unloaded_modules.size());
506 EXPECT_EQ(1u, ModuleIdCount(m1->module_id, p1->loaded_modules));
507 EXPECT_EQ(1u, ModuleIdCount(m2->module_id, p1->unloaded_modules));
508
509 // Start a process.
510 module_database_->OnProcessStarted(kPid2, content::PROCESS_TYPE_RENDERER);
511 EXPECT_EQ(2u, modules().size());
512 EXPECT_EQ(2u, processes().size());
513 auto p2 = processes().rbegin();
514 EXPECT_EQ(kPid2, p2->process_id);
515 EXPECT_EQ(content::PROCESS_TYPE_RENDERER, p2->process_type);
516 EXPECT_EQ(0u, p2->loaded_modules.size());
517 EXPECT_EQ(0u, p2->unloaded_modules.size());
518
519 // Load the dummy.dll in the second process as well.
520 module_database_->OnModuleEvent(
521 kPid2,
522 ModuleWatcher::ModuleEvent(mojom::ModuleEventType::MODULE_ALREADY_LOADED,
523 dll1_, kGoodAddress1, kSize1));
524 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER) |
525 ProcessTypeToBit(content::PROCESS_TYPE_RENDERER),
526 m1->process_types);
527 EXPECT_EQ(kPid2, p2->process_id);
528 EXPECT_EQ(content::PROCESS_TYPE_RENDERER, p2->process_type);
529 EXPECT_EQ(1u, p2->loaded_modules.size());
530 EXPECT_EQ(0u, p2->unloaded_modules.size());
531 EXPECT_EQ(1u, ModuleIdCount(m1->module_id, p2->loaded_modules));
532
533 // End the second process without an explicit unload. This invalidates |p2|.
534 module_database_->OnProcessEnded(kPid2);
535 EXPECT_EQ(2u, modules().size());
536 EXPECT_EQ(1u, processes().size());
537 EXPECT_EQ(kPid1, p1->process_id);
538 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER) |
539 ProcessTypeToBit(content::PROCESS_TYPE_RENDERER),
540 m1->process_types);
541 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER), m2->process_types);
542
543 // End the first process without an explicit unload. This invalidates |p1|.
544 module_database_->OnProcessEnded(kPid1);
545 EXPECT_EQ(2u, modules().size());
546 EXPECT_EQ(0u, processes().size());
547 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER) |
548 ProcessTypeToBit(content::PROCESS_TYPE_RENDERER),
549 m1->process_types);
550 EXPECT_EQ(ProcessTypeToBit(content::PROCESS_TYPE_BROWSER), m2->process_types);
551 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698