TsPlugin.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
3 
4  This file is part of the TerraLib - a Framework for building GIS enabled
5  applications.
6 
7  TerraLib is free software: you can redistribute it and/or modify
8  it under the terms of the GNU Lesser General Public License as published by
9  the Free Software Foundation, either version 3 of the License,
10  or (at your option) any later version.
11 
12  TerraLib is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public License
18  along with TerraLib. See COPYING. If not, write to
19  TerraLib Team at <terralib-team@terralib.org>.
20  */
21 
22 /*!
23  \file terralib/unittest/core/plugin/TsPlugin.cpp
24 
25  \brief A test suit for the TerraLib Core Plugin Module.
26 
27  \author Matheus Cavassan Zaglia.
28  */
29 
30 // TerraLib
31 #include <terralib/core/plugin.h>
32 #include <terralib/core/utils.h>
33 
34 // Boost
35 #include <boost/test/unit_test.hpp>
36 
37 std::vector<te::core::PluginInfo> LoadPluginsInfo()
38 {
39  std::vector<te::core::PluginInfo> v_pInfo;
40 
41  v_pInfo.push_back(te::core::JSONPluginInfoSerializer(
42  te::core::FindInTerraLibPath("unittest/plugins/plugin1.teplg.json")));
43  v_pInfo.push_back(te::core::JSONPluginInfoSerializer(
44  te::core::FindInTerraLibPath("unittest/plugins/plugin2.teplg.json")));
45  v_pInfo.push_back(te::core::JSONPluginInfoSerializer(
46  te::core::FindInTerraLibPath("unittest/plugins/plugin3.teplg.json")));
47  v_pInfo.push_back(te::core::JSONPluginInfoSerializer(
48  te::core::FindInTerraLibPath("unittest/plugins/plugin4.teplg.json")));
49 
50  return v_pInfo;
51 }
52 
53 BOOST_AUTO_TEST_SUITE(plugin_test_case)
54 
55 BOOST_AUTO_TEST_CASE(plugin_engine_test)
56 {
57  std::unique_ptr<te::core::AbstractPluginEngine> cppengine(nullptr);
58  BOOST_CHECK_NO_THROW(cppengine.reset(new te::core::CppPluginEngine()));
59 
60  BOOST_CHECK_NO_THROW(
61  te::core::PluginEngineManager::instance().insert(std::move(cppengine)));
62  BOOST_CHECK_THROW(
63  te::core::PluginEngineManager::instance().insert(std::move(cppengine)),
65 
66  BOOST_CHECK_NO_THROW(te::core::PluginEngineManager::instance().get("C++"));
67  BOOST_CHECK_THROW(te::core::PluginEngineManager::instance().get("++C"),
69 
70  te::core::AbstractPluginEngine& plugin_engine =
72 
73  BOOST_CHECK(plugin_engine.id() == "C++");
74  BOOST_CHECK(plugin_engine.name() == "Engine for plugins written in C++");
75 
76  BOOST_CHECK_NO_THROW(te::core::PluginEngineManager::instance().remove("C++"));
77  BOOST_CHECK_THROW(te::core::PluginEngineManager::instance().remove("C++"),
79 
80  BOOST_CHECK_NO_THROW(te::core::plugin::InitializePluginSystem());
81  BOOST_CHECK_NO_THROW(te::core::plugin::FinalizePluginSystem());
82 }
83 
84 BOOST_AUTO_TEST_CASE(plugin_serializer_test)
85 {
86  BOOST_CHECK_THROW(
87  te::core::JSONPluginInfoSerializer("plugin/plugin1.teplg.json"),
89 
90  std::string p_manifest =
91  te::core::FindInTerraLibPath("unittest/plugins/plugin1.teplg.json");
92  BOOST_CHECK_NO_THROW(te::core::JSONPluginInfoSerializer(p_manifest));
93 }
94 
95 BOOST_AUTO_TEST_CASE(plugin_load_test)
96 {
97  std::unique_ptr<te::core::AbstractPluginEngine> cppengine(
99  te::core::PluginEngineManager::instance().insert(std::move(cppengine));
100 
101  te::core::AbstractPluginEngine& plugin_engine =
103 
104  std::string p_manifest =
105  te::core::FindInTerraLibPath("unittest/plugins/plugin1.teplg.json");
106 
108 
109  BOOST_CHECK_NO_THROW(plugin_engine.load(p_info));
110 
112 }
113 
114 BOOST_AUTO_TEST_CASE(plugin_usage_test)
115 {
116  std::unique_ptr<te::core::AbstractPluginEngine> cppengine(
118 
119  te::core::PluginEngineManager::instance().insert(std::move(cppengine));
120 
121  te::core::AbstractPluginEngine& plugin_engine =
123 
124  std::string p_manifest =
125  te::core::FindInTerraLibPath("unittest/plugins/plugin1.teplg.json");
126 
128 
129  std::unique_ptr<te::core::AbstractPlugin> plugin(plugin_engine.load(p_info));
130 
131  BOOST_CHECK_NO_THROW(plugin->info());
132 
133  BOOST_CHECK_NO_THROW(plugin->initialized());
134 
135  BOOST_CHECK_NO_THROW(plugin->startup());
136 
137  BOOST_CHECK_NO_THROW(plugin->shutdown());
138 
139  BOOST_CHECK_NO_THROW(plugin_engine.unload(std::move(plugin)));
140 
142 }
143 
144 BOOST_AUTO_TEST_CASE(plugin_sort_test)
145 {
146  te::core::PluginInfo pInfo1;
147  te::core::PluginInfo pInfo2;
148  te::core::PluginInfo pInfo3;
149  te::core::PluginInfo pInfo4;
150 
151  pInfo1.name = "plugin1";
152  pInfo2.name = "plugin2";
153  pInfo3.name = "plugin3";
154  pInfo4.name = "plugin4";
155  // 1<------+4
156  pInfo2.dependencies.push_back(pInfo3.name); // ^ +
157  pInfo3.dependencies.push_back(pInfo1.name); // | |
158  pInfo4.dependencies.push_back(pInfo1.name); // | |
159  pInfo4.dependencies.push_back(pInfo2.name); // + v
160  // 3<------+2
161  std::vector<te::core::PluginInfo> v_pInfo;
162  v_pInfo.push_back(pInfo1);
163  v_pInfo.push_back(pInfo2);
164  v_pInfo.push_back(pInfo3);
165  v_pInfo.push_back(pInfo4);
166 
167  BOOST_CHECK_NO_THROW(v_pInfo = te::core::plugin::TopologicalSort(v_pInfo));
168 
169  BOOST_CHECK(v_pInfo[0].name == "plugin1");
170 
171  BOOST_CHECK(v_pInfo[1].name == "plugin3");
172 
173  BOOST_CHECK(v_pInfo[2].name == "plugin2");
174 
175  BOOST_CHECK(v_pInfo[3].name == "plugin4");
176 }
177 
178 BOOST_AUTO_TEST_CASE(plugin_cyclic_dependency_test)
179 {
180  te::core::PluginInfo pInfo1;
181  te::core::PluginInfo pInfo2;
182 
183  pInfo1.name = "plugin1";
184  pInfo2.name = "plugin2";
185 
186  pInfo1.dependencies.push_back(pInfo2.name);
187  pInfo2.dependencies.push_back(pInfo1.name);
188 
189  std::vector<te::core::PluginInfo> v_pInfo;
190  v_pInfo.push_back(pInfo1);
191  v_pInfo.push_back(pInfo2);
192 
193  BOOST_CHECK_THROW(te::core::plugin::TopologicalSort(v_pInfo),
195 }
196 
197 BOOST_AUTO_TEST_CASE(plugin_dependency_test)
198 {
199  BOOST_CHECK_NO_THROW(te::core::plugin::InitializePluginSystem());
200 
201  std::vector<te::core::PluginInfo> v_pInfo = LoadPluginsInfo();
202 
203  BOOST_CHECK_NO_THROW(v_pInfo = te::core::plugin::TopologicalSort(v_pInfo));
204 
205  for(const te::core::PluginInfo& pinfo : v_pInfo)
206  {
207  BOOST_CHECK_NO_THROW(te::core::PluginManager::instance().insert(pinfo));
208  BOOST_CHECK_NO_THROW(te::core::PluginManager::instance().load(pinfo.name));
209  }
210  std::vector<te::core::PluginInfo> pVec =
212 
213  for(auto plugin = pVec.rbegin(); plugin != pVec.rend(); ++plugin)
214  {
215  BOOST_CHECK_NO_THROW(
216  te::core::PluginManager::instance().stop(plugin->name));
217  BOOST_CHECK_NO_THROW(
218  te::core::PluginManager::instance().unload(plugin->name));
219  }
220  BOOST_CHECK_NO_THROW(te::core::PluginManager::instance().clear());
221  BOOST_CHECK_NO_THROW(te::core::plugin::FinalizePluginSystem());
222 }
223 BOOST_AUTO_TEST_CASE(plugin_missing_dependency_test)
224 {
225  BOOST_CHECK_NO_THROW(te::core::plugin::InitializePluginSystem());
226 
227  std::vector<te::core::PluginInfo> v_pInfo = LoadPluginsInfo();
228 
229  // plugin 3 depends of plugin 1
230  BOOST_CHECK_NO_THROW(te::core::PluginManager::instance().insert(v_pInfo[2]));
231  BOOST_CHECK_THROW(te::core::PluginManager::instance().load(v_pInfo[2].name),
233 
236 }
237 BOOST_AUTO_TEST_CASE(plugin_unload_with_dependent_test)
238 {
240 
241  std::vector<te::core::PluginInfo> v_pInfo = LoadPluginsInfo();
242 
243  v_pInfo = te::core::plugin::TopologicalSort(v_pInfo);
244 
245  for(const te::core::PluginInfo& pinfo : v_pInfo)
246  {
249  }
250  // plugin 1 has plugin 4 and plugin 2 as dependents
251  BOOST_CHECK_THROW(te::core::PluginManager::instance().unload(v_pInfo[0].name),
253 
256 }
257 
258 BOOST_AUTO_TEST_SUITE_END()
TECOREEXPORT void FinalizePluginSystem()
void insert(std::unique_ptr< AbstractPluginEngine > engine)
Register a new plugin engine.
Include files for Core Plugin Library.
An exception indicating an error when unloading a plugin.
TECOREEXPORT std::vector< PluginInfo > TopologicalSort(const std::vector< PluginInfo > &v_pinfo)
An exception indicating an error when loading a plugin.
void insert(const PluginInfo &pinfo)
Adds plugin with its plugin information to the list of unloaded plugins.
Basic information about a plugin.
void load(const std::string &plugin_name, const bool start=true)
It tries to load the informed plugin.
void remove(const std::string &engine_id)
Unregister the plugin engine.
virtual std::unique_ptr< AbstractPlugin > load(const PluginInfo &pinfo)=0
Load the informed plugin.
std::string name
The plugin name: an internal value used to identify the plugin in the system. Must be a unique value...
static PluginManager & instance()
Access the singleton.
Include files for Core Utility Library.
std::vector< te::core::PluginInfo > LoadPluginsInfo()
Definition: TsPlugin.cpp:37
mydialect insert("+", new te::da::BinaryOpEncoder("+"))
AbstractPluginEngine & get(const std::string &engine_id) const
Find a plugin engine with the given id.
std::vector< std::string > dependencies
The list of required plugins in order to launch the plugin.
virtual void unload(std::unique_ptr< AbstractPlugin > plugin)=0
Unload the informed plugin.
virtual const std::string & id() const =0
Every plugin engine must have a unique identifier.
An exception indicating an error when two or more plugins have cyclic dependecy.
An exception indicating that a given item was not found in a collection (or range).
BOOST_AUTO_TEST_SUITE(plugin_test_case) BOOST_AUTO_TEST_CASE(plugin_engine_test)
Definition: TsPlugin.cpp:53
TECOREEXPORT PluginInfo JSONPluginInfoSerializer(const std::string &file_name)
A plugin finder that search for plugins in some special directories defined by compile time macros...
Definition: Serializers.cpp:44
TECOREEXPORT std::string FindInTerraLibPath(const std::string &path)
Returns the path relative to a directory or file in the context of TerraLib.
TECOREEXPORT void InitializePluginSystem()
An exception indicating that a given argument is not valid, for instance if a given item already exis...
void clear()
Stop and unload all plugins, then clear the internal list of plugins.
virtual const std::string & name() const =0
The name of plugin engine with a brief title or description.
BOOST_AUTO_TEST_CASE(plugin_serializer_test)
Definition: TsPlugin.cpp:84
std::vector< PluginInfo > getLoadedPlugins() const
Return the list of plugins that are loaded.
static PluginEngineManager & instance()
Access the singleton.