master
go 817 lines 38.7 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package mongo
4
5 import (
6 "context"
7 "encoding/json"
8 "errors"
9 "os"
10 "testing"
11 "time"
12
13 "github.com/netdata/netdata/go/plugins/pkg/matcher"
14 "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/collecttest"
15
16 "github.com/stretchr/testify/assert"
17 "github.com/stretchr/testify/require"
18 )
19
20 var (
21 dataConfigJSON, _ = os.ReadFile("testdata/config.json")
22 dataConfigYAML, _ = os.ReadFile("testdata/config.yaml")
23
24 dataVer6MongodServerStatus, _ = os.ReadFile("testdata/v6.0.3/mongod-serverStatus.json")
25 dataVer6MongosServerStatus, _ = os.ReadFile("testdata/v6.0.3/mongos-serverStatus.json")
26 dataVer6DbStats, _ = os.ReadFile("testdata/v6.0.3/dbStats.json")
27 dataVer6ReplSetGetStatus, _ = os.ReadFile("testdata/v6.0.3/replSetGetStatus.json")
28 )
29
30 func Test_testDataIsValid(t *testing.T) {
31 for name, data := range map[string][]byte{
32 "dataConfigJSON": dataConfigJSON,
33 "dataConfigYAML": dataConfigYAML,
34 "dataVer6MongodServerStatus": dataVer6MongodServerStatus,
35 "dataVer6MongosServerStatus": dataVer6MongosServerStatus,
36 "dataVer6DbStats": dataVer6DbStats,
37 "dataVer6ReplSetGetStatus": dataVer6ReplSetGetStatus,
38 } {
39 require.NotNil(t, data, name)
40 }
41 }
42
43 func TestCollector_ConfigurationSerialize(t *testing.T) {
44 collecttest.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
45 }
46
47 func TestCollector_Init(t *testing.T) {
48 tests := map[string]struct {
49 config Config
50 wantFail bool
51 }{
52 "success on default config": {
53 wantFail: false,
54 config: New().Config,
55 },
56 "fails on unset 'address'": {
57 wantFail: true,
58 config: Config{
59 URI: "",
60 },
61 },
62 "fails on invalid database selector": {
63 wantFail: true,
64 config: Config{
65 URI: "mongodb://localhost:27017",
66 Databases: matcher.SimpleExpr{
67 Includes: []string{"!@#"},
68 },
69 },
70 },
71 }
72
73 for name, test := range tests {
74 t.Run(name, func(t *testing.T) {
75 collr := New()
76 collr.Config = test.config
77
78 if test.wantFail {
79 assert.Error(t, collr.Init(context.Background()))
80 } else {
81 assert.NoError(t, collr.Init(context.Background()))
82 }
83 })
84 }
85 }
86
87 func TestCollector_Charts(t *testing.T) {
88 assert.NotNil(t, New().Charts())
89 }
90
91 func TestCollector_Cleanup(t *testing.T) {
92 tests := map[string]struct {
93 prepare func(t *testing.T) *Collector
94 wantClose bool
95 }{
96 "client not initialized": {
97 wantClose: false,
98 prepare: func(t *testing.T) *Collector {
99 return New()
100 },
101 },
102 "client initialized": {
103 wantClose: true,
104 prepare: func(t *testing.T) *Collector {
105 collr := New()
106 collr.conn = caseMongod()
107 _ = collr.conn.initClient("", 0)
108
109 return collr
110 },
111 },
112 }
113
114 for name, test := range tests {
115 t.Run(name, func(t *testing.T) {
116 collr := test.prepare(t)
117
118 require.NotPanics(t, func() { collr.Cleanup(context.Background()) })
119 if test.wantClose {
120 collr, ok := collr.conn.(*mockMongoClient)
121 require.True(t, ok)
122 assert.True(t, collr.closeCalled)
123 }
124 })
125 }
126 }
127
128 func TestCollector_Check(t *testing.T) {
129 tests := map[string]struct {
130 prepare func() *mockMongoClient
131 wantFail bool
132 }{
133 "success on Mongod (v6)": {
134 wantFail: false,
135 prepare: caseMongod,
136 },
137 "success on Mongod Replicas Set(v6)": {
138 wantFail: false,
139 prepare: caseMongodReplicaSet,
140 },
141 "success on Mongos (v6)": {
142 wantFail: false,
143 prepare: caseMongos,
144 },
145 }
146
147 for name, test := range tests {
148 t.Run(name, func(t *testing.T) {
149 collr := prepareMongo()
150 defer collr.Cleanup(context.Background())
151 collr.conn = test.prepare()
152
153 require.NoError(t, collr.Init(context.Background()))
154
155 if test.wantFail {
156 assert.Error(t, collr.Check(context.Background()))
157 } else {
158 assert.NoError(t, collr.Check(context.Background()))
159 }
160 })
161 }
162 }
163
164 func TestCollector_Collect(t *testing.T) {
165 tests := map[string]struct {
166 prepare func() *mockMongoClient
167 wantCollected map[string]int64
168 }{
169 "success on Mongod (v6)": {
170 prepare: caseMongod,
171 wantCollected: map[string]int64{
172 "asserts_msg": 0,
173 "asserts_regular": 0,
174 "asserts_rollovers": 0,
175 "asserts_tripwire": 0,
176 "asserts_user": 246,
177 "asserts_warning": 0,
178 "connections_active": 7,
179 "connections_available": 838841,
180 "connections_awaiting_topology_changes": 5,
181 "connections_current": 19,
182 "connections_exhaust_hello": 2,
183 "connections_exhaust_is_master": 1,
184 "connections_threaded": 19,
185 "connections_total_created": 77,
186 "database_admin_collections": 3,
187 "database_admin_data_size": 796,
188 "database_admin_documents": 5,
189 "database_admin_index_size": 81920,
190 "database_admin_indexes": 4,
191 "database_admin_storage_size": 61440,
192 "database_admin_views": 0,
193 "database_config_collections": 3,
194 "database_config_data_size": 796,
195 "database_config_documents": 5,
196 "database_config_index_size": 81920,
197 "database_config_indexes": 4,
198 "database_config_storage_size": 61440,
199 "database_config_views": 0,
200 "database_local_collections": 3,
201 "database_local_data_size": 796,
202 "database_local_documents": 5,
203 "database_local_index_size": 81920,
204 "database_local_indexes": 4,
205 "database_local_storage_size": 61440,
206 "database_local_views": 0,
207 "extra_info_page_faults": 0,
208 "global_lock_active_clients_readers": 0,
209 "global_lock_active_clients_writers": 0,
210 "global_lock_current_queue_readers": 0,
211 "global_lock_current_queue_writers": 0,
212 "locks_collection_acquire_exclusive": 6,
213 "locks_collection_acquire_intent_exclusive": 172523,
214 "locks_collection_acquire_intent_shared": 336370,
215 "locks_collection_acquire_shared": 0,
216 "locks_database_acquire_exclusive": 3,
217 "locks_database_acquire_intent_exclusive": 172539,
218 "locks_database_acquire_intent_shared": 50971,
219 "locks_database_acquire_shared": 0,
220 "locks_global_acquire_exclusive": 6,
221 "locks_global_acquire_intent_exclusive": 174228,
222 "locks_global_acquire_intent_shared": 437905,
223 "locks_global_acquire_shared": 0,
224 "locks_mutex_acquire_exclusive": 0,
225 "locks_mutex_acquire_intent_exclusive": 0,
226 "locks_mutex_acquire_intent_shared": 245077,
227 "locks_mutex_acquire_shared": 0,
228 "locks_oplog_acquire_exclusive": 0,
229 "locks_oplog_acquire_intent_exclusive": 1,
230 "locks_oplog_acquire_intent_shared": 16788,
231 "locks_oplog_acquire_shared": 0,
232 "memory_resident": 193986560,
233 "memory_virtual": 3023044608,
234 "metrics_cursor_lifespan_greater_than_or_equal_10_minutes": 0,
235 "metrics_cursor_lifespan_less_than_10_minutes": 0,
236 "metrics_cursor_lifespan_less_than_15_seconds": 0,
237 "metrics_cursor_lifespan_less_than_1_minute": 0,
238 "metrics_cursor_lifespan_less_than_1_second": 0,
239 "metrics_cursor_lifespan_less_than_30_seconds": 0,
240 "metrics_cursor_lifespan_less_than_5_seconds": 0,
241 "metrics_cursor_open_no_timeout": 0,
242 "metrics_cursor_open_total": 1,
243 "metrics_cursor_timed_out": 0,
244 "metrics_cursor_total_opened": 1,
245 "metrics_document_deleted": 7,
246 "metrics_document_inserted": 0,
247 "metrics_document_returned": 1699,
248 "metrics_document_updated": 52,
249 "metrics_query_executor_scanned": 61,
250 "metrics_query_executor_scanned_objects": 1760,
251 "network_bytes_in": 38851356,
252 "network_bytes_out": 706335836,
253 "network_requests": 130530,
254 "network_slow_dns_operations": 0,
255 "network_slow_ssl_operations": 0,
256 "operations_command": 125531,
257 "operations_delete": 7,
258 "operations_getmore": 5110,
259 "operations_insert": 0,
260 "operations_latencies_commands_latency": 46432082,
261 "operations_latencies_commands_ops": 125412,
262 "operations_latencies_reads_latency": 1009868,
263 "operations_latencies_reads_ops": 5111,
264 "operations_latencies_writes_latency": 0,
265 "operations_latencies_writes_ops": 0,
266 "operations_query": 76,
267 "operations_update": 59,
268 "tcmalloc_aggressive_memory_decommit": 0,
269 "tcmalloc_central_cache_free_bytes": 406680,
270 "tcmalloc_current_total_thread_cache_bytes": 2490832,
271 "tcmalloc_generic_current_allocated_bytes": 109050648,
272 "tcmalloc_generic_heap_size": 127213568,
273 "tcmalloc_max_total_thread_cache_bytes": 1073741824,
274 "tcmalloc_pageheap_commit_count": 376,
275 "tcmalloc_pageheap_committed_bytes": 127086592,
276 "tcmalloc_pageheap_decommit_count": 122,
277 "tcmalloc_pageheap_free_bytes": 13959168,
278 "tcmalloc_pageheap_reserve_count": 60,
279 "tcmalloc_pageheap_scavenge_bytes": 0,
280 "tcmalloc_pageheap_total_commit_bytes": 229060608,
281 "tcmalloc_pageheap_total_decommit_bytes": 101974016,
282 "tcmalloc_pageheap_total_reserve_bytes": 127213568,
283 "tcmalloc_pageheap_unmapped_bytes": 126976,
284 "tcmalloc_spinlock_total_delay_ns": 33426251,
285 "tcmalloc_thread_cache_free_bytes": 2490832,
286 "tcmalloc_total_free_bytes": 4076776,
287 "tcmalloc_transfer_cache_free_bytes": 1179264,
288 "txn_active": 0,
289 "txn_inactive": 0,
290 "txn_open": 0,
291 "txn_prepared": 0,
292 "txn_total_aborted": 0,
293 "txn_total_committed": 0,
294 "txn_total_prepared": 0,
295 "txn_total_started": 0,
296 "wiredtiger_cache_currently_in_cache_bytes": 814375,
297 "wiredtiger_cache_maximum_configured_bytes": 7854882816,
298 "wiredtiger_cache_modified_evicted_pages": 0,
299 "wiredtiger_cache_read_into_cache_pages": 108,
300 "wiredtiger_cache_tracked_dirty_in_the_cache_bytes": 456446,
301 "wiredtiger_cache_unmodified_evicted_pages": 0,
302 "wiredtiger_cache_written_from_cache_pages": 3177,
303 "wiredtiger_concurrent_txn_read_available": 128,
304 "wiredtiger_concurrent_txn_read_out": 0,
305 "wiredtiger_concurrent_txn_write_available": 128,
306 "wiredtiger_concurrent_txn_write_out": 0,
307 },
308 },
309 "success on Mongod Replica Set (v6)": {
310 prepare: caseMongodReplicaSet,
311 wantCollected: map[string]int64{
312 "asserts_msg": 0,
313 "asserts_regular": 0,
314 "asserts_rollovers": 0,
315 "asserts_tripwire": 0,
316 "asserts_user": 246,
317 "asserts_warning": 0,
318 "connections_active": 7,
319 "connections_available": 838841,
320 "connections_awaiting_topology_changes": 5,
321 "connections_current": 19,
322 "connections_exhaust_hello": 2,
323 "connections_exhaust_is_master": 1,
324 "connections_threaded": 19,
325 "connections_total_created": 77,
326 "database_admin_collections": 3,
327 "database_admin_data_size": 796,
328 "database_admin_documents": 5,
329 "database_admin_index_size": 81920,
330 "database_admin_indexes": 4,
331 "database_admin_storage_size": 61440,
332 "database_admin_views": 0,
333 "database_config_collections": 3,
334 "database_config_data_size": 796,
335 "database_config_documents": 5,
336 "database_config_index_size": 81920,
337 "database_config_indexes": 4,
338 "database_config_storage_size": 61440,
339 "database_config_views": 0,
340 "database_local_collections": 3,
341 "database_local_data_size": 796,
342 "database_local_documents": 5,
343 "database_local_index_size": 81920,
344 "database_local_indexes": 4,
345 "database_local_storage_size": 61440,
346 "database_local_views": 0,
347 "extra_info_page_faults": 0,
348 "global_lock_active_clients_readers": 0,
349 "global_lock_active_clients_writers": 0,
350 "global_lock_current_queue_readers": 0,
351 "global_lock_current_queue_writers": 0,
352 "locks_collection_acquire_exclusive": 6,
353 "locks_collection_acquire_intent_exclusive": 172523,
354 "locks_collection_acquire_intent_shared": 336370,
355 "locks_collection_acquire_shared": 0,
356 "locks_database_acquire_exclusive": 3,
357 "locks_database_acquire_intent_exclusive": 172539,
358 "locks_database_acquire_intent_shared": 50971,
359 "locks_database_acquire_shared": 0,
360 "locks_global_acquire_exclusive": 6,
361 "locks_global_acquire_intent_exclusive": 174228,
362 "locks_global_acquire_intent_shared": 437905,
363 "locks_global_acquire_shared": 0,
364 "locks_mutex_acquire_exclusive": 0,
365 "locks_mutex_acquire_intent_exclusive": 0,
366 "locks_mutex_acquire_intent_shared": 245077,
367 "locks_mutex_acquire_shared": 0,
368 "locks_oplog_acquire_exclusive": 0,
369 "locks_oplog_acquire_intent_exclusive": 1,
370 "locks_oplog_acquire_intent_shared": 16788,
371 "locks_oplog_acquire_shared": 0,
372 "memory_resident": 193986560,
373 "memory_virtual": 3023044608,
374 "metrics_cursor_lifespan_greater_than_or_equal_10_minutes": 0,
375 "metrics_cursor_lifespan_less_than_10_minutes": 0,
376 "metrics_cursor_lifespan_less_than_15_seconds": 0,
377 "metrics_cursor_lifespan_less_than_1_minute": 0,
378 "metrics_cursor_lifespan_less_than_1_second": 0,
379 "metrics_cursor_lifespan_less_than_30_seconds": 0,
380 "metrics_cursor_lifespan_less_than_5_seconds": 0,
381 "metrics_cursor_open_no_timeout": 0,
382 "metrics_cursor_open_total": 1,
383 "metrics_cursor_timed_out": 0,
384 "metrics_cursor_total_opened": 1,
385 "metrics_document_deleted": 7,
386 "metrics_document_inserted": 0,
387 "metrics_document_returned": 1699,
388 "metrics_document_updated": 52,
389 "metrics_query_executor_scanned": 61,
390 "metrics_query_executor_scanned_objects": 1760,
391 "network_bytes_in": 38851356,
392 "network_bytes_out": 706335836,
393 "network_requests": 130530,
394 "network_slow_dns_operations": 0,
395 "network_slow_ssl_operations": 0,
396 "operations_command": 125531,
397 "operations_delete": 7,
398 "operations_getmore": 5110,
399 "operations_insert": 0,
400 "operations_latencies_commands_latency": 46432082,
401 "operations_latencies_commands_ops": 125412,
402 "operations_latencies_reads_latency": 1009868,
403 "operations_latencies_reads_ops": 5111,
404 "operations_latencies_writes_latency": 0,
405 "operations_latencies_writes_ops": 0,
406 "operations_query": 76,
407 "operations_update": 59,
408 "repl_set_member_mongodb-primary:27017_health_status_down": 0,
409 "repl_set_member_mongodb-primary:27017_health_status_up": 1,
410 "repl_set_member_mongodb-primary:27017_replication_lag": 4572,
411 "repl_set_member_mongodb-primary:27017_state_arbiter": 0,
412 "repl_set_member_mongodb-primary:27017_state_down": 0,
413 "repl_set_member_mongodb-primary:27017_state_primary": 1,
414 "repl_set_member_mongodb-primary:27017_state_recovering": 0,
415 "repl_set_member_mongodb-primary:27017_state_removed": 0,
416 "repl_set_member_mongodb-primary:27017_state_rollback": 0,
417 "repl_set_member_mongodb-primary:27017_state_secondary": 0,
418 "repl_set_member_mongodb-primary:27017_state_startup": 0,
419 "repl_set_member_mongodb-primary:27017_state_startup2": 0,
420 "repl_set_member_mongodb-primary:27017_state_unknown": 0,
421 "repl_set_member_mongodb-secondary:27017_health_status_down": 0,
422 "repl_set_member_mongodb-secondary:27017_health_status_up": 1,
423 "repl_set_member_mongodb-secondary:27017_heartbeat_latency": 1359,
424 "repl_set_member_mongodb-secondary:27017_ping_rtt": 0,
425 "repl_set_member_mongodb-secondary:27017_replication_lag": 4572,
426 "repl_set_member_mongodb-secondary:27017_state_arbiter": 0,
427 "repl_set_member_mongodb-secondary:27017_state_down": 0,
428 "repl_set_member_mongodb-secondary:27017_state_primary": 0,
429 "repl_set_member_mongodb-secondary:27017_state_recovering": 0,
430 "repl_set_member_mongodb-secondary:27017_state_removed": 0,
431 "repl_set_member_mongodb-secondary:27017_state_rollback": 0,
432 "repl_set_member_mongodb-secondary:27017_state_secondary": 1,
433 "repl_set_member_mongodb-secondary:27017_state_startup": 0,
434 "repl_set_member_mongodb-secondary:27017_state_startup2": 0,
435 "repl_set_member_mongodb-secondary:27017_state_unknown": 0,
436 "repl_set_member_mongodb-secondary:27017_uptime": 192370,
437 "tcmalloc_aggressive_memory_decommit": 0,
438 "tcmalloc_central_cache_free_bytes": 406680,
439 "tcmalloc_current_total_thread_cache_bytes": 2490832,
440 "tcmalloc_generic_current_allocated_bytes": 109050648,
441 "tcmalloc_generic_heap_size": 127213568,
442 "tcmalloc_max_total_thread_cache_bytes": 1073741824,
443 "tcmalloc_pageheap_commit_count": 376,
444 "tcmalloc_pageheap_committed_bytes": 127086592,
445 "tcmalloc_pageheap_decommit_count": 122,
446 "tcmalloc_pageheap_free_bytes": 13959168,
447 "tcmalloc_pageheap_reserve_count": 60,
448 "tcmalloc_pageheap_scavenge_bytes": 0,
449 "tcmalloc_pageheap_total_commit_bytes": 229060608,
450 "tcmalloc_pageheap_total_decommit_bytes": 101974016,
451 "tcmalloc_pageheap_total_reserve_bytes": 127213568,
452 "tcmalloc_pageheap_unmapped_bytes": 126976,
453 "tcmalloc_spinlock_total_delay_ns": 33426251,
454 "tcmalloc_thread_cache_free_bytes": 2490832,
455 "tcmalloc_total_free_bytes": 4076776,
456 "tcmalloc_transfer_cache_free_bytes": 1179264,
457 "txn_active": 0,
458 "txn_inactive": 0,
459 "txn_open": 0,
460 "txn_prepared": 0,
461 "txn_total_aborted": 0,
462 "txn_total_committed": 0,
463 "txn_total_prepared": 0,
464 "txn_total_started": 0,
465 "wiredtiger_cache_currently_in_cache_bytes": 814375,
466 "wiredtiger_cache_maximum_configured_bytes": 7854882816,
467 "wiredtiger_cache_modified_evicted_pages": 0,
468 "wiredtiger_cache_read_into_cache_pages": 108,
469 "wiredtiger_cache_tracked_dirty_in_the_cache_bytes": 456446,
470 "wiredtiger_cache_unmodified_evicted_pages": 0,
471 "wiredtiger_cache_written_from_cache_pages": 3177,
472 "wiredtiger_concurrent_txn_read_available": 128,
473 "wiredtiger_concurrent_txn_read_out": 0,
474 "wiredtiger_concurrent_txn_write_available": 128,
475 "wiredtiger_concurrent_txn_write_out": 0,
476 },
477 },
478 "success on Mongos (v6)": {
479 prepare: caseMongos,
480 wantCollected: map[string]int64{
481 "asserts_msg": 0,
482 "asserts_regular": 0,
483 "asserts_rollovers": 0,
484 "asserts_tripwire": 0,
485 "asserts_user": 352,
486 "asserts_warning": 0,
487 "connections_active": 5,
488 "connections_available": 838842,
489 "connections_awaiting_topology_changes": 4,
490 "connections_current": 18,
491 "connections_exhaust_hello": 3,
492 "connections_exhaust_is_master": 0,
493 "connections_threaded": 18,
494 "connections_total_created": 89,
495 "database_admin_collections": 3,
496 "database_admin_data_size": 796,
497 "database_admin_documents": 5,
498 "database_admin_index_size": 81920,
499 "database_admin_indexes": 4,
500 "database_admin_storage_size": 61440,
501 "database_admin_views": 0,
502 "database_config_collections": 3,
503 "database_config_data_size": 796,
504 "database_config_documents": 5,
505 "database_config_index_size": 81920,
506 "database_config_indexes": 4,
507 "database_config_storage_size": 61440,
508 "database_config_views": 0,
509 "database_local_collections": 3,
510 "database_local_data_size": 796,
511 "database_local_documents": 5,
512 "database_local_index_size": 81920,
513 "database_local_indexes": 4,
514 "database_local_storage_size": 61440,
515 "database_local_views": 0,
516 "extra_info_page_faults": 526,
517 "memory_resident": 84934656,
518 "memory_virtual": 2596274176,
519 "metrics_document_deleted": 0,
520 "metrics_document_inserted": 0,
521 "metrics_document_returned": 0,
522 "metrics_document_updated": 0,
523 "metrics_query_executor_scanned": 0,
524 "metrics_query_executor_scanned_objects": 0,
525 "network_bytes_in": 57943348,
526 "network_bytes_out": 247343709,
527 "network_requests": 227310,
528 "network_slow_dns_operations": 0,
529 "network_slow_ssl_operations": 0,
530 "operations_command": 227283,
531 "operations_delete": 0,
532 "operations_getmore": 0,
533 "operations_insert": 0,
534 "operations_query": 10,
535 "operations_update": 0,
536 "shard_collections_partitioned": 1,
537 "shard_collections_unpartitioned": 1,
538 "shard_databases_partitioned": 1,
539 "shard_databases_unpartitioned": 1,
540 "shard_id_shard0_chunks": 1,
541 "shard_id_shard1_chunks": 1,
542 "shard_nodes_aware": 1,
543 "shard_nodes_unaware": 1,
544 "tcmalloc_aggressive_memory_decommit": 0,
545 "tcmalloc_central_cache_free_bytes": 736960,
546 "tcmalloc_current_total_thread_cache_bytes": 1638104,
547 "tcmalloc_generic_current_allocated_bytes": 13519784,
548 "tcmalloc_generic_heap_size": 24576000,
549 "tcmalloc_max_total_thread_cache_bytes": 1042284544,
550 "tcmalloc_pageheap_commit_count": 480,
551 "tcmalloc_pageheap_committed_bytes": 24518656,
552 "tcmalloc_pageheap_decommit_count": 127,
553 "tcmalloc_pageheap_free_bytes": 5697536,
554 "tcmalloc_pageheap_reserve_count": 15,
555 "tcmalloc_pageheap_scavenge_bytes": 0,
556 "tcmalloc_pageheap_total_commit_bytes": 84799488,
557 "tcmalloc_pageheap_total_decommit_bytes": 60280832,
558 "tcmalloc_pageheap_total_reserve_bytes": 24576000,
559 "tcmalloc_pageheap_unmapped_bytes": 57344,
560 "tcmalloc_spinlock_total_delay_ns": 96785212,
561 "tcmalloc_thread_cache_free_bytes": 1638104,
562 "tcmalloc_total_free_bytes": 5301336,
563 "tcmalloc_transfer_cache_free_bytes": 2926272,
564 "txn_active": 0,
565 "txn_commit_types_no_shards_initiated": 0,
566 "txn_commit_types_no_shards_successful": 0,
567 "txn_commit_types_no_shards_successful_duration_micros": 0,
568 "txn_commit_types_no_shards_unsuccessful": 0,
569 "txn_commit_types_read_only_initiated": 0,
570 "txn_commit_types_read_only_successful": 0,
571 "txn_commit_types_read_only_successful_duration_micros": 0,
572 "txn_commit_types_read_only_unsuccessful": 0,
573 "txn_commit_types_recover_with_token_initiated": 0,
574 "txn_commit_types_recover_with_token_successful": 0,
575 "txn_commit_types_recover_with_token_successful_duration_micros": 0,
576 "txn_commit_types_recover_with_token_unsuccessful": 0,
577 "txn_commit_types_single_shard_initiated": 0,
578 "txn_commit_types_single_shard_successful": 0,
579 "txn_commit_types_single_shard_successful_duration_micros": 0,
580 "txn_commit_types_single_shard_unsuccessful": 0,
581 "txn_commit_types_single_write_shard_initiated": 0,
582 "txn_commit_types_single_write_shard_successful": 0,
583 "txn_commit_types_single_write_shard_successful_duration_micros": 0,
584 "txn_commit_types_single_write_shard_unsuccessful": 0,
585 "txn_commit_types_two_phase_commit_initiated": 0,
586 "txn_commit_types_two_phase_commit_successful": 0,
587 "txn_commit_types_two_phase_commit_successful_duration_micros": 0,
588 "txn_commit_types_two_phase_commit_unsuccessful": 0,
589 "txn_inactive": 0,
590 "txn_open": 0,
591 "txn_total_aborted": 0,
592 "txn_total_committed": 0,
593 "txn_total_started": 0,
594 },
595 },
596 }
597
598 for name, test := range tests {
599 t.Run(name, func(t *testing.T) {
600 collr := prepareMongo()
601 defer collr.Cleanup(context.Background())
602 collr.conn = test.prepare()
603
604 require.NoError(t, collr.Init(context.Background()))
605
606 mx := collr.Collect(context.Background())
607
608 assert.Equal(t, test.wantCollected, mx)
609 })
610 }
611 }
612
613 func prepareMongo() *Collector {
614 collr := New()
615 collr.Databases = matcher.SimpleExpr{Includes: []string{"* *"}}
616 return collr
617 }
618
619 func caseMongodReplicaSet() *mockMongoClient {
620 return &mockMongoClient{replicaSet: true}
621 }
622
623 func caseMongod() *mockMongoClient {
624 return &mockMongoClient{}
625 }
626
627 func caseMongos() *mockMongoClient {
628 return &mockMongoClient{mongos: true}
629 }
630
631 type mockMongoClient struct {
632 replicaSet bool
633 mongos bool
634 errOnServerStatus bool
635 errOnListDatabaseNames bool
636 errOnDbStats bool
637 errOnReplSetGetStatus bool
638 errOnShardNodes bool
639 errOnShardDatabasesPartitioning bool
640 errOnShardCollectionsPartitioning bool
641 errOnShardChunks bool
642 errOnInitClient bool
643 clientInited bool
644 closeCalled bool
645 }
646
647 func (m *mockMongoClient) serverStatus() (*documentServerStatus, error) {
648 if !m.clientInited {
649 return nil, errors.New("mock.serverStatus() error: mongo client not inited")
650 }
651 if m.errOnServerStatus {
652 return nil, errors.New("mock.serverStatus() error")
653 }
654
655 data := dataVer6MongodServerStatus
656 if m.mongos {
657 data = dataVer6MongosServerStatus
658 }
659
660 var s documentServerStatus
661 if err := json.Unmarshal(data, &s); err != nil {
662 return nil, err
663 }
664
665 return &s, nil
666 }
667
668 func (m *mockMongoClient) listDatabaseNames() ([]string, error) {
669 if !m.clientInited {
670 return nil, errors.New("mock.listDatabaseNames() error: mongo client not inited")
671 }
672 if m.errOnListDatabaseNames {
673 return nil, errors.New("mock.listDatabaseNames() error")
674 }
675 return []string{"admin", "config", "local"}, nil
676 }
677
678 func (m *mockMongoClient) dbStats(_ string) (*documentDBStats, error) {
679 if !m.clientInited {
680 return nil, errors.New("mock.dbStats() error: mongo client not inited")
681 }
682 if m.errOnDbStats {
683 return nil, errors.New("mock.dbStats() error")
684 }
685
686 var s documentDBStats
687 if err := json.Unmarshal(dataVer6DbStats, &s); err != nil {
688 return nil, err
689 }
690
691 return &s, nil
692 }
693
694 func (m *mockMongoClient) isReplicaSet() bool {
695 return m.replicaSet
696 }
697
698 func (m *mockMongoClient) isMongos() bool {
699 return m.mongos
700 }
701
702 func (m *mockMongoClient) replSetGetStatus() (*documentReplSetStatus, error) {
703 if !m.clientInited {
704 return nil, errors.New("mock.replSetGetStatus() error: mongo client not inited")
705 }
706 if m.mongos {
707 return nil, errors.New("mock.replSetGetStatus() error: shouldn't be called for mongos")
708 }
709 if !m.replicaSet {
710 return nil, errors.New("mock.replSetGetStatus() error: should be called for replica set")
711 }
712 if m.errOnReplSetGetStatus {
713 return nil, errors.New("mock.replSetGetStatus() error")
714 }
715
716 var s documentReplSetStatus
717 if err := json.Unmarshal(dataVer6ReplSetGetStatus, &s); err != nil {
718 return nil, err
719 }
720
721 return &s, nil
722 }
723
724 func (m *mockMongoClient) shardNodes() (*documentShardNodesResult, error) {
725 if !m.clientInited {
726 return nil, errors.New("mock.shardNodes() error: mongo client not inited")
727 }
728 if m.replicaSet {
729 return nil, errors.New("mock.replSetGetStatus() error: shouldn't be called for replica set")
730 }
731 if !m.mongos {
732 return nil, errors.New("mock.shardNodes() error: should be called for mongos")
733 }
734 if m.errOnShardNodes {
735 return nil, errors.New("mock.shardNodes() error")
736 }
737
738 return &documentShardNodesResult{
739 ShardAware: 1,
740 ShardUnaware: 1,
741 }, nil
742 }
743
744 func (m *mockMongoClient) shardDatabasesPartitioning() (*documentPartitionedResult, error) {
745 if !m.clientInited {
746 return nil, errors.New("mock.shardDatabasesPartitioning() error: mongo client not inited")
747 }
748 if m.replicaSet {
749 return nil, errors.New("mock.shardDatabasesPartitioning() error: shouldn't be called for replica set")
750 }
751 if !m.mongos {
752 return nil, errors.New("mock.shardDatabasesPartitioning() error: should be called for mongos")
753 }
754 if m.errOnShardDatabasesPartitioning {
755 return nil, errors.New("mock.shardDatabasesPartitioning() error")
756 }
757
758 return &documentPartitionedResult{
759 Partitioned: 1,
760 UnPartitioned: 1,
761 }, nil
762 }
763
764 func (m *mockMongoClient) shardCollectionsPartitioning() (*documentPartitionedResult, error) {
765 if !m.clientInited {
766 return nil, errors.New("mock.shardCollectionsPartitioning() error: mongo client not inited")
767 }
768 if m.replicaSet {
769 return nil, errors.New("mock.shardCollectionsPartitioning() error: shouldn't be called for replica set")
770 }
771 if !m.mongos {
772 return nil, errors.New("mock.shardCollectionsPartitioning() error: should be called for mongos")
773 }
774 if m.errOnShardCollectionsPartitioning {
775 return nil, errors.New("mock.shardCollectionsPartitioning() error")
776 }
777
778 return &documentPartitionedResult{
779 Partitioned: 1,
780 UnPartitioned: 1,
781 }, nil
782 }
783
784 func (m *mockMongoClient) shardChunks() (map[string]int64, error) {
785 if !m.clientInited {
786 return nil, errors.New("mock.shardChunks() error: mongo client not inited")
787 }
788 if m.replicaSet {
789 return nil, errors.New("mock.shardChunks() error: shouldn't be called for replica set")
790 }
791 if !m.mongos {
792 return nil, errors.New("mock.shardChunks() error: should be called for mongos")
793 }
794 if m.errOnShardChunks {
795 return nil, errors.New("mock.shardChunks() error")
796 }
797
798 return map[string]int64{
799 "shard0": 1,
800 "shard1": 1,
801 }, nil
802 }
803
804 func (m *mockMongoClient) initClient(_ string, _ time.Duration) error {
805 if m.errOnInitClient {
806 return errors.New("mock.initClient() error")
807 }
808 m.clientInited = true
809 return nil
810 }
811
812 func (m *mockMongoClient) close() error {
813 if m.clientInited {
814 m.closeCalled = true
815 }
816 return nil
817 }