Test default TaskQueue implementation via TaskQueueBase interface
Bug: webrtc:10191
Change-Id: I97a73311790e8ceac00d5575dd124ad8ad76503f
Reviewed-on: https://webrtc-review.googlesource.com/c/124400
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26853}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index ed3c708..32f4c8e 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -681,6 +681,7 @@
"../rtc_base:gunit_helpers",
"../rtc_base:rtc_base_approved",
"../test:test_support",
+ "task_queue:task_queue_default_factory_unittests",
"units:units_unittests",
]
}
diff --git a/api/task_queue/BUILD.gn b/api/task_queue/BUILD.gn
index 578a212..e7e3aec 100644
--- a/api/task_queue/BUILD.gn
+++ b/api/task_queue/BUILD.gn
@@ -60,9 +60,7 @@
}
rtc_source_set("default_task_queue_factory") {
- # TODO(bugs.webrtc.org/10191): Make public when implemented for all
- # supported platforms.
- visibility = [ ":global_task_queue_factory" ]
+ visibility = [ "*" ]
sources = [
"default_task_queue_factory.h",
]
@@ -112,6 +110,20 @@
}
}
+if (rtc_include_tests) {
+ rtc_source_set("task_queue_default_factory_unittests") {
+ testonly = true
+ sources = [
+ "default_task_queue_factory_unittest.cc",
+ ]
+ deps = [
+ ":default_task_queue_factory",
+ ":task_queue_test",
+ "../../test:test_support",
+ ]
+ }
+}
+
# Linking with global_task_queue_factory adds link-time implementation of the
# rtc::TaskQueue that allows run-time injection of the TaskQueue implementaion.
rtc_source_set("global_task_queue_factory") {
diff --git a/api/task_queue/default_task_queue_factory_unittest.cc b/api/task_queue/default_task_queue_factory_unittest.cc
new file mode 100644
index 0000000..92c17d8
--- /dev/null
+++ b/api/task_queue/default_task_queue_factory_unittest.cc
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2019 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/task_queue/default_task_queue_factory.h"
+
+#include "api/task_queue/task_queue_test.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace {
+
+INSTANTIATE_TEST_SUITE_P(Default,
+ TaskQueueTest,
+ ::testing::Values(CreateDefaultTaskQueueFactory));
+
+} // namespace
+} // namespace webrtc
diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn
index 63b4f3f..0c66af8 100644
--- a/rtc_base/BUILD.gn
+++ b/rtc_base/BUILD.gn
@@ -1321,7 +1321,6 @@
":rtc_base_tests_main",
":rtc_base_tests_utils",
":rtc_task_queue",
- ":rtc_task_queue_for_test",
"../test:test_support",
"//third_party/abseil-cpp/absl/memory",
]
diff --git a/rtc_base/task_queue_unittest.cc b/rtc_base/task_queue_unittest.cc
index 9086206..04861f3 100644
--- a/rtc_base/task_queue_unittest.cc
+++ b/rtc_base/task_queue_unittest.cc
@@ -24,12 +24,9 @@
#include "rtc_base/bind.h"
#include "rtc_base/event.h"
#include "rtc_base/task_queue.h"
-#include "rtc_base/task_queue_for_test.h"
#include "rtc_base/time_utils.h"
#include "test/gtest.h"
-using rtc::test::TaskQueueForTest;
-
namespace rtc {
namespace {
@@ -60,89 +57,6 @@
} // namespace
-TEST(TaskQueueTest, Construct) {
- static const char kQueueName[] = "Construct";
- TaskQueue queue(kQueueName);
- EXPECT_FALSE(queue.IsCurrent());
-}
-
-TEST(TaskQueueTest, PostAndCheckCurrent) {
- static const char kQueueName[] = "PostAndCheckCurrent";
- Event event;
- TaskQueue queue(kQueueName);
-
- // We're not running a task, so there shouldn't be a current queue.
- EXPECT_FALSE(queue.IsCurrent());
- EXPECT_FALSE(TaskQueue::Current());
-
- queue.PostTask(Bind(&CheckCurrent, &event, &queue));
- EXPECT_TRUE(event.Wait(1000));
-}
-
-TEST(TaskQueueTest, PostCustomTask) {
- static const char kQueueName[] = "PostCustomImplementation";
- TaskQueueForTest queue(kQueueName);
-
- class CustomTask : public QueuedTask {
- public:
- CustomTask() {}
- bool ran() const { return ran_; }
-
- private:
- bool Run() override {
- ran_ = true;
- return false; // Never allow the task to be deleted by the queue.
- }
-
- bool ran_ = false;
- } my_task;
-
- queue.SendTask(&my_task);
- EXPECT_TRUE(my_task.ran());
-}
-
-TEST(TaskQueueTest, PostLambda) {
- TaskQueueForTest queue("PostLambda");
- bool ran = false;
- queue.SendTask([&ran]() { ran = true; });
- EXPECT_TRUE(ran);
-}
-
-TEST(TaskQueueTest, PostDelayedZero) {
- static const char kQueueName[] = "PostDelayedZero";
- Event event;
- TaskQueue queue(kQueueName);
-
- queue.PostDelayedTask([&event]() { event.Set(); }, 0);
- EXPECT_TRUE(event.Wait(1000));
-}
-
-TEST(TaskQueueTest, PostFromQueue) {
- static const char kQueueName[] = "PostFromQueue";
- Event event;
- TaskQueue queue(kQueueName);
-
- queue.PostTask(
- [&event, &queue]() { queue.PostTask([&event]() { event.Set(); }); });
- EXPECT_TRUE(event.Wait(1000));
-}
-
-TEST(TaskQueueTest, PostDelayed) {
- static const char kQueueName[] = "PostDelayed";
- Event event;
- TaskQueue queue(kQueueName, TaskQueue::Priority::HIGH);
-
- uint32_t start = Time();
- queue.PostDelayedTask(Bind(&CheckCurrent, &event, &queue), 100);
- EXPECT_TRUE(event.Wait(1000));
- uint32_t end = Time();
- // These tests are a little relaxed due to how "powerful" our test bots can
- // be. Most recently we've seen windows bots fire the callback after 94-99ms,
- // which is why we have a little bit of leeway backwards as well.
- EXPECT_GE(end - start, 90u);
- EXPECT_NEAR(end - start, 190u, 100u); // Accept 90-290.
-}
-
// This task needs to be run manually due to the slowness of some of our bots.
// TODO(tommi): Can we run this on the perf bots?
TEST(TaskQueueTest, DISABLED_PostDelayedHighRes) {
@@ -163,80 +77,13 @@
EXPECT_NEAR(end - start, 3, 3u);
}
-TEST(TaskQueueTest, PostMultipleDelayed) {
- static const char kQueueName[] = "PostMultipleDelayed";
- TaskQueue queue(kQueueName);
-
- std::vector<std::unique_ptr<Event>> events;
- for (int i = 0; i < 100; ++i) {
- events.push_back(absl::make_unique<Event>());
- queue.PostDelayedTask(Bind(&CheckCurrent, events.back().get(), &queue), i);
- }
-
- for (const auto& e : events)
- EXPECT_TRUE(e->Wait(1000));
-}
-
-TEST(TaskQueueTest, PostDelayedAfterDestruct) {
- static const char kQueueName[] = "PostDelayedAfterDestruct";
- Event run;
- Event deleted;
- {
- TaskQueue queue(kQueueName);
- queue.PostDelayedTask(
- rtc::NewClosure([&run] { run.Set(); }, [&deleted] { deleted.Set(); }),
- 100);
- }
- // Task might outlive the TaskQueue, but still should be deleted.
- EXPECT_TRUE(deleted.Wait(200));
- EXPECT_FALSE(run.Wait(0)); // and should not run.
-}
-
-TEST(TaskQueueTest, PostAndReuse) {
- static const char kPostQueue[] = "PostQueue";
- static const char kReplyQueue[] = "ReplyQueue";
- Event event;
- TaskQueue post_queue(kPostQueue);
- TaskQueue reply_queue(kReplyQueue);
-
- int call_count = 0;
-
- class ReusedTask : public QueuedTask {
- public:
- ReusedTask(int* counter, TaskQueue* reply_queue, Event* event)
- : counter_(counter), reply_queue_(reply_queue), event_(event) {
- EXPECT_EQ(0, *counter_);
- }
-
- private:
- bool Run() override {
- if (++(*counter_) == 1) {
- std::unique_ptr<QueuedTask> myself(this);
- reply_queue_->PostTask(std::move(myself));
- // At this point, the object is owned by reply_queue_ and it's
- // theoratically possible that the object has been deleted (e.g. if
- // posting wasn't possible). So, don't touch any member variables here.
-
- // Indicate to the current queue that ownership has been transferred.
- return false;
- } else {
- EXPECT_EQ(2, *counter_);
- EXPECT_TRUE(reply_queue_->IsCurrent());
- event_->Set();
- return true; // Indicate that the object should be deleted.
- }
- }
-
- int* const counter_;
- TaskQueue* const reply_queue_;
- Event* const event_;
- };
-
- std::unique_ptr<ReusedTask> task(
- new ReusedTask(&call_count, &reply_queue, &event));
-
- post_queue.PostTask(std::move(task));
- EXPECT_TRUE(event.Wait(1000));
+// TODO(danilchap): Reshape and rename tests below to show they are verifying
+// rtc::NewClosure helper rather than TaskQueue implementation.
+TEST(TaskQueueTest, PostLambda) {
+ TaskQueue queue("PostLambda");
+ Event ran;
+ queue.PostTask([&ran] { ran.Set(); });
+ EXPECT_TRUE(ran.Wait(1000));
}
TEST(TaskQueueTest, PostCopyableClosure) {
@@ -338,66 +185,4 @@
EXPECT_TRUE(event_run.Wait(0));
}
-// Tests posting more messages than a queue can queue up.
-// In situations like that, tasks will get dropped.
-TEST(TaskQueueTest, PostALot) {
- // To destruct the event after the queue has gone out of scope.
- Event event;
-
- int tasks_executed = 0;
- int tasks_cleaned_up = 0;
- static const int kTaskCount = 0xffff;
-
- {
- static const char kQueueName[] = "PostALot";
- TaskQueue queue(kQueueName);
-
- // On linux, the limit of pending bytes in the pipe buffer is 0xffff.
- // So here we post a total of 0xffff+1 messages, which triggers a failure
- // case inside of the libevent queue implementation.
-
- queue.PostTask([&event]() { event.Wait(Event::kForever); });
- for (int i = 0; i < kTaskCount; ++i)
- queue.PostTask(NewClosure([&tasks_executed]() { ++tasks_executed; },
- [&tasks_cleaned_up]() { ++tasks_cleaned_up; }));
- event.Set(); // Unblock the first task.
- }
-
- EXPECT_GE(tasks_cleaned_up, tasks_executed);
- EXPECT_EQ(kTaskCount, tasks_cleaned_up);
-}
-
-// Test posting two tasks that have shared state not protected by a
-// lock. The TaskQueue should guarantee memory read-write order and
-// FIFO task execution order, so the second task should always see the
-// changes that were made by the first task.
-//
-// If the TaskQueue doesn't properly synchronize the execution of
-// tasks, there will be a data race, which is undefined behavior. The
-// EXPECT calls may randomly catch this, but to make the most of this
-// unit test, run it under TSan or some other tool that is able to
-// directly detect data races.
-TEST(TaskQueueTest, PostTwoWithSharedUnprotectedState) {
- static const char kQueueName[] = "PostTwoWithSharedUnprotectedState";
- struct SharedState {
- // First task will set this value to 1 and second will assert it.
- int state = 0;
- } state;
-
- TaskQueue queue(kQueueName);
- rtc::Event done;
- queue.PostTask([&state, &queue, &done] {
- // Post tasks from queue to guarantee, that 1st task won't be
- // executed before the second one will be posted.
- queue.PostTask([&state] { state.state = 1; });
- queue.PostTask([&state, &done] {
- EXPECT_EQ(state.state, 1);
- done.Set();
- });
- // Check, that state changing tasks didn't start yet.
- EXPECT_EQ(state.state, 0);
- });
- EXPECT_TRUE(done.Wait(1000));
-}
-
} // namespace rtc