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