1 /* Copyright (c) 2008, 2021, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software Foundation,
21 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
22
23 #include <my_global.h>
24 #include <my_thread.h>
25 #include <pfs_instr.h>
26 #include <pfs_stat.h>
27 #include <pfs_global.h>
28 #include <pfs_instr_class.h>
29 #include <pfs_buffer_container.h>
30 #include <tap.h>
31
32 #include "stub_global_status_var.h"
33
34 #include <memory.h>
35
test_no_instruments()36 void test_no_instruments()
37 {
38 int rc;
39 PFS_global_param param;
40
41 memset(& param, 0xFF, sizeof(param));
42 param.m_enabled= true;
43 param.m_mutex_class_sizing= 0;
44 param.m_rwlock_class_sizing= 0;
45 param.m_cond_class_sizing= 0;
46 param.m_thread_class_sizing= 0;
47 param.m_table_share_sizing= 0;
48 param.m_file_class_sizing= 0;
49 param.m_socket_class_sizing= 0;
50 param.m_mutex_sizing= 0;
51 param.m_rwlock_sizing= 0;
52 param.m_cond_sizing= 0;
53 param.m_thread_sizing= 0;
54 param.m_table_sizing= 0;
55 param.m_file_sizing= 0;
56 param.m_file_handle_sizing= 0;
57 param.m_socket_sizing= 0;
58 param.m_events_waits_history_sizing= 0;
59 param.m_events_waits_history_long_sizing= 0;
60 param.m_setup_actor_sizing= 0;
61 param.m_setup_object_sizing= 0;
62 param.m_host_sizing= 0;
63 param.m_user_sizing= 0;
64 param.m_account_sizing= 0;
65 param.m_stage_class_sizing= 0;
66 param.m_events_stages_history_sizing= 0;
67 param.m_events_stages_history_long_sizing= 0;
68 param.m_statement_class_sizing= 0;
69 param.m_events_statements_history_sizing= 0;
70 param.m_events_statements_history_long_sizing= 0;
71 param.m_events_transactions_history_sizing= 0;
72 param.m_events_transactions_history_long_sizing= 0;
73 param.m_digest_sizing= 0;
74 param.m_session_connect_attrs_sizing= 0;
75 param.m_program_sizing= 0;
76 param.m_prepared_stmt_sizing= 0;
77 param.m_statement_stack_sizing= 0;
78 param.m_memory_class_sizing= 0;
79 param.m_metadata_lock_sizing= 0;
80
81 init_event_name_sizing(& param);
82 rc= init_instruments(& param);
83 ok(rc == 0, "zero init");
84
85 cleanup_instruments();
86 }
87
test_no_instances()88 void test_no_instances()
89 {
90 int rc;
91 PFS_mutex_class dummy_mutex_class;
92 PFS_rwlock_class dummy_rwlock_class;
93 PFS_cond_class dummy_cond_class;
94 PFS_thread_class dummy_thread_class;
95 PFS_file_class dummy_file_class;
96 PFS_table_share dummy_table_share;
97 PFS_socket_class dummy_socket_class;
98 PFS_mutex *mutex;
99 PFS_rwlock *rwlock;
100 PFS_cond *cond;
101 PFS_thread *thread;
102 PFS_file *file;
103 PFS_socket *socket;
104 PFS_table *table;
105 PFS_global_param param;
106
107 dummy_mutex_class.m_event_name_index = 0;
108 dummy_mutex_class.m_flags = 0;
109 dummy_mutex_class.m_enabled = true;
110 dummy_mutex_class.m_volatility = PSI_VOLATILITY_UNKNOWN;
111 dummy_rwlock_class.m_event_name_index = 1;
112 dummy_rwlock_class.m_flags = 0;
113 dummy_rwlock_class.m_enabled = true;
114 dummy_rwlock_class.m_volatility = PSI_VOLATILITY_UNKNOWN;
115 dummy_cond_class.m_event_name_index = 2;
116 dummy_cond_class.m_flags = 0;
117 dummy_cond_class.m_enabled = true;
118 dummy_cond_class.m_volatility = PSI_VOLATILITY_UNKNOWN;
119 dummy_file_class.m_event_name_index = 3;
120 dummy_file_class.m_flags = 0;
121 dummy_file_class.m_enabled = true;
122 dummy_file_class.m_volatility = PSI_VOLATILITY_UNKNOWN;
123 dummy_socket_class.m_event_name_index = 4;
124 dummy_socket_class.m_flags = 0;
125 dummy_socket_class.m_enabled = true;
126 dummy_socket_class.m_volatility = PSI_VOLATILITY_UNKNOWN;
127
128 memset(& param, 0xFF, sizeof(param));
129 param.m_enabled= true;
130 param.m_mutex_class_sizing= 1;
131 param.m_rwlock_class_sizing= 1;
132 param.m_cond_class_sizing= 1;
133 param.m_thread_class_sizing= 1;
134 param.m_table_share_sizing= 1;
135 param.m_file_class_sizing= 1;
136 param.m_socket_class_sizing= 0;
137 param.m_mutex_sizing= 0;
138 param.m_rwlock_sizing= 0;
139 param.m_cond_sizing= 0;
140 param.m_thread_sizing= 0;
141 param.m_table_sizing= 0;
142 param.m_file_sizing= 0;
143 param.m_file_handle_sizing= 0;
144 param.m_socket_sizing= 0;
145 param.m_events_waits_history_sizing= 0;
146 param.m_events_waits_history_long_sizing= 0;
147 param.m_setup_actor_sizing= 0;
148 param.m_setup_object_sizing= 0;
149 param.m_host_sizing= 0;
150 param.m_user_sizing= 0;
151 param.m_account_sizing= 0;
152 param.m_stage_class_sizing= 0;
153 param.m_events_stages_history_sizing= 0;
154 param.m_events_stages_history_long_sizing= 0;
155 param.m_statement_class_sizing= 0;
156 param.m_events_statements_history_sizing= 0;
157 param.m_events_statements_history_long_sizing= 0;
158 param.m_events_transactions_history_sizing= 0;
159 param.m_events_transactions_history_long_sizing= 0;
160 param.m_digest_sizing= 0;
161 param.m_session_connect_attrs_sizing= 0;
162 param.m_program_sizing= 0;
163 param.m_prepared_stmt_sizing= 0;
164 param.m_statement_stack_sizing= 0;
165 param.m_memory_class_sizing= 1;
166 param.m_metadata_lock_sizing= 0;
167
168 init_event_name_sizing(& param);
169 rc= init_instruments(& param);
170 ok(rc == 0, "no instances init");
171
172 mutex= create_mutex(& dummy_mutex_class, NULL);
173 ok(mutex == NULL, "no mutex");
174 ok(global_mutex_container.get_lost_counter() == 1, "lost 1");
175 mutex= create_mutex(& dummy_mutex_class, NULL);
176 ok(mutex == NULL, "no mutex");
177 ok(global_mutex_container.get_lost_counter() == 2, "lost 2");
178
179 rwlock= create_rwlock(& dummy_rwlock_class, NULL);
180 ok(rwlock == NULL, "no rwlock");
181 ok(global_rwlock_container.m_lost == 1, "lost 1");
182 rwlock= create_rwlock(& dummy_rwlock_class, NULL);
183 ok(rwlock == NULL, "no rwlock");
184 ok(global_rwlock_container.m_lost == 2, "lost 2");
185
186 cond= create_cond(& dummy_cond_class, NULL);
187 ok(cond == NULL, "no cond");
188 ok(global_cond_container.m_lost == 1, "lost 1");
189 cond= create_cond(& dummy_cond_class, NULL);
190 ok(cond == NULL, "no cond");
191 ok(global_cond_container.m_lost == 2, "lost 2");
192
193 thread= create_thread(& dummy_thread_class, NULL, 0);
194 ok(thread == NULL, "no thread");
195 ok(global_thread_container.m_lost == 1, "lost 1");
196 thread= create_thread(& dummy_thread_class, NULL, 0);
197 ok(thread == NULL, "no thread");
198 ok(global_thread_container.m_lost == 2, "lost 2");
199
200 PFS_thread fake_thread;
201 fake_thread.m_filename_hash_pins= NULL;
202
203 file= find_or_create_file(& fake_thread, & dummy_file_class, "dummy", 5, true);
204 ok(file == NULL, "no file");
205 ok(global_file_container.m_lost == 1, "lost 1");
206 file= find_or_create_file(& fake_thread, & dummy_file_class, "dummy", 5, true);
207 ok(file == NULL, "no file");
208 ok(global_file_container.m_lost == 2, "lost 2");
209
210 init_file_hash(& param);
211
212 file= find_or_create_file(& fake_thread, & dummy_file_class, "dummy", 5, true);
213 ok(file == NULL, "no file");
214 ok(global_file_container.m_lost == 3, "lost 3");
215 file= find_or_create_file(& fake_thread, & dummy_file_class, "dummy", 5, true);
216 ok(file == NULL, "no file");
217 ok(global_file_container.m_lost == 4, "lost 4");
218
219 char long_file_name[10000];
220 int size= sizeof(long_file_name);
221 memset(long_file_name, 'X', size);
222
223 file= find_or_create_file(& fake_thread, & dummy_file_class, long_file_name, size, true);
224 ok(file == NULL, "no file");
225 ok(global_file_container.m_lost == 5, "lost 5");
226
227 table= create_table(& dummy_table_share, & fake_thread, NULL);
228 ok(table == NULL, "no table");
229 ok(global_table_container.m_lost == 1, "lost 1");
230 table= create_table(& dummy_table_share, & fake_thread, NULL);
231 ok(table == NULL, "no table");
232 ok(global_table_container.m_lost == 2, "lost 2");
233
234 socket= create_socket(& dummy_socket_class, NULL, NULL, 0);
235 ok(socket == NULL, "no socket");
236 ok(global_socket_container.m_lost == 1, "lost 1");
237 socket= create_socket(& dummy_socket_class, NULL, NULL, 0);
238 ok(socket == NULL, "no socket");
239 ok(global_socket_container.m_lost == 2, "lost 2");
240
241 /* No result to test, just make sure it does not crash */
242 reset_events_waits_by_instance();
243 reset_events_waits_by_thread();
244
245 cleanup_file_hash();
246 cleanup_instruments();
247 }
248
test_with_instances()249 void test_with_instances()
250 {
251 int rc;
252 PFS_mutex_class dummy_mutex_class;
253 PFS_rwlock_class dummy_rwlock_class;
254 PFS_cond_class dummy_cond_class;
255 PFS_thread_class dummy_thread_class;
256 PFS_file_class dummy_file_class;
257 PFS_socket_class dummy_socket_class;
258 PFS_table_share dummy_table_share;
259 PFS_mutex *mutex_1;
260 PFS_mutex *mutex_2;
261 PFS_rwlock *rwlock_1;
262 PFS_rwlock *rwlock_2;
263 PFS_cond *cond_1;
264 PFS_cond *cond_2;
265 PFS_thread *thread_1;
266 PFS_thread *thread_2;
267 PFS_file *file_1;
268 PFS_file *file_2;
269 PFS_socket *socket_1;
270 PFS_socket *socket_2;
271 PFS_table *table_1;
272 PFS_table *table_2;
273 PFS_global_param param;
274
275 memset(& param, 0xFF, sizeof(param));
276 param.m_enabled= true;
277 param.m_mutex_class_sizing= 1;
278 param.m_rwlock_class_sizing= 1;
279 param.m_cond_class_sizing= 1;
280 param.m_thread_class_sizing= 1;
281 param.m_table_share_sizing= 1;
282 param.m_file_class_sizing= 1;
283 param.m_socket_class_sizing= 1;
284 param.m_mutex_sizing= 2;
285 param.m_rwlock_sizing= 2;
286 param.m_cond_sizing= 2;
287 param.m_thread_sizing= 2;
288 param.m_table_sizing= 2;
289 param.m_file_sizing= 2;
290 param.m_file_handle_sizing= 100;
291 param.m_socket_sizing= 2;
292 param.m_events_waits_history_sizing= 10;
293 param.m_events_waits_history_long_sizing= 10000;
294 param.m_setup_actor_sizing= 0;
295 param.m_setup_object_sizing= 0;
296 param.m_host_sizing= 0;
297 param.m_user_sizing= 0;
298 param.m_account_sizing= 0;
299 param.m_stage_class_sizing= 0;
300 param.m_events_stages_history_sizing= 0;
301 param.m_events_stages_history_long_sizing= 0;
302 param.m_statement_class_sizing= 0;
303 param.m_events_statements_history_sizing= 0;
304 param.m_events_statements_history_long_sizing= 0;
305 param.m_events_transactions_history_sizing= 0;
306 param.m_events_transactions_history_long_sizing= 0;
307 param.m_digest_sizing= 0;
308 param.m_session_connect_attrs_sizing= 0;
309 param.m_program_sizing= 0;
310 param.m_prepared_stmt_sizing= 0;
311 param.m_statement_stack_sizing= 0;
312 param.m_memory_class_sizing= 1;
313 param.m_metadata_lock_sizing= 0;
314
315 init_event_name_sizing(& param);
316 rc= init_instruments(& param);
317 ok(rc == 0, "instances init");
318
319 dummy_mutex_class.m_event_name_index= 0;
320 dummy_mutex_class.m_flags= 0;
321 dummy_mutex_class.m_enabled= true;
322 dummy_mutex_class.m_volatility = PSI_VOLATILITY_UNKNOWN;
323 dummy_rwlock_class.m_event_name_index= 1;
324 dummy_rwlock_class.m_flags= 0;
325 dummy_rwlock_class.m_enabled= true;
326 dummy_rwlock_class.m_volatility = PSI_VOLATILITY_UNKNOWN;
327 dummy_cond_class.m_event_name_index= 2;
328 dummy_cond_class.m_flags= 0;
329 dummy_cond_class.m_enabled= true;
330 dummy_cond_class.m_volatility = PSI_VOLATILITY_UNKNOWN;
331 dummy_file_class.m_event_name_index= 3;
332 dummy_file_class.m_flags= 0;
333 dummy_file_class.m_enabled= true;
334 dummy_file_class.m_volatility = PSI_VOLATILITY_UNKNOWN;
335 dummy_socket_class.m_event_name_index= 4;
336 dummy_socket_class.m_flags= 0;
337 dummy_socket_class.m_enabled= true;
338 dummy_socket_class.m_volatility = PSI_VOLATILITY_UNKNOWN;
339
340 dummy_table_share.m_enabled= true;
341 dummy_table_share.m_timed= true;
342
343 mutex_1= create_mutex(& dummy_mutex_class, NULL);
344 ok(mutex_1 != NULL, "mutex");
345 ok(global_mutex_container.get_lost_counter() == 0, "not lost");
346 mutex_2= create_mutex(& dummy_mutex_class, NULL);
347 ok(mutex_2 != NULL, "mutex");
348 ok(global_mutex_container.get_lost_counter() == 0, "not lost");
349 mutex_2= create_mutex(& dummy_mutex_class, NULL);
350 ok(mutex_2 == NULL, "no mutex");
351 ok(global_mutex_container.get_lost_counter() == 1, "lost 1");
352 destroy_mutex(mutex_1);
353 mutex_2= create_mutex(& dummy_mutex_class, NULL);
354 ok(mutex_2 != NULL, "mutex");
355 ok(global_mutex_container.get_lost_counter() == 1, "no new loss");
356
357 rwlock_1= create_rwlock(& dummy_rwlock_class, NULL);
358 ok(rwlock_1 != NULL, "rwlock");
359 ok(global_rwlock_container.m_lost == 0, "not lost");
360 rwlock_2= create_rwlock(& dummy_rwlock_class, NULL);
361 ok(rwlock_2 != NULL, "rwlock");
362 ok(global_rwlock_container.m_lost == 0, "not lost");
363 rwlock_2= create_rwlock(& dummy_rwlock_class, NULL);
364 ok(rwlock_2 == NULL, "no rwlock");
365 ok(global_rwlock_container.m_lost == 1, "lost 1");
366 destroy_rwlock(rwlock_1);
367 rwlock_2= create_rwlock(& dummy_rwlock_class, NULL);
368 ok(rwlock_2 != NULL, "rwlock");
369 ok(global_rwlock_container.m_lost == 1, "no new loss");
370
371 cond_1= create_cond(& dummy_cond_class, NULL);
372 ok(cond_1 != NULL, "cond");
373 ok(global_cond_container.m_lost == 0, "not lost");
374 cond_2= create_cond(& dummy_cond_class, NULL);
375 ok(cond_2 != NULL, "cond");
376 ok(global_cond_container.m_lost == 0, "not lost");
377 cond_2= create_cond(& dummy_cond_class, NULL);
378 ok(cond_2 == NULL, "no cond");
379 ok(global_cond_container.m_lost == 1, "lost 1");
380 destroy_cond(cond_1);
381 cond_2= create_cond(& dummy_cond_class, NULL);
382 ok(cond_2 != NULL, "cond");
383 ok(global_cond_container.m_lost == 1, "no new loss");
384
385 thread_1= create_thread(& dummy_thread_class, NULL, 0);
386 ok(thread_1 != NULL, "thread");
387 ok(global_thread_container.m_lost == 0, "not lost");
388 thread_2= create_thread(& dummy_thread_class, NULL, 0);
389 ok(thread_2 != NULL, "thread");
390 ok(global_thread_container.m_lost == 0, "not lost");
391 thread_2= create_thread(& dummy_thread_class, NULL, 0);
392 ok(thread_2 == NULL, "no thread");
393 ok(global_thread_container.m_lost == 1, "lost 1");
394 destroy_thread(thread_1);
395 thread_2= create_thread(& dummy_thread_class, NULL, 0);
396 ok(thread_2 != NULL, "thread");
397 ok(global_thread_container.m_lost == 1, "no new loss");
398
399 PFS_thread fake_thread;
400 fake_thread.m_filename_hash_pins= NULL;
401
402 file_1= find_or_create_file(& fake_thread, & dummy_file_class, "dummy", 5, true);
403 ok(file_1 == NULL, "no file");
404 ok(global_file_container.m_lost == 1, "lost 1");
405 file_1= find_or_create_file(& fake_thread, & dummy_file_class, "dummy", 5, true);
406 ok(file_1 == NULL, "no file");
407 ok(global_file_container.m_lost == 2, "lost 2");
408
409 init_file_hash(& param);
410 global_file_container.m_lost= 0;
411
412 file_1= find_or_create_file(& fake_thread, & dummy_file_class, "dummy_A", 7, true);
413 ok(file_1 != NULL, "file");
414 ok(file_1->m_file_stat.m_open_count == 1, "open count 1");
415 ok(global_file_container.m_lost == 0, "not lost");
416 file_2= find_or_create_file(& fake_thread, & dummy_file_class, "dummy_A", 7, true);
417 ok(file_1 == file_2, "same file");
418 ok(file_1->m_file_stat.m_open_count == 2, "open count 2");
419 ok(global_file_container.m_lost == 0, "not lost");
420 release_file(file_2);
421 ok(file_1->m_file_stat.m_open_count == 1, "open count 1");
422 file_2= find_or_create_file(& fake_thread, & dummy_file_class, "dummy_B", 7, true);
423 ok(file_2 != NULL, "file");
424 ok(global_file_container.m_lost == 0, "not lost");
425 file_2= find_or_create_file(& fake_thread, & dummy_file_class, "dummy_C", 7, true);
426 ok(file_2 == NULL, "no file");
427 ok(global_file_container.m_lost == 1, "lost");
428 release_file(file_1);
429 /* the file still exists, not destroyed */
430 ok(file_1->m_file_stat.m_open_count == 0, "open count 0");
431 file_2= find_or_create_file(& fake_thread, & dummy_file_class, "dummy_D", 7, true);
432 ok(file_2 == NULL, "no file");
433 ok(global_file_container.m_lost == 2, "lost");
434
435 socket_1= create_socket(& dummy_socket_class, NULL, NULL, 0);
436 ok(socket_1 != NULL, "socket");
437 ok(global_socket_container.m_lost == 0, "not lost");
438 socket_2= create_socket(& dummy_socket_class, NULL, NULL, 0);
439 ok(socket_2 != NULL, "socket");
440 ok(global_socket_container.m_lost == 0, "not lost");
441 socket_2= create_socket(& dummy_socket_class, NULL, NULL, 0);
442 ok(socket_2 == NULL, "no socket");
443 ok(global_socket_container.m_lost == 1, "lost 1");
444 destroy_socket(socket_1);
445 socket_2= create_socket(& dummy_socket_class, NULL, NULL, 0);
446 ok(socket_2 != NULL, "socket");
447 ok(global_socket_container.m_lost == 1, "no new loss");
448
449 table_1= create_table(& dummy_table_share, & fake_thread, NULL);
450 ok(table_1 != NULL, "table");
451 ok(global_table_container.m_lost == 0, "not lost");
452 table_2= create_table(& dummy_table_share, & fake_thread, NULL);
453 ok(table_2 != NULL, "table");
454 ok(global_table_container.m_lost == 0, "not lost");
455 table_2= create_table(& dummy_table_share, & fake_thread, NULL);
456 ok(table_2 == NULL, "no table");
457 ok(global_table_container.m_lost == 1, "lost 1");
458 destroy_table(table_1);
459 table_2= create_table(& dummy_table_share, & fake_thread, NULL);
460 ok(table_2 != NULL, "table");
461 ok(global_table_container.m_lost == 1, "no new loss");
462
463 //TODO: test that cleanup works
464 reset_events_waits_by_instance();
465 reset_events_waits_by_thread();
466
467 cleanup_file_hash();
468 cleanup_instruments();
469 }
470
do_all_tests()471 void do_all_tests()
472 {
473 flag_global_instrumentation= true;
474 flag_thread_instrumentation= true;
475
476 test_no_instruments();
477 test_no_instances();
478 test_with_instances();
479 }
480
main(int,char **)481 int main(int, char **)
482 {
483 plan(103);
484 MY_INIT("pfs_instr-t");
485 do_all_tests();
486 return (exit_status());
487 }
488
489