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, Fifth Floor, 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
36 PFS_global_param param;
37
test_no_instruments()38 void test_no_instruments()
39 {
40 int rc;
41
42 memset(& param, 0xFF, sizeof(param));
43 param.m_enabled= true;
44 param.m_mutex_class_sizing= 0;
45 param.m_rwlock_class_sizing= 0;
46 param.m_cond_class_sizing= 0;
47 param.m_thread_class_sizing= 0;
48 param.m_table_share_sizing= 0;
49 param.m_file_class_sizing= 0;
50 param.m_socket_class_sizing= 0;
51 param.m_mutex_sizing= 0;
52 param.m_rwlock_sizing= 0;
53 param.m_cond_sizing= 0;
54 param.m_thread_sizing= 0;
55 param.m_table_sizing= 0;
56 param.m_file_sizing= 0;
57 param.m_file_handle_sizing= 0;
58 param.m_socket_sizing= 0;
59 param.m_events_waits_history_sizing= 0;
60 param.m_events_waits_history_long_sizing= 0;
61 param.m_setup_actor_sizing= 0;
62 param.m_setup_object_sizing= 0;
63 param.m_host_sizing= 0;
64 param.m_user_sizing= 0;
65 param.m_account_sizing= 0;
66 param.m_stage_class_sizing= 0;
67 param.m_events_stages_history_sizing= 0;
68 param.m_events_stages_history_long_sizing= 0;
69 param.m_statement_class_sizing= 0;
70 param.m_events_statements_history_sizing= 0;
71 param.m_events_statements_history_long_sizing= 0;
72 param.m_events_transactions_history_sizing= 0;
73 param.m_events_transactions_history_long_sizing= 0;
74 param.m_digest_sizing= 0;
75 param.m_session_connect_attrs_sizing= 0;
76 param.m_program_sizing= 0;
77 param.m_prepared_stmt_sizing= 0;
78 param.m_statement_stack_sizing= 0;
79 param.m_memory_class_sizing= 0;
80 param.m_metadata_lock_sizing= 0;
81
82 init_event_name_sizing(& param);
83 rc= init_instruments(& param);
84 ok(rc == 0, "zero init");
85
86 cleanup_instruments();
87 }
88
test_no_instances()89 void test_no_instances()
90 {
91 int rc;
92 PFS_mutex_class dummy_mutex_class;
93 PFS_rwlock_class dummy_rwlock_class;
94 PFS_cond_class dummy_cond_class;
95 PFS_thread_class dummy_thread_class;
96 PFS_file_class dummy_file_class;
97 PFS_table_share dummy_table_share;
98 PFS_socket_class dummy_socket_class;
99 PFS_mutex *mutex;
100 PFS_rwlock *rwlock;
101 PFS_cond *cond;
102 PFS_thread *thread;
103 PFS_file *file;
104 PFS_socket *socket;
105 PFS_table *table;
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
274 memset(& param, 0xFF, sizeof(param));
275 param.m_enabled= true;
276 param.m_mutex_class_sizing= 1;
277 param.m_rwlock_class_sizing= 1;
278 param.m_cond_class_sizing= 1;
279 param.m_thread_class_sizing= 1;
280 param.m_table_share_sizing= 1;
281 param.m_file_class_sizing= 1;
282 param.m_socket_class_sizing= 1;
283 param.m_mutex_sizing= 2;
284 param.m_rwlock_sizing= 2;
285 param.m_cond_sizing= 2;
286 param.m_thread_sizing= 2;
287 param.m_table_sizing= 2;
288 param.m_file_sizing= 2;
289 param.m_file_handle_sizing= 100;
290 param.m_socket_sizing= 2;
291 param.m_events_waits_history_sizing= 10;
292 param.m_events_waits_history_long_sizing= 10000;
293 param.m_setup_actor_sizing= 0;
294 param.m_setup_object_sizing= 0;
295 param.m_host_sizing= 0;
296 param.m_user_sizing= 0;
297 param.m_account_sizing= 0;
298 param.m_stage_class_sizing= 0;
299 param.m_events_stages_history_sizing= 0;
300 param.m_events_stages_history_long_sizing= 0;
301 param.m_statement_class_sizing= 0;
302 param.m_events_statements_history_sizing= 0;
303 param.m_events_statements_history_long_sizing= 0;
304 param.m_events_transactions_history_sizing= 0;
305 param.m_events_transactions_history_long_sizing= 0;
306 param.m_digest_sizing= 0;
307 param.m_session_connect_attrs_sizing= 0;
308 param.m_program_sizing= 0;
309 param.m_prepared_stmt_sizing= 0;
310 param.m_statement_stack_sizing= 0;
311 param.m_memory_class_sizing= 1;
312 param.m_metadata_lock_sizing= 0;
313
314 init_event_name_sizing(& param);
315 rc= init_instruments(& param);
316 ok(rc == 0, "instances init");
317
318 dummy_mutex_class.m_event_name_index= 0;
319 dummy_mutex_class.m_flags= 0;
320 dummy_mutex_class.m_enabled= true;
321 dummy_mutex_class.m_volatility = PSI_VOLATILITY_UNKNOWN;
322 dummy_rwlock_class.m_event_name_index= 1;
323 dummy_rwlock_class.m_flags= 0;
324 dummy_rwlock_class.m_enabled= true;
325 dummy_rwlock_class.m_volatility = PSI_VOLATILITY_UNKNOWN;
326 dummy_cond_class.m_event_name_index= 2;
327 dummy_cond_class.m_flags= 0;
328 dummy_cond_class.m_enabled= true;
329 dummy_cond_class.m_volatility = PSI_VOLATILITY_UNKNOWN;
330 dummy_file_class.m_event_name_index= 3;
331 dummy_file_class.m_flags= 0;
332 dummy_file_class.m_enabled= true;
333 dummy_file_class.m_volatility = PSI_VOLATILITY_UNKNOWN;
334 dummy_socket_class.m_event_name_index= 4;
335 dummy_socket_class.m_flags= 0;
336 dummy_socket_class.m_enabled= true;
337 dummy_socket_class.m_volatility = PSI_VOLATILITY_UNKNOWN;
338
339 dummy_table_share.m_enabled= true;
340 dummy_table_share.m_timed= true;
341
342 mutex_1= create_mutex(& dummy_mutex_class, NULL);
343 ok(mutex_1 != NULL, "mutex");
344 ok(global_mutex_container.get_lost_counter() == 0, "not lost");
345 mutex_2= create_mutex(& dummy_mutex_class, NULL);
346 ok(mutex_2 != NULL, "mutex");
347 ok(global_mutex_container.get_lost_counter() == 0, "not lost");
348 mutex_2= create_mutex(& dummy_mutex_class, NULL);
349 ok(mutex_2 == NULL, "no mutex");
350 ok(global_mutex_container.get_lost_counter() == 1, "lost 1");
351 destroy_mutex(mutex_1);
352 mutex_2= create_mutex(& dummy_mutex_class, NULL);
353 ok(mutex_2 != NULL, "mutex");
354 ok(global_mutex_container.get_lost_counter() == 1, "no new loss");
355
356 rwlock_1= create_rwlock(& dummy_rwlock_class, NULL);
357 ok(rwlock_1 != NULL, "rwlock");
358 ok(global_rwlock_container.m_lost == 0, "not lost");
359 rwlock_2= create_rwlock(& dummy_rwlock_class, NULL);
360 ok(rwlock_2 != NULL, "rwlock");
361 ok(global_rwlock_container.m_lost == 0, "not lost");
362 rwlock_2= create_rwlock(& dummy_rwlock_class, NULL);
363 ok(rwlock_2 == NULL, "no rwlock");
364 ok(global_rwlock_container.m_lost == 1, "lost 1");
365 destroy_rwlock(rwlock_1);
366 rwlock_2= create_rwlock(& dummy_rwlock_class, NULL);
367 ok(rwlock_2 != NULL, "rwlock");
368 ok(global_rwlock_container.m_lost == 1, "no new loss");
369
370 cond_1= create_cond(& dummy_cond_class, NULL);
371 ok(cond_1 != NULL, "cond");
372 ok(global_cond_container.m_lost == 0, "not lost");
373 cond_2= create_cond(& dummy_cond_class, NULL);
374 ok(cond_2 != NULL, "cond");
375 ok(global_cond_container.m_lost == 0, "not lost");
376 cond_2= create_cond(& dummy_cond_class, NULL);
377 ok(cond_2 == NULL, "no cond");
378 ok(global_cond_container.m_lost == 1, "lost 1");
379 destroy_cond(cond_1);
380 cond_2= create_cond(& dummy_cond_class, NULL);
381 ok(cond_2 != NULL, "cond");
382 ok(global_cond_container.m_lost == 1, "no new loss");
383
384 thread_1= create_thread(& dummy_thread_class, NULL, 0);
385 ok(thread_1 != NULL, "thread");
386 ok(global_thread_container.m_lost == 0, "not lost");
387 thread_2= create_thread(& dummy_thread_class, NULL, 0);
388 ok(thread_2 != NULL, "thread");
389 ok(global_thread_container.m_lost == 0, "not lost");
390 thread_2= create_thread(& dummy_thread_class, NULL, 0);
391 ok(thread_2 == NULL, "no thread");
392 ok(global_thread_container.m_lost == 1, "lost 1");
393 destroy_thread(thread_1);
394 thread_2= create_thread(& dummy_thread_class, NULL, 0);
395 ok(thread_2 != NULL, "thread");
396 ok(global_thread_container.m_lost == 1, "no new loss");
397
398 PFS_thread fake_thread;
399 fake_thread.m_filename_hash_pins= NULL;
400
401 file_1= find_or_create_file(& fake_thread, & dummy_file_class, "dummy", 5, true);
402 ok(file_1 == NULL, "no file");
403 ok(global_file_container.m_lost == 1, "lost 1");
404 file_1= find_or_create_file(& fake_thread, & dummy_file_class, "dummy", 5, true);
405 ok(file_1 == NULL, "no file");
406 ok(global_file_container.m_lost == 2, "lost 2");
407
408 init_file_hash(& param);
409 global_file_container.m_lost= 0;
410
411 file_1= find_or_create_file(& fake_thread, & dummy_file_class, "dummy_A", 7, true);
412 ok(file_1 != NULL, "file");
413 ok(file_1->m_file_stat.m_open_count == 1, "open count 1");
414 ok(global_file_container.m_lost == 0, "not lost");
415 file_2= find_or_create_file(& fake_thread, & dummy_file_class, "dummy_A", 7, true);
416 ok(file_1 == file_2, "same file");
417 ok(file_1->m_file_stat.m_open_count == 2, "open count 2");
418 ok(global_file_container.m_lost == 0, "not lost");
419 release_file(file_2);
420 ok(file_1->m_file_stat.m_open_count == 1, "open count 1");
421 file_2= find_or_create_file(& fake_thread, & dummy_file_class, "dummy_B", 7, true);
422 ok(file_2 != NULL, "file");
423 ok(global_file_container.m_lost == 0, "not lost");
424 file_2= find_or_create_file(& fake_thread, & dummy_file_class, "dummy_C", 7, true);
425 ok(file_2 == NULL, "no file");
426 ok(global_file_container.m_lost == 1, "lost");
427 release_file(file_1);
428 /* the file still exists, not destroyed */
429 ok(file_1->m_file_stat.m_open_count == 0, "open count 0");
430 file_2= find_or_create_file(& fake_thread, & dummy_file_class, "dummy_D", 7, true);
431 ok(file_2 == NULL, "no file");
432 ok(global_file_container.m_lost == 2, "lost");
433
434 socket_1= create_socket(& dummy_socket_class, NULL, NULL, 0);
435 ok(socket_1 != NULL, "socket");
436 ok(global_socket_container.m_lost == 0, "not lost");
437 socket_2= create_socket(& dummy_socket_class, NULL, NULL, 0);
438 ok(socket_2 != NULL, "socket");
439 ok(global_socket_container.m_lost == 0, "not lost");
440 socket_2= create_socket(& dummy_socket_class, NULL, NULL, 0);
441 ok(socket_2 == NULL, "no socket");
442 ok(global_socket_container.m_lost == 1, "lost 1");
443 destroy_socket(socket_1);
444 socket_2= create_socket(& dummy_socket_class, NULL, NULL, 0);
445 ok(socket_2 != NULL, "socket");
446 ok(global_socket_container.m_lost == 1, "no new loss");
447
448 table_1= create_table(& dummy_table_share, & fake_thread, NULL);
449 ok(table_1 != NULL, "table");
450 ok(global_table_container.m_lost == 0, "not lost");
451 table_2= create_table(& dummy_table_share, & fake_thread, NULL);
452 ok(table_2 != NULL, "table");
453 ok(global_table_container.m_lost == 0, "not lost");
454 table_2= create_table(& dummy_table_share, & fake_thread, NULL);
455 ok(table_2 == NULL, "no table");
456 ok(global_table_container.m_lost == 1, "lost 1");
457 destroy_table(table_1);
458 table_2= create_table(& dummy_table_share, & fake_thread, NULL);
459 ok(table_2 != NULL, "table");
460 ok(global_table_container.m_lost == 1, "no new loss");
461
462 //TODO: test that cleanup works
463 reset_events_waits_by_instance();
464 reset_events_waits_by_thread();
465
466 cleanup_file_hash();
467 cleanup_instruments();
468 }
469
do_all_tests()470 void do_all_tests()
471 {
472 flag_global_instrumentation= true;
473 flag_thread_instrumentation= true;
474
475 test_no_instruments();
476 test_no_instances();
477 test_with_instances();
478 }
479
main(int argc,char ** argv)480 int main(int argc, char **argv)
481 {
482 plan(103);
483 MY_INIT(argv[0]);
484 do_all_tests();
485 my_end(0);
486 return (exit_status());
487 }
488
489