master
go 376 lines 11.2 KB
Raw
1 //go:build cgo
2
3 package jmx
4
5 import (
6 "context"
7 "testing"
8
9 "github.com/netdata/netdata/go/plugins/pkg/confopt"
10 "github.com/netdata/netdata/go/plugins/plugin/ibm.d/modules/websphere/common"
11 "github.com/netdata/netdata/go/plugins/plugin/ibm.d/modules/websphere/jmx/contexts"
12 jmxproto "github.com/netdata/netdata/go/plugins/plugin/ibm.d/protocols/websphere/jmx"
13 )
14
15 type fakeClient struct {
16 jvm *jmxproto.JVMStats
17 threadPools []jmxproto.ThreadPool
18 jdbcPools []jmxproto.JDBCPool
19 jcaPools []jmxproto.JCAPool
20 jmsDestinations []jmxproto.JMSDestination
21 applications []jmxproto.ApplicationMetric
22 jvmErr error
23 poolErr error
24 jdbcErr error
25 jcaErr error
26 jmsErr error
27 }
28
29 func (f *fakeClient) Start(context.Context) error { return nil }
30 func (f *fakeClient) Shutdown() {}
31
32 func (f *fakeClient) FetchJVM(context.Context) (*jmxproto.JVMStats, error) {
33 if f.jvmErr != nil {
34 return nil, f.jvmErr
35 }
36 return f.jvm, nil
37 }
38
39 func (f *fakeClient) FetchThreadPools(context.Context, int) ([]jmxproto.ThreadPool, error) {
40 if f.poolErr != nil {
41 return nil, f.poolErr
42 }
43 return f.threadPools, nil
44 }
45
46 func (f *fakeClient) FetchJDBCPools(context.Context, int) ([]jmxproto.JDBCPool, error) {
47 if f.jdbcErr != nil {
48 return nil, f.jdbcErr
49 }
50 return f.jdbcPools, nil
51 }
52
53 func (f *fakeClient) FetchJMSDestinations(context.Context, int) ([]jmxproto.JMSDestination, error) {
54 if f.jmsErr != nil {
55 return nil, f.jmsErr
56 }
57 return f.jmsDestinations, nil
58 }
59
60 func (f *fakeClient) FetchJCAPools(context.Context, int) ([]jmxproto.JCAPool, error) {
61 if f.jcaErr != nil {
62 return nil, f.jcaErr
63 }
64 return f.jcaPools, nil
65 }
66
67 func (f *fakeClient) FetchApplications(context.Context, int, bool, bool) ([]jmxproto.ApplicationMetric, error) {
68 return f.applications, nil
69 }
70
71 func newTestCollector(t *testing.T, client jmxClient) *Collector {
72 t.Helper()
73
74 cfg := defaultConfig()
75 collector := &Collector{
76 Config: cfg,
77 client: client,
78 identity: common.Identity{},
79 }
80
81 collector.Collector.Config = cfg.Config
82 if err := collector.Collector.Init(context.Background()); err != nil {
83 t.Fatalf("framework init failed: %v", err)
84 }
85 collector.RegisterContexts(contexts.GetAllContexts()...)
86 collector.SetImpl(collector)
87
88 return collector
89 }
90
91 func TestCollectorCollectOnceExportsJVMMetrics(t *testing.T) {
92 client := &fakeClient{
93 jvm: &jmxproto.JVMStats{
94 Heap: struct {
95 Used float64
96 Committed float64
97 Max float64
98 }{
99 Used: 512,
100 Committed: 1024,
101 Max: 2048,
102 },
103 NonHeap: struct {
104 Used float64
105 Committed float64
106 }{
107 Used: 128,
108 Committed: 256,
109 },
110 GC: struct {
111 Count float64
112 Time float64
113 }{
114 Count: 12,
115 Time: 345,
116 },
117 Threads: struct {
118 Count float64
119 Daemon float64
120 Peak float64
121 Started float64
122 }{
123 Count: 44,
124 Daemon: 30,
125 Peak: 60,
126 Started: 100,
127 },
128 Classes: struct {
129 Loaded float64
130 Unloaded float64
131 }{
132 Loaded: 5000,
133 Unloaded: 200,
134 },
135 CPU: struct{ ProcessUsage float64 }{ProcessUsage: 42},
136 Uptime: 900,
137 },
138 }
139
140 collector := newTestCollector(t, client)
141 collector.Config.CollectThreadPoolMetrics = confopt.AutoBoolDisabled
142
143 metrics := collector.Collect(context.Background())
144
145 expects := map[string]int64{
146 "websphere_jmx.jvm_heap_memory.used": 512,
147 "websphere_jmx.jvm_heap_memory.committed": 1024,
148 "websphere_jmx.jvm_heap_memory.max": 2048,
149 "websphere_jmx.jvm_heap_usage.usage": 25,
150 "websphere_jmx.jvm_nonheap_memory.used": 128,
151 "websphere_jmx.jvm_nonheap_memory.committed": 256,
152 "websphere_jmx.jvm_gc_count.collections": 12,
153 "websphere_jmx.jvm_gc_time.time": 345,
154 "websphere_jmx.jvm_threads.total": 44,
155 "websphere_jmx.jvm_threads.daemon": 30,
156 "websphere_jmx.jvm_thread_states.peak": 60,
157 "websphere_jmx.jvm_thread_states.started": 100,
158 "websphere_jmx.jvm_classes.loaded": 5000,
159 "websphere_jmx.jvm_classes.unloaded": 200,
160 "websphere_jmx.jvm_process_cpu_usage.cpu": 42,
161 "websphere_jmx.jvm_uptime.uptime": 900,
162 }
163
164 for key, want := range expects {
165 if got, ok := metrics[key]; !ok {
166 t.Errorf("expected metric %s to be present", key)
167 } else if got != want {
168 t.Errorf("metric %s mismatch: want %d got %d", key, want, got)
169 }
170 }
171 }
172
173 func TestCollectorCollectsThreadPools(t *testing.T) {
174 client := &fakeClient{
175 jvm: &jmxproto.JVMStats{},
176 threadPools: []jmxproto.ThreadPool{
177 {Name: "Default", PoolSize: 50, ActiveCount: 5, MaximumPoolSize: 75},
178 {Name: "WebContainer", PoolSize: 80, ActiveCount: 12, MaximumPoolSize: 100},
179 },
180 }
181
182 collector := newTestCollector(t, client)
183
184 metrics := collector.Collect(context.Background())
185
186 expected := map[string]int64{
187 "websphere_jmx.threadpool_size.default.size": 50,
188 "websphere_jmx.threadpool_size.default.max": 75,
189 "websphere_jmx.threadpool_active.default.active": 5,
190 "websphere_jmx.threadpool_size.webcontainer.size": 80,
191 "websphere_jmx.threadpool_size.webcontainer.max": 100,
192 "websphere_jmx.threadpool_active.webcontainer.active": 12,
193 }
194
195 for key, want := range expected {
196 if got, ok := metrics[key]; !ok {
197 t.Fatalf("expected metric %s to be present", key)
198 } else if got != want {
199 t.Errorf("metric %s mismatch: want %d got %d", key, want, got)
200 }
201 }
202 }
203
204 func TestCollectorCollectsJDBCPools(t *testing.T) {
205 client := &fakeClient{
206 jvm: &jmxproto.JVMStats{},
207 jdbcPools: []jmxproto.JDBCPool{
208 {
209 Name: "DefaultDS",
210 PoolSize: 40,
211 NumConnectionsUsed: 8,
212 NumConnectionsFree: 12,
213 AvgWaitTime: 1.5,
214 AvgInUseTime: 2.5,
215 NumConnectionsCreated: 100,
216 NumConnectionsDestroyed: 90,
217 WaitingThreadCount: 3,
218 },
219 },
220 }
221
222 collector := newTestCollector(t, client)
223 collector.Config.CollectThreadPoolMetrics = confopt.AutoBoolDisabled
224
225 metrics := collector.Collect(context.Background())
226
227 expected := map[string]int64{
228 "websphere_jmx.jdbc_pool_size.defaultds.size": 40,
229 "websphere_jmx.jdbc_pool_usage.defaultds.active": 8,
230 "websphere_jmx.jdbc_pool_usage.defaultds.free": 12,
231 "websphere_jmx.jdbc_pool_wait_time.defaultds.wait": 1500,
232 "websphere_jmx.jdbc_pool_use_time.defaultds.use": 2500,
233 "websphere_jmx.jdbc_pool_connections.defaultds.created": 100,
234 "websphere_jmx.jdbc_pool_connections.defaultds.destroyed": 90,
235 "websphere_jmx.jdbc_pool_waiting_threads.defaultds.waiting": 3,
236 }
237
238 for key, want := range expected {
239 if got, ok := metrics[key]; !ok {
240 t.Fatalf("expected metric %s to be present", key)
241 } else if got != want {
242 t.Errorf("metric %s mismatch: want %d got %d", key, want, got)
243 }
244 }
245 }
246
247 func TestCollectorCollectsJMSDestinations(t *testing.T) {
248 client := &fakeClient{
249 jvm: &jmxproto.JVMStats{},
250 jmsDestinations: []jmxproto.JMSDestination{
251 {
252 Name: "Queue1",
253 Type: "queue",
254 MessagesCurrentCount: 12,
255 MessagesPendingCount: 4,
256 MessagesAddedCount: 80,
257 ConsumerCount: 6,
258 },
259 },
260 }
261
262 collector := newTestCollector(t, client)
263 collector.Config.CollectThreadPoolMetrics = confopt.AutoBoolDisabled
264 collector.Config.CollectJDBCMetrics = confopt.AutoBoolDisabled
265
266 metrics := collector.Collect(context.Background())
267
268 expected := map[string]int64{
269 "websphere_jmx.jms_messages_current.queue1_queue.current": 12,
270 "websphere_jmx.jms_messages_pending.queue1_queue.pending": 4,
271 "websphere_jmx.jms_messages_total.queue1_queue.total": 80,
272 "websphere_jmx.jms_consumers.queue1_queue.consumers": 6,
273 }
274
275 for key, want := range expected {
276 if got, ok := metrics[key]; !ok {
277 t.Fatalf("expected metric %s to be present", key)
278 } else if got != want {
279 t.Errorf("metric %s mismatch: want %d got %d", key, want, got)
280 }
281 }
282 }
283
284 func TestCollectorCollectsApplications(t *testing.T) {
285 client := &fakeClient{
286 jvm: &jmxproto.JVMStats{},
287 applications: []jmxproto.ApplicationMetric{
288 {
289 Name: "sample-app",
290 Module: "moduleA",
291 Requests: 120,
292 ResponseTime: 0.24,
293 ActiveSessions: 5,
294 LiveSessions: 7,
295 SessionCreates: 60,
296 SessionInvalidates: 10,
297 TransactionsCommitted: 40,
298 TransactionsRolledback: 2,
299 },
300 },
301 }
302
303 collector := newTestCollector(t, client)
304 collector.Config.CollectThreadPoolMetrics = confopt.AutoBoolDisabled
305 collector.Config.CollectJDBCMetrics = confopt.AutoBoolDisabled
306 collector.Config.CollectJMSMetrics = confopt.AutoBoolDisabled
307 collector.Config.CollectWebAppMetrics = confopt.AutoBoolEnabled
308 collector.Config.CollectSessionMetrics = confopt.AutoBoolEnabled
309 collector.Config.CollectTransactionMetrics = confopt.AutoBoolEnabled
310
311 metrics := collector.Collect(context.Background())
312
313 expected := map[string]int64{
314 "websphere_jmx.app_requests.sample_app_modulea.requests": 120,
315 "websphere_jmx.app_response_time.sample_app_modulea.response_time": 240,
316 "websphere_jmx.app_sessions_active.sample_app_modulea.active": 5,
317 "websphere_jmx.app_sessions_live.sample_app_modulea.live": 7,
318 "websphere_jmx.app_session_events.sample_app_modulea.creates": 60,
319 "websphere_jmx.app_session_events.sample_app_modulea.invalidates": 10,
320 "websphere_jmx.app_transactions.sample_app_modulea.committed": 40,
321 "websphere_jmx.app_transactions.sample_app_modulea.rolledback": 2,
322 }
323
324 for key, want := range expected {
325 if got, ok := metrics[key]; !ok {
326 t.Fatalf("expected metric %s to be present", key)
327 } else if got != want {
328 t.Errorf("metric %s mismatch: want %d got %d", key, want, got)
329 }
330 }
331 }
332 func TestCollectorCollectsJCAPools(t *testing.T) {
333 client := &fakeClient{
334 jvm: &jmxproto.JVMStats{},
335 jcaPools: []jmxproto.JCAPool{
336 {
337 Name: "JCAPool1",
338 PoolSize: 20,
339 NumConnectionsUsed: 6,
340 NumConnectionsFree: 4,
341 AvgWaitTime: 1.2,
342 AvgInUseTime: 3.4,
343 NumConnectionsCreated: 30,
344 NumConnectionsDestroyed: 12,
345 WaitingThreadCount: 2,
346 },
347 },
348 }
349
350 collector := newTestCollector(t, client)
351 collector.Config.CollectThreadPoolMetrics = confopt.AutoBoolDisabled
352 collector.Config.CollectJDBCMetrics = confopt.AutoBoolDisabled
353 collector.Config.CollectJMSMetrics = confopt.AutoBoolDisabled
354 collector.Config.CollectWebAppMetrics = confopt.AutoBoolDisabled
355
356 metrics := collector.Collect(context.Background())
357
358 expected := map[string]int64{
359 "websphere_jmx.jca_pool_size.jcapool1.size": 20,
360 "websphere_jmx.jca_pool_usage.jcapool1.active": 6,
361 "websphere_jmx.jca_pool_usage.jcapool1.free": 4,
362 "websphere_jmx.jca_pool_wait_time.jcapool1.wait": 1200,
363 "websphere_jmx.jca_pool_use_time.jcapool1.use": 3400,
364 "websphere_jmx.jca_pool_connections.jcapool1.created": 30,
365 "websphere_jmx.jca_pool_connections.jcapool1.destroyed": 12,
366 "websphere_jmx.jca_pool_waiting_threads.jcapool1.waiting": 2,
367 }
368
369 for key, want := range expected {
370 if got, ok := metrics[key]; !ok {
371 t.Fatalf("expected metric %s to be present", key)
372 } else if got != want {
373 t.Errorf("metric %s mismatch: want %d got %d", key, want, got)
374 }
375 }
376 }