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

Unified Diff: webrtc/base/task_unittest.cc

Issue 2622923002: Delete unused TaskRunner abstraction. (Closed)
Patch Set: Rebase. Created 3 years, 10 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 | « webrtc/base/task.cc ('k') | webrtc/base/taskparent.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/base/task_unittest.cc
diff --git a/webrtc/base/task_unittest.cc b/webrtc/base/task_unittest.cc
deleted file mode 100644
index 38ceb145fddb00550f1bbce2ce535a9f74a1d10a..0000000000000000000000000000000000000000
--- a/webrtc/base/task_unittest.cc
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- * Copyright 2004 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.
- */
-
-#if defined(WEBRTC_POSIX)
-#include <sys/time.h>
-#endif // WEBRTC_POSIX
-
-// TODO: Remove this once the cause of sporadic failures in these
-// tests is tracked down.
-#include <iostream>
-
-#if defined(WEBRTC_WIN)
-#include "webrtc/base/win32.h"
-#endif // WEBRTC_WIN
-
-#include "webrtc/base/arraysize.h"
-#include "webrtc/base/constructormagic.h"
-#include "webrtc/base/gunit.h"
-#include "webrtc/base/logging.h"
-#include "webrtc/base/task.h"
-#include "webrtc/base/taskrunner.h"
-#include "webrtc/base/thread.h"
-#include "webrtc/base/timeutils.h"
-
-namespace rtc {
-
-static int64_t GetCurrentTime() {
- return TimeMillis() * 10000;
-}
-
-// feel free to change these numbers. Note that '0' won't work, though
-#define STUCK_TASK_COUNT 5
-#define HAPPY_TASK_COUNT 20
-
-// this is a generic timeout task which, when it signals timeout, will
-// include the unique ID of the task in the signal (we don't use this
-// in production code because we haven't yet had occasion to generate
-// an array of the same types of task)
-
-class IdTimeoutTask : public Task, public sigslot::has_slots<> {
- public:
- explicit IdTimeoutTask(TaskParent *parent) : Task(parent) {
- SignalTimeout.connect(this, &IdTimeoutTask::OnLocalTimeout);
- }
-
- sigslot::signal1<const int> SignalTimeoutId;
- sigslot::signal1<const int> SignalDoneId;
-
- virtual int ProcessStart() {
- return STATE_RESPONSE;
- }
-
- void OnLocalTimeout() {
- SignalTimeoutId(unique_id());
- }
-
- protected:
- virtual void Stop() {
- SignalDoneId(unique_id());
- Task::Stop();
- }
-};
-
-class StuckTask : public IdTimeoutTask {
- public:
- explicit StuckTask(TaskParent *parent) : IdTimeoutTask(parent) {}
- virtual int ProcessStart() {
- return STATE_BLOCKED;
- }
-};
-
-class HappyTask : public IdTimeoutTask {
- public:
- explicit HappyTask(TaskParent *parent) : IdTimeoutTask(parent) {
- time_to_perform_ = rand() % (STUCK_TASK_COUNT / 2);
- }
- virtual int ProcessStart() {
- if (ElapsedTime() > (time_to_perform_ * 1000 * 10000))
- return STATE_RESPONSE;
- else
- return STATE_BLOCKED;
- }
-
- private:
- int time_to_perform_;
-};
-
-// simple implementation of a task runner which uses Windows'
-// GetSystemTimeAsFileTime() to get the current clock ticks
-
-class MyTaskRunner : public TaskRunner {
- public:
- virtual void WakeTasks() { RunTasks(); }
- virtual int64_t CurrentTime() { return GetCurrentTime(); }
-
- bool timeout_change() const {
- return timeout_change_;
- }
-
- void clear_timeout_change() {
- timeout_change_ = false;
- }
- protected:
- virtual void OnTimeoutChange() {
- timeout_change_ = true;
- }
- bool timeout_change_;
-};
-
-//
-// this unit test is primarily concerned (for now) with the timeout
-// functionality in tasks. It works as follows:
-//
-// * Create a bunch of tasks, some "stuck" (ie., guaranteed to timeout)
-// and some "happy" (will immediately finish).
-// * Set the timeout on the "stuck" tasks to some number of seconds between
-// 1 and the number of stuck tasks
-// * Start all the stuck & happy tasks in random order
-// * Wait "number of stuck tasks" seconds and make sure everything timed out
-
-class TaskTest : public sigslot::has_slots<> {
- public:
- TaskTest() {}
-
- // no need to delete any tasks; the task runner owns them
- ~TaskTest() {}
-
- void Start() {
- // create and configure tasks
- for (int i = 0; i < STUCK_TASK_COUNT; ++i) {
- stuck_[i].task_ = new StuckTask(&task_runner_);
- stuck_[i].task_->SignalTimeoutId.connect(this,
- &TaskTest::OnTimeoutStuck);
- stuck_[i].timed_out_ = false;
- stuck_[i].xlat_ = stuck_[i].task_->unique_id();
- stuck_[i].task_->set_timeout_seconds(i + 1);
- LOG(LS_INFO) << "Task " << stuck_[i].xlat_ << " created with timeout "
- << stuck_[i].task_->timeout_seconds();
- }
-
- for (int i = 0; i < HAPPY_TASK_COUNT; ++i) {
- happy_[i].task_ = new HappyTask(&task_runner_);
- happy_[i].task_->SignalTimeoutId.connect(this,
- &TaskTest::OnTimeoutHappy);
- happy_[i].task_->SignalDoneId.connect(this,
- &TaskTest::OnDoneHappy);
- happy_[i].timed_out_ = false;
- happy_[i].xlat_ = happy_[i].task_->unique_id();
- }
-
- // start all the tasks in random order
- int stuck_index = 0;
- int happy_index = 0;
- for (int i = 0; i < STUCK_TASK_COUNT + HAPPY_TASK_COUNT; ++i) {
- if ((stuck_index < STUCK_TASK_COUNT) &&
- (happy_index < HAPPY_TASK_COUNT)) {
- if (rand() % 2 == 1) {
- stuck_[stuck_index++].task_->Start();
- } else {
- happy_[happy_index++].task_->Start();
- }
- } else if (stuck_index < STUCK_TASK_COUNT) {
- stuck_[stuck_index++].task_->Start();
- } else {
- happy_[happy_index++].task_->Start();
- }
- }
-
- for (int i = 0; i < STUCK_TASK_COUNT; ++i) {
- std::cout << "Stuck task #" << i << " timeout is " <<
- stuck_[i].task_->timeout_seconds() << " at " <<
- stuck_[i].task_->timeout_time() << std::endl;
- }
-
- // just a little self-check to make sure we started all the tasks
- ASSERT_EQ(STUCK_TASK_COUNT, stuck_index);
- ASSERT_EQ(HAPPY_TASK_COUNT, happy_index);
-
- // run the unblocked tasks
- LOG(LS_INFO) << "Running tasks";
- task_runner_.RunTasks();
-
- std::cout << "Start time is " << GetCurrentTime() << std::endl;
-
- // give all the stuck tasks time to timeout
- for (int i = 0; !task_runner_.AllChildrenDone() && i < STUCK_TASK_COUNT;
- ++i) {
- Thread::Current()->ProcessMessages(1000);
- for (int j = 0; j < HAPPY_TASK_COUNT; ++j) {
- if (happy_[j].task_) {
- happy_[j].task_->Wake();
- }
- }
- LOG(LS_INFO) << "Polling tasks";
- task_runner_.PollTasks();
- }
-
- // We see occasional test failures here due to the stuck tasks not having
- // timed-out yet, which seems like it should be impossible. To help track
- // this down we have added logging of the timing information, which we send
- // directly to stdout so that we get it in opt builds too.
- std::cout << "End time is " << GetCurrentTime() << std::endl;
- }
-
- void OnTimeoutStuck(const int id) {
- LOG(LS_INFO) << "Timed out task " << id;
-
- int i;
- for (i = 0; i < STUCK_TASK_COUNT; ++i) {
- if (stuck_[i].xlat_ == id) {
- stuck_[i].timed_out_ = true;
- stuck_[i].task_ = NULL;
- break;
- }
- }
-
- // getting a bad ID here is a failure, but let's continue
- // running to see what else might go wrong
- EXPECT_LT(i, STUCK_TASK_COUNT);
- }
-
- void OnTimeoutHappy(const int id) {
- int i;
- for (i = 0; i < HAPPY_TASK_COUNT; ++i) {
- if (happy_[i].xlat_ == id) {
- happy_[i].timed_out_ = true;
- happy_[i].task_ = NULL;
- break;
- }
- }
-
- // getting a bad ID here is a failure, but let's continue
- // running to see what else might go wrong
- EXPECT_LT(i, HAPPY_TASK_COUNT);
- }
-
- void OnDoneHappy(const int id) {
- int i;
- for (i = 0; i < HAPPY_TASK_COUNT; ++i) {
- if (happy_[i].xlat_ == id) {
- happy_[i].task_ = NULL;
- break;
- }
- }
-
- // getting a bad ID here is a failure, but let's continue
- // running to see what else might go wrong
- EXPECT_LT(i, HAPPY_TASK_COUNT);
- }
-
- void check_passed() {
- EXPECT_TRUE(task_runner_.AllChildrenDone());
-
- // make sure none of our happy tasks timed out
- for (int i = 0; i < HAPPY_TASK_COUNT; ++i) {
- EXPECT_FALSE(happy_[i].timed_out_);
- }
-
- // make sure all of our stuck tasks timed out
- for (int i = 0; i < STUCK_TASK_COUNT; ++i) {
- EXPECT_TRUE(stuck_[i].timed_out_);
- if (!stuck_[i].timed_out_) {
- std::cout << "Stuck task #" << i << " timeout is at "
- << stuck_[i].task_->timeout_time() << std::endl;
- }
- }
-
- std::cout.flush();
- }
-
- private:
- struct TaskInfo {
- IdTimeoutTask *task_;
- bool timed_out_;
- int xlat_;
- };
-
- MyTaskRunner task_runner_;
- TaskInfo stuck_[STUCK_TASK_COUNT];
- TaskInfo happy_[HAPPY_TASK_COUNT];
-};
-
-TEST(start_task_test, Timeout) {
- TaskTest task_test;
- task_test.Start();
- task_test.check_passed();
-}
-
-// Test for aborting the task while it is running
-
-class AbortTask : public Task {
- public:
- explicit AbortTask(TaskParent *parent) : Task(parent) {
- set_timeout_seconds(1);
- }
-
- virtual int ProcessStart() {
- Abort();
- return STATE_NEXT;
- }
- private:
- RTC_DISALLOW_COPY_AND_ASSIGN(AbortTask);
-};
-
-class TaskAbortTest : public sigslot::has_slots<> {
- public:
- TaskAbortTest() {}
-
- // no need to delete any tasks; the task runner owns them
- ~TaskAbortTest() {}
-
- void Start() {
- Task *abort_task = new AbortTask(&task_runner_);
- abort_task->SignalTimeout.connect(this, &TaskAbortTest::OnTimeout);
- abort_task->Start();
-
- // run the task
- task_runner_.RunTasks();
- }
-
- private:
- void OnTimeout() {
- FAIL() << "Task timed out instead of aborting.";
- }
-
- MyTaskRunner task_runner_;
- RTC_DISALLOW_COPY_AND_ASSIGN(TaskAbortTest);
-};
-
-TEST(start_task_test, Abort) {
- TaskAbortTest abort_test;
- abort_test.Start();
-}
-
-// Test for aborting a task to verify that it does the Wake operation
-// which gets it deleted.
-
-class SetBoolOnDeleteTask : public Task {
- public:
- SetBoolOnDeleteTask(TaskParent *parent, bool *set_when_deleted)
- : Task(parent),
- set_when_deleted_(set_when_deleted) {
- EXPECT_TRUE(NULL != set_when_deleted);
- EXPECT_FALSE(*set_when_deleted);
- }
-
- virtual ~SetBoolOnDeleteTask() {
- *set_when_deleted_ = true;
- }
-
- virtual int ProcessStart() {
- return STATE_BLOCKED;
- }
-
- private:
- bool* set_when_deleted_;
- RTC_DISALLOW_COPY_AND_ASSIGN(SetBoolOnDeleteTask);
-};
-
-class AbortShouldWakeTest : public sigslot::has_slots<> {
- public:
- AbortShouldWakeTest() {}
-
- // no need to delete any tasks; the task runner owns them
- ~AbortShouldWakeTest() {}
-
- void Start() {
- bool task_deleted = false;
- Task *task_to_abort = new SetBoolOnDeleteTask(&task_runner_, &task_deleted);
- task_to_abort->Start();
-
- // Task::Abort() should call TaskRunner::WakeTasks(). WakeTasks calls
- // TaskRunner::RunTasks() immediately which should delete the task.
- task_to_abort->Abort();
- EXPECT_TRUE(task_deleted);
-
- if (!task_deleted) {
- // avoid a crash (due to referencing a local variable)
- // if the test fails.
- task_runner_.RunTasks();
- }
- }
-
- private:
- void OnTimeout() {
- FAIL() << "Task timed out instead of aborting.";
- }
-
- MyTaskRunner task_runner_;
- RTC_DISALLOW_COPY_AND_ASSIGN(AbortShouldWakeTest);
-};
-
-TEST(start_task_test, AbortShouldWake) {
- AbortShouldWakeTest abort_should_wake_test;
- abort_should_wake_test.Start();
-}
-
-// Validate that TaskRunner's OnTimeoutChange gets called appropriately
-// * When a task calls UpdateTaskTimeout
-// * When the next timeout task time, times out
-class TimeoutChangeTest : public sigslot::has_slots<> {
- public:
- TimeoutChangeTest()
- : task_count_(arraysize(stuck_tasks_)) {}
-
- // no need to delete any tasks; the task runner owns them
- ~TimeoutChangeTest() {}
-
- void Start() {
- for (int i = 0; i < task_count_; ++i) {
- stuck_tasks_[i] = new StuckTask(&task_runner_);
- stuck_tasks_[i]->set_timeout_seconds(i + 2);
- stuck_tasks_[i]->SignalTimeoutId.connect(this,
- &TimeoutChangeTest::OnTimeoutId);
- }
-
- for (int i = task_count_ - 1; i >= 0; --i) {
- stuck_tasks_[i]->Start();
- }
- task_runner_.clear_timeout_change();
-
- // At this point, our timeouts are set as follows
- // task[0] is 2 seconds, task[1] at 3 seconds, etc.
-
- stuck_tasks_[0]->set_timeout_seconds(2);
- // Now, task[0] is 2 seconds, task[1] at 3 seconds...
- // so timeout change shouldn't be called.
- EXPECT_FALSE(task_runner_.timeout_change());
- task_runner_.clear_timeout_change();
-
- stuck_tasks_[0]->set_timeout_seconds(1);
- // task[0] is 1 seconds, task[1] at 3 seconds...
- // The smallest timeout got smaller so timeout change be called.
- EXPECT_TRUE(task_runner_.timeout_change());
- task_runner_.clear_timeout_change();
-
- stuck_tasks_[1]->set_timeout_seconds(2);
- // task[0] is 1 seconds, task[1] at 2 seconds...
- // The smallest timeout is still 1 second so no timeout change.
- EXPECT_FALSE(task_runner_.timeout_change());
- task_runner_.clear_timeout_change();
-
- while (task_count_ > 0) {
- int previous_count = task_count_;
- task_runner_.PollTasks();
- if (previous_count != task_count_) {
- // We only get here when a task times out. When that
- // happens, the timeout change should get called because
- // the smallest timeout is now in the past.
- EXPECT_TRUE(task_runner_.timeout_change());
- task_runner_.clear_timeout_change();
- }
- Thread::Current()->socketserver()->Wait(500, false);
- }
- }
-
- private:
- void OnTimeoutId(const int id) {
- for (size_t i = 0; i < arraysize(stuck_tasks_); ++i) {
- if (stuck_tasks_[i] && stuck_tasks_[i]->unique_id() == id) {
- task_count_--;
- stuck_tasks_[i] = NULL;
- break;
- }
- }
- }
-
- MyTaskRunner task_runner_;
- StuckTask* (stuck_tasks_[3]);
- int task_count_;
- RTC_DISALLOW_COPY_AND_ASSIGN(TimeoutChangeTest);
-};
-
-TEST(start_task_test, TimeoutChange) {
- TimeoutChangeTest timeout_change_test;
- timeout_change_test.Start();
-}
-
-class DeleteTestTaskRunner : public TaskRunner {
- public:
- DeleteTestTaskRunner() {
- }
- virtual void WakeTasks() { }
- virtual int64_t CurrentTime() { return GetCurrentTime(); }
- private:
- RTC_DISALLOW_COPY_AND_ASSIGN(DeleteTestTaskRunner);
-};
-
-TEST(unstarted_task_test, DeleteTask) {
- // This test ensures that we don't
- // crash if a task is deleted without running it.
- DeleteTestTaskRunner task_runner;
- HappyTask* happy_task = new HappyTask(&task_runner);
- happy_task->Start();
-
- // try deleting the task directly
- HappyTask* child_happy_task = new HappyTask(happy_task);
- delete child_happy_task;
-
- // run the unblocked tasks
- task_runner.RunTasks();
-}
-
-TEST(unstarted_task_test, DoNotDeleteTask1) {
- // This test ensures that we don't
- // crash if a task runner is deleted without
- // running a certain task.
- DeleteTestTaskRunner task_runner;
- HappyTask* happy_task = new HappyTask(&task_runner);
- happy_task->Start();
-
- HappyTask* child_happy_task = new HappyTask(happy_task);
- child_happy_task->Start();
-
- // Never run the tasks
-}
-
-TEST(unstarted_task_test, DoNotDeleteTask2) {
- // This test ensures that we don't
- // crash if a taskrunner is delete with a
- // task that has never been started.
- DeleteTestTaskRunner task_runner;
- HappyTask* happy_task = new HappyTask(&task_runner);
- happy_task->Start();
-
- // Do not start the task.
- // Note: this leaks memory, so don't do this.
- // Instead, always run your tasks or delete them.
- new HappyTask(happy_task);
-
- // run the unblocked tasks
- task_runner.RunTasks();
-}
-
-} // namespace rtc
« no previous file with comments | « webrtc/base/task.cc ('k') | webrtc/base/taskparent.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698