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

Unified Diff: components/scheduler/promises/thread_pool_promise_executor_unittest.cc

Issue 1401553002: NOT INTENDED FOR LANDING: A promises demo (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Support for rejectatble promises! Created 4 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/scheduler/promises/thread_pool_promise_executor.cc ('k') | components/scheduler/scheduler.gypi » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/scheduler/promises/thread_pool_promise_executor_unittest.cc
diff --git a/components/scheduler/promises/thread_pool_promise_executor_unittest.cc b/components/scheduler/promises/thread_pool_promise_executor_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f77757c3f006d98c15597489197370b1482be32a
--- /dev/null
+++ b/components/scheduler/promises/thread_pool_promise_executor_unittest.cc
@@ -0,0 +1,437 @@
+// Copyright 2016 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 "components/scheduler/promises/thread_pool_promise_executor.h"
+
+#include "base/bind.h"
+#include "base/synchronization/waitable_event.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::ElementsAre;
+using testing::WhenSorted;
+
+#if 0
+
+namespace promise {
+
+class ThreadPoolPromiseExecutorTest : public testing::Test {
+ public:
+ ThreadPoolPromiseExecutorTest() {}
+ ~ThreadPoolPromiseExecutorTest() override {}
+
+ void SetUp() override {
+ promise_executor_.reset(new internal::ThreadPoolPromiseExecutor());
+ }
+
+ scoped_ptr<internal::ThreadPoolPromiseExecutor> promise_executor_;
+};
+
+namespace {
+bool ReturnTrue() {
+ return true;
+}
+
+int ReturnOne() {
+ return 1;
+}
+
+int ReturnTwo() {
+ return 2;
+}
+
+int ReturnTen() {
+ return 10;
+}
+
+int AddOne(int i) {
+ return i + 1;
+}
+
+int CondTimesThree(int i, bool do_smth) {
+ if (do_smth)
+ return i * 3;
+ return i;
+}
+
+int ReturnZero() {
+ return 0;
+}
+
+scoped_refptr<Promise<int>> Choose(scoped_refptr<Promise<int>> p1,
+ scoped_refptr<Promise<int>> p2,
+ int i) {
+ return i ? p1 : p2;
+}
+
+void RecordOrder(int value, std::vector<int>* out_result) {
+ out_result->push_back(value);
+}
+
+void SignalWaitableEvent(base::WaitableEvent* waitable_event, int) {
+ waitable_event->Signal();
+}
+
+void SignalWaitableEventVoid(base::WaitableEvent* waitable_event) {
+ waitable_event->Signal();
+}
+
+} // namespace
+
+TEST_F(ThreadPoolPromiseExecutorTest, NonVoidPromise) {
+ base::WaitableEvent event(true, false);
+ scoped_refptr<Promise<int>> promise(promise::Create(base::Bind(&ReturnOne)));
+
+ scoped_refptr<Promise<void>> wait_promise(
+ promise.Then(base::Bind(&SignalWaitableEvent, &event)));
+
+ promise_executor_->StartResolve(wait_promise.get());
+ event.Wait();
+ EXPECT_EQ(1, promise->GetResolved());
+}
+
+TEST_F(ThreadPoolPromiseExecutorTest, RunAfter_OnePromise_AndThen) {
+ scoped_refptr<Promise<int>> promise(
+ promise::Create(base::Bind(&ReturnOne)).Then(base::Bind(&AddOne)));
+
+ base::WaitableEvent event(true, false);
+ scoped_refptr<Promise<void>> wait_promise(
+ promise.Then(base::Bind(&SignalWaitableEvent, &event)));
+
+ promise_executor_->StartResolve(wait_promise.get());
+ event.Wait();
+ EXPECT_EQ(2, promise->GetResolved());
+}
+
+TEST_F(ThreadPoolPromiseExecutorTest, RunAfter_TwoPromises_AndThen) {
+ base::WaitableEvent event(true, false);
+ scoped_refptr<Promise<int>> promise(
+ promise::All(promise::Create(base::Bind(&ReturnOne)),
+ promise::Create(base::Bind(&ReturnTrue)))
+ .Then(base::Bind(&CondTimesThree)));
+
+ scoped_refptr<Promise<void>> wait_promise(
+ promise.Then(base::Bind(&SignalWaitableEvent, &event)));
+
+ promise_executor_->StartResolve(wait_promise.get());
+ event.Wait();
+ EXPECT_EQ(3, promise->GetResolved());
+}
+
+TEST_F(ThreadPoolPromiseExecutorTest, ChainOfPromises) {
+ scoped_refptr<Promise<int>> promise(promise::Create(base::Bind(&ReturnOne))
+ .Then(base::Bind(&AddOne))
+ .Then(base::Bind(&AddOne))
+ .Then(base::Bind(&AddOne))
+ .Then(base::Bind(&AddOne)));
+
+ base::WaitableEvent event(true, false);
+ scoped_refptr<Promise<void>> wait_promise(
+ promise.Then(base::Bind(&SignalWaitableEvent, &event)));
+
+ promise_executor_->StartResolve(wait_promise.get());
+ event.Wait();
+ EXPECT_EQ(5, promise->GetResolved());
+}
+
+TEST_F(ThreadPoolPromiseExecutorTest, EagerTasksExecutedFirst) {
+ std::vector<int> run_order;
+
+ scoped_refptr<Promise<void>> promiseA(
+ promise::Create(base::Bind(&RecordOrder, 0, &run_order))
+ .Then(base::Bind(&RecordOrder, 1, &run_order))
+ .Then(base::Bind(&RecordOrder, 2, &run_order))
+ .Then(base::Bind(&RecordOrder, 3, &run_order))
+ .Then(base::Bind(&RecordOrder, 4, &run_order)));
+
+ scoped_refptr<Promise<void>> promiseB(
+ promise::Create(base::Bind(&RecordOrder, 10, &run_order))
+ .Then(base::Bind(&RecordOrder, 11, &run_order))
+ .Then(base::Bind(&RecordOrder, 12, &run_order))
+ .Then(base::Bind(&RecordOrder, 13, &run_order))
+ .Then(base::Bind(&RecordOrder, 14, &run_order)));
+
+ promiseB->SetEager(true);
+
+ base::WaitableEvent event(true, false);
+ scoped_refptr<Promise<void>> wait_promise(
+ promise::All(promiseA, promiseB)
+ .Then(base::Bind(&SignalWaitableEventVoid, &event)));
+
+ promise_executor_->StartResolve(wait_promise.get());
+ event.Wait();
+
+ EXPECT_THAT(run_order, ElementsAre(10, 11, 12, 13, 14, 0, 1, 2, 3, 4));
+}
+
+TEST_F(ThreadPoolPromiseExecutorTest, Cancel) {
+ /*std::vector<int> run_order;
+
+ scoped_refptr<Promise<void>> promise(promise::Create(
+ base::Bind(&RecordOrder, 1, &run_order)));
+
+ base::WaitableEvent event(true, false);
+ scoped_refptr<Promise<void>> wait_promise(
+ promise.Then(base::Bind(&SignalWaitableEventVoid, &event)));
+
+ promise_executor_->StartResolve(wait_promise.get());
+ wait_promise->Cancel();
+ event.Wait();
+
+ EXPECT_TRUE(run_order.empty());*/
+}
+
+TEST_F(ThreadPoolPromiseExecutorTest, CancelChainOfTasks) {
+ std::vector<int> run_order;
+
+ scoped_refptr<Promise<void>> promiseA(
+ promise::Create(base::Bind(&RecordOrder, 0, &run_order))
+ .Then(base::Bind(&RecordOrder, 1, &run_order))
+ .Then(base::Bind(&RecordOrder, 2, &run_order))
+ .Then(base::Bind(&RecordOrder, 3, &run_order))
+ .Then(base::Bind(&RecordOrder, 4, &run_order)));
+
+ scoped_refptr<Promise<void>> promiseB(
+ promise::Create(base::Bind(&RecordOrder, 10, &run_order))
+ .Then(base::Bind(&RecordOrder, 11, &run_order))
+ .Then(base::Bind(&RecordOrder, 12, &run_order))
+ .Then(base::Bind(&RecordOrder, 13, &run_order))
+ .Then(base::Bind(&RecordOrder, 14, &run_order)));
+
+ base::WaitableEvent event(true, false);
+ scoped_refptr<Promise<void>> wait_promise(
+ promiseA.Then(base::Bind(&SignalWaitableEventVoid, &event)));
+
+ promise_executor_->StartResolve(promiseB.get());
+ promiseB->Cancel();
+ promise_executor_->StartResolve(wait_promise.get());
+ event.Wait();
+
+ EXPECT_THAT(run_order, ElementsAre(0, 1, 2, 3, 4));
+}
+
+TEST_F(ThreadPoolPromiseExecutorTest, CancelOneBranch) {
+ std::vector<int> run_order;
+
+ scoped_refptr<Promise<void>> promiseA(
+ promise::Create(base::Bind(&RecordOrder, 0, &run_order))
+ .Then(base::Bind(&RecordOrder, 1, &run_order)));
+
+ scoped_refptr<Promise<void>> promiseB(
+ promiseA.Then(base::Bind(&RecordOrder, 2, &run_order))
+ .Then(base::Bind(&RecordOrder, 3, &run_order)));
+
+ scoped_refptr<Promise<void>> promiseC(
+ promiseA.Then(base::Bind(&RecordOrder, 4, &run_order))
+ .Then(base::Bind(&RecordOrder, 5, &run_order)));
+
+ base::WaitableEvent event(true, false);
+ scoped_refptr<Promise<void>> wait_promise(
+ promiseC.Then(base::Bind(&SignalWaitableEventVoid, &event)));
+
+ promise_executor_->StartResolve(promiseB.get());
+ promise_executor_->StartResolve(wait_promise.get());
+
+ promiseB->Cancel();
+
+ event.Wait();
+
+ EXPECT_THAT(run_order, ElementsAre(0, 1, 4, 5));
+}
+
+TEST_F(ThreadPoolPromiseExecutorTest, Choose) {
+ scoped_refptr<Promise<int>> promise_two(
+ promise::Create(base::Bind(&ReturnTwo)));
+ scoped_refptr<Promise<int>> promise_ten(
+ promise::Create(base::Bind(&ReturnTen)));
+ scoped_refptr<Promise<int>> promiseA(
+ promise::Create(base::Bind(&ReturnZero))
+ .Then(base::Bind(&Choose, promise_two, promise_ten)));
+
+ scoped_refptr<Promise<int>> promiseB(
+ promise::Create(base::Bind(&ReturnOne))
+ .Then(base::Bind(&Choose, promise_two, promise_ten)));
+
+ base::WaitableEvent event(true, false);
+ scoped_refptr<Promise<void>> wait_promise(
+ promise::All(promiseA, promiseB)
+ .Then(base::Bind(&SignalWaitableEventVoid, &event)));
+
+ promise_executor_->StartResolve(wait_promise.get());
+ event.Wait();
+
+ EXPECT_EQ(10, promiseA->GetResolved());
+ EXPECT_EQ(2, promiseB->GetResolved());
+}
+/*
+TEST_F(ThreadPoolPromiseExecutorTest, ChooseAndAddOne) {
+ scoped_refptr<Promise<int>> promise_a(
+ promise::Create(base::Bind(&ReturnZero)));
+ scoped_refptr<Promise<int>> promise_b(
+ promise::Create(base::Bind(&ReturnOne)));
+ scoped_refptr<Promise<int>> promise_c(
+ promise::Create(base::Bind(&ReturnTen)));
+
+ scoped_refptr<Promise<int>> promise_d_zero(promise_executor_->RunAfter(
+ base::Bind(&Choose, promise_b, promise_c), promise_a));
+
+ scoped_refptr<Promise<int>> promise_d_one(promise_executor_->RunAfter(
+ base::Bind(&Choose, promise_b, promise_c), promise_b));
+
+ scoped_refptr<Promise<int>> promise_e(
+ promise_executor_->RunAfter(base::Bind(&AddOne), promise_d_zero));
+
+ scoped_refptr<Promise<int>> promise_f(
+ promise_executor_->RunAfter(base::Bind(&AddOne), promise_d_one));
+
+ base::WaitableEvent event(true, false);
+ scoped_refptr<Promise<void>> wait_promise(promise_executor_->RunAfter(
+ base::Bind(&SignalWaitableEventVoid, &event), promise_e, promise_f));
+
+ promise_executor_->StartResolve(wait_promise.get());
+ event.Wait();
+
+ EXPECT_EQ(11, promise_e->GetResolved());
+ EXPECT_EQ(2, promise_f->GetResolved());
+}
+
+TEST_F(ThreadPoolPromiseExecutorTest, ChooseAndAddOne_ResolvedPromise) {
+ scoped_refptr<Promise<int>> promise_one(
+ promise::Create(base::Bind(&ReturnOne)));
+
+ scoped_refptr<Promise<int>> promise_zero(
+ promise::Create(base::Bind(&ReturnZero)));
+
+ scoped_refptr<Promise<int>> promise_a(promise_executor_->RunAfter(
+ base::Bind(&Choose,
+make_scoped_refptr(promise::Create<int>(1)),
+ make_scoped_refptr(promise::Create<int>(10))),
+ promise_zero));
+
+ scoped_refptr<Promise<int>> promise_b(promise_executor_->RunAfter(
+ base::Bind(&Choose,
+make_scoped_refptr(promise::Create<int>(1)),
+ make_scoped_refptr(promise::Create<int>(10))),
+ promise_one));
+
+ scoped_refptr<Promise<int>> promise_c(
+ promise_executor_->RunAfter(base::Bind(&AddOne), promise_a));
+
+ scoped_refptr<Promise<int>> promise_d(
+ promise_executor_->RunAfter(base::Bind(&AddOne), promise_b));
+
+ base::WaitableEvent event(true, false);
+ scoped_refptr<Promise<void>> wait_promise(promise_executor_->RunAfter(
+ base::Bind(&SignalWaitableEventVoid, &event), promise_c, promise_d));
+
+ promise_executor_->StartResolve(wait_promise.get());
+ event.Wait();
+
+ EXPECT_EQ(11, promise_c->GetResolved());
+ EXPECT_EQ(2, promise_d->GetResolved());
+}
+*/
+
+namespace {
+class BlockingResolveFixture {
+ public:
+ void Root() { run_order_.push_back("Root"); }
+
+ void L() { run_order_.push_back("L"); }
+
+ void LL() { run_order_.push_back("LL"); }
+
+ void LR() { run_order_.push_back("LR"); }
+
+ void R() { run_order_.push_back("R"); }
+
+ void RL() { run_order_.push_back("RL"); }
+
+ void RR() { run_order_.push_back("RL"); }
+
+ std::vector<std::string> run_order_;
+};
+} // namespace
+
+/*
+TEST_F(ThreadPoolPromiseExecutorTest, BlockingResolve) {
+ BlockingResolveFixture fixture;
+
+ scoped_refptr<Promise<void>> promise_ll(promise::Create(
+ base::Bind(&BlockingResolveFixture::LL, base::Unretained(&fixture))));
+
+ scoped_refptr<Promise<void>> promise_lr(promise::Create(
+ base::Bind(&BlockingResolveFixture::LR, base::Unretained(&fixture))));
+
+ scoped_refptr<Promise<void>> promise_l(promise_executor_->RunAfter(
+ base::Bind(&BlockingResolveFixture::L, base::Unretained(&fixture)),
+ promise_ll, promise_lr));
+
+ scoped_refptr<Promise<void>> promise_rl(promise::Create(
+ base::Bind(&BlockingResolveFixture::RL, base::Unretained(&fixture))));
+
+ scoped_refptr<Promise<void>> promise_rr(promise::Create(
+ base::Bind(&BlockingResolveFixture::RR, base::Unretained(&fixture))));
+
+ scoped_refptr<Promise<void>> blocking_promise(
+ promise::Create<void>());
+
+ scoped_refptr<Promise<void>> promise_r(promise_executor_->RunAfter(
+ base::Bind(&BlockingResolveFixture::R, base::Unretained(&fixture)),
+ promise_rl, promise_rr, scoped_refptr<Promise<void>>(blocking_promise)));
+
+ scoped_refptr<Promise<void>> promise_root(promise_executor_->RunAfter(
+ base::Bind(&BlockingResolveFixture::Root, base::Unretained(&fixture)),
+ promise_l, promise_r));
+
+ promise_executor_->StartResolve(promise_root.get());
+ mock_task_runner_->RunUntilIdle();
+ EXPECT_THAT(fixture.run_order_,
+ WhenSorted(ElementsAre(std::string("L"), std::string("LL"),
+ std::string("LR"), std::string("RL"),
+ std::string("RL"))));
+
+ fixture.run_order_.clear();
+ blocking_promise.Resolve();
+ mock_task_runner_->RunUntilIdle();
+ EXPECT_THAT(fixture.run_order_,
+ ElementsAre(std::string("R"), std::string("Root")));
+}
+
+namespace {
+scoped_refptr<Promise<void>> GenerateNewTask(PromiseExecutor* executor,
+ std::vector<int>* out_result) {
+ out_result->push_back(1);
+
+ scoped_refptr<Promise<void>> promise0(
+ executor->promise::Create(base::Bind(&RecordOrder, 2, out_result)));
+
+ return executor->RunAfter(base::Bind(&RecordOrder, 3, out_result), promise0);
+}
+} // namespace
+
+TEST_F(ThreadPoolPromiseExecutorTest, NewPromiseFromWithinPromise) {
+ std::vector<int> run_order;
+
+ scoped_refptr<Promise<void>> promise0(promise::Create(
+ base::Bind(&RecordOrder, 0, &run_order)));
+
+ scoped_refptr<Promise<void>> promise1(promise_executor_->RunAfter(
+ base::Bind(&GenerateNewTask, base::Unretained(promise_executor_.get()),
+ &run_order),
+ promise0));
+
+ scoped_refptr<Promise<void>> promise4(promise_executor_->RunAfter(
+ base::Bind(&RecordOrder, 4, &run_order), promise1));
+
+ promise_executor_->StartResolve(promise4.get());
+
+ mock_task_runner_->RunUntilIdle();
+
+ EXPECT_THAT(run_order, ElementsAre(0, 1, 2, 3, 4));
+}*/
+
+} // namespace promise
+
+#endif
« no previous file with comments | « components/scheduler/promises/thread_pool_promise_executor.cc ('k') | components/scheduler/scheduler.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698