Monitoring System 0.1.0
System resource monitoring with pluggable collectors and alerting
Loading...
Searching...
No Matches
test_security_collector.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>
7
8namespace kcenon {
9namespace monitoring {
10namespace {
11
12// Test fixture for security_collector tests
13class SecurityCollectorTest : public ::testing::Test {
14 protected:
15 void SetUp() override {
16 collector_ = std::make_unique<security_collector>();
17 std::unordered_map<std::string, std::string> config;
18 collector_->initialize(config);
19 }
20
21 std::unique_ptr<security_collector> collector_;
22};
23
24// Test basic initialization
25TEST_F(SecurityCollectorTest, InitializesSuccessfully) {
26 EXPECT_NE(collector_, nullptr);
27 EXPECT_EQ(collector_->name(), "security_collector");
28}
29
30// Test metric types returned
31TEST_F(SecurityCollectorTest, ReturnsCorrectMetricTypes) {
32 auto types = collector_->get_metric_types();
33 EXPECT_FALSE(types.empty());
34
35 // Check for expected metric types
36 std::vector<std::string> expected_types = {
37 "security_login_success_total",
38 "security_login_failure_total",
39 "security_sudo_usage_total",
40 "security_events_total"
41 };
42
43 for (const auto& expected : expected_types) {
44 bool found = std::find(types.begin(), types.end(), expected) != types.end();
45 EXPECT_TRUE(found) << "Expected metric type not found: " << expected;
46 }
47}
48
49// Test configuration options
50TEST_F(SecurityCollectorTest, ConfigurationOptions) {
51 auto collector = std::make_unique<security_collector>();
52
53 std::unordered_map<std::string, std::string> config = {
54 {"enabled", "true"},
55 {"mask_pii", "true"},
56 {"max_recent_events", "50"},
57 {"login_failure_rate_limit", "500"}
58 };
59
60 EXPECT_TRUE(collector->initialize(config));
61}
62
63// Test disable collector
64TEST_F(SecurityCollectorTest, CanBeDisabled) {
65 auto collector = std::make_unique<security_collector>();
66
67 std::unordered_map<std::string, std::string> config = {
68 {"enabled", "false"}
69 };
70
71 collector->initialize(config);
72
73 auto metrics = collector->collect();
74 // Disabled collector should return empty metrics
75 EXPECT_TRUE(metrics.empty());
76}
77
78// Test statistics
79TEST_F(SecurityCollectorTest, TracksStatistics) {
80 auto stats = collector_->get_statistics();
81 EXPECT_TRUE(stats.find("collection_count") != stats.end());
82 EXPECT_TRUE(stats.find("collection_errors") != stats.end());
83 EXPECT_TRUE(stats.find("enabled") != stats.end());
84 EXPECT_TRUE(stats.find("available") != stats.end());
85 EXPECT_TRUE(stats.find("mask_pii") != stats.end());
86}
87
88// Test collect returns metrics (graceful degradation when unavailable)
89TEST_F(SecurityCollectorTest, CollectReturnsMetrics) {
90 auto metrics = collector_->collect();
91 // May be empty if not available on this platform
92 // Just verify it doesn't crash
93}
94
95// Test get_last_metrics
96TEST_F(SecurityCollectorTest, GetLastMetrics) {
97 collector_->collect(); // Trigger a collection
98 auto last = collector_->get_last_metrics();
99 // Verify timestamp is set
100 auto now = std::chrono::system_clock::now();
101 auto diff = std::chrono::duration_cast<std::chrono::seconds>(now - last.timestamp);
102 EXPECT_LT(diff.count(), 10); // Should be recent
103}
104
105// Test is_security_monitoring_available
106TEST_F(SecurityCollectorTest, SecurityMonitoringAvailabilityCheck) {
107 bool available = collector_->is_security_monitoring_available();
108 // Just check it returns a boolean without crashing
109 (void)available;
110}
111
112// Test security_event_counts structure
113TEST(SecurityEventCountsTest, DefaultInitialization) {
114 security_event_counts counts;
115 EXPECT_EQ(counts.login_success, 0);
116 EXPECT_EQ(counts.login_failure, 0);
117 EXPECT_EQ(counts.logout, 0);
118 EXPECT_EQ(counts.sudo_usage, 0);
119 EXPECT_EQ(counts.permission_change, 0);
120 EXPECT_EQ(counts.account_created, 0);
121 EXPECT_EQ(counts.account_deleted, 0);
122 EXPECT_EQ(counts.unknown, 0);
123}
124
125// Test security_event_counts increment
126TEST(SecurityEventCountsTest, IncrementWorks) {
127 security_event_counts counts;
128 counts.increment(security_event_type::login_success);
129 counts.increment(security_event_type::login_success);
130 counts.increment(security_event_type::login_failure);
131
132 EXPECT_EQ(counts.login_success, 2);
133 EXPECT_EQ(counts.login_failure, 1);
134 EXPECT_EQ(counts.total(), 3);
135}
136
137// Test security_event_counts get_count
138TEST(SecurityEventCountsTest, GetCountWorks) {
139 security_event_counts counts;
140 counts.login_success = 10;
141 counts.login_failure = 5;
142
143 EXPECT_EQ(counts.get_count(security_event_type::login_success), 10);
144 EXPECT_EQ(counts.get_count(security_event_type::login_failure), 5);
145 EXPECT_EQ(counts.get_count(security_event_type::sudo_usage), 0);
146}
147
148// Test security_event_type_to_string
149TEST(SecurityEventTypeTest, ToStringWorks) {
155}
156
157// Test security_info_collector basic functionality
158TEST(SecurityInfoCollectorTest, BasicFunctionality) {
159 security_info_collector collector;
160
161 // Check availability
162 bool available = collector.is_security_monitoring_available();
163
164 // Collect metrics
165 auto metrics = collector.collect_metrics();
166
167 // If available, should have valid data
168 if (available) {
169 EXPECT_TRUE(metrics.metrics_available);
170 }
171}
172
173// Test multiple collections are stable
174TEST_F(SecurityCollectorTest, MultipleCollectionsAreStable) {
175 for (int i = 0; i < 3; ++i) {
176 auto metrics = collector_->collect();
177 // Should not crash
178 }
179
180 auto stats = collector_->get_statistics();
181 // Collection count should have increased
182}
183
184// Test that metrics have correct tags when collected
185TEST_F(SecurityCollectorTest, MetricsHaveCorrectTags) {
186 auto metrics = collector_->collect();
187 for (const auto& m : metrics) {
188 // All metrics should have collector tag
189 auto it = m.tags.find("collector");
190 if (it != m.tags.end()) {
191 EXPECT_EQ(it->second, "security");
192 }
193 }
194}
195
196// Test is_healthy reflects actual state
197TEST_F(SecurityCollectorTest, IsHealthyReflectsState) {
198 bool healthy = collector_->is_healthy();
199 // Should be healthy initially (no errors yet)
200 EXPECT_TRUE(healthy);
201}
202
203// Test PII masking configuration
204TEST_F(SecurityCollectorTest, PIIMaskingConfiguration) {
205 auto collector = std::make_unique<security_collector>();
206
207 std::unordered_map<std::string, std::string> config = {
208 {"enabled", "true"},
209 {"mask_pii", "true"}
210 };
211
212 EXPECT_TRUE(collector->initialize(config));
213
214 auto stats = collector->get_statistics();
215 EXPECT_EQ(stats["mask_pii"], 1.0);
216}
217
218#if defined(__linux__) || defined(__APPLE__)
219// Platform-specific test: On Unix-like systems, check availability
220TEST_F(SecurityCollectorTest, UnixSecurityMonitoringCheck) {
221 // On Linux/macOS, security monitoring may or may not be available
222 // depending on permissions and log file presence
223 bool available = collector_->is_security_monitoring_available();
224 // Just verify the check completes without error
225 (void)available;
226}
227#endif
228
229#if defined(_WIN32)
230// Platform-specific test: On Windows, security monitoring is not yet implemented
231TEST_F(SecurityCollectorTest, WindowsSecurityMonitoringUnavailable) {
232 EXPECT_FALSE(collector_->is_security_monitoring_available());
233}
234
235// Platform-specific test: Windows metrics should indicate unavailability
236TEST(SecurityInfoCollectorTest, WindowsReturnsUnavailableMetrics) {
237 security_info_collector collector;
238 auto metrics = collector.collect_metrics();
239 EXPECT_FALSE(metrics.metrics_available);
240}
241#endif
242
243} // namespace
244} // namespace monitoring
245} // namespace kcenon
@ sudo_usage
Privilege escalation (sudo)
@ login_success
Successful login attempt.
@ account_created
New account creation.
@ login_failure
Failed login attempt.
std::string security_event_type_to_string(security_event_type type)
Convert security_event_type to string representation.
Security event monitoring collector.
TEST(AdapterFunctionalityTest, WorksWithoutLogger)
Test Scenario 1: Adapter with NULL logger.
TEST_F(AdaptiveMonitoringTest, AdaptiveConfigDefaults)
std::unique_ptr< battery_collector > collector_