Monitoring System 0.1.0
System resource monitoring with pluggable collectors and alerting
Loading...
Searching...
No Matches
test_collector_registry.cpp
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2021-2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
5#include <gtest/gtest.h>
6
8
9namespace kcenon {
10namespace monitoring {
11namespace {
12
13// Mock collector plugin for testing
14class mock_collector_plugin : public collector_plugin {
15public:
16 explicit mock_collector_plugin(std::string_view name,
18 bool available = true)
19 : name_(name), category_(category), available_(available) {}
20
21 auto name() const -> std::string_view override { return name_; }
22
23 auto collect() -> std::vector<metric> override {
25 return {};
26 }
27
28 auto interval() const -> std::chrono::milliseconds override {
29 return std::chrono::seconds(1);
30 }
31
32 auto is_available() const -> bool override { return available_; }
33
34 auto get_metadata() const -> plugin_metadata override {
35 return plugin_metadata{
36 .name = name_,
37 .description = "Mock plugin for testing",
38 .category = category_,
39 .version = "1.0.0",
40 .dependencies = {},
41 .requires_platform_support = false
42 };
43 }
44
45 auto initialize(const config_map& /* config */) -> bool override {
46 initialized_ = true;
47 return true;
48 }
49
50 void shutdown() override { shutdown_called_ = true; }
51
52 auto get_metric_types() const -> std::vector<std::string> override {
53 return {"test_metric"};
54 }
55
56 // Test helpers
57 bool is_initialized() const { return initialized_; }
58 bool is_shutdown_called() const { return shutdown_called_; }
59 size_t get_collect_count() const { return collect_count_; }
60
61private:
62 std::string name_;
65 bool initialized_{false};
66 bool shutdown_called_{false};
67 mutable size_t collect_count_{0};
68};
69
70// Test fixture
71class CollectorRegistryTest : public ::testing::Test {
72protected:
73 void SetUp() override {
74 // Clear registry before each test
76 }
77
78 void TearDown() override {
79 // Clean up after each test
81 }
82};
83
84// Test singleton instance
85TEST_F(CollectorRegistryTest, SingletonInstance) {
86 auto& registry1 = collector_registry::instance();
87 auto& registry2 = collector_registry::instance();
88
89 EXPECT_EQ(&registry1, &registry2);
90}
91
92// Test plugin registration
93TEST_F(CollectorRegistryTest, RegisterPlugin) {
94 auto& registry = collector_registry::instance();
95
96 auto plugin = std::make_unique<mock_collector_plugin>("test_plugin");
97 EXPECT_TRUE(registry.register_plugin(std::move(plugin)));
98
99 EXPECT_TRUE(registry.has_plugin("test_plugin"));
100 EXPECT_EQ(registry.plugin_count(), 1);
101}
102
103// Test duplicate registration fails
104TEST_F(CollectorRegistryTest, RejectsDuplicateRegistration) {
105 auto& registry = collector_registry::instance();
106
107 auto plugin1 = std::make_unique<mock_collector_plugin>("test_plugin");
108 EXPECT_TRUE(registry.register_plugin(std::move(plugin1)));
109
110 auto plugin2 = std::make_unique<mock_collector_plugin>("test_plugin");
111 EXPECT_FALSE(registry.register_plugin(std::move(plugin2)));
112
113 EXPECT_EQ(registry.plugin_count(), 1);
114}
115
116// Test unavailable plugins are rejected
117TEST_F(CollectorRegistryTest, RejectsUnavailablePlugin) {
118 auto& registry = collector_registry::instance();
119
120 auto plugin = std::make_unique<mock_collector_plugin>("unavailable", plugin_category::custom, false);
121 EXPECT_FALSE(registry.register_plugin(std::move(plugin)));
122
123 EXPECT_FALSE(registry.has_plugin("unavailable"));
124 EXPECT_EQ(registry.plugin_count(), 0);
125}
126
127// Test plugin retrieval
128TEST_F(CollectorRegistryTest, GetPlugin) {
129 auto& registry = collector_registry::instance();
130
131 auto plugin = std::make_unique<mock_collector_plugin>("test_plugin");
132 auto* plugin_ptr = plugin.get();
133 registry.register_plugin(std::move(plugin));
134
135 auto* retrieved = registry.get_plugin("test_plugin");
136 EXPECT_EQ(retrieved, plugin_ptr);
137
138 auto* not_found = registry.get_plugin("nonexistent");
139 EXPECT_EQ(not_found, nullptr);
140}
141
142// Test get all plugins
143TEST_F(CollectorRegistryTest, GetAllPlugins) {
144 auto& registry = collector_registry::instance();
145
146 registry.register_plugin(std::make_unique<mock_collector_plugin>("plugin1"));
147 registry.register_plugin(std::make_unique<mock_collector_plugin>("plugin2"));
148 registry.register_plugin(std::make_unique<mock_collector_plugin>("plugin3"));
149
150 auto plugins = registry.get_plugins();
151 EXPECT_EQ(plugins.size(), 3);
152}
153
154// Test get plugins by category
155TEST_F(CollectorRegistryTest, GetPluginsByCategory) {
156 auto& registry = collector_registry::instance();
157
158 registry.register_plugin(std::make_unique<mock_collector_plugin>("hw1", plugin_category::hardware));
159 registry.register_plugin(std::make_unique<mock_collector_plugin>("hw2", plugin_category::hardware));
160 registry.register_plugin(std::make_unique<mock_collector_plugin>("sys1", plugin_category::system));
161
162 auto hw_plugins = registry.get_plugins_by_category(plugin_category::hardware);
163 EXPECT_EQ(hw_plugins.size(), 2);
164
165 auto sys_plugins = registry.get_plugins_by_category(plugin_category::system);
166 EXPECT_EQ(sys_plugins.size(), 1);
167
168 auto net_plugins = registry.get_plugins_by_category(plugin_category::network);
169 EXPECT_EQ(net_plugins.size(), 0);
170}
171
172// Test plugin unregistration
173TEST_F(CollectorRegistryTest, UnregisterPlugin) {
174 auto& registry = collector_registry::instance();
175
176 auto plugin = std::make_unique<mock_collector_plugin>("test_plugin");
177 registry.register_plugin(std::move(plugin));
178
179 EXPECT_TRUE(registry.has_plugin("test_plugin"));
180 EXPECT_TRUE(registry.unregister_plugin("test_plugin"));
181 EXPECT_FALSE(registry.has_plugin("test_plugin"));
182}
183
184// Test unregistering nonexistent plugin
185TEST_F(CollectorRegistryTest, UnregisterNonexistentPlugin) {
186 auto& registry = collector_registry::instance();
187
188 EXPECT_FALSE(registry.unregister_plugin("nonexistent"));
189}
190
191// Test initialize all plugins
192TEST_F(CollectorRegistryTest, InitializeAllPlugins) {
193 auto& registry = collector_registry::instance();
194
195 auto plugin1 = std::make_unique<mock_collector_plugin>("plugin1");
196 auto plugin2 = std::make_unique<mock_collector_plugin>("plugin2");
197 auto* ptr1 = plugin1.get();
198 auto* ptr2 = plugin2.get();
199
200 registry.register_plugin(std::move(plugin1));
201 registry.register_plugin(std::move(plugin2));
202
203 auto initialized_count = registry.initialize_all();
204 EXPECT_EQ(initialized_count, 2);
205
206 EXPECT_TRUE(ptr1->is_initialized());
207 EXPECT_TRUE(ptr2->is_initialized());
208}
209
210// Test shutdown all plugins
211TEST_F(CollectorRegistryTest, ShutdownAllPlugins) {
212 auto& registry = collector_registry::instance();
213
214 auto plugin1 = std::make_unique<mock_collector_plugin>("plugin1");
215 auto plugin2 = std::make_unique<mock_collector_plugin>("plugin2");
216 auto* ptr1 = plugin1.get();
217 auto* ptr2 = plugin2.get();
218
219 registry.register_plugin(std::move(plugin1));
220 registry.register_plugin(std::move(plugin2));
221 registry.initialize_all();
222
223 registry.shutdown_all();
224
225 EXPECT_TRUE(ptr1->is_shutdown_called());
226 EXPECT_TRUE(ptr2->is_shutdown_called());
227}
228
229// Test shutdown is called on unregistration
230TEST_F(CollectorRegistryTest, ShutdownOnUnregister) {
231 auto& registry = collector_registry::instance();
232
233 auto plugin = std::make_unique<mock_collector_plugin>("test_plugin");
234 auto* ptr = plugin.get();
235
236 registry.register_plugin(std::move(plugin));
237 registry.initialize_all();
238
239 EXPECT_TRUE(ptr->is_initialized());
240 EXPECT_FALSE(ptr->is_shutdown_called());
241
242 registry.unregister_plugin("test_plugin");
243
244 EXPECT_TRUE(ptr->is_shutdown_called());
245}
246
247// Test registry statistics
248TEST_F(CollectorRegistryTest, GetRegistryStats) {
249 auto& registry = collector_registry::instance();
250
251 registry.register_plugin(std::make_unique<mock_collector_plugin>("hw1", plugin_category::hardware));
252 registry.register_plugin(std::make_unique<mock_collector_plugin>("hw2", plugin_category::hardware));
253 registry.register_plugin(std::make_unique<mock_collector_plugin>("sys1", plugin_category::system));
254
255 auto stats = registry.get_registry_stats();
256
257 EXPECT_EQ(stats["total_plugins"], 3);
258 EXPECT_EQ(stats["available_plugins"], 3);
259 EXPECT_EQ(stats["category_hardware_count"], 2);
260 EXPECT_EQ(stats["category_system_count"], 1);
261}
262
263// Test factory registration
264TEST_F(CollectorRegistryTest, RegisterFactory) {
265 auto& registry = collector_registry::instance();
266
267 registry.register_factory<mock_collector_plugin>("lazy_plugin");
268
269 EXPECT_TRUE(registry.has_plugin("lazy_plugin"));
270 EXPECT_EQ(registry.plugin_count(), 1);
271
272 // Factory should not have instantiated yet
273 auto stats = registry.get_registry_stats();
274 EXPECT_EQ(stats["total_plugins"], 0);
275}
276
277// Test factory instantiation on get
278TEST_F(CollectorRegistryTest, FactoryInstantiatesOnGet) {
279 auto& registry = collector_registry::instance();
280
281 registry.register_factory<mock_collector_plugin>("lazy_plugin");
282
283 auto* plugin = registry.get_plugin("lazy_plugin");
284 EXPECT_NE(plugin, nullptr);
285
286 // Now it should be instantiated
287 auto stats = registry.get_registry_stats();
288 EXPECT_EQ(stats["total_plugins"], 1);
289}
290
291// Test clear removes all plugins
292TEST_F(CollectorRegistryTest, ClearRemovesAllPlugins) {
293 auto& registry = collector_registry::instance();
294
295 registry.register_plugin(std::make_unique<mock_collector_plugin>("plugin1"));
296 registry.register_plugin(std::make_unique<mock_collector_plugin>("plugin2"));
297
298 EXPECT_EQ(registry.plugin_count(), 2);
299
300 registry.clear();
301
302 EXPECT_EQ(registry.plugin_count(), 0);
303}
304
305} // namespace
306} // namespace monitoring
307} // namespace kcenon
static auto instance() -> collector_registry &
Get the singleton instance.
Registry for managing collector plugin lifecycle.
plugin_category
Categorization of collector plugins.
@ hardware
Hardware sensors (GPU, temperature, battery, power)
@ system
System integration (threads, loggers, containers)
@ custom
User-defined plugins.
@ network
Network metrics (connectivity, bandwidth)
std::unordered_map< std::string, std::string > config_map
Type alias for configuration map.
TEST_F(AdaptiveMonitoringTest, AdaptiveConfigDefaults)
std::string name_
plugin_category category_
size_t collect_count_
bool shutdown_called_
bool initialized_