1a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// found in the LICENSE file. 4a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "content/browser/startup_task_runner.h" 6a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 7a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/bind.h" 8a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/bind_helpers.h" 9a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/callback.h" 10a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/location.h" 11a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/run_loop.h" 12a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/task_runner.h" 13a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 14a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 16a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 17a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace content { 18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace { 19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 20a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using base::Closure; 21a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using testing::_; 22a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using testing::Assign; 23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using testing::Invoke; 24a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using testing::WithArg; 25a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int observer_calls = 0; 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int task_count = 0; 28a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int observer_result; 29a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)base::Closure task; 30a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 31a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// I couldn't get gMock's SaveArg to compile, hence had to save the argument 32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// this way 33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool SaveTaskArg(const Closure& arg) { 34a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) task = arg; 35a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return true; 36a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 37a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 38a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void Observer(int result) { 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) observer_calls++; 40a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) observer_result = result; 41a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class StartupTaskRunnerTest : public testing::Test { 44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) public: 45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) virtual void SetUp() { 47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) last_task_ = 0; 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) observer_calls = 0; 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) task_count = 0; 50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int Task1() { 53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) last_task_ = 1; 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) task_count++; 55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return 0; 56a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 58a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int Task2() { 59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) last_task_ = 2; 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) task_count++; 61a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return 0; 62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 64a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int FailingTask() { 65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Task returning failure 66a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) last_task_ = 3; 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) task_count++; 68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return 1; 69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int GetLastTask() { return last_task_; } 72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) private: 74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int last_task_; 76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}; 77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// We can't use the real message loop, even if we want to, since doing so on 79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Android requires a complex Java infrastructure. The test would have to built 80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// as a content_shell test; but content_shell startup invokes the class we are 81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// trying to test. 82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// 83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// The mocks are not directly in TaskRunnerProxy because reference counted 84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// objects seem to confuse the mocking framework 85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class MockTaskRunner { 87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) public: 88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) MOCK_METHOD3( 89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PostDelayedTask, 90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool(const tracked_objects::Location&, const Closure&, base::TimeDelta)); 91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) MOCK_METHOD3( 92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PostNonNestableDelayedTask, 93a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool(const tracked_objects::Location&, const Closure&, base::TimeDelta)); 94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}; 95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class TaskRunnerProxy : public base::SingleThreadTaskRunner { 97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) public: 98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) TaskRunnerProxy(MockTaskRunner* mock) : mock_(mock) {} 99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) virtual bool RunsTasksOnCurrentThread() const OVERRIDE { return true; } 100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) virtual bool PostDelayedTask(const tracked_objects::Location& location, 101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const Closure& closure, 102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::TimeDelta delta) OVERRIDE { 103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return mock_->PostDelayedTask(location, closure, delta); 104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) virtual bool PostNonNestableDelayedTask( 106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const tracked_objects::Location& location, 107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const Closure& closure, 108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::TimeDelta delta) OVERRIDE { 109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return mock_->PostNonNestableDelayedTask(location, closure, delta); 110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) private: 113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) MockTaskRunner* mock_; 114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) virtual ~TaskRunnerProxy() {} 115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}; 116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(StartupTaskRunnerTest, SynchronousExecution) { 118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) MockTaskRunner mock_runner; 119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner); 120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 121a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0); 122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _, _)).Times(0); 123a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 124424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) StartupTaskRunner runner(base::Bind(&Observer), proxy); 125a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) StartupTask task1 = 127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind(&StartupTaskRunnerTest::Task1, base::Unretained(this)); 128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) runner.AddTask(task1); 129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(GetLastTask(), 0); 130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) StartupTask task2 = 131a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this)); 132424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) runner.AddTask(task2); 133a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Nothing should run until we tell them to. 135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(GetLastTask(), 0); 136424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) runner.RunAllTasksNow(); 137a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 138a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // On an immediate StartupTaskRunner the tasks should now all have run. 139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(GetLastTask(), 2); 140a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(task_count, 2); 1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(observer_calls, 1); 143a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(observer_result, 0); 1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Running the tasks asynchronously shouldn't do anything 1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // In particular Post... should not be called 1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) runner.StartRunningTasksAsync(); 1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // No more tasks should be run and the observer should not have been called 1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // again 1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(task_count, 2); 1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(observer_calls, 1); 153a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 154a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 155a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(StartupTaskRunnerTest, NullObserver) { 156a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) MockTaskRunner mock_runner; 157a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner); 158a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 159a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0); 160a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _, _)).Times(0); 161a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 162424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) StartupTaskRunner runner(base::Callback<void(int)>(), proxy); 163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 164a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) StartupTask task1 = 165a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind(&StartupTaskRunnerTest::Task1, base::Unretained(this)); 166424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) runner.AddTask(task1); 167a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(GetLastTask(), 0); 168a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) StartupTask task2 = 169a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this)); 170424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) runner.AddTask(task2); 171a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 172a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Nothing should run until we tell them to. 173a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(GetLastTask(), 0); 174424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) runner.RunAllTasksNow(); 175a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 176a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // On an immediate StartupTaskRunner the tasks should now all have run. 177a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(GetLastTask(), 2); 1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(task_count, 2); 1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Running the tasks asynchronously shouldn't do anything 1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // In particular Post... should not be called 1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) runner.StartRunningTasksAsync(); 1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // No more tasks should have been run 1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(task_count, 2); 186a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(observer_calls, 0); 188a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 189a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 190a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(StartupTaskRunnerTest, SynchronousExecutionFailedTask) { 191a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) MockTaskRunner mock_runner; 192a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner); 193a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 194a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0); 195a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _, _)).Times(0); 196a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 197424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) StartupTaskRunner runner(base::Bind(&Observer), proxy); 198a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 199a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) StartupTask task3 = 200a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind(&StartupTaskRunnerTest::FailingTask, base::Unretained(this)); 201424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) runner.AddTask(task3); 202a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(GetLastTask(), 0); 203a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) StartupTask task2 = 204a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this)); 205424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) runner.AddTask(task2); 206a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 207a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Nothing should run until we tell them to. 208a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(GetLastTask(), 0); 209424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) runner.RunAllTasksNow(); 210a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 211a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Only the first task should have run, since it failed 212a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(GetLastTask(), 3); 2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(task_count, 1); 2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(observer_calls, 1); 215a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(observer_result, 1); 2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // After a failed task all remaining tasks should be cancelled 2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // In particular Post... should not be called by running asynchronously 2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) runner.StartRunningTasksAsync(); 2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // The observer should only be called the first time the queue completes and 2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // no more tasks should have run 2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(observer_calls, 1); 2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(task_count, 1); 225a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 226a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 227a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(StartupTaskRunnerTest, AsynchronousExecution) { 228a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 229a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) MockTaskRunner mock_runner; 230a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner); 231a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 232a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0); 233a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_CALL( 234a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) mock_runner, 235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PostNonNestableDelayedTask(_, _, base::TimeDelta::FromMilliseconds(0))) 236a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) .Times(testing::Between(2, 3)) 237a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) .WillRepeatedly(WithArg<1>(Invoke(SaveTaskArg))); 238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 239424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) StartupTaskRunner runner(base::Bind(&Observer), proxy); 240a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 241a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) StartupTask task1 = 242a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind(&StartupTaskRunnerTest::Task1, base::Unretained(this)); 243424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) runner.AddTask(task1); 244a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) StartupTask task2 = 245a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this)); 246424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) runner.AddTask(task2); 247a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 248a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Nothing should run until we tell them to. 249a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(GetLastTask(), 0); 250424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) runner.StartRunningTasksAsync(); 251a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 252a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // No tasks should have run yet, since we the message loop hasn't run. 253a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(GetLastTask(), 0); 254a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 255a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Fake the actual message loop. Each time a task is run a new task should 256a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // be added to the queue, hence updating "task". The loop should actually run 257a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // at most 3 times (once for each task plus possibly once for the observer), 258a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // the "4" is a backstop. 2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (int i = 0; i < 4 && observer_calls == 0; i++) { 260a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) task.Run(); 261a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(i + 1, GetLastTask()); 262a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(task_count, 2); 2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(observer_calls, 1); 265a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(observer_result, 0); 2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Check that running synchronously now doesn't do anything 2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) runner.RunAllTasksNow(); 2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(task_count, 2); 2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(observer_calls, 1); 272a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 273a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(StartupTaskRunnerTest, AsynchronousExecutionFailedTask) { 275a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 276a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) MockTaskRunner mock_runner; 277a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner); 278a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 279a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0); 280a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_CALL( 281a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) mock_runner, 282a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PostNonNestableDelayedTask(_, _, base::TimeDelta::FromMilliseconds(0))) 283a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) .Times(testing::Between(1, 2)) 284a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) .WillRepeatedly(WithArg<1>(Invoke(SaveTaskArg))); 285a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 286424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) StartupTaskRunner runner(base::Bind(&Observer), proxy); 287a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 288a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) StartupTask task3 = 289a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind(&StartupTaskRunnerTest::FailingTask, base::Unretained(this)); 290424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) runner.AddTask(task3); 291a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) StartupTask task2 = 292a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this)); 293424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) runner.AddTask(task2); 294a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 295a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Nothing should run until we tell them to. 296a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(GetLastTask(), 0); 297424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) runner.StartRunningTasksAsync(); 298a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 299a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // No tasks should have run yet, since we the message loop hasn't run. 300a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(GetLastTask(), 0); 301a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 302a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Fake the actual message loop. Each time a task is run a new task should 303a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // be added to the queue, hence updating "task". The loop should actually run 304a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // at most twice (once for the failed task plus possibly once for the 305a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // observer), the "4" is a backstop. 3064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (int i = 0; i < 4 && observer_calls == 0; i++) { 307a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) task.Run(); 308a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 309a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(GetLastTask(), 3); 3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(task_count, 1); 311a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 3124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(observer_calls, 1); 313a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(observer_result, 1); 3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Check that running synchronously now doesn't do anything 3164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) runner.RunAllTasksNow(); 3174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(observer_calls, 1); 3184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(task_count, 1); 319a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 320a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} // namespace 321a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} // namespace content 322