1 /* Copyright (c) 2011, 2016, 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 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 "test_utils.h"
28 #include "rpl_handler.h"                        // delegates_init()
29 #include "global_threads.h"                     // LOCK_thread_count
30 
31 namespace my_testing {
32 
chars_2_decimal(const char * chars,my_decimal * to)33 int chars_2_decimal(const char *chars, my_decimal *to)
34 {
35   char *end= strend(chars);
36   return string2decimal(chars, to, &end);
37 }
38 
39 
40 /*
41   A mock error handler for error_handler_hook.
42 */
43 uint expected_error= 0;
test_error_handler_hook(uint err,const char * str,myf MyFlags)44 extern "C" void test_error_handler_hook(uint err, const char *str, myf MyFlags)
45 {
46   EXPECT_EQ(expected_error, err) << str;
47 }
48 
setup_server_for_unit_tests()49 void setup_server_for_unit_tests()
50 {
51   static char *my_name= strdup(my_progname);
52   char *argv[] = { my_name,
53                    const_cast<char*>("--log_syslog=0"),
54                    const_cast<char*>("--explicit_defaults_for_timestamp"),
55                    const_cast<char*>("--datadir=" DATA_DIR),
56                    const_cast<char*>("--secure-file-priv=NULL"),
57                    const_cast<char*>("--lc-messages-dir=" ERRMSG_DIR), 0 };
58   set_remaining_args(6, argv);
59   mysql_mutex_init(key_LOCK_error_log, &LOCK_error_log, MY_MUTEX_INIT_FAST);
60   system_charset_info= &my_charset_utf8_general_ci;
61   sys_var_init();
62   init_common_variables();
63   my_init_signals();
64   randominit(&sql_rand, 0, 0);
65   xid_cache_init();
66   delegates_init();
67   gtid_server_init();
68   error_handler_hook= test_error_handler_hook;
69   // Initialize logger last, to avoid spurious warnings to stderr.
70   logger.init_base();
71 }
72 
teardown_server_for_unit_tests()73 void teardown_server_for_unit_tests()
74 {
75   sys_var_end();
76   delegates_destroy();
77   xid_cache_free();
78   gtid_server_cleanup();
79   mysql_mutex_destroy(&LOCK_error_log);
80   logger.cleanup_base();
81   logger.cleanup_end();
82 }
83 
set_expected_error(uint val)84 void Server_initializer::set_expected_error(uint val)
85 {
86   expected_error= val;
87 }
88 
SetUp()89 void Server_initializer::SetUp()
90 {
91   expected_error= 0;
92   m_thd= new THD(false);
93   THD *stack_thd= m_thd;
94   m_thd->thread_stack= (char*) &stack_thd;
95   m_thd->store_globals();
96   lex_start(m_thd);
97   m_thd->set_current_time();
98 
99   mysql_mutex_lock(&LOCK_thread_count);
100   m_thd->thread_id= m_thd->variables.pseudo_thread_id= thread_id++;
101   mysql_mutex_unlock(&LOCK_thread_count);
102 
103   my_pthread_setspecific_ptr(THR_THD, m_thd);
104 }
105 
TearDown()106 void Server_initializer::TearDown()
107 {
108   m_thd->cleanup_after_query();
109   my_pthread_setspecific_ptr(THR_THD, NULL);
110   delete m_thd;
111 }
112 
113 
Mock_error_handler(THD * thd,uint expected_error)114 Mock_error_handler::Mock_error_handler(THD *thd, uint expected_error)
115   : m_thd(thd),
116     m_expected_error(expected_error),
117     m_handle_called(0)
118 {
119   thd->push_internal_handler(this);
120 }
121 
~Mock_error_handler()122 Mock_error_handler::~Mock_error_handler()
123 {
124   // Strange Visual Studio bug: have to store 'this' in local variable.
125   Internal_error_handler *me= this;
126   EXPECT_EQ(me, m_thd->pop_internal_handler());
127   if (m_expected_error == 0)
128   {
129     EXPECT_EQ(0, m_handle_called);
130   }
131   else
132   {
133     EXPECT_GT(m_handle_called, 0);
134   }
135 }
136 
handle_condition(THD * thd,uint sql_errno,const char * sqlstate,Sql_condition::enum_warning_level level,const char * msg,Sql_condition ** cond_hdl)137 bool Mock_error_handler::handle_condition(THD *thd,
138                                           uint sql_errno,
139                                           const char* sqlstate,
140                                           Sql_condition::enum_warning_level level,
141                                           const char* msg,
142                                           Sql_condition ** cond_hdl)
143 {
144   EXPECT_EQ(m_expected_error, sql_errno);
145   ++m_handle_called;
146   return true;
147 }
148 
149 
150 }  // namespace my_testing
151