blob: a7407e216b571535041b30366beca5eb0558903d [file] [log] [blame]
license.botf003cfe2008-08-24 09:55:55 +09001// 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.commit3f4a7322008-07-27 06:49:38 +09004
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"
jeremy@chromium.org0d8eba72008-12-03 04:20:15 +090010#include "testing/platform_test.h"
initial.commit3f4a7322008-07-27 06:49:38 +090011
darin@google.comd936b5b2008-08-26 14:53:57 +090012using base::Thread;
13
mmentovai@google.com4304cf92008-08-28 10:17:02 +090014typedef PlatformTest ThreadTest;
15
initial.commit3f4a7322008-07-27 06:49:38 +090016namespace {
initial.commit3f4a7322008-07-27 06:49:38 +090017
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:
maruel@google.comf6e3db82008-08-13 03:37:35 +090031 explicit SleepSome(int msec) : msec_(msec) {
initial.commit3f4a7322008-07-27 06:49:38 +090032 }
33 virtual void Run() {
darin@google.comc18d7ae2008-08-21 18:46:32 +090034 PlatformThread::Sleep(msec_);
initial.commit3f4a7322008-07-27 06:49:38 +090035 }
36 private:
maruel@google.comf6e3db82008-08-13 03:37:35 +090037 int msec_;
initial.commit3f4a7322008-07-27 06:49:38 +090038};
39
jrg@chromium.orge0e2b252009-01-27 10:26:16 +090040class 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
maruel@google.comf6e3db82008-08-13 03:37:35 +090054} // namespace
55
mmentovai@google.com4304cf92008-08-28 10:17:02 +090056TEST_F(ThreadTest, Restart) {
maruel@google.comf6e3db82008-08-13 03:37:35 +090057 Thread a("Restart");
58 a.Stop();
59 EXPECT_FALSE(a.message_loop());
ralphl@chromium.orgd94c5162009-01-29 02:21:23 +090060 EXPECT_FALSE(a.IsRunning());
maruel@google.comf6e3db82008-08-13 03:37:35 +090061 EXPECT_TRUE(a.Start());
initial.commit3f4a7322008-07-27 06:49:38 +090062 EXPECT_TRUE(a.message_loop());
ralphl@chromium.orgd94c5162009-01-29 02:21:23 +090063 EXPECT_TRUE(a.IsRunning());
initial.commit3f4a7322008-07-27 06:49:38 +090064 a.Stop();
65 EXPECT_FALSE(a.message_loop());
ralphl@chromium.orgd94c5162009-01-29 02:21:23 +090066 EXPECT_FALSE(a.IsRunning());
maruel@google.comf6e3db82008-08-13 03:37:35 +090067 EXPECT_TRUE(a.Start());
initial.commit3f4a7322008-07-27 06:49:38 +090068 EXPECT_TRUE(a.message_loop());
ralphl@chromium.orgd94c5162009-01-29 02:21:23 +090069 EXPECT_TRUE(a.IsRunning());
initial.commit3f4a7322008-07-27 06:49:38 +090070 a.Stop();
71 EXPECT_FALSE(a.message_loop());
ralphl@chromium.orgd94c5162009-01-29 02:21:23 +090072 EXPECT_FALSE(a.IsRunning());
maruel@google.comf6e3db82008-08-13 03:37:35 +090073 a.Stop();
74 EXPECT_FALSE(a.message_loop());
ralphl@chromium.orgd94c5162009-01-29 02:21:23 +090075 EXPECT_FALSE(a.IsRunning());
initial.commit3f4a7322008-07-27 06:49:38 +090076}
77
mmentovai@google.com4304cf92008-08-28 10:17:02 +090078TEST_F(ThreadTest, StartWithOptions_StackSize) {
maruel@google.comf6e3db82008-08-13 03:37:35 +090079 Thread a("StartWithStackSize");
80 // Ensure that the thread can work with only 12 kb and still process a
81 // message.
darin@google.comd936b5b2008-08-26 14:53:57 +090082 Thread::Options options;
83 options.stack_size = 12*1024;
84 EXPECT_TRUE(a.StartWithOptions(options));
initial.commit3f4a7322008-07-27 06:49:38 +090085 EXPECT_TRUE(a.message_loop());
ralphl@chromium.orgd94c5162009-01-29 02:21:23 +090086 EXPECT_TRUE(a.IsRunning());
initial.commit3f4a7322008-07-27 06:49:38 +090087
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).
maruel@google.comf6e3db82008-08-13 03:37:35 +090094 for (int i = 100; i >= 0 && !was_invoked; --i) {
darin@google.comc18d7ae2008-08-21 18:46:32 +090095 PlatformThread::Sleep(10);
initial.commit3f4a7322008-07-27 06:49:38 +090096 }
97 EXPECT_TRUE(was_invoked);
98}
99
mmentovai@google.com4304cf92008-08-28 10:17:02 +0900100TEST_F(ThreadTest, TwoTasks) {
initial.commit3f4a7322008-07-27 06:49:38 +0900101 bool was_invoked = false;
102 {
maruel@google.comf6e3db82008-08-13 03:37:35 +0900103 Thread a("TwoTasks");
104 EXPECT_TRUE(a.Start());
initial.commit3f4a7322008-07-27 06:49:38 +0900105 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.
maruel@google.comf6e3db82008-08-13 03:37:35 +0900110 a.message_loop()->PostTask(FROM_HERE, new SleepSome(20));
initial.commit3f4a7322008-07-27 06:49:38 +0900111 a.message_loop()->PostTask(FROM_HERE, new ToggleValue(&was_invoked));
112 }
113 EXPECT_TRUE(was_invoked);
114}
115
mmentovai@google.com4304cf92008-08-28 10:17:02 +0900116TEST_F(ThreadTest, StopSoon) {
maruel@google.comf6e3db82008-08-13 03:37:35 +0900117 Thread a("StopSoon");
118 EXPECT_TRUE(a.Start());
119 EXPECT_TRUE(a.message_loop());
ralphl@chromium.orgd94c5162009-01-29 02:21:23 +0900120 EXPECT_TRUE(a.IsRunning());
maruel@google.comf6e3db82008-08-13 03:37:35 +0900121 a.StopSoon();
maruel@google.comf6e3db82008-08-13 03:37:35 +0900122 a.StopSoon();
maruel@chromium.org7ea3bbb2008-12-01 23:34:42 +0900123 a.Stop();
maruel@google.comf6e3db82008-08-13 03:37:35 +0900124 EXPECT_FALSE(a.message_loop());
ralphl@chromium.orgd94c5162009-01-29 02:21:23 +0900125 EXPECT_FALSE(a.IsRunning());
initial.commit3f4a7322008-07-27 06:49:38 +0900126}
127
mmentovai@google.com4304cf92008-08-28 10:17:02 +0900128TEST_F(ThreadTest, ThreadName) {
maruel@google.comf6e3db82008-08-13 03:37:35 +0900129 Thread a("ThreadName");
130 EXPECT_TRUE(a.Start());
131 EXPECT_EQ("ThreadName", a.thread_name());
initial.commit3f4a7322008-07-27 06:49:38 +0900132}
jrg@chromium.orge0e2b252009-01-27 10:26:16 +0900133
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}