From: Tor Didriksen Date: December 21 2010 3:21pm Subject: bzr commit into mysql-trunk-bugfixing branch (tor.didriksen:3362) List-Archive: http://lists.mysql.com/commits/127444 Message-Id: <20101221152202.890FE3731@atum07.norway.sun.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============5812204214986173460==" --===============5812204214986173460== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///export/home/didrik/repo/next-mr-gtest/ based on revid:tor.didriksen@stripped 3362 Tor Didriksen 2010-12-21 More experiments with unit tests for Item, now with a mock Field. added: unittest/gunit/item-t.cc modified: sql/mysqld.cc sql/mysqld.h sql/sql_class.cc sql/sql_class.h sql/sql_plugin.cc unittest/gunit/CMakeLists.txt === modified file 'sql/mysqld.cc' --- a/sql/mysqld.cc 2010-12-20 13:26:51 +0000 +++ b/sql/mysqld.cc 2010-12-21 15:21:52 +0000 @@ -943,7 +943,6 @@ static int get_options(int *argc_ptr, ch static bool add_terminator(DYNAMIC_ARRAY *options); extern "C" my_bool mysqld_get_one_option(int, const struct my_option *, char *); static void set_server_version(void); -static int init_thread_environment(); static char *get_relative_path(const char *path); static int fix_paths(void); void handle_connections_sockets(); @@ -3548,7 +3547,7 @@ You should consider changing lower_case_ } -static int init_thread_environment() +int init_thread_environment() { mysql_mutex_init(key_LOCK_thread_count, &LOCK_thread_count, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_status, &LOCK_status, MY_MUTEX_INIT_FAST); === modified file 'sql/mysqld.h' --- a/sql/mysqld.h 2010-12-17 11:28:59 +0000 +++ b/sql/mysqld.h 2010-12-21 15:21:52 +0000 @@ -72,6 +72,7 @@ bool one_thread_per_connection_end(THD * void flush_thread_cache(); void refresh_status(THD *thd); bool is_secure_file_path(char *path); +int init_thread_environment(); extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *system_charset_info; extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *files_charset_info ; === modified file 'sql/sql_class.cc' --- a/sql/sql_class.cc 2010-12-17 16:14:15 +0000 +++ b/sql/sql_class.cc 2010-12-21 15:21:52 +0000 @@ -496,9 +496,10 @@ bool Drop_table_error_handler::handle_co } -THD::THD() +THD::THD(bool enable_plugins) :Statement(&main_lex, &main_mem_root, CONVENTIONAL_EXECUTION, /* statement id */ 0), + m_enable_plugins(enable_plugins), rli_fake(0), user_time(0), in_sub_stmt(0), binlog_unsafe_warning_flags(0), @@ -926,7 +927,8 @@ extern "C" THD *_current_thd_noinline( void THD::init(void) { mysql_mutex_lock(&LOCK_global_system_variables); - plugin_thdvar_init(this); + if (m_enable_plugins) + plugin_thdvar_init(this); /* variables= global_system_variables above has reset variables.pseudo_thread_id to 0. We need to correct it here to @@ -1100,7 +1102,8 @@ THD::~THD() mdl_context.destroy(); ha_close_connection(this); mysql_audit_release(this); - plugin_thdvar_cleanup(this); + if (m_enable_plugins) + plugin_thdvar_cleanup(this); DBUG_PRINT("info", ("freeing security context")); main_security_ctx.destroy(); === modified file 'sql/sql_class.h' --- a/sql/sql_class.h 2010-12-20 17:18:14 +0000 +++ b/sql/sql_class.h 2010-12-21 15:21:52 +0000 @@ -1483,6 +1483,8 @@ class THD :public Statement, public: MDL_context mdl_context; + bool m_enable_plugins; + /* Used to execute base64 coded binlog events in MySQL server */ Relay_log_info* rli_fake; @@ -2237,7 +2239,9 @@ public: /* Debug Sync facility. See debug_sync.cc. */ struct st_debug_sync_control *debug_sync_control; #endif /* defined(ENABLED_DEBUG_SYNC) */ - THD(); + + // We don't want to load/unload plugins for unit tests. + THD(bool enable_plugins= true); ~THD(); void init(void); === modified file 'sql/sql_plugin.cc' --- a/sql/sql_plugin.cc 2010-12-06 13:12:51 +0000 +++ b/sql/sql_plugin.cc 2010-12-21 15:21:52 +0000 @@ -1039,6 +1039,9 @@ void plugin_unlock_list(THD *thd, plugin LEX *lex= thd ? thd->lex : 0; DBUG_ENTER("plugin_unlock_list"); DBUG_ASSERT(list); + if (count == 0) + DBUG_VOID_RETURN; + mysql_mutex_lock(&LOCK_plugin); while (count--) intern_plugin_unlock(lex, *list++); === modified file 'unittest/gunit/CMakeLists.txt' --- a/unittest/gunit/CMakeLists.txt 2010-12-17 09:41:21 +0000 +++ b/unittest/gunit/CMakeLists.txt 2010-12-21 15:21:52 +0000 @@ -122,7 +122,7 @@ IF(NOT GTEST_FOUND) FIND_PROGRAM(WGET_EXECUTABLE wget) MARK_AS_ADVANCED(WGET_EXECUTABLE) IF(WGET_EXECUTABLE) - EXECUTE_PROCESS(COMMAND ${WGET_EXECUTABLE} -T 30 ${GTEST_DOWNLOAD_URL} + EXECUTE_PROCESS(COMMAND ${WGET_EXECUTABLE} -T 30 ${GTEST_DOWNLOAD_URL} WORKING_DIRECTORY ${DOWNLOAD_ROOT} RESULT_VARIABLE ERR) IF(ERR EQUAL 0) SET(DOWNLOAD_SUCCEEDED 1) @@ -217,6 +217,11 @@ SET(TESTS thread_utils ) +# Add tests (link them with gunit library and the server libraries) +SET(SERVER_TESTS + item +) + FOREACH(test ${TESTS}) ADD_EXECUTABLE(${test}-t ${test}-t.cc) TARGET_LINK_LIBRARIES(${test}-t gunit sqlgunitlib strings dbug regex) @@ -225,3 +230,17 @@ FOREACH(test ${TESTS}) ENDIF() ADD_TEST(${test} ${test}-t) ENDFOREACH() + +FOREACH(test ${SERVER_TESTS}) + IF(WIN32) + ADD_EXECUTABLE(${test}-t ${test}-t.cc ../../sql/nt_servc.cc) + ELSE() + ADD_EXECUTABLE(${test}-t ${test}-t.cc) + ENDIF() + TARGET_LINK_LIBRARIES(${test}-t sql binlog rpl master slave sql) + TARGET_LINK_LIBRARIES(${test}-t gunit sqlgunitlib strings dbug regex) + IF (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro") + SET_TARGET_PROPERTIES(${test}-t PROPERTIES LINK_FLAGS "-library=stlport4") + ENDIF() + ADD_TEST(${test} ${test}-t) +ENDFOREACH() === added file 'unittest/gunit/item-t.cc' --- a/unittest/gunit/item-t.cc 1970-01-01 00:00:00 +0000 +++ b/unittest/gunit/item-t.cc 2010-12-21 15:21:52 +0000 @@ -0,0 +1,138 @@ +/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +// First include (the generated) my_config.h, to get correct platform defines, +// then gtest.h (before any other MySQL headers), to avoid min() macros etc ... +#include "my_config.h" +#include + +#include "item.h" +#include "sql_class.h" +#include "rpl_handler.h" // delegates_init() + +namespace { + +class ItemTest : public ::testing::Test +{ +protected: + static void SetUpTestCase() + { + init_thread_environment(); + randominit(&sql_rand, 0, 0); + xid_cache_init(); + delegates_init(); + } + + static void TearDownTestCase() + { + delegates_destroy(); + xid_cache_free(); + } + + ItemTest() : m_thd(NULL) {} + + void SetUp() + { + m_thd= new THD(false); + m_thd->thread_stack= (char*) &m_thd; + m_thd->store_globals(); + } + + void TearDown() + { + m_thd->cleanup_after_query(); + delete m_thd; + } + +private: + THD *m_thd; +}; + + +/** + This is a simple mock Field class, which verifies that store() is called. + TODO: Introduce Google Mock to simplify writing of mock classes. +*/ +class Mock_field_long : public Field_long +{ +public: + Mock_field_long(uint32 lenght, longlong expected_value) + : Field_long(0, // ptr_arg + lenght, // len_arg + NULL, // null_ptr_arg + 0, // null_bit_arg + Field::NONE, // unireg_check_arg + 0, // field_name_arg + false, // zero_arg + false), // unsigned_arg + m_store_called(0), + m_expected_value(expected_value) + {} + + virtual ~Mock_field_long() + { + EXPECT_EQ(1, m_store_called); + } + + virtual int store(longlong nr, bool unsigned_val) + { + EXPECT_EQ(m_expected_value, nr); + EXPECT_FALSE(unsigned_val); + ++m_store_called; + return 0; + } + +private: + int m_store_called; + longlong m_expected_value; +}; + + +TEST_F(ItemTest, item_int) +{ + const int32 val= 42; + char stringbuf[10]; + (void) my_snprintf(stringbuf, sizeof(stringbuf), "%d", val); + Item_int *item_int= new Item_int(val); + + EXPECT_EQ(Item::INT_ITEM, item_int->type()); + EXPECT_EQ(INT_RESULT, item_int->result_type()); + EXPECT_EQ(MYSQL_TYPE_LONGLONG, item_int->field_type()); + EXPECT_EQ(val, item_int->val_int()); + EXPECT_FLOAT_EQ((double) val, item_int->val_real()); + EXPECT_TRUE(item_int->basic_const_item()); + + my_decimal decimal_val; + EXPECT_EQ(&decimal_val, item_int->val_decimal(&decimal_val)); + + String string_val; + EXPECT_EQ(&string_val, item_int->val_str(&string_val)); + EXPECT_STREQ(stringbuf, string_val.c_ptr_safe()); + + Field *field_val= new Mock_field_long(item_int->max_length, val); + EXPECT_EQ(0, item_int->save_in_field(field_val, true)); + delete field_val; + + Item *clone= item_int->clone_item(); + EXPECT_TRUE(item_int->eq(clone, true)); + EXPECT_TRUE(item_int->eq(item_int, true)); + + String print_val; + item_int->print(&print_val, QT_ORDINARY); + EXPECT_STREQ(stringbuf, print_val.c_ptr_safe()); +} + +} --===============5812204214986173460== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/tor.didriksen@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: tor.didriksen@stripped\ # 0gxsh5xg56jnxk3w # target_branch: file:///export/home/didrik/repo/next-mr-gtest/ # testament_sha1: e779b0406d190144cb7c4ce2ddd5e448e5917d11 # timestamp: 2010-12-21 16:22:02 +0100 # source_branch: file:///export/home/didrik/repo/next-mr-bugfixing/ # base_revision_id: tor.didriksen@stripped\ # grwzzombinx9y0a0 # # Begin bundle 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 --===============5812204214986173460==--