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