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