1 /* Copyright (c) 2010, 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
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
22
23 // First include (the generated) my_config.h, to get correct platform defines.
24 #include "my_config.h"
25 #include <gtest/gtest.h>
26
27 #include "thread_utils.h"
28
29 #include "my_global.h"
30 #include "my_dbug.h"
31
32 using thread::Notification;
33 using thread::Thread;
34
35 namespace dbug_unittest {
36
37 #if defined(NDEBUG)
TEST(DebugTest,NoSuicide)38 TEST(DebugTest, NoSuicide)
39 {
40 DBUG_SUICIDE();
41 }
42 #else
43 TEST(DebugDeathTest, Suicide)
44 {
45 ::testing::FLAGS_gtest_death_test_style = "threadsafe";
46 EXPECT_DEATH_IF_SUPPORTED(DBUG_SUICIDE(), "");
47 }
48 #endif
49
50
51 #if !defined(NDEBUG) && !defined(_WIN32)
52 class DbugGcovThread : public Thread
53 {
54 public:
DbugGcovThread(Notification * start_notification)55 DbugGcovThread(Notification *start_notification)
56 : m_start_notification(start_notification)
57 {}
58
run()59 virtual void run()
60 {
61 m_start_notification->notify();
62 _db_flush_gcov_();
63 }
64
65 private:
66 Notification *m_start_notification;
67 };
68
69
TEST(DebugFlushGcov,FlushGcovParallel)70 TEST(DebugFlushGcov, FlushGcovParallel)
71 {
72 Notification start_notification;
73 DbugGcovThread debug_thread(&start_notification);
74 debug_thread.start();
75
76 // Wait for the other thread to start, then flush in parallel.
77 start_notification.wait_for_notification();
78 _db_flush_gcov_();
79 debug_thread.join();
80 }
81 #endif
82
83
84 #if !defined(NDEBUG)
TEST(DebugPrintTest,PrintEval)85 TEST(DebugPrintTest, PrintEval)
86 {
87 int y= 0;
88
89 // This DBUG_PRINT args should never be evaluated.
90 DBUG_PRINT("never",("%d", y+= 1));
91 EXPECT_EQ(y, 0) << "DBUG_PRINT arg is evaluated.";
92 }
93
94
TEST(DebugPrintEvalTest,PrintEval)95 TEST(DebugPrintEvalTest, PrintEval)
96 {
97 int y= 0;
98
99 DBUG_SET("+d,never");
100 DBUG_PRINT("never",("%d", y+= 1));
101 DBUG_SET("");
102 EXPECT_GE(y, 1) << "DBUG_PRINT arg is not evaluated.";
103 }
104
105
TEST(DebugSetTest,DebugKeywordsTest)106 TEST(DebugSetTest, DebugKeywordsTest)
107 {
108 char buf[1024];
109
110 /*
111 Enable d flag, then enable debug on a keyword. The debug should
112 remain set to d and empty list of keywords indicating debug is
113 enabled for all.
114 */
115 DBUG_SET("d");
116 DBUG_SET("+d,keyword");
117 DBUG_EXPLAIN(buf, sizeof(buf));
118 EXPECT_STREQ("d", buf);
119 DBUG_SET("");
120
121 /*
122 Set debug on a specific keyword. Debug should be enabled
123 for the keyword.
124 */
125 DBUG_SET("+d,keyword");
126 DBUG_EXPLAIN(buf, sizeof(buf));
127 EXPECT_STREQ("d,keyword", buf);
128
129 /*
130 Remove the keyword from debug list. Debug should be
131 disabled.
132 */
133 DBUG_SET("-d,keyword");
134 DBUG_EXPLAIN(buf, sizeof(buf));
135 EXPECT_STREQ("",buf);
136 DBUG_SET("");
137
138 /*
139 Enable debug for a keyword. Then enable debug for all
140 keywords. Debug should now be enabled for all keywords.
141 */
142 DBUG_SET("+d,keyword");
143 DBUG_SET("+d");
144 DBUG_EXPLAIN(buf,sizeof(buf));
145 EXPECT_STREQ("d",buf);
146 DBUG_SET("");
147
148 // Add multiple debug keywords.
149 DBUG_SET("+d,keyword1");
150 DBUG_SET("+d,keyword2");
151 DBUG_EXPLAIN(buf,sizeof(buf));
152 EXPECT_STREQ("d,keyword1,keyword2",buf);
153 DBUG_SET("-d,keyword1");
154 DBUG_EXPLAIN(buf,sizeof(buf));
155 EXPECT_STREQ("d,keyword2",buf);
156 DBUG_SET("-d,keyword2");
157 DBUG_EXPLAIN(buf,sizeof(buf));
158 EXPECT_STREQ("",buf);
159 DBUG_SET("");
160
161 // Add two keywords, the second keyword being a prefix of the first keyword.
162 DBUG_SET("+d,simulate_file_error_once,simulate_file_error");
163 DBUG_EXPLAIN(buf,sizeof(buf));
164 EXPECT_STREQ("d,simulate_file_error_once,simulate_file_error",buf);
165 DBUG_SET("");
166
167 // Add same keyword thrice, keyword should show up once in debug list.
168 DBUG_SET("+d,keyword,keyword,keyword");
169 DBUG_EXPLAIN(buf,sizeof(buf));
170 EXPECT_STREQ("d,keyword",buf);
171 DBUG_SET("");
172
173 // Add some combination of keywords with whitespace and duplicates.
174 DBUG_SET("+d, keyword1, keyword2, keyword1,keyword3 ");
175 DBUG_EXPLAIN(buf,sizeof(buf));
176 EXPECT_STREQ("d,keyword1,keyword2,keyword3",buf);
177 DBUG_SET("");
178 }
179 #endif /* NDEBUG */
180 }
181