MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sql_list-t.cc
1 /* Copyright (c) 2009, 2012, 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 as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 /*
17  This is a simple example of how to use the google unit test framework.
18 
19  For an introduction to the constructs used below, see:
20  http://code.google.com/p/googletest/wiki/GoogleTestPrimer
21 */
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 "sql_list.h"
28 
29 #include "thr_malloc.h"
30 #include "sql_string.h"
31 #include "sql_error.h"
32 #include <my_pthread.h>
33 #include "test_utils.h"
34 
35 namespace sql_list_unittest {
36 
37 // A simple helper function to insert values into a List.
38 template <class T, int size>
39 void insert_values(T (&array)[size], List<T> *list)
40 {
41  for (int ix= 0; ix < size; ++ix)
42  {
43  EXPECT_FALSE(list->push_back(&array[ix]));
44  }
45 }
46 
47 /*
48  The fixture for testing the MySQL List and List_iterator classes.
49  A fresh instance of this class will be created for each of the
50  TEST_F functions below.
51  The functions SetUp(), TearDown(), SetUpTestCase(), TearDownTestCase() are
52  inherited from ::testing::Test (google naming style differs from MySQL).
53 */
54 class SqlListTest : public ::testing::Test
55 {
56 protected:
57  SqlListTest()
58  : m_mem_root_p(&m_mem_root), m_int_list(), m_int_list_iter(m_int_list)
59  {
60  }
61 
62  virtual void SetUp()
63  {
64  init_sql_alloc(&m_mem_root, 1024, 0);
65  ASSERT_EQ(0, my_pthread_setspecific_ptr(THR_MALLOC, &m_mem_root_p));
66  MEM_ROOT *root= *my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC);
67  ASSERT_EQ(root, m_mem_root_p);
68  }
69 
70  virtual void TearDown()
71  {
72  free_root(&m_mem_root, MYF(0));
73  }
74 
75  static void SetUpTestCase()
76  {
77  ASSERT_EQ(0, pthread_key_create(&THR_THD, NULL));
78  ASSERT_EQ(0, pthread_key_create(&THR_MALLOC, NULL));
79  }
80 
81  static void TearDownTestCase()
82  {
83  pthread_key_delete(THR_THD);
84  pthread_key_delete(THR_MALLOC);
85  }
86 
87  MEM_ROOT m_mem_root;
88  MEM_ROOT *m_mem_root_p;
89  List<int> m_int_list;
90  List_iterator<int> m_int_list_iter;
91 
92 private:
93  // Declares (but does not define) copy constructor and assignment operator.
94  GTEST_DISALLOW_COPY_AND_ASSIGN_(SqlListTest);
95 };
96 
97 
98 // Tests that we can construct and destruct lists.
99 TEST_F(SqlListTest, ConstructAndDestruct)
100 {
101  EXPECT_TRUE(m_int_list.is_empty());
102  List<int> *p_int_list= new List<int>;
103  EXPECT_TRUE(p_int_list->is_empty());
104  delete p_int_list;
105 }
106 
107 
108 // Tests basic operations push and pop.
109 TEST_F(SqlListTest, BasicOperations)
110 {
111  int i1= 1;
112  int i2= 2;
113  EXPECT_FALSE(m_int_list.push_front(&i1));
114  EXPECT_FALSE(m_int_list.push_back(&i2));
115  EXPECT_FALSE(m_int_list.is_empty());
116  EXPECT_EQ(2U, m_int_list.elements);
117 
118  EXPECT_EQ(&i1, m_int_list.head());
119  EXPECT_EQ(&i1, m_int_list.pop());
120  EXPECT_EQ(&i2, m_int_list.head());
121  EXPECT_EQ(&i2, m_int_list.pop());
122  EXPECT_TRUE(m_int_list.is_empty()) << "The list should be empty now!";
123 }
124 
125 
126 // Tests list copying.
127 TEST_F(SqlListTest, DeepCopy)
128 {
129  int values[] = {11, 22, 33, 42, 5};
130  insert_values(values, &m_int_list);
131  MEM_ROOT mem_root;
132  init_alloc_root(&mem_root, 4096, 4096);
133  List<int> list_copy(m_int_list, &mem_root);
134  EXPECT_EQ(list_copy.elements, m_int_list.elements);
135  while (!list_copy.is_empty())
136  {
137  EXPECT_EQ(*m_int_list.pop(), *list_copy.pop());
138  }
139  EXPECT_TRUE(m_int_list.is_empty());
140  free_root(&mem_root, MYF(0));
141 }
142 
143 
144 // Tests that we can iterate over values.
145 TEST_F(SqlListTest, Iterate)
146 {
147  int values[] = {3, 2, 1};
148  insert_values(values, &m_int_list);
149  for (int ix= 0; ix < array_size(values); ++ix)
150  {
151  EXPECT_EQ(values[ix], *m_int_list_iter++);
152  }
153  m_int_list_iter.init(m_int_list);
154  int *value;
155  int value_number= 0;
156  while ((value= m_int_list_iter++))
157  {
158  EXPECT_EQ(values[value_number++], *value);
159  }
160 }
161 
162 
163 // A simple helper class for testing intrusive lists.
164 class Linked_node : public ilink<Linked_node>
165 {
166 public:
167  Linked_node(int val) : m_value(val) {}
168  int get_value() const { return m_value; }
169 private:
170  int m_value;
171 };
172 const Linked_node * const null_node= NULL;
173 
174 
175 // An example of a test without any fixture.
176 TEST(SqlIlistTest, ConstructAndDestruct)
177 {
178  I_List<Linked_node> i_list;
179  I_List_iterator<Linked_node> i_list_iter(i_list);
180  EXPECT_TRUE(i_list.is_empty());
181  EXPECT_EQ(null_node, i_list_iter++);
182 }
183 
184 
185 // Tests iteration over intrusive lists.
186 TEST(SqlIlistTest, PushBackAndIterate)
187 {
188  I_List<Linked_node> i_list;
189  I_List_iterator<Linked_node> i_list_iter(i_list);
190  int values[] = {11, 22, 33, 42, 5};
191  EXPECT_EQ(null_node, i_list.head());
192  for (int ix= 0; ix < array_size(values); ++ix)
193  {
194  i_list.push_back(new Linked_node(values[ix]));
195  }
196 
197  Linked_node *node;
198  int value_number= 0;
199  while ((node= i_list_iter++))
200  {
201  EXPECT_EQ(values[value_number++], node->get_value());
202  }
203  for (value_number= 0; (node= i_list.get()); ++value_number)
204  {
205  EXPECT_EQ(values[value_number], node->get_value());
206  delete node;
207  }
208  EXPECT_EQ(array_size(values), value_number);
209 }
210 
211 // Another iteration test over intrusive lists.
212 TEST(SqlIlistTest, PushFrontAndIterate)
213 {
214  I_List<Linked_node> i_list;
215  I_List_iterator<Linked_node> i_list_iter(i_list);
216  int values[] = {11, 22, 33, 42, 5};
217  for (int ix= 0; ix < array_size(values); ++ix)
218  {
219  i_list.push_front(new Linked_node(values[ix]));
220  }
221 
222  Linked_node *node;
223  int value_number= array_size(values) - 1;
224  while ((node= i_list_iter++))
225  {
226  EXPECT_EQ(values[value_number--], node->get_value());
227  }
228  while ((node= i_list.get()))
229  delete node;
230 }
231 
232 static int cmp_test(void *a, void *b, void *c)
233 {
234  EXPECT_EQ(c, (void *)0xFEE1BEEF);
235  return (*(int*)a < *(int*)b) ? -1 : (*(int*)a > *(int*)b) ? 1 : 0;
236 }
237 
238 // Tests list sorting.
239 TEST_F(SqlListTest, Sort)
240 {
241  int values[] = {1, 9, 2, 7, 3, 6, 4, 5, 8};
242  insert_values(values, &m_int_list);
243  m_int_list.sort(cmp_test, (void*)0xFEE1BEEF);
244  for (int i= 1; i < 10 ; i++)
245  {
246  EXPECT_EQ(*m_int_list.pop(), i);
247  }
248  EXPECT_TRUE(m_int_list.is_empty());
249  // Test sorting of empty string.
250  m_int_list.sort(cmp_test, (void*)0xFEE1BEEF);
251  // Check that nothing has changed.
252  EXPECT_TRUE(m_int_list.is_empty());
253 }
254 
255 
256 } // namespace