Line data Source code
1 : /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
2 : * Copyright (C) 2021 Frediano Ziglio
3 : *
4 : * This library is free software; you can redistribute it and/or
5 : * modify it under the terms of the GNU Library General Public
6 : * License as published by the Free Software Foundation; either
7 : * version 2 of the License, or (at your option) any later version.
8 : *
9 : * This library is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 : * Library General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU Library General Public
15 : * License along with this library; if not, write to the
16 : * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 : * Boston, MA 02111-1307, USA.
18 : */
19 :
20 : /*
21 : * Check log elision implementation
22 : */
23 : #include "common.h"
24 : #include <assert.h>
25 : #include <freetds/utils.h>
26 :
27 : #if HAVE_UNISTD_H
28 : #undef getpid
29 : #include <unistd.h>
30 : #endif /* HAVE_UNISTD_H */
31 :
32 : enum {
33 : LOOP = 100,
34 : THREADS = 3,
35 : };
36 :
37 24 : static TDS_THREAD_PROC_DECLARE(log_func, idx_ptr)
38 : {
39 24 : const int idx = TDS_PTR2INT(idx_ptr);
40 24 : const char letter = 'A' + idx;
41 : TDSDUMP_OFF_ITEM off_item;
42 24 : int n = idx, i;
43 :
44 : /* LOOP times */
45 2424 : for (i = 0; i < LOOP; ++i) {
46 : /* send log */
47 2400 : tdsdump_log(TDS_DBG_ERROR, "Some log from %c number %d\n", letter, n);
48 :
49 : /* wait 1-10 ms */
50 2400 : tds_sleep_ms((rand() % 10) + 1);
51 :
52 : /* disable logs */
53 2400 : tdsdump_off(&off_item);
54 :
55 : /* send wrong log */
56 2400 : tdsdump_log(TDS_DBG_ERROR, "Disabled log %c number %d\n", letter, n);
57 :
58 : /* wait 1-10 ms */
59 2400 : tds_sleep_ms((rand() % 10) + 1);
60 :
61 : /* enable logs */
62 2400 : tdsdump_on(&off_item);
63 :
64 2400 : n += 3;
65 : }
66 :
67 24 : return TDS_THREAD_RESULT(0);
68 : }
69 :
70 : int
71 8 : main(int argc, char **argv)
72 : {
73 : int i, ret;
74 : tds_thread threads[THREADS];
75 : FILE *f;
76 : char line[1024];
77 8 : int wrong_lines = 0;
78 : int nexts[THREADS];
79 :
80 8 : tds_debug_flags = TDS_DBGFLAG_ALL | TDS_DBGFLAG_SOURCE;
81 :
82 : /* remove file */
83 8 : unlink("log_elision.out");
84 :
85 : /* set output file */
86 8 : tdsdump_open("log_elision.out");
87 :
88 : /* THREADS thread */
89 32 : for (i = 0; i < THREADS; ++i) {
90 24 : nexts[i] = i;
91 : }
92 16 : for (i = 1; i < THREADS; ++i) {
93 32 : ret = tds_thread_create(&threads[i], log_func, TDS_INT2PTR(i));
94 16 : assert(ret == 0);
95 : }
96 8 : log_func(TDS_INT2PTR(0));
97 24 : for (i = 1; i < THREADS; ++i) {
98 32 : ret = tds_thread_join(threads[i], NULL);
99 16 : assert(ret == 0);
100 : }
101 :
102 : /* close logs */
103 8 : tdsdump_close();
104 :
105 : /* open logs to read */
106 8 : f = fopen("log_elision.out", "r");
107 8 : assert(f != NULL);
108 :
109 : /* read line by line */
110 2424 : while (fgets(line, sizeof(line), f) != NULL) {
111 : char thread_letter;
112 : int num_line, num, idx;
113 :
114 : /* ignore some start lines */
115 2416 : if (strstr(line, "log_elision.c") == NULL) {
116 16 : assert(++wrong_lines < 4);
117 16 : continue;
118 : }
119 :
120 2400 : ret = sscanf(line, "log_elision.c:%d:Some log from %c number %d\n",
121 : &num_line, &thread_letter, &num);
122 2400 : assert(ret == 3);
123 :
124 : /* detect number of thread */
125 2400 : assert(thread_letter >= 'A' && thread_letter < 'A' + THREADS);
126 2400 : idx = thread_letter - 'A';
127 :
128 : /* check number inside string match the next */
129 2400 : assert(num == nexts[idx]);
130 2400 : nexts[idx] += 3;
131 : }
132 8 : fclose(f);
133 8 : f = NULL;
134 :
135 : /* check we got all numbers */
136 32 : for (i = 0; i < THREADS; ++i) {
137 24 : assert(nexts[i] == i + LOOP * 3);
138 : }
139 :
140 : /* cleanup file */
141 8 : unlink("log_elision.out");
142 :
143 : return 0;
144 : }
|