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