~compiz-team/compiz/0.9.10

« back to all changes in this revision

Viewing changes to src/plugin/tests/test-plugin.cpp

Introduce test framework around the plugin loader.
Merged from lp:~alan-griffiths/compiz-core/test-infrastructure-for-plugin

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "core/plugin.h"
 
2
 
 
3
// This prevents an instantiation error - not sure why ATM
 
4
#include "core/screen.h"
 
5
 
 
6
// Get rid of stupid macro from X.h
 
7
// Why, oh why, are we including X.h?
 
8
#undef None
 
9
 
 
10
#include <gtest/gtest.h>
 
11
#include <gmock/gmock.h>
 
12
 
 
13
#include <iostream>
 
14
 
 
15
namespace {
 
16
 
 
17
class PluginFilesystem
 
18
{
 
19
public:
 
20
    virtual bool
 
21
    LoadPlugin(CompPlugin *p, const char *path, const char *name) const = 0;
 
22
 
 
23
    virtual void
 
24
    UnloadPlugin(CompPlugin *p) const = 0;
 
25
 
 
26
    virtual CompStringList
 
27
    ListPlugins(const char *path) const = 0;
 
28
 
 
29
    static PluginFilesystem const* instance;
 
30
 
 
31
protected:
 
32
    PluginFilesystem();
 
33
    virtual ~PluginFilesystem() {}
 
34
};
 
35
 
 
36
class MockPluginFilesystem : public PluginFilesystem
 
37
{
 
38
public:
 
39
    MOCK_CONST_METHOD3(LoadPlugin, bool (CompPlugin *, const char *, const char *));
 
40
 
 
41
    MOCK_CONST_METHOD1(UnloadPlugin, void (CompPlugin *p));
 
42
 
 
43
    MOCK_CONST_METHOD1(ListPlugins, CompStringList (const char *path));
 
44
};
 
45
 
 
46
class MockVTable : public CompPlugin::VTable
 
47
{
 
48
public:
 
49
    MOCK_METHOD0(init, bool ());
 
50
};
 
51
 
 
52
 
 
53
bool
 
54
ThunkLoadPluginProc(CompPlugin *p, const char *path_, const char *name)
 
55
{
 
56
    return PluginFilesystem::instance->LoadPlugin(p, path_, name);
 
57
}
 
58
 
 
59
void
 
60
ThunkUnloadPluginProc(CompPlugin *p)
 
61
{
 
62
    PluginFilesystem::instance->UnloadPlugin(p);
 
63
}
 
64
 
 
65
 
 
66
CompStringList
 
67
ThunkListPluginsProc(const char *path)
 
68
{
 
69
    return PluginFilesystem::instance->ListPlugins(path);
 
70
}
 
71
 
 
72
PluginFilesystem::PluginFilesystem()
 
73
{
 
74
        ::loaderLoadPlugin = ::ThunkLoadPluginProc;
 
75
        ::loaderUnloadPlugin = ::ThunkUnloadPluginProc;
 
76
        ::loaderListPlugins = ::ThunkListPluginsProc;
 
77
 
 
78
        instance = this;
 
79
}
 
80
 
 
81
PluginFilesystem const* PluginFilesystem::instance = 0;
 
82
 
 
83
} // (abstract) namespace
 
84
 
 
85
 
 
86
 
 
87
TEST(PluginTest, load_non_existant_plugin_must_fail)
 
88
{
 
89
    MockPluginFilesystem mockfs;
 
90
 
 
91
    using namespace testing;
 
92
 
 
93
    EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))).
 
94
        WillOnce(Return(false));
 
95
 
 
96
    EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(PLUGINDIR), StrEq("dummy"))).
 
97
        WillOnce(Return(false));
 
98
 
 
99
    EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), Eq((void*)0), StrEq("dummy"))).
 
100
        WillOnce(Return(false));
 
101
 
 
102
    EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(AtMost(0));
 
103
    EXPECT_CALL(mockfs, ListPlugins(_)).Times(AtMost(0));
 
104
 
 
105
    ASSERT_EQ(0, CompPlugin::load("dummy"));
 
106
}
 
107
 
 
108
TEST(PluginTest, load_plugin_from_HOME_PLUGINDIR_succeeds)
 
109
{
 
110
    MockPluginFilesystem mockfs;
 
111
 
 
112
    using namespace testing;
 
113
 
 
114
    EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))).
 
115
        WillOnce(Return(true));
 
116
 
 
117
    EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(PLUGINDIR), StrEq("dummy"))).
 
118
        Times(AtMost(0));
 
119
 
 
120
    EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), Eq((void*)0), StrEq("dummy"))).
 
121
        Times(AtMost(0));
 
122
 
 
123
    EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(1);
 
124
    EXPECT_CALL(mockfs, ListPlugins(_)).Times(AtMost(0));
 
125
 
 
126
    CompPlugin* cp = CompPlugin::load("dummy");
 
127
    ASSERT_NE((void*)0, cp);
 
128
 
 
129
    CompPlugin::unload(cp);
 
130
}
 
131
 
 
132
TEST(PluginTest, load_plugin_from_PLUGINDIR_succeeds)
 
133
{
 
134
    MockPluginFilesystem mockfs;
 
135
 
 
136
    using namespace testing;
 
137
 
 
138
    EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))).
 
139
        WillOnce(Return(false));
 
140
 
 
141
    EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(PLUGINDIR), StrEq("dummy"))).
 
142
        WillOnce(Return(true));
 
143
 
 
144
    EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), Eq((void*)0), StrEq("dummy"))).
 
145
            Times(AtMost(0));;
 
146
 
 
147
    EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(1);
 
148
    EXPECT_CALL(mockfs, ListPlugins(_)).Times(AtMost(0));
 
149
 
 
150
    CompPlugin* cp = CompPlugin::load("dummy");
 
151
    ASSERT_NE((void*)0, cp);
 
152
 
 
153
    CompPlugin::unload(cp);
 
154
}
 
155
 
 
156
TEST(PluginTest, load_plugin_from_void_succeeds)
 
157
{
 
158
    MockPluginFilesystem mockfs;
 
159
 
 
160
    using namespace testing;
 
161
 
 
162
    EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))).
 
163
        WillOnce(Return(false));
 
164
 
 
165
    EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(PLUGINDIR), StrEq("dummy"))).
 
166
        WillOnce(Return(false));
 
167
 
 
168
    EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), Eq((void*)0), StrEq("dummy"))).
 
169
        WillOnce(Return(true));
 
170
 
 
171
    EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(1);
 
172
    EXPECT_CALL(mockfs, ListPlugins(_)).Times(AtMost(0));
 
173
 
 
174
    CompPlugin* cp = CompPlugin::load("dummy");
 
175
    ASSERT_NE((void*)0, cp);
 
176
 
 
177
    CompPlugin::unload(cp);
 
178
}
 
179
 
 
180
 
 
181
TEST(PluginTest, list_plugins_none)
 
182
{
 
183
    MockPluginFilesystem mockfs;
 
184
 
 
185
    using namespace testing;
 
186
 
 
187
    EXPECT_CALL(mockfs, LoadPlugin(_, _, _)).Times(AtMost(0));
 
188
    EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(AtMost(0));
 
189
 
 
190
    EXPECT_CALL(mockfs, ListPlugins(EndsWith(HOME_PLUGINDIR))).
 
191
        WillOnce(Return(CompStringList()));
 
192
 
 
193
    EXPECT_CALL(mockfs, ListPlugins(EndsWith(PLUGINDIR))).
 
194
        WillOnce(Return(CompStringList()));
 
195
 
 
196
    EXPECT_CALL(mockfs, ListPlugins(Eq((void*)0))).
 
197
        WillOnce(Return(CompStringList()));
 
198
 
 
199
    CompStringList cl = CompPlugin::availablePlugins();
 
200
    ASSERT_EQ(0, cl.size());
 
201
}
 
202
 
 
203
 
 
204
TEST(PluginTest, list_plugins_some)
 
205
{
 
206
    std::string one = "one";
 
207
    std::string two = "two";
 
208
    std::string three = "three";
 
209
 
 
210
    CompStringList home(1, one);
 
211
    CompStringList plugin(1, two);
 
212
    CompStringList local(1, three);
 
213
 
 
214
    MockPluginFilesystem mockfs;
 
215
 
 
216
    using namespace testing;
 
217
 
 
218
    EXPECT_CALL(mockfs, LoadPlugin(_, _, _)).Times(AtMost(0));
 
219
    EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(AtMost(0));
 
220
 
 
221
    EXPECT_CALL(mockfs, ListPlugins(EndsWith(HOME_PLUGINDIR))).WillOnce(Return(home));
 
222
    EXPECT_CALL(mockfs, ListPlugins(EndsWith(PLUGINDIR))).WillOnce(Return(plugin));
 
223
    EXPECT_CALL(mockfs, ListPlugins(Eq((void*)0))).WillOnce(Return(local));
 
224
 
 
225
    CompStringList cl = CompPlugin::availablePlugins();
 
226
    ASSERT_EQ(3, cl.size());
 
227
 
 
228
    ASSERT_THAT(cl, Contains(one));
 
229
    ASSERT_THAT(cl, Contains(two));
 
230
    ASSERT_THAT(cl, Contains(three));
 
231
}
 
232
 
 
233
TEST(PluginTest, list_plugins_are_deduped)
 
234
{
 
235
    std::string one = "one";
 
236
    std::string two = "two";
 
237
    std::string three = "three";
 
238
 
 
239
    CompStringList home(1, one);
 
240
    CompStringList plugin(1, two);
 
241
    CompStringList local(1, three);
 
242
 
 
243
    plugin.push_back(one);
 
244
    local.push_back(two);
 
245
 
 
246
    MockPluginFilesystem mockfs;
 
247
 
 
248
    using namespace testing;
 
249
 
 
250
    EXPECT_CALL(mockfs, LoadPlugin(_, _, _)).Times(AtMost(0));
 
251
    EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(AtMost(0));
 
252
 
 
253
    EXPECT_CALL(mockfs, ListPlugins(EndsWith(HOME_PLUGINDIR))).WillOnce(Return(home));
 
254
    EXPECT_CALL(mockfs, ListPlugins(EndsWith(PLUGINDIR))).WillOnce(Return(plugin));
 
255
    EXPECT_CALL(mockfs, ListPlugins(Eq((void*)0))).WillOnce(Return(local));
 
256
 
 
257
    CompStringList cl = CompPlugin::availablePlugins();
 
258
    ASSERT_EQ(3, cl.size());
 
259
 
 
260
    ASSERT_THAT(cl, Contains(one));
 
261
    ASSERT_THAT(cl, Contains(two));
 
262
    ASSERT_THAT(cl, Contains(three));
 
263
}
 
264
 
 
265
 
 
266
TEST(PluginTest, when_we_push_plugin_init_is_called)
 
267
{
 
268
    MockPluginFilesystem mockfs;
 
269
 
 
270
    using namespace testing;
 
271
 
 
272
    EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))).
 
273
        WillOnce(Return(true));
 
274
 
 
275
    EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(PLUGINDIR), StrEq("dummy"))).
 
276
        Times(AtMost(0));
 
277
 
 
278
    EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), Eq((void*)0), StrEq("dummy"))).
 
279
        Times(AtMost(0));
 
280
 
 
281
    EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(1);
 
282
    EXPECT_CALL(mockfs, ListPlugins(_)).Times(0);
 
283
 
 
284
    MockVTable mockVtable;
 
285
    EXPECT_CALL(mockVtable, init()).WillOnce(Return(true));
 
286
 
 
287
    CompPlugin* cp = CompPlugin::load("dummy");
 
288
 
 
289
    cp->vTable = &mockVtable;
 
290
 
 
291
    CompPlugin::push(cp);
 
292
    ASSERT_EQ(cp, CompPlugin::pop());
 
293
    CompPlugin::unload(cp);
 
294
}