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

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

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

Powered by Google App Engine
This is Rietveld 408576698