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