| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chromecast/crash/linux/synchronized_minidump_manager.h" | 5 #include "chromecast/crash/linux/synchronized_minidump_manager.h" |
| 6 | 6 |
| 7 #include <fcntl.h> | 7 #include <fcntl.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <stdio.h> // perror | 9 #include <stdio.h> // perror |
| 10 #include <stdlib.h> | 10 #include <stdlib.h> |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 ASSERT_TRUE(base::PathExists(lockfile_)); | 239 ASSERT_TRUE(base::PathExists(lockfile_)); |
| 240 } | 240 } |
| 241 | 241 |
| 242 TEST_F(SynchronizedMinidumpManagerTest, | 242 TEST_F(SynchronizedMinidumpManagerTest, |
| 243 AddEntryToLockFile_FailsWithInvalidEntry) { | 243 AddEntryToLockFile_FailsWithInvalidEntry) { |
| 244 // Create invalid dump info value | 244 // Create invalid dump info value |
| 245 base::DictionaryValue val; | 245 base::DictionaryValue val; |
| 246 | 246 |
| 247 // Test that the manager tried to log the entry and failed. | 247 // Test that the manager tried to log the entry and failed. |
| 248 SynchronizedMinidumpManagerSimple manager; | 248 SynchronizedMinidumpManagerSimple manager; |
| 249 manager.SetDumpInfoToWrite(base::WrapUnique(new DumpInfo(&val))); | 249 manager.SetDumpInfoToWrite(base::MakeUnique<DumpInfo>(&val)); |
| 250 ASSERT_TRUE(manager.DoWorkLocked()); | 250 ASSERT_TRUE(manager.DoWorkLocked()); |
| 251 ASSERT_FALSE(manager.add_entry_return_code()); | 251 ASSERT_FALSE(manager.add_entry_return_code()); |
| 252 | 252 |
| 253 // Verify the lockfile is untouched. | 253 // Verify the lockfile is untouched. |
| 254 DumpList dumps; | 254 DumpList dumps; |
| 255 ASSERT_TRUE(FetchDumps(lockfile_.value(), &dumps)); | 255 ASSERT_TRUE(FetchDumps(lockfile_.value(), &dumps)); |
| 256 ASSERT_EQ(0u, dumps.size()); | 256 ASSERT_EQ(0u, dumps.size()); |
| 257 } | 257 } |
| 258 | 258 |
| 259 TEST_F(SynchronizedMinidumpManagerTest, | 259 TEST_F(SynchronizedMinidumpManagerTest, |
| 260 AddEntryToLockFile_SucceedsWithValidEntries) { | 260 AddEntryToLockFile_SucceedsWithValidEntries) { |
| 261 // Sample parameters. | 261 // Sample parameters. |
| 262 base::Time now = base::Time::Now(); | 262 base::Time now = base::Time::Now(); |
| 263 MinidumpParams params; | 263 MinidumpParams params; |
| 264 params.process_name = "process"; | 264 params.process_name = "process"; |
| 265 | 265 |
| 266 // Write the first entry. | 266 // Write the first entry. |
| 267 SynchronizedMinidumpManagerSimple manager; | 267 SynchronizedMinidumpManagerSimple manager; |
| 268 manager.SetDumpInfoToWrite( | 268 manager.SetDumpInfoToWrite( |
| 269 base::WrapUnique(new DumpInfo("dump1", "log1", now, params))); | 269 base::MakeUnique<DumpInfo>("dump1", "log1", now, params)); |
| 270 ASSERT_TRUE(manager.DoWorkLocked()); | 270 ASSERT_TRUE(manager.DoWorkLocked()); |
| 271 ASSERT_TRUE(manager.add_entry_return_code()); | 271 ASSERT_TRUE(manager.add_entry_return_code()); |
| 272 | 272 |
| 273 // Test that the manager was successful in logging the entry. | 273 // Test that the manager was successful in logging the entry. |
| 274 DumpList dumps; | 274 DumpList dumps; |
| 275 ASSERT_TRUE(FetchDumps(lockfile_.value(), &dumps)); | 275 ASSERT_TRUE(FetchDumps(lockfile_.value(), &dumps)); |
| 276 ASSERT_EQ(1u, dumps.size()); | 276 ASSERT_EQ(1u, dumps.size()); |
| 277 | 277 |
| 278 // Write the second entry. | 278 // Write the second entry. |
| 279 manager.SetDumpInfoToWrite( | 279 manager.SetDumpInfoToWrite( |
| 280 base::WrapUnique(new DumpInfo("dump2", "log2", now, params))); | 280 base::MakeUnique<DumpInfo>("dump2", "log2", now, params)); |
| 281 ASSERT_TRUE(manager.DoWorkLocked()); | 281 ASSERT_TRUE(manager.DoWorkLocked()); |
| 282 ASSERT_TRUE(manager.add_entry_return_code()); | 282 ASSERT_TRUE(manager.add_entry_return_code()); |
| 283 | 283 |
| 284 // Test that the second entry is also valid. | 284 // Test that the second entry is also valid. |
| 285 ASSERT_TRUE(FetchDumps(lockfile_.value(), &dumps)); | 285 ASSERT_TRUE(FetchDumps(lockfile_.value(), &dumps)); |
| 286 ASSERT_EQ(2u, dumps.size()); | 286 ASSERT_EQ(2u, dumps.size()); |
| 287 } | 287 } |
| 288 | 288 |
| 289 TEST_F(SynchronizedMinidumpManagerTest, AcquireLockFile_WaitsForOtherThread) { | 289 TEST_F(SynchronizedMinidumpManagerTest, AcquireLockFile_WaitsForOtherThread) { |
| 290 // Create some parameters for a minidump. | 290 // Create some parameters for a minidump. |
| 291 base::Time now = base::Time::Now(); | 291 base::Time now = base::Time::Now(); |
| 292 MinidumpParams params; | 292 MinidumpParams params; |
| 293 params.process_name = "process"; | 293 params.process_name = "process"; |
| 294 | 294 |
| 295 // Create a manager that grabs the lock then sleeps. Post a DoWork task to | 295 // Create a manager that grabs the lock then sleeps. Post a DoWork task to |
| 296 // another thread. |sleepy_manager| will grab the lock and hold it for | 296 // another thread. |sleepy_manager| will grab the lock and hold it for |
| 297 // |sleep_time_ms|. It will then write a dump and release the lock. | 297 // |sleep_time_ms|. It will then write a dump and release the lock. |
| 298 const int sleep_time_ms = 100; | 298 const int sleep_time_ms = 100; |
| 299 SleepySynchronizedMinidumpManagerSimple sleepy_manager(sleep_time_ms); | 299 SleepySynchronizedMinidumpManagerSimple sleepy_manager(sleep_time_ms); |
| 300 sleepy_manager.SetDumpInfoToWrite( | 300 sleepy_manager.SetDumpInfoToWrite( |
| 301 base::WrapUnique(new DumpInfo("dump", "log", now, params))); | 301 base::MakeUnique<DumpInfo>("dump", "log", now, params)); |
| 302 base::Thread sleepy_thread("sleepy"); | 302 base::Thread sleepy_thread("sleepy"); |
| 303 sleepy_thread.Start(); | 303 sleepy_thread.Start(); |
| 304 sleepy_thread.task_runner()->PostTask( | 304 sleepy_thread.task_runner()->PostTask( |
| 305 FROM_HERE, | 305 FROM_HERE, |
| 306 base::Bind(&DoWorkLockedTask, base::Unretained(&sleepy_manager))); | 306 base::Bind(&DoWorkLockedTask, base::Unretained(&sleepy_manager))); |
| 307 | 307 |
| 308 // Meanwhile, this thread should wait brielfy to allow the other thread to | 308 // Meanwhile, this thread should wait brielfy to allow the other thread to |
| 309 // grab the lock. | 309 // grab the lock. |
| 310 const int concurrency_delay = 50; | 310 const int concurrency_delay = 50; |
| 311 base::PlatformThread::Sleep( | 311 base::PlatformThread::Sleep( |
| 312 base::TimeDelta::FromMilliseconds(concurrency_delay)); | 312 base::TimeDelta::FromMilliseconds(concurrency_delay)); |
| 313 | 313 |
| 314 // |sleepy_manager| has the lock by now, but has not released it. Attempt to | 314 // |sleepy_manager| has the lock by now, but has not released it. Attempt to |
| 315 // grab it. DoWorkLocked() should block until |manager| has a chance to write | 315 // grab it. DoWorkLocked() should block until |manager| has a chance to write |
| 316 // the dump. | 316 // the dump. |
| 317 SynchronizedMinidumpManagerSimple manager; | 317 SynchronizedMinidumpManagerSimple manager; |
| 318 manager.SetDumpInfoToWrite( | 318 manager.SetDumpInfoToWrite( |
| 319 base::WrapUnique(new DumpInfo("dump", "log", now, params))); | 319 base::MakeUnique<DumpInfo>("dump", "log", now, params)); |
| 320 | 320 |
| 321 EXPECT_TRUE(manager.DoWorkLocked()); | 321 EXPECT_TRUE(manager.DoWorkLocked()); |
| 322 EXPECT_TRUE(manager.add_entry_return_code()); | 322 EXPECT_TRUE(manager.add_entry_return_code()); |
| 323 EXPECT_TRUE(manager.work_done()); | 323 EXPECT_TRUE(manager.work_done()); |
| 324 | 324 |
| 325 // Check that the other manager was also successful. | 325 // Check that the other manager was also successful. |
| 326 EXPECT_TRUE(sleepy_manager.add_entry_return_code()); | 326 EXPECT_TRUE(sleepy_manager.add_entry_return_code()); |
| 327 EXPECT_TRUE(sleepy_manager.work_done()); | 327 EXPECT_TRUE(sleepy_manager.work_done()); |
| 328 | 328 |
| 329 // Test that both entries were logged. | 329 // Test that both entries were logged. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 TEST_F(SynchronizedMinidumpManagerTest, | 382 TEST_F(SynchronizedMinidumpManagerTest, |
| 383 Upload_SucceedsWhenDumpLimitsNotExceeded) { | 383 Upload_SucceedsWhenDumpLimitsNotExceeded) { |
| 384 // Sample parameters. | 384 // Sample parameters. |
| 385 base::Time now = base::Time::Now(); | 385 base::Time now = base::Time::Now(); |
| 386 MinidumpParams params; | 386 MinidumpParams params; |
| 387 params.process_name = "process"; | 387 params.process_name = "process"; |
| 388 | 388 |
| 389 FakeSynchronizedMinidumpUploader uploader; | 389 FakeSynchronizedMinidumpUploader uploader; |
| 390 SynchronizedMinidumpManagerSimple producer; | 390 SynchronizedMinidumpManagerSimple producer; |
| 391 producer.SetDumpInfoToWrite( | 391 producer.SetDumpInfoToWrite( |
| 392 base::WrapUnique(new DumpInfo("dump1", "log1", now, params))); | 392 base::MakeUnique<DumpInfo>("dump1", "log1", now, params)); |
| 393 | 393 |
| 394 const int max_dumps = SynchronizedMinidumpManager::kRatelimitPeriodMaxDumps; | 394 const int max_dumps = SynchronizedMinidumpManager::kRatelimitPeriodMaxDumps; |
| 395 produce_dumps(producer, max_dumps); | 395 produce_dumps(producer, max_dumps); |
| 396 consume_dumps(uploader, max_dumps); | 396 consume_dumps(uploader, max_dumps); |
| 397 } | 397 } |
| 398 | 398 |
| 399 TEST_F(SynchronizedMinidumpManagerTest, Upload_FailsWhenTooManyRecentDumps) { | 399 TEST_F(SynchronizedMinidumpManagerTest, Upload_FailsWhenTooManyRecentDumps) { |
| 400 // Sample parameters. | 400 // Sample parameters. |
| 401 base::Time now = base::Time::Now(); | 401 base::Time now = base::Time::Now(); |
| 402 MinidumpParams params; | 402 MinidumpParams params; |
| 403 params.process_name = "process"; | 403 params.process_name = "process"; |
| 404 | 404 |
| 405 FakeSynchronizedMinidumpUploader uploader; | 405 FakeSynchronizedMinidumpUploader uploader; |
| 406 SynchronizedMinidumpManagerSimple producer; | 406 SynchronizedMinidumpManagerSimple producer; |
| 407 producer.SetDumpInfoToWrite( | 407 producer.SetDumpInfoToWrite( |
| 408 base::WrapUnique(new DumpInfo("dump1", "log1", now, params))); | 408 base::MakeUnique<DumpInfo>("dump1", "log1", now, params)); |
| 409 | 409 |
| 410 const int max_dumps = SynchronizedMinidumpManager::kRatelimitPeriodMaxDumps; | 410 const int max_dumps = SynchronizedMinidumpManager::kRatelimitPeriodMaxDumps; |
| 411 produce_dumps(producer, max_dumps + 1); | 411 produce_dumps(producer, max_dumps + 1); |
| 412 consume_dumps(uploader, max_dumps); | 412 consume_dumps(uploader, max_dumps); |
| 413 | 413 |
| 414 // Should fail with too many dumps | 414 // Should fail with too many dumps |
| 415 ASSERT_TRUE(uploader.DoWorkLocked()); | 415 ASSERT_TRUE(uploader.DoWorkLocked()); |
| 416 ASSERT_FALSE(uploader.can_upload_return_val()); | 416 ASSERT_FALSE(uploader.can_upload_return_val()); |
| 417 } | 417 } |
| 418 | 418 |
| 419 TEST_F(SynchronizedMinidumpManagerTest, UploadSucceedsAfterRateLimitPeriodEnd) { | 419 TEST_F(SynchronizedMinidumpManagerTest, UploadSucceedsAfterRateLimitPeriodEnd) { |
| 420 // Sample parameters. | 420 // Sample parameters. |
| 421 base::Time now = base::Time::Now(); | 421 base::Time now = base::Time::Now(); |
| 422 MinidumpParams params; | 422 MinidumpParams params; |
| 423 params.process_name = "process"; | 423 params.process_name = "process"; |
| 424 | 424 |
| 425 FakeSynchronizedMinidumpUploader uploader; | 425 FakeSynchronizedMinidumpUploader uploader; |
| 426 SynchronizedMinidumpManagerSimple producer; | 426 SynchronizedMinidumpManagerSimple producer; |
| 427 producer.SetDumpInfoToWrite( | 427 producer.SetDumpInfoToWrite( |
| 428 base::WrapUnique(new DumpInfo("dump1", "log1", now, params))); | 428 base::MakeUnique<DumpInfo>("dump1", "log1", now, params)); |
| 429 | 429 |
| 430 const int iters = 3; | 430 const int iters = 3; |
| 431 const int max_dumps = SynchronizedMinidumpManager::kRatelimitPeriodMaxDumps; | 431 const int max_dumps = SynchronizedMinidumpManager::kRatelimitPeriodMaxDumps; |
| 432 | 432 |
| 433 for (int i = 0; i < iters; ++i) { | 433 for (int i = 0; i < iters; ++i) { |
| 434 produce_dumps(producer, max_dumps + 1); | 434 produce_dumps(producer, max_dumps + 1); |
| 435 consume_dumps(uploader, max_dumps); | 435 consume_dumps(uploader, max_dumps); |
| 436 | 436 |
| 437 // Should fail with too many dumps | 437 // Should fail with too many dumps |
| 438 ASSERT_TRUE(uploader.DoWorkLocked()); | 438 ASSERT_TRUE(uploader.DoWorkLocked()); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 464 TEST_F(SynchronizedMinidumpManagerTest, HasDumpsWithDumps) { | 464 TEST_F(SynchronizedMinidumpManagerTest, HasDumpsWithDumps) { |
| 465 // Sample parameters. | 465 // Sample parameters. |
| 466 base::Time now = base::Time::Now(); | 466 base::Time now = base::Time::Now(); |
| 467 MinidumpParams params; | 467 MinidumpParams params; |
| 468 params.process_name = "process"; | 468 params.process_name = "process"; |
| 469 | 469 |
| 470 SynchronizedMinidumpManagerSimple producer; | 470 SynchronizedMinidumpManagerSimple producer; |
| 471 FakeSynchronizedMinidumpUploader uploader; | 471 FakeSynchronizedMinidumpUploader uploader; |
| 472 | 472 |
| 473 producer.SetDumpInfoToWrite( | 473 producer.SetDumpInfoToWrite( |
| 474 base::WrapUnique(new DumpInfo("dump1", "log1", now, params))); | 474 base::MakeUnique<DumpInfo>("dump1", "log1", now, params)); |
| 475 | 475 |
| 476 const int kNumDumps = 3; | 476 const int kNumDumps = 3; |
| 477 for (int i = 0; i < kNumDumps; ++i) { | 477 for (int i = 0; i < kNumDumps; ++i) { |
| 478 produce_dumps(producer, 1); | 478 produce_dumps(producer, 1); |
| 479 ASSERT_TRUE(uploader.HasDumps()); | 479 ASSERT_TRUE(uploader.HasDumps()); |
| 480 } | 480 } |
| 481 | 481 |
| 482 for (int i = 0; i < kNumDumps; ++i) { | 482 for (int i = 0; i < kNumDumps; ++i) { |
| 483 ASSERT_TRUE(uploader.HasDumps()); | 483 ASSERT_TRUE(uploader.HasDumps()); |
| 484 consume_dumps(uploader, 1); | 484 consume_dumps(uploader, 1); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 495 const base::FilePath path = | 495 const base::FilePath path = |
| 496 base::FilePath(manager.dump_path()).Append("hello123"); | 496 base::FilePath(manager.dump_path()).Append("hello123"); |
| 497 const char kFileContents[] = "foobar"; | 497 const char kFileContents[] = "foobar"; |
| 498 ASSERT_EQ(static_cast<int>(sizeof(kFileContents)), | 498 ASSERT_EQ(static_cast<int>(sizeof(kFileContents)), |
| 499 WriteFile(path, kFileContents, sizeof(kFileContents))); | 499 WriteFile(path, kFileContents, sizeof(kFileContents))); |
| 500 | 500 |
| 501 ASSERT_TRUE(manager.HasDumps()); | 501 ASSERT_TRUE(manager.HasDumps()); |
| 502 } | 502 } |
| 503 | 503 |
| 504 } // namespace chromecast | 504 } // namespace chromecast |
| OLD | NEW |