List:Commits« Previous MessageNext Message »
From:Tor Didriksen Date:May 5 2011 11:25am
Subject:bzr commit into mysql-trunk branch (tor.didriksen:3366) Bug#60110
View as plain text  
#At file:///export/home/didrik/repo/next-mr-gtest/ based on revid:alexander.nozdrin@stripped

 3366 Tor Didriksen	2011-05-05
      Bug#60110 move THD and error handling to separate utility file

    added:
      unittest/gunit/opt_range-t.cc
      unittest/gunit/test_utils.cc
      unittest/gunit/test_utils.h
    modified:
      unittest/gunit/CMakeLists.txt
      unittest/gunit/item-t.cc
=== modified file 'unittest/gunit/CMakeLists.txt'
--- a/unittest/gunit/CMakeLists.txt	2011-04-13 11:31:44 +0000
+++ b/unittest/gunit/CMakeLists.txt	2011-05-05 11:25:45 +0000
@@ -219,6 +219,7 @@ SET(TESTS
 # Add tests (link them with gunit library and the server libraries) 
 SET(SERVER_TESTS
   item
+  opt_range
 )
 
 FOREACH(test ${TESTS})
@@ -232,9 +233,9 @@ ENDFOREACH()
 
 FOREACH(test ${SERVER_TESTS})
   IF(WIN32)
-    ADD_EXECUTABLE(${test}-t ${test}-t.cc ../../sql/nt_servc.cc)
+    ADD_EXECUTABLE(${test}-t ${test}-t.cc test_utils.cc ../../sql/nt_servc.cc)
   ELSE()
-    ADD_EXECUTABLE(${test}-t ${test}-t.cc)
+    ADD_EXECUTABLE(${test}-t ${test}-t.cc test_utils.cc)
   ENDIF()
   TARGET_LINK_LIBRARIES(${test}-t sql binlog rpl master slave sql)
   TARGET_LINK_LIBRARIES(${test}-t gunit sqlgunitlib strings dbug regex mysys)

=== modified file 'unittest/gunit/item-t.cc'
--- a/unittest/gunit/item-t.cc	2011-03-18 12:25:56 +0000
+++ b/unittest/gunit/item-t.cc	2011-05-05 11:25:45 +0000
@@ -18,112 +18,42 @@
 #include "my_config.h"
 #include <gtest/gtest.h>
 
+#include "test_utils.h"
+
 #include "item.h"
 #include "sql_class.h"
-#include "rpl_handler.h"                        // delegates_init()
 
 namespace {
 
-/*
-  A mock error handler for error_handler_hook.
-*/
-uint expected_error= 0;
-extern "C" void test_error_handler_hook(uint err, const char *str, myf MyFlags)
-{
-  EXPECT_EQ(expected_error, err) << str;
-}
-
-
-/**
-   A mock error handler which registers itself with the THD in the CTOR,
-   and unregisters in the DTOR. The function handle_condition() will
-   verify that it is called with the expected error number.
-   The DTOR will verify that handle_condition() has actually been called.
-*/
-class Mock_error_handler : public Internal_error_handler
-{
-public:
-  Mock_error_handler(THD *thd, uint expected_error)
-    : m_thd(thd),
-      m_expected_error(expected_error),
-      m_handle_called(0)
-  {
-    thd->push_internal_handler(this);
-  }
-
-  virtual ~Mock_error_handler()
-  {
-    // Strange Visual Studio bug: have to store 'this' in local variable.
-    Internal_error_handler *me= this;
-    EXPECT_EQ(me, m_thd->pop_internal_handler());
-    EXPECT_GE(m_handle_called, 0);
-  }
-
-  virtual bool handle_condition(THD *thd,
-                                uint sql_errno,
-                                const char* sqlstate,
-                                MYSQL_ERROR::enum_warning_level level,
-                                const char* msg,
-                                MYSQL_ERROR ** cond_hdl)
-  {
-    EXPECT_EQ(sql_errno, m_expected_error);
-    ++m_handle_called;
-    return true;
-  }
-private:
-  THD *m_thd;
-  uint m_expected_error;
-  int  m_handle_called;
-};
-
+using my_testing::Server_initializer;
+using my_testing::Mock_error_handler;
 
 class ItemTest : public ::testing::Test
 {
 protected:
-  /*
-    This is the part of the server global things which have to be initialized
-    for this (very simple) unit test. Presumably the list will grow once
-    we start writing tests for more advanced classes.
-    TODO: Move to a common library.
-   */
   static void SetUpTestCase()
   {
-    static char *my_name= strdup(my_progname);
-    char *argv[] = { my_name, 0 };
-    set_remaining_args(1, argv);
-    init_common_variables();
-    my_init_signals();
-    randominit(&sql_rand, 0, 0);
-    xid_cache_init();
-    delegates_init();
-    error_handler_hook= test_error_handler_hook;
+    Server_initializer::SetUpTestCase();
   }
 
   static void TearDownTestCase()
   {
-    delegates_destroy();
-    xid_cache_free();
+    Server_initializer::TearDownTestCase();
   }
 
-  ItemTest() : m_thd(NULL) {}
-
   virtual void SetUp()
   {
-    expected_error= 0;
-    m_thd= new THD(false);
-    THD *stack_thd= m_thd;
-    m_thd->thread_stack= (char*) &stack_thd;
-    m_thd->store_globals();
-    lex_start(m_thd);
+    initializer.SetUp();
   }
 
   virtual void TearDown()
   {
-    m_thd->cleanup_after_query();
-    delete m_thd;
+    initializer.TearDown();
   }
 
-  THD *m_thd;
+  THD *thd() { return initializer.thd(); }
+
+  Server_initializer initializer;
 };
 
 
@@ -239,7 +169,7 @@ TEST_F(ItemTest, ItemFuncDesDecrypt)
   Item_func_des_decrypt *item_decrypt=
     new Item_func_des_decrypt(item_two, item_one);
   
-  EXPECT_FALSE(item_decrypt->fix_fields(m_thd, NULL));
+  EXPECT_FALSE(item_decrypt->fix_fields(thd(), NULL));
   EXPECT_EQ(length, item_one->max_length);
   EXPECT_EQ(length, item_two->max_length);
   EXPECT_LE(item_decrypt->max_length, length);
@@ -256,9 +186,9 @@ TEST_F(ItemTest, ItemFuncIntDivOverflow)
   Item_float *divisor= new Item_float(divisor_str, sizeof(divisor_str));
   Item_func_int_div* quotient= new Item_func_int_div(dividend, divisor);
 
-  Mock_error_handler error_handler(m_thd, ER_TRUNCATED_WRONG_VALUE);
-  EXPECT_FALSE(quotient->fix_fields(m_thd, NULL));
-  expected_error= ER_DATA_OUT_OF_RANGE;
+  Mock_error_handler error_handler(thd(), ER_TRUNCATED_WRONG_VALUE);
+  EXPECT_FALSE(quotient->fix_fields(thd(), NULL));
+  initializer.set_expected_error(ER_DATA_OUT_OF_RANGE);
   quotient->val_int();
 }
 
@@ -272,8 +202,8 @@ TEST_F(ItemTest, ItemFuncIntDivUnderflow
   Item_float *divisor= new Item_float(divisor_str, sizeof(divisor_str));
   Item_func_int_div* quotient= new Item_func_int_div(dividend, divisor);
 
-  Mock_error_handler error_handler(m_thd, ER_TRUNCATED_WRONG_VALUE);
-  EXPECT_FALSE(quotient->fix_fields(m_thd, NULL));
+  Mock_error_handler error_handler(thd(), ER_TRUNCATED_WRONG_VALUE);
+  EXPECT_FALSE(quotient->fix_fields(thd(), NULL));
   EXPECT_EQ(0, quotient->val_int());
 }
 
@@ -291,8 +221,8 @@ TEST_F(ItemTest, ItemFuncSetUserVar)
   LEX_STRING var_name= { C_STRING_WITH_LEN("a") };
   Item_func_set_user_var *user_var=
     new Item_func_set_user_var(var_name, item_str);
-  EXPECT_FALSE(user_var->set_entry(m_thd, true));
-  EXPECT_FALSE(user_var->fix_fields(m_thd, NULL));
+  EXPECT_FALSE(user_var->set_entry(thd(), true));
+  EXPECT_FALSE(user_var->fix_fields(thd(), NULL));
   EXPECT_EQ(val1, user_var->val_int());
   
   my_decimal decimal;
@@ -323,7 +253,7 @@ TEST_F(ItemTest, OutOfMemory)
   EXPECT_EQ(null_item, item);
 
   DBUG_SET("+d,simulate_out_of_memory");
-  item= new (m_thd->mem_root) Item_int(42);
+  item= new (thd()->mem_root) Item_int(42);
   EXPECT_EQ(null_item, item);
 #endif
 }
@@ -337,7 +267,7 @@ TEST_F(ItemTest, ItemFuncXor)
   Item_func_xor *item_xor=
     new Item_func_xor(item_zero, item_one_a);
 
-  EXPECT_FALSE(item_xor->fix_fields(m_thd, NULL));
+  EXPECT_FALSE(item_xor->fix_fields(thd(), NULL));
   EXPECT_EQ(1, item_xor->val_int());
   EXPECT_EQ(1U, item_xor->decimal_precision());
 
@@ -346,7 +276,7 @@ TEST_F(ItemTest, ItemFuncXor)
   Item_func_xor *item_xor_same=
     new Item_func_xor(item_one_a, item_one_b);
 
-  EXPECT_FALSE(item_xor_same->fix_fields(m_thd, NULL));
+  EXPECT_FALSE(item_xor_same->fix_fields(thd(), NULL));
   EXPECT_EQ(0, item_xor_same->val_int());
   EXPECT_FALSE(item_xor_same->val_bool());
   EXPECT_FALSE(item_xor_same->is_null());
@@ -355,8 +285,8 @@ TEST_F(ItemTest, ItemFuncXor)
   item_xor->print(&print_buffer, QT_ORDINARY);
   EXPECT_STREQ("(0 xor 1)", print_buffer.c_ptr_safe());
 
-  Item *neg_xor= item_xor->neg_transformer(m_thd);
-  EXPECT_FALSE(neg_xor->fix_fields(m_thd, NULL));
+  Item *neg_xor= item_xor->neg_transformer(thd());
+  EXPECT_FALSE(neg_xor->fix_fields(thd(), NULL));
   EXPECT_EQ(0, neg_xor->val_int());
   EXPECT_DOUBLE_EQ(0.0, neg_xor->val_real());
   EXPECT_FALSE(neg_xor->val_bool());
@@ -368,7 +298,7 @@ TEST_F(ItemTest, ItemFuncXor)
 
   Item_func_xor *item_xor_null=
     new Item_func_xor(item_zero, new Item_null());
-  EXPECT_FALSE(item_xor_null->fix_fields(m_thd, NULL));
+  EXPECT_FALSE(item_xor_null->fix_fields(thd(), NULL));
 
   EXPECT_EQ(0, item_xor_null->val_int());
   EXPECT_TRUE(item_xor_null->is_null());

=== added file 'unittest/gunit/opt_range-t.cc'
--- a/unittest/gunit/opt_range-t.cc	1970-01-01 00:00:00 +0000
+++ b/unittest/gunit/opt_range-t.cc	2011-05-05 11:25:45 +0000
@@ -0,0 +1,150 @@
+/* Copyright (c) 2011, 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 <gtest/gtest.h>
+
+#include "test_utils.h"
+
+#include "opt_range.cc"
+
+namespace {
+
+using my_testing::Server_initializer;
+
+class SelArgTest : public ::testing::Test
+{
+protected:
+  static void SetUpTestCase()
+  {
+    Server_initializer::SetUpTestCase();
+  }
+
+  static void TearDownTestCase()
+  {
+    Server_initializer::TearDownTestCase();
+  }
+
+  SelArgTest()
+  {
+    memset(&m_opt_param, 0, sizeof(m_opt_param));
+  }
+
+  virtual void SetUp()
+  {
+    initializer.SetUp();
+    m_opt_param.thd= thd();
+    m_opt_param.mem_root= &m_alloc;
+    init_sql_alloc(&m_alloc, thd()->variables.range_alloc_block_size, 0);
+  }
+
+  virtual void TearDown()
+  {
+    initializer.TearDown();
+    free_root(&m_alloc, MYF(0));
+  }
+
+  THD *thd() { return initializer.thd(); }
+
+  Server_initializer initializer;
+  MEM_ROOT           m_alloc;
+  RANGE_OPT_PARAM    m_opt_param;
+};
+
+/*
+ Experiment with these to measure performance of
+   'new (thd->mem_root)' Foo vs. 'new Foo'.
+ With gcc 4.4.2 I see ~4% difference (in optimized mode).
+*/
+const int num_iterations= 10;
+const int num_allocs= 10;
+
+TEST_F(SelArgTest, AllocateExplicit)
+{
+  for (int ix= 0; ix < num_iterations; ++ix)
+  {
+    free_root(thd()->mem_root, MYF(MY_KEEP_PREALLOC));
+    for (int ii= 0; ii < num_allocs; ++ii)
+      new (thd()->mem_root) SEL_ARG;
+  }
+}
+
+TEST_F(SelArgTest, AllocateImplicit)
+{
+  for (int ix= 0; ix < num_iterations; ++ix)
+  {
+    free_root(thd()->mem_root, MYF(MY_KEEP_PREALLOC));
+    for (int ii= 0; ii < num_allocs; ++ii)
+      new SEL_ARG;
+  }
+}
+
+/*
+  We cannot do EXPECT_NE(NULL, get_mm_tree(...))
+  because of limits in google test.
+ */
+const SEL_TREE *null_tree= NULL;
+
+
+class Mock_field_long : public Field_long
+{
+public:
+  Mock_field_long()
+    : Field_long(0,                             // ptr_arg
+                 8,                             // len_arg
+                 NULL,                          // null_ptr_arg
+                 0,                             // null_bit_arg
+                 Field::NONE,                   // unireg_check_arg
+                 "field_name",                  // field_name_arg
+                 false,                         // zero_arg
+                 false)                         // unsigned_arg
+  {
+    m_table_name= "mock_table";
+    memset(&m_share, 0, sizeof(m_share));
+    const char *foo= "mock_db";
+    m_share.db.str= const_cast<char*>(foo);
+    m_share.db.length= strlen(m_share.db.str);
+
+    memset(&m_table, 0, sizeof(m_table));
+    m_table.s= &m_share;
+    this->table_name= &m_table_name;
+    this->table= &m_table;
+  }
+  const char *m_table_name;
+  TABLE_SHARE m_share;
+  TABLE       m_table;
+};
+
+
+TEST_F(SelArgTest, SimpleCond)
+{
+  EXPECT_NE(null_tree, get_mm_tree(&m_opt_param, new Item_int(42)));
+}
+
+
+TEST_F(SelArgTest, EqualCond)
+{
+  Mock_field_long field_long;
+  EXPECT_EQ(null_tree,
+            get_mm_tree(&m_opt_param,
+                        new Item_equal(new Item_int(42), 
+                                       new Item_field(&field_long))));
+}
+
+}
+
+

=== added file 'unittest/gunit/test_utils.cc'
--- a/unittest/gunit/test_utils.cc	1970-01-01 00:00:00 +0000
+++ b/unittest/gunit/test_utils.cc	2011-05-05 11:25:45 +0000
@@ -0,0 +1,105 @@
+/* Copyright (c) 2011, 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 <gtest/gtest.h>
+
+#include "test_utils.h"
+#include "rpl_handler.h"                        // delegates_init()
+
+namespace my_testing {
+
+/*
+  A mock error handler for error_handler_hook.
+*/
+uint expected_error= 0;
+extern "C" void test_error_handler_hook(uint err, const char *str, myf MyFlags)
+{
+  EXPECT_EQ(expected_error, err) << str;
+}
+
+void Server_initializer::set_expected_error(uint val)
+{
+  expected_error= val;
+}
+
+void Server_initializer::SetUpTestCase()
+{
+  static char *my_name= strdup(my_progname);
+  char *argv[] = { my_name, 0 };
+  set_remaining_args(1, argv);
+  init_common_variables();
+  my_init_signals();
+  randominit(&sql_rand, 0, 0);
+  xid_cache_init();
+  delegates_init();
+  error_handler_hook= test_error_handler_hook;
+}
+
+void Server_initializer::TearDownTestCase()
+{
+  delegates_destroy();
+  xid_cache_free();
+}
+
+void Server_initializer::SetUp()
+{
+  expected_error= 0;
+  m_thd= new THD(false);
+  THD *stack_thd= m_thd;
+  m_thd->thread_stack= (char*) &stack_thd;
+  m_thd->store_globals();
+  lex_start(m_thd);
+}
+
+void Server_initializer::TearDown()
+{
+  m_thd->cleanup_after_query();
+  delete m_thd;
+}
+
+
+Mock_error_handler::Mock_error_handler(THD *thd, uint expected_error)
+  : m_thd(thd),
+    m_expected_error(expected_error),
+    m_handle_called(0)
+{
+  thd->push_internal_handler(this);
+}
+
+Mock_error_handler::~Mock_error_handler()
+{
+  // Strange Visual Studio bug: have to store 'this' in local variable.
+  Internal_error_handler *me= this;
+  EXPECT_EQ(me, m_thd->pop_internal_handler());
+  EXPECT_GE(m_handle_called, 0);
+}
+
+bool Mock_error_handler::handle_condition(THD *thd,
+                                          uint sql_errno,
+                                          const char* sqlstate,
+                                          MYSQL_ERROR::enum_warning_level level,
+                                          const char* msg,
+                                          MYSQL_ERROR ** cond_hdl)
+{
+  EXPECT_EQ(m_expected_error, sql_errno);
+  ++m_handle_called;
+  return true;
+}
+
+
+}  // namespace my_testing

=== added file 'unittest/gunit/test_utils.h'
--- a/unittest/gunit/test_utils.h	1970-01-01 00:00:00 +0000
+++ b/unittest/gunit/test_utils.h	2011-05-05 11:25:45 +0000
@@ -0,0 +1,75 @@
+/* Copyright (c) 2011, 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 */
+
+
+#ifndef TEST_UTILS_INCLUDED
+#define TEST_UTILS_INCLUDED
+
+#include "sql_error.h"
+#include "sql_class.h"
+
+namespace my_testing {
+
+/*
+  A class which wraps the necessary setup/teardown logic for
+  unit tests which depend on a working THD environment.
+ */
+class Server_initializer
+{
+public:
+  Server_initializer() : m_thd(NULL) {}
+
+  // Invoke these from corresponding functions in test fixture classes.
+  static void SetUpTestCase();
+  static void TearDownTestCase();
+  void SetUp();
+  void TearDown();
+
+  // Sets expected error for error_handler_hook.
+  static void set_expected_error(uint val);
+
+  THD *thd() const { return m_thd; }
+private:
+  THD *m_thd;
+};
+
+/**
+   A mock error handler which registers itself with the THD in the CTOR,
+   and unregisters in the DTOR. The function handle_condition() will
+   verify that it is called with the expected error number.
+   The DTOR will verify that handle_condition() has actually been called.
+*/
+class Mock_error_handler : public Internal_error_handler
+{
+public:
+  Mock_error_handler(THD *thd, uint expected_error);
+  virtual ~Mock_error_handler();
+
+  virtual bool handle_condition(THD *thd,
+                                uint sql_errno,
+                                const char* sqlstate,
+                                MYSQL_ERROR::enum_warning_level level,
+                                const char* msg,
+                                MYSQL_ERROR ** cond_hdl);
+private:
+  THD *m_thd;
+  uint m_expected_error;
+  int  m_handle_called;
+};
+
+
+}  // namespace my_testing
+
+#endif  // TEST_UTILS_INCLUDED


Attachment: [text/bzr-bundle] bzr/tor.didriksen@oracle.com-20110505112545-u3g90bfs5a0w0wbg.bundle
Thread
bzr commit into mysql-trunk branch (tor.didriksen:3366) Bug#60110Tor Didriksen5 May