|
34 | 34 | #include "src/indexes/vector_flat.h" |
35 | 35 | #include "src/indexes/vector_hnsw.h" |
36 | 36 | #include "src/keyspace_event_manager.h" |
| 37 | +#include "src/metrics.h" |
37 | 38 | #include "src/schema_manager.h" |
38 | 39 | #include "src/utils/string_interning.h" |
39 | 40 | #include "testing/common.h" |
@@ -82,7 +83,17 @@ struct IndexSchemaSubscriptionTestCase { |
82 | 83 | }; |
83 | 84 |
|
84 | 85 | class IndexSchemaSubscriptionTest |
85 | | - : public ValkeySearchTestWithParam<IndexSchemaSubscriptionTestCase> {}; |
| 86 | + : public ValkeySearchTestWithParam<IndexSchemaSubscriptionTestCase> { |
| 87 | + protected: |
| 88 | + // Helper functions to check operation success/failure patterns |
| 89 | + static bool IsOperationSuccessful(const absl::optional<absl::StatusOr<bool>>& result) { |
| 90 | + return result.has_value() && result.value().ok() && result.value().value(); |
| 91 | + } |
| 92 | + |
| 93 | + static bool IsOperationFailed(const absl::optional<absl::StatusOr<bool>>& result) { |
| 94 | + return result.has_value() && !result.value().ok(); |
| 95 | + } |
| 96 | +}; |
86 | 97 |
|
87 | 98 | TEST_P(IndexSchemaSubscriptionTest, OnKeyspaceNotificationTest) { |
88 | 99 | const IndexSchemaSubscriptionTestCase &test_case = GetParam(); |
@@ -193,6 +204,12 @@ TEST_P(IndexSchemaSubscriptionTest, OnKeyspaceNotificationTest) { |
193 | 204 | .skipped_cnt = |
194 | 205 | index_schema->GetStats().subscription_modify.skipped_cnt}; |
195 | 206 | uint32_t document_cnt = index_schema->GetStats().document_cnt; |
| 207 | + |
| 208 | + // Capture initial Time Slice Mutex metrics |
| 209 | + auto& global_stats = Metrics::GetStats(); |
| 210 | + uint64_t initial_upserts = global_stats.time_slice_upserts; |
| 211 | + uint64_t initial_deletes = global_stats.time_slice_deletes; |
| 212 | + |
196 | 213 | index_schema->OnKeyspaceNotification(&fake_ctx, VALKEYMODULE_NOTIFY_HASH, |
197 | 214 | "event", key_valkey_str.get()); |
198 | 215 | if (use_thread_pool) { |
@@ -220,51 +237,60 @@ TEST_P(IndexSchemaSubscriptionTest, OnKeyspaceNotificationTest) { |
220 | 237 | EXPECT_EQ(index_schema->GetStats().document_cnt - document_cnt, |
221 | 238 | test_case.expected_document_cnt_delta); |
222 | 239 |
|
223 | | - // Check field type metrics based on test case's index_type and success/failure |
224 | | - if (test_case.expect_index_add_w_result.has_value() && |
225 | | - test_case.expect_index_add_w_result.value().ok() && |
226 | | - test_case.expect_index_add_w_result.value().value()) { |
227 | | - // For successful additions, check the appropriate field type metric |
| 240 | + // Determine operation success/failure states using helper functions |
| 241 | + bool successful_add = IsOperationSuccessful(test_case.expect_index_add_w_result); |
| 242 | + bool successful_modify = IsOperationSuccessful(test_case.expect_index_modify_w_result); |
| 243 | + bool successful_remove = IsOperationSuccessful(test_case.expect_index_remove_w_result); |
| 244 | + |
| 245 | + bool failed_operation = IsOperationFailed(test_case.expect_index_add_w_result) || |
| 246 | + IsOperationFailed(test_case.expect_index_modify_w_result) || |
| 247 | + IsOperationFailed(test_case.expect_index_remove_w_result); |
| 248 | + |
| 249 | + bool successful_upsert = successful_add || successful_modify; |
| 250 | + bool is_hash_operation = !test_case.open_key_fail && |
| 251 | + test_case.open_key_type == VALKEYMODULE_KEYTYPE_HASH && |
| 252 | + test_case.valkey_hash_data.has_value(); |
| 253 | + |
| 254 | + // Check field type metrics for successful operations with document count increase |
| 255 | + if (successful_upsert && test_case.expected_document_cnt_delta > 0) { |
228 | 256 | switch (test_case.index_type) { |
229 | 257 | case indexes::IndexerType::kVector: |
230 | | - // Only check if document count increased (real vector field indexed) |
231 | | - if (test_case.expected_document_cnt_delta > 0) { |
232 | | - EXPECT_GT(metrics.ingest_field_vector, initial_field_vector); |
233 | | - } |
| 258 | + EXPECT_GT(metrics.ingest_field_vector, initial_field_vector); |
234 | 259 | break; |
235 | 260 | case indexes::IndexerType::kNumeric: |
236 | | - if (test_case.expected_document_cnt_delta > 0) { |
237 | | - EXPECT_GT(metrics.ingest_field_numeric, initial_field_numeric); |
238 | | - } |
| 261 | + EXPECT_GT(metrics.ingest_field_numeric, initial_field_numeric); |
239 | 262 | break; |
240 | 263 | case indexes::IndexerType::kTag: |
241 | | - if (test_case.expected_document_cnt_delta > 0) { |
242 | | - EXPECT_GT(metrics.ingest_field_tag, initial_field_tag); |
243 | | - } |
| 264 | + EXPECT_GT(metrics.ingest_field_tag, initial_field_tag); |
244 | 265 | break; |
245 | 266 | default: |
246 | 267 | break; |
247 | 268 | } |
248 | 269 | } |
249 | 270 |
|
250 | | - // Check for failure metrics |
251 | | - if ((test_case.expect_index_add_w_result.has_value() && |
252 | | - !test_case.expect_index_add_w_result.value().ok()) || |
253 | | - (test_case.expect_index_modify_w_result.has_value() && |
254 | | - !test_case.expect_index_modify_w_result.value().ok()) || |
255 | | - (test_case.expect_index_remove_w_result.has_value() && |
256 | | - !test_case.expect_index_remove_w_result.value().ok())) { |
257 | | - // For failures, verify the total failures metric increased |
| 271 | + // Check failure metrics |
| 272 | + if (failed_operation) { |
258 | 273 | EXPECT_GT(metrics.ingest_total_failures, initial_total_failures); |
259 | 274 | } |
260 | 275 |
|
261 | | - // Check for hash keys metrics |
262 | | - if (!test_case.open_key_fail && test_case.open_key_type == VALKEYMODULE_KEYTYPE_HASH) { |
263 | | - if (test_case.valkey_hash_data.has_value()) { |
264 | | - EXPECT_GT(metrics.ingest_hash_keys, initial_hash_keys); |
265 | | - } |
| 276 | + // Check hash keys metrics |
| 277 | + if (is_hash_operation) { |
| 278 | + EXPECT_GT(metrics.ingest_hash_keys, initial_hash_keys); |
266 | 279 | } |
267 | | - } |
| 280 | + |
| 281 | + // Verify Time Slice Mutex metrics |
| 282 | + if (successful_upsert) { |
| 283 | + EXPECT_EQ(global_stats.time_slice_upserts, initial_upserts + 1); |
| 284 | + EXPECT_EQ(global_stats.time_slice_deletes, initial_deletes); |
| 285 | + } else if (successful_remove) { |
| 286 | + EXPECT_EQ(global_stats.time_slice_deletes, initial_deletes + 1); |
| 287 | + EXPECT_EQ(global_stats.time_slice_upserts, initial_upserts); |
| 288 | + } else { |
| 289 | + // No successful operation expected |
| 290 | + EXPECT_EQ(global_stats.time_slice_upserts, initial_upserts); |
| 291 | + EXPECT_EQ(global_stats.time_slice_deletes, initial_deletes); |
| 292 | + } |
| 293 | +} |
268 | 294 | } |
269 | 295 |
|
270 | 296 | INSTANTIATE_TEST_SUITE_P( |
|
0 commit comments