1 /*
2 * This file is part of Licq, an instant messaging client for UNIX.
3 * Copyright (C) 2010, 2012-2013 Licq Developers <licq-dev@googlegroups.com>
4 *
5 * Licq is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * Licq is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Licq; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include "../pluginthread.h"
21
22 #include <gtest/gtest.h>
23
24 using namespace LicqDaemon;
25
26 namespace LicqTest {
27
28 struct PluginThreadFixture : public ::testing::Test
29 {
30 PluginThread thread;
31 };
32
init(void * argument)33 static bool init(void* argument)
34 {
35 *static_cast<pthread_t*>(argument) = ::pthread_self();
36 return true;
37 }
38
create(void * argument)39 static void create(void* argument)
40 {
41 *static_cast<pthread_t*>(argument) = ::pthread_self();
42 }
43
start(void * argument)44 static void* start(void* argument)
45 {
46 *static_cast<pthread_t*>(argument) = ::pthread_self();
47 return (void*)42;
48 }
49
TEST_F(PluginThreadFixture,join)50 TEST_F(PluginThreadFixture, join)
51 {
52 thread.stop();
53 EXPECT_EQ(thread.join(), (void*)NULL);
54 }
55
TEST_F(PluginThreadFixture,cancel)56 TEST_F(PluginThreadFixture, cancel)
57 {
58 thread.cancel();
59 EXPECT_EQ(thread.join(), PTHREAD_CANCELED);
60 }
61
TEST_F(PluginThreadFixture,isThread)62 TEST_F(PluginThreadFixture, isThread)
63 {
64 EXPECT_FALSE(thread.isThread(::pthread_self()));
65 }
66
TEST_F(PluginThreadFixture,loadPlugin)67 TEST_F(PluginThreadFixture, loadPlugin)
68 {
69 EXPECT_TRUE(thread.loadPlugin(""));
70 }
71
TEST_F(PluginThreadFixture,loadMissingPlugin)72 TEST_F(PluginThreadFixture, loadMissingPlugin)
73 {
74 EXPECT_THROW(thread.loadPlugin("nosuchplugin.foo"),
75 DynamicLibrary::Exception);
76 }
77
TEST_F(PluginThreadFixture,initPlugin)78 TEST_F(PluginThreadFixture, initPlugin)
79 {
80 pthread_t id = ::pthread_self();
81 EXPECT_TRUE(thread.initPlugin(&init, &id));
82 EXPECT_FALSE(::pthread_equal(id, ::pthread_self()));
83 EXPECT_TRUE(thread.isThread(id));
84 }
85
TEST_F(PluginThreadFixture,createPlugin)86 TEST_F(PluginThreadFixture, createPlugin)
87 {
88 pthread_t id = ::pthread_self();
89 thread.createPlugin(&create, &id);
90 EXPECT_FALSE(::pthread_equal(id, ::pthread_self()));
91 EXPECT_TRUE(thread.isThread(id));
92 }
93
TEST_F(PluginThreadFixture,startPlugin)94 TEST_F(PluginThreadFixture, startPlugin)
95 {
96 pthread_t id = ::pthread_self();
97 thread.startPlugin(&start, &id);
98 EXPECT_EQ(thread.join(), (void*)42);
99 EXPECT_FALSE(::pthread_equal(id, ::pthread_self()));
100 }
101
102 static pthread_t mainThreadId;
103 static pthread_t pluginThreadId;
testMainThreadEntry(PluginThread::Ptr thread)104 static int testMainThreadEntry(PluginThread::Ptr thread)
105 {
106 mainThreadId = ::pthread_self();
107 thread->initPlugin(&init, &pluginThreadId);
108 return 17;
109 }
110
TEST(PluginThread,createWithCurrentThread)111 TEST(PluginThread, createWithCurrentThread)
112 {
113 // Verify that the plugin is executed in the current thread and that the main
114 // thread continues in a new thread.
115 mainThreadId = ::pthread_self();
116 pluginThreadId = 0;
117 EXPECT_EQ(PluginThread::createWithCurrentThread(testMainThreadEntry), 17);
118 EXPECT_FALSE(::pthread_equal(mainThreadId, ::pthread_self()));
119 EXPECT_TRUE(::pthread_equal(pluginThreadId, ::pthread_self()));
120 }
121
122 } // namespace LicqTest
123