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: base/threading/sequenced_worker_pool_unittest.cc

Issue 11649032: Flush SequenceWorkerPool tasks after each unit test. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 7 years, 11 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "base/threading/sequenced_worker_pool.h" 5 #include "base/threading/sequenced_worker_pool.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 { 90 {
91 base::AutoLock lock(lock_); 91 base::AutoLock lock(lock_);
92 started_events_++; 92 started_events_++;
93 } 93 }
94 cond_var_.Signal(); 94 cond_var_.Signal();
95 95
96 blocker->Block(); 96 blocker->Block();
97 SignalWorkerDone(id); 97 SignalWorkerDone(id);
98 } 98 }
99 99
100 void PostAdditionalTasks(int id, SequencedWorkerPool* pool) { 100 void PostAdditionalTasks(
101 int id, SequencedWorkerPool* pool,
102 const bool* expected_return_values) {
101 Closure fast_task = base::Bind(&TestTracker::FastTask, this, 100); 103 Closure fast_task = base::Bind(&TestTracker::FastTask, this, 100);
102 EXPECT_FALSE( 104 EXPECT_EQ(expected_return_values[0],
103 pool->PostWorkerTaskWithShutdownBehavior( 105 pool->PostWorkerTaskWithShutdownBehavior(
104 FROM_HERE, fast_task, 106 FROM_HERE, fast_task,
105 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)); 107 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN));
106 EXPECT_FALSE( 108 EXPECT_EQ(expected_return_values[1],
107 pool->PostWorkerTaskWithShutdownBehavior( 109 pool->PostWorkerTaskWithShutdownBehavior(
108 FROM_HERE, fast_task, 110 FROM_HERE, fast_task,
109 SequencedWorkerPool::SKIP_ON_SHUTDOWN)); 111 SequencedWorkerPool::SKIP_ON_SHUTDOWN));
110 pool->PostWorkerTaskWithShutdownBehavior( 112 pool->PostWorkerTaskWithShutdownBehavior(
111 FROM_HERE, fast_task, 113 FROM_HERE, fast_task,
112 SequencedWorkerPool::BLOCK_SHUTDOWN); 114 SequencedWorkerPool::BLOCK_SHUTDOWN);
113 SignalWorkerDone(id); 115 SignalWorkerDone(id);
114 } 116 }
115 117
116 // Waits until the given number of tasks have started executing. 118 // Waits until the given number of tasks have started executing.
117 void WaitUntilTasksBlocked(size_t count) { 119 void WaitUntilTasksBlocked(size_t count) {
118 { 120 {
119 base::AutoLock lock(lock_); 121 base::AutoLock lock(lock_);
(...skipping 10 matching lines...) Expand all
130 { 132 {
131 base::AutoLock lock(lock_); 133 base::AutoLock lock(lock_);
132 while (complete_sequence_.size() < num_tasks) 134 while (complete_sequence_.size() < num_tasks)
133 cond_var_.Wait(); 135 cond_var_.Wait();
134 ret = complete_sequence_; 136 ret = complete_sequence_;
135 } 137 }
136 cond_var_.Signal(); 138 cond_var_.Signal();
137 return ret; 139 return ret;
138 } 140 }
139 141
142 size_t GetTasksCompletedCount() {
143 base::AutoLock lock(lock_);
144 return complete_sequence_.size();
145 }
146
140 void ClearCompleteSequence() { 147 void ClearCompleteSequence() {
141 base::AutoLock lock(lock_); 148 base::AutoLock lock(lock_);
142 complete_sequence_.clear(); 149 complete_sequence_.clear();
143 started_events_ = 0; 150 started_events_ = 0;
144 } 151 }
145 152
146 private: 153 private:
147 friend class base::RefCountedThreadSafe<TestTracker>; 154 friend class base::RefCountedThreadSafe<TestTracker>;
148 ~TestTracker() {} 155 ~TestTracker() {}
149 156
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 for (int i = 0; i < kNumBlockTasks; ++i) { 450 for (int i = 0; i < kNumBlockTasks; ++i) {
444 EXPECT_TRUE(pool()->PostWorkerTask( 451 EXPECT_TRUE(pool()->PostWorkerTask(
445 FROM_HERE, 452 FROM_HERE,
446 base::Bind(&TestTracker::BlockTask, tracker(), i, &blocker))); 453 base::Bind(&TestTracker::BlockTask, tracker(), i, &blocker)));
447 } 454 }
448 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads); 455 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads);
449 456
450 // Queue up shutdown blocking tasks behind those which will attempt to post 457 // Queue up shutdown blocking tasks behind those which will attempt to post
451 // additional tasks when run, PostAdditionalTasks attemtps to post 3 458 // additional tasks when run, PostAdditionalTasks attemtps to post 3
452 // new FastTasks, one for each shutdown_behavior. 459 // new FastTasks, one for each shutdown_behavior.
460 const bool kExpectedReturnValues[] = {false, false};
453 const int kNumQueuedTasks = static_cast<int>(kNumWorkerThreads); 461 const int kNumQueuedTasks = static_cast<int>(kNumWorkerThreads);
454 for (int i = 0; i < kNumQueuedTasks; ++i) { 462 for (int i = 0; i < kNumQueuedTasks; ++i) {
455 EXPECT_TRUE(pool()->PostWorkerTaskWithShutdownBehavior( 463 EXPECT_TRUE(pool()->PostWorkerTaskWithShutdownBehavior(
456 FROM_HERE, 464 FROM_HERE,
457 base::Bind(&TestTracker::PostAdditionalTasks, tracker(), i, pool()), 465 base::Bind(&TestTracker::PostAdditionalTasks, tracker(), i, pool(),
466 kExpectedReturnValues),
458 SequencedWorkerPool::BLOCK_SHUTDOWN)); 467 SequencedWorkerPool::BLOCK_SHUTDOWN));
459 } 468 }
460 469
461 // Setup to open the floodgates from within Shutdown(). 470 // Setup to open the floodgates from within Shutdown().
462 SetWillWaitForShutdownCallback( 471 SetWillWaitForShutdownCallback(
463 base::Bind(&EnsureTasksToCompleteCountAndUnblock, 472 base::Bind(&EnsureTasksToCompleteCountAndUnblock,
464 scoped_refptr<TestTracker>(tracker()), 473 scoped_refptr<TestTracker>(tracker()),
465 0, &blocker, kNumBlockTasks)); 474 0, &blocker, kNumBlockTasks));
466 475
467 // Allow half of the additional blocking tasks thru. 476 // Allow half of the additional blocking tasks thru.
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 base::Bind(&IsRunningOnCurrentThreadTask, 688 base::Bind(&IsRunningOnCurrentThreadTask,
680 token2, unsequenced_token, pool(), unused_pool)); 689 token2, unsequenced_token, pool(), unused_pool));
681 pool()->PostWorkerTask( 690 pool()->PostWorkerTask(
682 FROM_HERE, 691 FROM_HERE,
683 base::Bind(&IsRunningOnCurrentThreadTask, 692 base::Bind(&IsRunningOnCurrentThreadTask,
684 unsequenced_token, token1, pool(), unused_pool)); 693 unsequenced_token, token1, pool(), unused_pool));
685 pool()->Shutdown(); 694 pool()->Shutdown();
686 unused_pool->Shutdown(); 695 unused_pool->Shutdown();
687 } 696 }
688 697
698 // Verify that FlushForTesting works as intended.
699 TEST_F(SequencedWorkerPoolTest, FlushForTesting) {
700 // Should be fine to call on a new instance.
701 pool()->FlushForTesting();
702
703 // Queue up a bunch of work, including work that produces additional
704 // work as an artifact.
705 pool()->PostDelayedWorkerTask(
706 FROM_HERE,
707 base::Bind(&TestTracker::FastTask, tracker(), 0),
708 TimeDelta::FromMinutes(5));
709 pool()->PostWorkerTask(FROM_HERE,
710 base::Bind(&TestTracker::SlowTask, tracker(), 0));
711 const size_t kNumFastTasks = 20;
712 for (size_t i = 0; i < kNumFastTasks; i++) {
713 pool()->PostWorkerTask(FROM_HERE,
714 base::Bind(&TestTracker::FastTask, tracker(), 0));
715 }
716 const bool kExpectedReturnValues[] = {true, true};
717 pool()->PostWorkerTask(
718 FROM_HERE,
719 base::Bind(&TestTracker::PostAdditionalTasks, tracker(), 0, pool(),
720 kExpectedReturnValues));
721 EXPECT_FALSE(tracker()->HasOneRef());
722 pool()->FlushForTesting();
723
724 // We expect all except the delayed task to have been run. We verify all
725 // closures have been deleted deleted by looking at the refcount of the
726 // tracker.
727 EXPECT_EQ(1 + kNumFastTasks + 1 + 3, tracker()->GetTasksCompletedCount());
728 EXPECT_TRUE(tracker()->HasOneRef());
729
730 // Should be fine to call on an idle instance with all threads created, and
731 // spamming the method shouldn't deadlock or confuse the class.
732 pool()->FlushForTesting();
733 pool()->FlushForTesting();
734 pool()->Shutdown();
735 }
736
689 class SequencedWorkerPoolTaskRunnerTestDelegate { 737 class SequencedWorkerPoolTaskRunnerTestDelegate {
690 public: 738 public:
691 SequencedWorkerPoolTaskRunnerTestDelegate() {} 739 SequencedWorkerPoolTaskRunnerTestDelegate() {}
692 740
693 ~SequencedWorkerPoolTaskRunnerTestDelegate() {} 741 ~SequencedWorkerPoolTaskRunnerTestDelegate() {}
694 742
695 void StartTaskRunner() { 743 void StartTaskRunner() {
696 pool_owner_.reset( 744 pool_owner_.reset(
697 new SequencedWorkerPoolOwner(10, "SequencedWorkerPoolTaskRunnerTest")); 745 new SequencedWorkerPoolOwner(10, "SequencedWorkerPoolTaskRunnerTest"));
698 } 746 }
699 747
700 scoped_refptr<SequencedWorkerPool> GetTaskRunner() { 748 scoped_refptr<SequencedWorkerPool> GetTaskRunner() {
701 return pool_owner_->pool(); 749 return pool_owner_->pool();
702 } 750 }
703 751
704 void StopTaskRunner() { 752 void StopTaskRunner() {
705 // Make sure all tasks (including delayed ones) are run before shutting 753 // Make sure all tasks are run before shutting down. Delayed tasks are
706 // down. 754 // not run, they're simply deleted.
707 pool_owner_->pool()->FlushForTesting(); 755 pool_owner_->pool()->FlushForTesting();
708 pool_owner_->pool()->Shutdown(); 756 pool_owner_->pool()->Shutdown();
709 // Don't reset |pool_owner_| here, as the test may still hold a 757 // Don't reset |pool_owner_| here, as the test may still hold a
710 // reference to the pool. 758 // reference to the pool.
711 } 759 }
712 760
713 bool TaskRunnerHandlesNonZeroDelays() const { 761 bool TaskRunnerHandlesNonZeroDelays() const {
714 return true; 762 return true;
715 } 763 }
716 764
(...skipping 18 matching lines...) Expand all
735 new SequencedWorkerPoolOwner(10, "SequencedWorkerPoolTaskRunnerTest")); 783 new SequencedWorkerPoolOwner(10, "SequencedWorkerPoolTaskRunnerTest"));
736 task_runner_ = pool_owner_->pool()->GetTaskRunnerWithShutdownBehavior( 784 task_runner_ = pool_owner_->pool()->GetTaskRunnerWithShutdownBehavior(
737 SequencedWorkerPool::BLOCK_SHUTDOWN); 785 SequencedWorkerPool::BLOCK_SHUTDOWN);
738 } 786 }
739 787
740 scoped_refptr<TaskRunner> GetTaskRunner() { 788 scoped_refptr<TaskRunner> GetTaskRunner() {
741 return task_runner_; 789 return task_runner_;
742 } 790 }
743 791
744 void StopTaskRunner() { 792 void StopTaskRunner() {
745 // Make sure all tasks (including delayed ones) are run before shutting 793 // Make sure all tasks are run before shutting down. Delayed tasks are
746 // down. 794 // not run, they're simply deleted.
747 pool_owner_->pool()->FlushForTesting(); 795 pool_owner_->pool()->FlushForTesting();
748 pool_owner_->pool()->Shutdown(); 796 pool_owner_->pool()->Shutdown();
749 // Don't reset |pool_owner_| here, as the test may still hold a 797 // Don't reset |pool_owner_| here, as the test may still hold a
750 // reference to the pool. 798 // reference to the pool.
751 } 799 }
752 800
753 bool TaskRunnerHandlesNonZeroDelays() const { 801 bool TaskRunnerHandlesNonZeroDelays() const {
754 return true; 802 return true;
755 } 803 }
756 804
(...skipping 19 matching lines...) Expand all
776 10, "SequencedWorkerPoolSequencedTaskRunnerTest")); 824 10, "SequencedWorkerPoolSequencedTaskRunnerTest"));
777 task_runner_ = pool_owner_->pool()->GetSequencedTaskRunner( 825 task_runner_ = pool_owner_->pool()->GetSequencedTaskRunner(
778 pool_owner_->pool()->GetSequenceToken()); 826 pool_owner_->pool()->GetSequenceToken());
779 } 827 }
780 828
781 scoped_refptr<SequencedTaskRunner> GetTaskRunner() { 829 scoped_refptr<SequencedTaskRunner> GetTaskRunner() {
782 return task_runner_; 830 return task_runner_;
783 } 831 }
784 832
785 void StopTaskRunner() { 833 void StopTaskRunner() {
786 // Make sure all tasks (including delayed ones) are run before shutting 834 // Make sure all tasks are run before shutting down. Delayed tasks are
787 // down. 835 // not run, they're simply deleted.
788 pool_owner_->pool()->FlushForTesting(); 836 pool_owner_->pool()->FlushForTesting();
789 pool_owner_->pool()->Shutdown(); 837 pool_owner_->pool()->Shutdown();
790 // Don't reset |pool_owner_| here, as the test may still hold a 838 // Don't reset |pool_owner_| here, as the test may still hold a
791 // reference to the pool. 839 // reference to the pool.
792 } 840 }
793 841
794 bool TaskRunnerHandlesNonZeroDelays() const { 842 bool TaskRunnerHandlesNonZeroDelays() const {
795 return true; 843 return true;
796 } 844 }
797 845
798 private: 846 private:
799 MessageLoop message_loop_; 847 MessageLoop message_loop_;
800 scoped_ptr<SequencedWorkerPoolOwner> pool_owner_; 848 scoped_ptr<SequencedWorkerPoolOwner> pool_owner_;
801 scoped_refptr<SequencedTaskRunner> task_runner_; 849 scoped_refptr<SequencedTaskRunner> task_runner_;
802 }; 850 };
803 851
804 INSTANTIATE_TYPED_TEST_CASE_P( 852 INSTANTIATE_TYPED_TEST_CASE_P(
805 SequencedWorkerPoolSequencedTaskRunner, TaskRunnerTest, 853 SequencedWorkerPoolSequencedTaskRunner, TaskRunnerTest,
806 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); 854 SequencedWorkerPoolSequencedTaskRunnerTestDelegate);
807 855
808 INSTANTIATE_TYPED_TEST_CASE_P( 856 INSTANTIATE_TYPED_TEST_CASE_P(
809 SequencedWorkerPoolSequencedTaskRunner, SequencedTaskRunnerTest, 857 SequencedWorkerPoolSequencedTaskRunner, SequencedTaskRunnerTest,
810 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); 858 SequencedWorkerPoolSequencedTaskRunnerTestDelegate);
811 859
812 } // namespace 860 } // namespace
813 861
814 } // namespace base 862 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698