blob: a7407e216b571535041b30366beca5eb0558903d [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commitd7cae122008-07-26 21:49:384
5#include "base/lock.h"
6#include "base/message_loop.h"
7#include "base/string_util.h"
8#include "base/thread.h"
9#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1510#include "testing/platform_test.h"
initial.commitd7cae122008-07-26 21:49:3811
[email protected]4d9bdfaf2008-08-26 05:53:5712using base::Thread;
13
[email protected]6e683db2008-08-28 01:17:0214typedef PlatformTest ThreadTest;
15
initial.commitd7cae122008-07-26 21:49:3816namespace {
initial.commitd7cae122008-07-26 21:49:3817
18class ToggleValue : public Task {
19 public:
20 explicit ToggleValue(bool* value) : value_(value) {
21 }
22 virtual void Run() {
23 *value_ = !*value_;
24 }
25 private:
26 bool* value_;
27};
28
29class SleepSome : public Task {
30 public:
[email protected]eff4aecb2008-08-12 18:37:3531 explicit SleepSome(int msec) : msec_(msec) {
initial.commitd7cae122008-07-26 21:49:3832 }
33 virtual void Run() {
[email protected]e9ba26d2008-08-21 09:46:3234 PlatformThread::Sleep(msec_);
initial.commitd7cae122008-07-26 21:49:3835 }
36 private:
[email protected]eff4aecb2008-08-12 18:37:3537 int msec_;
initial.commitd7cae122008-07-26 21:49:3838};
39
[email protected]cd636d82009-01-27 01:26:1640class SleepInsideInitThread : public Thread {
41 public:
42 SleepInsideInitThread() : Thread("none") { init_called_ = false; }
43 virtual ~SleepInsideInitThread() { }
44
45 virtual void Init() {
46 PlatformThread::Sleep(500);
47 init_called_ = true;
48 }
49 bool InitCalled() { return init_called_; }
50 private:
51 bool init_called_;
52};
53
[email protected]eff4aecb2008-08-12 18:37:3554} // namespace
55
[email protected]6e683db2008-08-28 01:17:0256TEST_F(ThreadTest, Restart) {
[email protected]eff4aecb2008-08-12 18:37:3557 Thread a("Restart");
58 a.Stop();
59 EXPECT_FALSE(a.message_loop());
[email protected]b026f4a2009-01-28 17:21:2360 EXPECT_FALSE(a.IsRunning());
[email protected]eff4aecb2008-08-12 18:37:3561 EXPECT_TRUE(a.Start());
initial.commitd7cae122008-07-26 21:49:3862 EXPECT_TRUE(a.message_loop());
[email protected]b026f4a2009-01-28 17:21:2363 EXPECT_TRUE(a.IsRunning());
initial.commitd7cae122008-07-26 21:49:3864 a.Stop();
65 EXPECT_FALSE(a.message_loop());
[email protected]b026f4a2009-01-28 17:21:2366 EXPECT_FALSE(a.IsRunning());
[email protected]eff4aecb2008-08-12 18:37:3567 EXPECT_TRUE(a.Start());
initial.commitd7cae122008-07-26 21:49:3868 EXPECT_TRUE(a.message_loop());
[email protected]b026f4a2009-01-28 17:21:2369 EXPECT_TRUE(a.IsRunning());
initial.commitd7cae122008-07-26 21:49:3870 a.Stop();
71 EXPECT_FALSE(a.message_loop());
[email protected]b026f4a2009-01-28 17:21:2372 EXPECT_FALSE(a.IsRunning());
[email protected]eff4aecb2008-08-12 18:37:3573 a.Stop();
74 EXPECT_FALSE(a.message_loop());
[email protected]b026f4a2009-01-28 17:21:2375 EXPECT_FALSE(a.IsRunning());
initial.commitd7cae122008-07-26 21:49:3876}
77
[email protected]6e683db2008-08-28 01:17:0278TEST_F(ThreadTest, StartWithOptions_StackSize) {
[email protected]eff4aecb2008-08-12 18:37:3579 Thread a("StartWithStackSize");
80 // Ensure that the thread can work with only 12 kb and still process a
81 // message.
[email protected]4d9bdfaf2008-08-26 05:53:5782 Thread::Options options;
83 options.stack_size = 12*1024;
84 EXPECT_TRUE(a.StartWithOptions(options));
initial.commitd7cae122008-07-26 21:49:3885 EXPECT_TRUE(a.message_loop());
[email protected]b026f4a2009-01-28 17:21:2386 EXPECT_TRUE(a.IsRunning());
initial.commitd7cae122008-07-26 21:49:3887
88 bool was_invoked = false;
89 a.message_loop()->PostTask(FROM_HERE, new ToggleValue(&was_invoked));
90
91 // wait for the task to run (we could use a kernel event here
92 // instead to avoid busy waiting, but this is sufficient for
93 // testing purposes).
[email protected]eff4aecb2008-08-12 18:37:3594 for (int i = 100; i >= 0 && !was_invoked; --i) {
[email protected]e9ba26d2008-08-21 09:46:3295 PlatformThread::Sleep(10);
initial.commitd7cae122008-07-26 21:49:3896 }
97 EXPECT_TRUE(was_invoked);
98}
99
[email protected]6e683db2008-08-28 01:17:02100TEST_F(ThreadTest, TwoTasks) {
initial.commitd7cae122008-07-26 21:49:38101 bool was_invoked = false;
102 {
[email protected]eff4aecb2008-08-12 18:37:35103 Thread a("TwoTasks");
104 EXPECT_TRUE(a.Start());
initial.commitd7cae122008-07-26 21:49:38105 EXPECT_TRUE(a.message_loop());
106
107 // Test that all events are dispatched before the Thread object is
108 // destroyed. We do this by dispatching a sleep event before the
109 // event that will toggle our sentinel value.
[email protected]eff4aecb2008-08-12 18:37:35110 a.message_loop()->PostTask(FROM_HERE, new SleepSome(20));
initial.commitd7cae122008-07-26 21:49:38111 a.message_loop()->PostTask(FROM_HERE, new ToggleValue(&was_invoked));
112 }
113 EXPECT_TRUE(was_invoked);
114}
115
[email protected]6e683db2008-08-28 01:17:02116TEST_F(ThreadTest, StopSoon) {
[email protected]eff4aecb2008-08-12 18:37:35117 Thread a("StopSoon");
118 EXPECT_TRUE(a.Start());
119 EXPECT_TRUE(a.message_loop());
[email protected]b026f4a2009-01-28 17:21:23120 EXPECT_TRUE(a.IsRunning());
[email protected]eff4aecb2008-08-12 18:37:35121 a.StopSoon();
[email protected]eff4aecb2008-08-12 18:37:35122 a.StopSoon();
[email protected]98c74f82008-12-01 14:34:42123 a.Stop();
[email protected]eff4aecb2008-08-12 18:37:35124 EXPECT_FALSE(a.message_loop());
[email protected]b026f4a2009-01-28 17:21:23125 EXPECT_FALSE(a.IsRunning());
initial.commitd7cae122008-07-26 21:49:38126}
127
[email protected]6e683db2008-08-28 01:17:02128TEST_F(ThreadTest, ThreadName) {
[email protected]eff4aecb2008-08-12 18:37:35129 Thread a("ThreadName");
130 EXPECT_TRUE(a.Start());
131 EXPECT_EQ("ThreadName", a.thread_name());
initial.commitd7cae122008-07-26 21:49:38132}
[email protected]cd636d82009-01-27 01:26:16133
134// Make sure we can't use a thread between Start() and Init().
135TEST_F(ThreadTest, SleepInsideInit) {
136 SleepInsideInitThread t;
137 EXPECT_FALSE(t.InitCalled());
138 t.Start();
139 EXPECT_TRUE(t.InitCalled());
140}