| Index: chrome/browser/storage_monitor/schedule_unittest.cc
|
| diff --git a/chrome/browser/storage_monitor/schedule_unittest.cc b/chrome/browser/storage_monitor/schedule_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..4ec351f7e7abe60bafce44a13cfa46883b948004
|
| --- /dev/null
|
| +++ b/chrome/browser/storage_monitor/schedule_unittest.cc
|
| @@ -0,0 +1,377 @@
|
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/message_loop/message_loop.h"
|
| +#include "base/run_loop.h"
|
| +#include "base/threading/sequenced_worker_pool.h"
|
| +#include "chrome/browser/storage_monitor/schedule.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace chrome {
|
| +
|
| +namespace {
|
| +
|
| +int global_state = 0;
|
| +
|
| +void SimpleStage1(int* state) { *state += 1; }
|
| +
|
| +void SimpleStage2(int* state) { *state += 10; }
|
| +
|
| +void SimpleStage3(int* state) { *state += 100; }
|
| +
|
| +void SimpleStage4(int* state) { *state += 1000; }
|
| +
|
| +void SimpleDone(int* state, int expect) { EXPECT_EQ(expect, *state); }
|
| +
|
| +void AsyncStage(int* state, base::Closure c) {
|
| + *state += 10000;
|
| + c.Run();
|
| +}
|
| +
|
| +int ReturnStage(int* state) { return 2 * (*state); }
|
| +
|
| +void TranscribeStage(int* state, int input) { *state = input; }
|
| +
|
| +void Canceller(base::WeakPtr<Schedule> schedule) {
|
| + schedule->Cancel(FROM_HERE);
|
| +}
|
| +
|
| +void DeleteInt(int* state) { delete state; }
|
| +
|
| +bool GreaterThanTwo(int* state) {
|
| + if (*state > 2)
|
| + return true;
|
| +
|
| + return false;
|
| +}
|
| +
|
| +void SetLatch(bool* latch) { *latch = true; }
|
| +
|
| +} // namespace
|
| +
|
| +class ScheduleTest : public testing::Test {
|
| + protected:
|
| + virtual void SetUp() OVERRIDE {
|
| + pool_a_ = make_scoped_refptr(new base::SequencedWorkerPool(1, "poolA"));
|
| + pool_b_ = make_scoped_refptr(new base::SequencedWorkerPool(1, "poolB"));
|
| + }
|
| +
|
| + virtual void TearDown() OVERRIDE {
|
| + pool_b_->Shutdown();
|
| + pool_a_->Shutdown();
|
| + }
|
| +
|
| + public:
|
| + void IncrementOnA(int* state) {
|
| + EXPECT_TRUE(pool_a_->RunsTasksOnCurrentThread());
|
| + EXPECT_FALSE(pool_b_->RunsTasksOnCurrentThread());
|
| + *state += 1;
|
| + }
|
| +
|
| + void IncrementOnB(int* state) {
|
| + EXPECT_TRUE(pool_b_->RunsTasksOnCurrentThread());
|
| + EXPECT_FALSE(pool_a_->RunsTasksOnCurrentThread());
|
| + *state += 10;
|
| + }
|
| +
|
| + protected:
|
| + base::MessageLoop loop_;
|
| + scoped_refptr<base::SequencedWorkerPool> pool_a_;
|
| + scoped_refptr<base::SequencedWorkerPool> pool_b_;
|
| +};
|
| +
|
| +TEST_F(ScheduleTest, TestEmpty) {
|
| + bool exited = false;
|
| +
|
| + base::RunLoop run_loop;
|
| + ScheduleBuilder b("Empty", FROM_HERE);
|
| + base::WeakPtr<Schedule> s = b.Build();
|
| + s->OnExit(run_loop.QuitClosure());
|
| + s->OnExit(base::Bind(&SetLatch, &exited));
|
| + s->Start();
|
| +
|
| + run_loop.Run();
|
| + EXPECT_TRUE(exited);
|
| +}
|
| +
|
| +TEST_F(ScheduleTest, TestEmptyState) {
|
| + bool exited = false;
|
| +
|
| + base::RunLoop run_loop;
|
| + ScheduleBuilder b("EmptyState", FROM_HERE);
|
| + b.NextStage();
|
| + b.NextStage();
|
| + b.NextStage();
|
| + base::WeakPtr<Schedule> s = b.Build();
|
| + s->OnExit(run_loop.QuitClosure());
|
| + s->OnExit(base::Bind(&SetLatch, &exited));
|
| + s->Start();
|
| +
|
| + run_loop.Run();
|
| + EXPECT_TRUE(exited);
|
| +}
|
| +
|
| +TEST_F(ScheduleTest, TestSimpleFlowWithState) {
|
| + base::RunLoop run_loop;
|
| +
|
| + int* int_state = new int;
|
| + *int_state = 0;
|
| +
|
| + ScheduleBuilder b("SimpleOwnedState", FROM_HERE);
|
| + b.Run(base::Bind(&SimpleStage1, int_state));
|
| + b.NextStage();
|
| + b.Run(base::Bind(&SimpleStage2, int_state));
|
| + b.NextStage();
|
| + b.Run(base::Bind(&SimpleStage3, int_state));
|
| + b.NextStage();
|
| + b.Run(base::Bind(&SimpleDone, int_state, 111));
|
| + base::WeakPtr<Schedule> s = b.Build();
|
| + s->OnExit(run_loop.QuitClosure());
|
| + s->OnExit(base::Bind(&DeleteInt, int_state));
|
| + s->Start();
|
| +
|
| + run_loop.Run();
|
| +}
|
| +
|
| +TEST_F(ScheduleTest, TestParallelFlowWithScheduleOwnership) {
|
| + base::RunLoop run_loop;
|
| +
|
| + int* int_state = new int;
|
| + *int_state = 0;
|
| +
|
| + ScheduleBuilder b("ParallelFlow", FROM_HERE);
|
| + b.Run(base::Bind(&SimpleStage1, int_state));
|
| + b.NextStage();
|
| + b.Run(base::Bind(&SimpleStage2, int_state));
|
| + b.NextStage();
|
| + b.Run(base::Bind(&SimpleStage3, int_state));
|
| + b.Run(base::Bind(&SimpleStage3, int_state));
|
| + b.Run(base::Bind(&SimpleStage3, int_state));
|
| + b.NextStage();
|
| + b.Run(base::Bind(&SimpleDone, int_state, 311));
|
| + base::WeakPtr<Schedule> s = b.Build();
|
| + s->OnExit(run_loop.QuitClosure());
|
| + s->DeleteOnExit(int_state);
|
| + s->Start();
|
| +
|
| + run_loop.Run();
|
| +}
|
| +
|
| +TEST_F(ScheduleTest, TestSimpleFlowUnownedState) {
|
| + base::RunLoop run_loop;
|
| +
|
| + int unowned_state = 0;
|
| +
|
| + ScheduleBuilder b("SimpleUnownedState", FROM_HERE);
|
| + b.Run(base::Bind(&SimpleStage1, &unowned_state));
|
| + b.NextStage();
|
| + b.Run(base::Bind(&SimpleStage2, &unowned_state));
|
| + b.NextStage();
|
| + b.Run(base::Bind(&SimpleStage3, &unowned_state));
|
| + b.NextStage();
|
| + b.Run(base::Bind(&SimpleDone, &unowned_state, 111));
|
| + base::WeakPtr<Schedule> s = b.Build();
|
| + s->OnExit(run_loop.QuitClosure());
|
| + s->Start();
|
| +
|
| + run_loop.Run();
|
| +
|
| + EXPECT_EQ(111, unowned_state);
|
| +}
|
| +
|
| +TEST_F(ScheduleTest, TestSimpleFlowGlobalState) {
|
| + base::RunLoop run_loop;
|
| +
|
| + ScheduleBuilder b("SimpleGlobalState", FROM_HERE);
|
| + b.Run(base::Bind(&SimpleStage1, &global_state));
|
| + b.NextStage();
|
| + b.Run(base::Bind(&SimpleStage2, &global_state));
|
| + b.NextStage();
|
| + b.Run(base::Bind(&SimpleStage3, &global_state));
|
| + base::WeakPtr<Schedule> s = b.Build();
|
| + s->OnExit(run_loop.QuitClosure());
|
| + s->Start();
|
| +
|
| + run_loop.Run();
|
| +
|
| + EXPECT_EQ(111, global_state);
|
| +}
|
| +
|
| +TEST_F(ScheduleTest, TestFlowCrossPool) {
|
| + base::RunLoop run_loop;
|
| +
|
| + int* int_state = new int;
|
| + *int_state = 0;
|
| +
|
| + ScheduleBuilder b("CrossPool", FROM_HERE);
|
| + b.RunOn(base::Bind(&SimpleStage1, int_state), pool_b_);
|
| + b.NextStage();
|
| + b.RunOn(base::Bind(&SimpleStage2, int_state), pool_a_);
|
| + b.NextStage();
|
| + b.RunOn(base::Bind(&SimpleStage3, int_state), pool_b_);
|
| + b.NextStage();
|
| + b.RunOn(base::Bind(&SimpleStage4, int_state), pool_a_);
|
| + b.NextStage();
|
| + b.RunOn(base::Bind(&SimpleDone, int_state, 1111), pool_b_);
|
| + base::WeakPtr<Schedule> s = b.Build();
|
| + s->OnExit(run_loop.QuitClosure());
|
| + s->OnExit(base::Bind(&DeleteInt, int_state));
|
| + s->Start();
|
| +
|
| + run_loop.Run();
|
| +}
|
| +
|
| +TEST_F(ScheduleTest, TestFlowCrossPoolMemberMethods) {
|
| + base::RunLoop run_loop;
|
| +
|
| + int int_state = 0;
|
| +
|
| + ScheduleBuilder b("CrossPoolMembers", FROM_HERE);
|
| + b.RunOn(base::Bind(
|
| + &ScheduleTest::IncrementOnA, base::Unretained(this), &int_state),
|
| + pool_a_);
|
| + b.NextStage();
|
| + b.RunOn(base::Bind(
|
| + &ScheduleTest::IncrementOnB, base::Unretained(this), &int_state),
|
| + pool_b_);
|
| + b.NextStage();
|
| + b.RunOn(base::Bind(&SimpleDone, &int_state, 11), pool_b_);
|
| + base::WeakPtr<Schedule> s = b.Build();
|
| + s->OnExit(run_loop.QuitClosure());
|
| + s->Start();
|
| +
|
| + run_loop.Run();
|
| +}
|
| +
|
| +TEST_F(ScheduleTest, TestAsyncCrossPool) {
|
| + base::RunLoop run_loop;
|
| + int int_state = 0;
|
| +
|
| + ScheduleBuilder b("CrossPoolAsync", FROM_HERE);
|
| + b.RunAsyncOn(base::Bind(&AsyncStage, &int_state, b.ContinueClosure()),
|
| + pool_a_);
|
| + b.NextStage();
|
| + b.RunOn(base::Bind(&SimpleDone, &int_state, 10000), pool_b_);
|
| + base::WeakPtr<Schedule> s = b.Build();
|
| + s->OnExit(run_loop.QuitClosure());
|
| + s->Start();
|
| +
|
| + run_loop.Run();
|
| +}
|
| +
|
| +TEST_F(ScheduleTest, TestAsync) {
|
| + base::RunLoop run_loop;
|
| +
|
| + int int_state = 0;
|
| +
|
| + ScheduleBuilder b("SimpleAsync", FROM_HERE);
|
| + b.Run(base::Bind(&SimpleStage1, &int_state));
|
| + b.NextStage();
|
| + b.RunAsync(base::Bind(&AsyncStage, &int_state, b.ContinueClosure()));
|
| + base::WeakPtr<Schedule> s = b.Build();
|
| + s->OnExit(run_loop.QuitClosure());
|
| + s->Start();
|
| +
|
| + run_loop.Run();
|
| + EXPECT_EQ(10001, int_state);
|
| +}
|
| +
|
| +TEST_F(ScheduleTest, TestConditional) {
|
| + base::RunLoop run_loop;
|
| +
|
| + int int_state = 0;
|
| +
|
| + ScheduleBuilder b("Conditional", FROM_HERE);
|
| + b.NextStageConditional(base::Bind(&GreaterThanTwo, &int_state));
|
| + b.Run(base::Bind(&SimpleStage3, &int_state));
|
| + b.NextStage();
|
| + b.Run(base::Bind(&SimpleStage2, &int_state));
|
| + b.NextStageConditional(base::Bind(&GreaterThanTwo, &int_state));
|
| + b.Run(base::Bind(&SimpleStage1, &int_state));
|
| + base::WeakPtr<Schedule> s = b.Build();
|
| + s->OnExit(run_loop.QuitClosure());
|
| + s->Start();
|
| +
|
| + run_loop.Run();
|
| + EXPECT_EQ(11, int_state);
|
| +}
|
| +
|
| +TEST_F(ScheduleTest, TestCancel) {
|
| + base::RunLoop run_loop;
|
| +
|
| + int int_state = 0;
|
| + bool cancelled = false;
|
| + bool exited = false;
|
| +
|
| + ScheduleBuilder b("Cancel", FROM_HERE);
|
| + b.Run(base::Bind(&SimpleStage1, &int_state));
|
| + b.NextStage();
|
| + b.Run(base::Bind(&Canceller, b.schedule()));
|
| + b.NextStage();
|
| + b.Run(base::Bind(&SimpleStage2, &int_state));
|
| + b.NextStage();
|
| + b.Run(base::Bind(&SimpleStage3, &int_state));
|
| + base::WeakPtr<Schedule> s = b.Build();
|
| + s->OnExit(run_loop.QuitClosure());
|
| + s->OnExit(base::Bind(&SetLatch, &exited));
|
| + s->OnCancel(base::Bind(&SetLatch, &cancelled));
|
| + s->Start();
|
| +
|
| + run_loop.Run();
|
| + EXPECT_EQ(1, int_state);
|
| + EXPECT_TRUE(cancelled);
|
| + EXPECT_TRUE(exited);
|
| +}
|
| +
|
| +TEST_F(ScheduleTest, TestUnstartedCancel) {
|
| + int int_state = 0;
|
| + bool cancelled = false;
|
| + bool exited = false;
|
| +
|
| + ScheduleBuilder b("Cancel", FROM_HERE);
|
| + b.Run(base::Bind(&SimpleStage1, &int_state));
|
| + b.NextStage();
|
| + b.Run(base::Bind(&Canceller, b.schedule()));
|
| + b.NextStage();
|
| + b.Run(base::Bind(&SimpleStage2, &int_state));
|
| + b.NextStage();
|
| + b.Run(base::Bind(&SimpleStage3, &int_state));
|
| + base::WeakPtr<Schedule> s = b.Build();
|
| + s->OnExit(base::Bind(&SetLatch, &exited));
|
| + s->OnCancel(base::Bind(&SetLatch, &cancelled));
|
| +
|
| + s->Cancel(FROM_HERE);
|
| +
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + EXPECT_EQ(0, int_state);
|
| + EXPECT_TRUE(cancelled);
|
| + EXPECT_TRUE(exited);
|
| +}
|
| +
|
| +struct IntState {
|
| + int s;
|
| +};
|
| +
|
| +TEST_F(ScheduleTest, TestReturnStorage) {
|
| + base::RunLoop run_loop;
|
| +
|
| + int input = 2;
|
| +
|
| + IntState state;
|
| + state.s = 10;
|
| +
|
| + ScheduleBuilder b("Storage", FROM_HERE);
|
| + b.Run(RunAndStore(base::Bind(&ReturnStage, &input), &(state.s)));
|
| + base::WeakPtr<Schedule> s = b.Build();
|
| + s->OnExit(run_loop.QuitClosure());
|
| + s->Start();
|
| +
|
| + run_loop.Run();
|
| +
|
| + EXPECT_EQ(4, state.s);
|
| +}
|
| +
|
| +} // namespace chrome
|
|
|