1 | // |
---|---|
2 | // ClassLoaderTest.cpp |
3 | // |
4 | // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. |
5 | // and Contributors. |
6 | // |
7 | // SPDX-License-Identifier: BSL-1.0 |
8 | // |
9 | |
10 | |
11 | #include "ClassLoaderTest.h" |
12 | #include "Poco/CppUnit/TestCaller.h" |
13 | #include "Poco/CppUnit/TestSuite.h" |
14 | #include "Poco/ClassLoader.h" |
15 | #include "Poco/Manifest.h" |
16 | #include "Poco/Path.h" |
17 | #include "Poco/Exception.h" |
18 | #include "TestPlugin.h" |
19 | |
20 | |
21 | using Poco::ClassLoader; |
22 | using Poco::Manifest; |
23 | using Poco::SharedLibrary; |
24 | using Poco::AbstractMetaObject; |
25 | using Poco::NotFoundException; |
26 | using Poco::InvalidAccessException; |
27 | using Poco::Path; |
28 | |
29 | |
30 | ClassLoaderTest::ClassLoaderTest(const std::string& rName): CppUnit::TestCase(rName) |
31 | { |
32 | } |
33 | |
34 | |
35 | ClassLoaderTest::~ClassLoaderTest() |
36 | { |
37 | } |
38 | |
39 | |
40 | void ClassLoaderTest::testClassLoader1() |
41 | { |
42 | std::string self = Path(Path::self()).makeParent().toString(); |
43 | std::string path = self + "TestLibrary"; |
44 | path.append(SharedLibrary::suffix()); |
45 | |
46 | ClassLoader<TestPlugin> cl; |
47 | |
48 | assertTrue (cl.begin() == cl.end()); |
49 | assertNullPtr (cl.findClass("PluginA")); |
50 | assertNullPtr (cl.findManifest(path)); |
51 | |
52 | assertTrue (!cl.isLibraryLoaded(path)); |
53 | |
54 | try |
55 | { |
56 | const ClassLoader<TestPlugin>::Meta& meta = cl.classFor("PluginA"); |
57 | fail("not found - must throw exception"); |
58 | } |
59 | catch (NotFoundException&) |
60 | { |
61 | } |
62 | catch (...) |
63 | { |
64 | failmsg("wrong exception"); |
65 | } |
66 | |
67 | try |
68 | { |
69 | const ClassLoader<TestPlugin>::Manif& manif = cl.manifestFor(path); |
70 | fail("not found - must throw exception"); |
71 | } |
72 | catch (NotFoundException&) |
73 | { |
74 | } |
75 | catch (...) |
76 | { |
77 | failmsg("wrong exception"); |
78 | } |
79 | } |
80 | |
81 | |
82 | void ClassLoaderTest::testClassLoader2() |
83 | { |
84 | std::string self = Path(Path::self()).makeParent().toString(); |
85 | std::string path = self + "TestLibrary"; |
86 | path.append(SharedLibrary::suffix()); |
87 | |
88 | ClassLoader<TestPlugin> cl; |
89 | cl.loadLibrary(path); |
90 | |
91 | assertTrue (cl.begin() != cl.end()); |
92 | assertNotNullPtr (cl.findClass("PluginA")); |
93 | assertNotNullPtr (cl.findClass("PluginB")); |
94 | assertNotNullPtr (cl.findClass("PluginC")); |
95 | assertNotNullPtr (cl.findManifest(path)); |
96 | |
97 | assertTrue (cl.isLibraryLoaded(path)); |
98 | assertTrue (cl.manifestFor(path).size() == 3); |
99 | |
100 | ClassLoader<TestPlugin>::Iterator it = cl.begin(); |
101 | assertTrue (it != cl.end()); |
102 | assertTrue (it->first == path); |
103 | assertTrue (it->second->size() == 3); |
104 | ++it; |
105 | assertTrue (it == cl.end()); |
106 | |
107 | TestPlugin* pPluginA = cl.classFor("PluginA").create(); |
108 | assertTrue (pPluginA->name() == "PluginA"); |
109 | assertTrue (!cl.classFor("PluginA").isAutoDelete(pPluginA)); |
110 | delete pPluginA; |
111 | |
112 | TestPlugin* pPluginB = cl.classFor("PluginB").create(); |
113 | assertTrue (pPluginB->name() == "PluginB"); |
114 | delete pPluginB; |
115 | |
116 | pPluginB = cl.create("PluginB"); |
117 | assertTrue (pPluginB->name() == "PluginB"); |
118 | delete pPluginB; |
119 | |
120 | assertTrue (cl.canCreate("PluginA")); |
121 | assertTrue (cl.canCreate("PluginB")); |
122 | assertTrue (!cl.canCreate("PluginC")); |
123 | |
124 | TestPlugin& pluginC = cl.instance("PluginC"); |
125 | assertTrue (pluginC.name() == "PluginC"); |
126 | |
127 | try |
128 | { |
129 | TestPlugin& plgB = cl.instance("PluginB"); |
130 | fail("not a singleton - must throw"); |
131 | } |
132 | catch (InvalidAccessException&) |
133 | { |
134 | } |
135 | |
136 | try |
137 | { |
138 | TestPlugin* pPluginC = cl.create("PluginC"); |
139 | fail("cannot create a singleton - must throw"); |
140 | } |
141 | catch (InvalidAccessException&) |
142 | { |
143 | } |
144 | |
145 | try |
146 | { |
147 | const AbstractMetaObject<TestPlugin>& meta = cl.classFor("PluginC"); |
148 | meta.autoDelete(&(meta.instance())); |
149 | fail("cannot take ownership of a singleton - must throw"); |
150 | } |
151 | catch (InvalidAccessException&) |
152 | { |
153 | } |
154 | |
155 | const AbstractMetaObject<TestPlugin>& meta1 = cl.classFor("PluginC"); |
156 | assertTrue (meta1.isAutoDelete(&(meta1.instance()))); |
157 | |
158 | // the following must not produce memory leaks |
159 | const AbstractMetaObject<TestPlugin>& meta2 = cl.classFor("PluginA"); |
160 | meta2.autoDelete(meta2.create()); |
161 | meta2.autoDelete(meta2.create()); |
162 | |
163 | TestPlugin* pPlugin = meta2.create(); |
164 | meta2.autoDelete(pPlugin); |
165 | assertTrue (meta2.isAutoDelete(pPlugin)); |
166 | meta2.destroy(pPlugin); |
167 | assertTrue (!meta2.isAutoDelete(pPlugin)); |
168 | |
169 | cl.unloadLibrary(path); |
170 | } |
171 | |
172 | |
173 | void ClassLoaderTest::testClassLoader3() |
174 | { |
175 | std::string self = Path(Path::self()).makeParent().toString(); |
176 | std::string path = self + "TestLibrary"; |
177 | path.append(SharedLibrary::suffix()); |
178 | |
179 | ClassLoader<TestPlugin> cl; |
180 | cl.loadLibrary(path); |
181 | cl.loadLibrary(path); |
182 | cl.unloadLibrary(path); |
183 | |
184 | assertTrue (cl.manifestFor(path).size() == 3); |
185 | |
186 | ClassLoader<TestPlugin>::Iterator it = cl.begin(); |
187 | assertTrue (it != cl.end()); |
188 | assertTrue (it->first == path); |
189 | assertTrue (it->second->size() == 3); |
190 | ++it; |
191 | assertTrue (it == cl.end()); |
192 | |
193 | cl.unloadLibrary(path); |
194 | assertNullPtr (cl.findManifest(path)); |
195 | } |
196 | |
197 | |
198 | void ClassLoaderTest::setUp() |
199 | { |
200 | } |
201 | |
202 | |
203 | void ClassLoaderTest::tearDown() |
204 | { |
205 | } |
206 | |
207 | |
208 | CppUnit::Test* ClassLoaderTest::suite() |
209 | { |
210 | CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("ClassLoaderTest"); |
211 | |
212 | CppUnit_addTest(pSuite, ClassLoaderTest, testClassLoader1); |
213 | CppUnit_addTest(pSuite, ClassLoaderTest, testClassLoader2); |
214 | CppUnit_addTest(pSuite, ClassLoaderTest, testClassLoader3); |
215 | |
216 | return pSuite; |
217 | } |
218 |