1 /* Copyright (c) 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, 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 Foundation,
21    51 Franklin Street, Suite 500, Boston, MA 02110-1335 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 #include "test_utils.h"
27 
28 #include "table_cache.h"
29 
30 #include "ha_example.h"
31 
32 /*
33   We need example_hton to be able short-cut creation of example
34   handler instances for mock TABLE objects.
35 */
36 extern handlerton *example_hton;
37 
38 namespace table_cache_unittest {
39 
40 using my_testing::Server_initializer;
41 
42 
43 /**
44   Test fixture for basic tests involving Table_cache
45   and Table_cache_manager classes.
46 
47   Unlike more advanced fixture it doesn't initialize
48   table cache manager, but only prepares THD objects
49   necessary for testing.
50 */
51 
52 class TableCacheBasicTest : public ::testing::Test
53 {
54 protected:
55   static const uint MAX_THREADS= 3;
56 
SetUp()57   virtual void SetUp()
58   {
59     for (uint i= 0; i < MAX_THREADS; ++i)
60     {
61       initializer[i].SetUp();
62       initializer[i].thd()->thread_id= i + 1;
63     }
64 
65     ::testing::FLAGS_gtest_death_test_style = "threadsafe";
66   }
TearDown()67   virtual void TearDown()
68   {
69     for (uint i= 0; i < MAX_THREADS; ++i)
70       initializer[i].TearDown();
71   }
72 
get_thd(uint index)73   THD *get_thd(uint index) { return initializer[index].thd(); }
74 
75   Server_initializer initializer[MAX_THREADS];
76 };
77 
78 
79 /**
80   A more advanced fixture that also initializes table_cache_manager
81   with one Table_cache instance and TDC.
82 */
83 
84 class TableCacheSingleCacheTest : public TableCacheBasicTest
85 {
86 protected:
CachesNumber()87   virtual uint CachesNumber() { return 1; }
SetUp()88   virtual void SetUp()
89   {
90     TableCacheBasicTest::SetUp();
91 
92     /*
93       In addition to table_cache_manager we want to have initialized
94       TDC so we can use its HASH object for calculating hash values
95       and be able to free TABLE objects correctly (we need LOCK_open
96       initialized for this).
97     */
98     table_cache_instances= CachesNumber();
99     table_cache_size_per_instance= 100;
100     ASSERT_FALSE(table_def_init());
101   }
TearDown()102   virtual void TearDown()
103   {
104     table_def_free();
105     TableCacheBasicTest::TearDown();
106   }
107 };
108 
109 
110 /**
111   Another advanced fixture that also initializes table_cache_manager
112   with two Table_cache instances and TDC.
113 */
114 
115 class TableCacheDoubleCacheTest : public TableCacheSingleCacheTest
116 {
117 protected:
CachesNumber()118   virtual uint CachesNumber() { return 2; }
119 };
120 
121 
122 /**
123   Class for mock TABLE_SHARE object which also allows to create
124   associated TABLE objects which are usable with Table_cache.
125 */
126 
127 class Mock_share : public TABLE_SHARE
128 {
129   MEM_ROOT m_mem_root;
130   Table_cache_element *cache_element_arr[Table_cache_manager::MAX_TABLE_CACHES];
131 
132 public:
Mock_share(const char * key)133   Mock_share(const char *key)
134   {
135     memset(static_cast<void*>(this), 0, sizeof(TABLE_SHARE));
136     /*
137       Both table_cache_key and cache_element array are used by
138       Table_cache code.
139     */
140     table_cache_key.str= (char*)key;
141     table_cache_key.length= strlen(key);
142     memset(cache_element_arr, 0, sizeof(cache_element_arr));
143     cache_element= cache_element_arr;
144     // MEM_ROOT is used for constructing ha_example() instances.
145     init_alloc_root(&m_mem_root, 1024, 0);
146     /*
147       Assertion in some of Table_cache methods check that version of
148       the share is up-to-date.
149     */
150     version= refresh_version;
151     // Ensure that share is never destroyed.
152     ref_count= UINT_MAX;
153   }
154 
~Mock_share()155   ~Mock_share()
156   {
157     free_root(&m_mem_root, MYF(0));
158   }
159 
create_table(THD * thd)160   TABLE *create_table(THD *thd)
161   {
162     TABLE *result= (TABLE *)my_malloc(sizeof(TABLE), MYF(0));
163 
164     memset(static_cast<void*>(result), 0, sizeof(TABLE));
165     result->s= this;
166     // We create TABLE which is already marked as used
167     result->in_use= thd;
168     /*
169       Assertions in some of Table_cache methods need non-NULL
170       TABLE::file and TABLE::db_stat. Code that frees unused
171       TABLE objects needs proper "handler" instance.
172     */
173     result->file= new (&m_mem_root) ha_example(example_hton, this);
174     result->db_stat= HA_READ_ONLY;
175 
176     return result;
177   }
178 
destroy_table(TABLE * table)179   void destroy_table(TABLE *table)
180   {
181     my_free(table);
182   }
183 };
184 
185 // Google Test recommends DeathTest suffix for classes used in death tests.
186 typedef TableCacheBasicTest TableCacheBasicDeathTest;
187 typedef TableCacheDoubleCacheTest TableCacheDoubleCacheDeathTest;
188 
189 /*
190   Test initilization/destruction of Table_cache.
191 */
192 
TEST_F(TableCacheBasicDeathTest,CacheCreateAndDestroy)193 TEST_F(TableCacheBasicDeathTest, CacheCreateAndDestroy)
194 {
195   Table_cache table_cache;
196 
197   ASSERT_FALSE(table_cache.init());
198 
199   // Cache should be empty after creation
200   EXPECT_EQ(0U, table_cache.cached_tables());
201 
202   // Cache should be not locked after creation
203 #ifdef SAFE_MUTEX
204   MY_EXPECT_DEATH_IF_SUPPORTED(table_cache.assert_owner(),
205                             ".*Assertion.*count > 0.*pthread_equal.*");
206 #endif
207   table_cache.destroy();
208 }
209 
210 
211 /*
212   Test locking for Table_cache object.
213 */
214 
TEST_F(TableCacheBasicDeathTest,CacheLockAndUnlock)215 TEST_F(TableCacheBasicDeathTest, CacheLockAndUnlock)
216 {
217   Table_cache table_cache;
218 
219   ASSERT_FALSE(table_cache.init());
220 
221 #ifdef SAFE_MUTEX
222   // Cache should not be locked after creation
223   MY_EXPECT_DEATH_IF_SUPPORTED(table_cache.assert_owner(),
224                             ".*Assertion.*count > 0.*pthread_equal.*");
225 #endif
226 
227   // And get locked after we call its lock() method
228   table_cache.lock();
229   table_cache.assert_owner();
230 
231   // And get unlocked after we call its unlock() method
232   table_cache.unlock();
233 #ifdef SAFE_MUTEX
234   MY_EXPECT_DEATH_IF_SUPPORTED(table_cache.assert_owner(),
235                             ".*Assertion.*count > 0.*pthread_equal.*");
236 #endif
237 
238   table_cache.destroy();
239 }
240 
241 
242 /*
243   Tests for the rest of methods of Table_cache need to use an
244   object controlled by the global instance of Table_cache_manager.
245   Let us start testing of Table_cache_manager with test for
246   its initialization/destruction. This test also covers well
247   Table_cache_manager::get_cache() method.
248 */
249 
TEST_F(TableCacheBasicDeathTest,ManagerCreateAndDestroy)250 TEST_F(TableCacheBasicDeathTest, ManagerCreateAndDestroy)
251 {
252   // Request two instances of Table_cache
253   table_cache_instances= 2;
254 
255   ASSERT_FALSE(table_cache_manager.init());
256 
257   // All caches are empty after creation
258   EXPECT_EQ(0U, table_cache_manager.cached_tables());
259 
260   // There should be two different caches in the manager
261   Table_cache *cache_1, *cache_2, *cache_3;
262   cache_1= table_cache_manager.get_cache(get_thd(0));
263   cache_2= table_cache_manager.get_cache(get_thd(1));
264   cache_3= table_cache_manager.get_cache(get_thd(2));
265   EXPECT_TRUE(cache_1 != cache_2);
266   // And not three !
267   EXPECT_TRUE(cache_3 == cache_1);
268 
269   // Both caches should be empty
270   EXPECT_EQ(0U, cache_1->cached_tables());
271   EXPECT_EQ(0U, cache_2->cached_tables());
272 
273   // And not locked
274 #ifdef SAFE_MUTEX
275   MY_EXPECT_DEATH_IF_SUPPORTED(cache_1->assert_owner(),
276                             ".*Assertion.*count > 0.*pthread_equal.*");
277   MY_EXPECT_DEATH_IF_SUPPORTED(cache_2->assert_owner(),
278                             ".*Assertion.*count > 0.*pthread_equal.*");
279 #endif
280 
281   table_cache_manager.destroy();
282 }
283 
284 
285 /*
286   Test addition and removal of TABLE objects to/from the table cache.
287 */
288 
TEST_F(TableCacheSingleCacheTest,CacheAddAndRemove)289 TEST_F(TableCacheSingleCacheTest, CacheAddAndRemove)
290 {
291   THD *thd= get_thd(0);
292 
293   Mock_share share_1("share_1");
294   TABLE *table_1= share_1.create_table(thd);
295 
296   Table_cache *table_cache= table_cache_manager.get_cache(thd);
297   table_cache->lock();
298   EXPECT_FALSE(table_cache->add_used_table(thd, table_1));
299 
300   // There should be one TABLE in the cache after we have added table_1.
301   EXPECT_EQ(1U, table_cache->cached_tables());
302 
303   // There should be no unused TABLE objects for the same table in the
304   // cache. OTOH it should contain info about table share of table_1.
305   my_hash_value_type hash_value= my_calc_hash(&table_def_cache,
306                                    (uchar*)share_1.table_cache_key.str,
307                                    share_1.table_cache_key.length);
308   TABLE *table_2;
309   TABLE_SHARE *share_2;
310   table_2= table_cache->get_table(thd, hash_value,
311                                   share_1.table_cache_key.str,
312                                   share_1.table_cache_key.length,
313                                   &share_2);
314   EXPECT_TRUE(table_2 == NULL);
315   EXPECT_TRUE(share_2 == &share_1);
316 
317   // Table_cache_iterator should be able to find only one TABLE instance
318   // in all caches. And this instance should be table_1.
319   Table_cache_iterator it(&share_1);
320   EXPECT_TRUE(it++ == table_1);
321   EXPECT_TRUE(it++ == NULL);
322 
323   // We must be able to release TABLE into table cache and reuse it after
324   // this.
325   table_cache->release_table(thd, table_1);
326   table_2= table_cache->get_table(thd, hash_value,
327                                   share_1.table_cache_key.str,
328                                   share_1.table_cache_key.length,
329                                   &share_2);
330   EXPECT_TRUE(table_2 == table_1);
331   EXPECT_TRUE(share_2 == &share_1);
332 
333   table_cache->remove_table(table_1);
334 
335   // Once TABLE is removed from the cache the latter should become empty.
336   EXPECT_EQ(0U, table_cache->cached_tables());
337 
338   table_2= table_cache->get_table(thd, hash_value,
339                                   share_1.table_cache_key.str,
340                                   share_1.table_cache_key.length,
341                                   &share_2);
342   EXPECT_TRUE(table_2 == NULL);
343   EXPECT_TRUE(share_2 == NULL);
344 
345   it.rewind();
346   EXPECT_TRUE(it++ == NULL);
347 
348   // Also it should be possible to remove unused TABLE from the cache
349   // Add TABLE instance and mark it as unused
350   EXPECT_FALSE(table_cache->add_used_table(thd, table_1));
351   table_cache->release_table(thd, table_1);
352 
353   table_cache->remove_table(table_1);
354 
355   // Once TABLE is removed from cache the latter should become empty.
356   EXPECT_EQ(0U, table_cache->cached_tables());
357 
358   table_2= table_cache->get_table(thd, hash_value,
359                                   share_1.table_cache_key.str,
360                                   share_1.table_cache_key.length,
361                                   &share_2);
362   EXPECT_TRUE(table_2 == NULL);
363   EXPECT_TRUE(share_2 == NULL);
364 
365   table_cache->unlock();
366 
367   share_1.destroy_table(table_1);
368 }
369 
370 
371 /*
372   Now let us test how Table_cache handles overflows.
373 */
374 
TEST_F(TableCacheSingleCacheTest,CacheOverflow)375 TEST_F(TableCacheSingleCacheTest, CacheOverflow)
376 {
377   THD *thd= get_thd(0);
378 
379   // Set cache size low so it will overflow quickly.
380   table_cache_size_per_instance= 2;
381 
382   Mock_share share_1("share_1");
383   Mock_share share_2("share_2");
384   TABLE *table_1= share_1.create_table(thd);
385   TABLE *table_2= share_1.create_table(thd);
386   TABLE *table_3= share_2.create_table(thd);
387 
388   Table_cache *table_cache= table_cache_manager.get_cache(thd);
389 
390   table_cache->lock();
391   table_cache->add_used_table(thd, table_1);
392   table_cache->add_used_table(thd, table_2);
393 
394   // There should be two TABLE instances in the cache.
395   EXPECT_EQ(2U, table_cache->cached_tables());
396 
397   table_cache->release_table(thd, table_1);
398   table_cache->release_table(thd, table_2);
399 
400   // Still there should be two TABLE instances in the cache.
401   EXPECT_EQ(2U, table_cache->cached_tables());
402 
403   table_cache->add_used_table(thd, table_3);
404 
405   // One TABLE was added and one expelled (table_1), so still two TABLE objects.
406   EXPECT_EQ(2U, table_cache->cached_tables());
407 
408   // Old value of table_1 points to garbage thanks to expelling
409   table_1= share_1.create_table(thd);
410   table_cache->add_used_table(thd, table_1);
411 
412   // Still two TABLE instances (table_2 was expelled).
413   EXPECT_EQ(2U, table_cache->cached_tables());
414 
415   // Old value of table_2 points to garbage thanks to expelling
416   table_2= share_1.create_table(thd);
417   table_cache->add_used_table(thd, table_2);
418 
419   /*
420     Now we should have three TABLE instances in cache since all
421     of them are used.
422   */
423   EXPECT_EQ(3U, table_cache->cached_tables());
424 
425   table_cache->release_table(thd, table_2);
426 
427   // The first table that gets released is expelled.
428   EXPECT_EQ(2U, table_cache->cached_tables());
429 
430   table_cache->remove_table(table_1);
431   table_cache->remove_table(table_3);
432 
433   // Cache should be empty after that
434   EXPECT_EQ(0U, table_cache->cached_tables());
435 
436   table_cache->unlock();
437 
438   share_1.destroy_table(table_1);
439   share_1.destroy_table(table_3);
440 }
441 
442 
TEST_F(TableCacheSingleCacheTest,CacheGetAndRelease)443 TEST_F(TableCacheSingleCacheTest, CacheGetAndRelease)
444 {
445   THD *thd= get_thd(0);
446 
447   Table_cache *table_cache= table_cache_manager.get_cache(thd);
448 
449   table_cache->lock();
450 
451   TABLE *table_1, *table_2, *table_3;
452   Mock_share share_1("share_1"), share_0("share_0");
453   TABLE_SHARE *share_2;
454 
455   // There should be no TABLE in cache, nor information about share.
456   my_hash_value_type hash_value_1= my_calc_hash(&table_def_cache,
457                                      (uchar*)share_1.table_cache_key.str,
458                                      share_1.table_cache_key.length);
459   table_1= table_cache->get_table(thd, hash_value_1,
460                                   share_1.table_cache_key.str,
461                                   share_1.table_cache_key.length,
462                                   &share_2);
463   EXPECT_TRUE(table_1 == NULL);
464   EXPECT_TRUE(share_2 == NULL);
465 
466   table_1= share_1.create_table(thd);
467   table_cache->add_used_table(thd, table_1);
468 
469   // There should be no unused TABLE in cache, but there should be
470   // information about the share.
471   table_2= table_cache->get_table(thd, hash_value_1,
472                                   share_1.table_cache_key.str,
473                                   share_1.table_cache_key.length,
474                                   &share_2);
475   EXPECT_TRUE(table_2 == NULL);
476   EXPECT_TRUE(share_2 == &share_1);
477 
478   // There should be even no information about the share for which
479   // TABLE was not added to cache.
480   my_hash_value_type hash_value_0= my_calc_hash(&table_def_cache,
481                                      (uchar*)share_0.table_cache_key.str,
482                                      share_0.table_cache_key.length);
483   table_2= table_cache->get_table(thd, hash_value_0,
484                                   share_0.table_cache_key.str,
485                                   share_0.table_cache_key.length,
486                                   &share_2);
487   EXPECT_TRUE(table_2 == NULL);
488   EXPECT_TRUE(share_2 == NULL);
489 
490   table_2= share_1.create_table(thd);
491   table_cache->add_used_table(thd, table_2);
492 
493   // Still there should be no unused TABLE in cache, but there should
494   // be information about the share.
495   table_3= table_cache->get_table(thd, hash_value_1,
496                                   share_1.table_cache_key.str,
497                                   share_1.table_cache_key.length,
498                                   &share_2);
499   EXPECT_TRUE(table_3 == NULL);
500   EXPECT_TRUE(share_2 == &share_1);
501 
502   table_cache->release_table(thd, table_1);
503 
504   // After releasing one of TABLE objects it should be possible to get
505   // unused TABLE from cache.
506   table_3= table_cache->get_table(thd, hash_value_1,
507                                   share_1.table_cache_key.str,
508                                   share_1.table_cache_key.length,
509                                   &share_2);
510   EXPECT_TRUE(table_3 == table_1);
511   EXPECT_TRUE(share_2 == &share_1);
512 
513   // But only once!
514   table_3= table_cache->get_table(thd, hash_value_1,
515                                   share_1.table_cache_key.str,
516                                   share_1.table_cache_key.length,
517                                   &share_2);
518   EXPECT_TRUE(table_3 == NULL);
519   EXPECT_TRUE(share_2 == &share_1);
520 
521   // After releasing of both TABLE objects it should be possible to
522   // get two unused TABLE objects from cache (for 'share_1').
523   // There should be nothing for 'share_0'.
524   table_cache->release_table(thd, table_1);
525   table_cache->release_table(thd, table_2);
526 
527   table_3= table_cache->get_table(thd, hash_value_0,
528                                   share_0.table_cache_key.str,
529                                   share_0.table_cache_key.length,
530                                   &share_2);
531   EXPECT_TRUE(table_3 == NULL);
532   EXPECT_TRUE(share_2 == NULL);
533 
534 
535   table_3= table_cache->get_table(thd, hash_value_1,
536                                   share_1.table_cache_key.str,
537                                   share_1.table_cache_key.length,
538                                   &share_2);
539   EXPECT_TRUE(table_3 != NULL);
540   EXPECT_TRUE(share_2 == &share_1);
541   table_3= table_cache->get_table(thd, hash_value_1,
542                                   share_1.table_cache_key.str,
543                                   share_1.table_cache_key.length,
544                                   &share_2);
545   EXPECT_TRUE(table_3 != NULL);
546   EXPECT_TRUE(share_2 == &share_1);
547   table_3= table_cache->get_table(thd, hash_value_1,
548                                   share_1.table_cache_key.str,
549                                   share_1.table_cache_key.length,
550                                   &share_2);
551   EXPECT_TRUE(table_3 == NULL);
552   EXPECT_TRUE(share_2 == &share_1);
553 
554   // Clean-up
555   table_cache->remove_table(table_1);
556   table_cache->remove_table(table_2);
557 
558   share_1.destroy_table(table_1);
559   share_1.destroy_table(table_2);
560 
561   table_cache->unlock();
562 }
563 
564 
565 /*
566   Test for Table_cache_manager/Table_cache::free_all_unused_tables().
567 */
568 
TEST_F(TableCacheDoubleCacheTest,ManagerFreeAllUnused)569 TEST_F(TableCacheDoubleCacheTest, ManagerFreeAllUnused)
570 {
571   THD *thd_1= get_thd(0);
572   THD *thd_2= get_thd(1);
573 
574   Table_cache *table_cache_1= table_cache_manager.get_cache(thd_1);
575   Table_cache *table_cache_2= table_cache_manager.get_cache(thd_2);
576 
577   // There should be no TABLE instances in all cachea.
578   EXPECT_EQ(0U, table_cache_manager.cached_tables());
579 
580   Mock_share share_1("share_1");
581   Mock_share share_2("share_2");
582   Mock_share share_3("share_2");
583   TABLE *table_1= share_1.create_table(thd_1);
584   TABLE *table_2= share_1.create_table(thd_1);
585   TABLE *table_3= share_2.create_table(thd_1);
586   TABLE *table_4= share_2.create_table(thd_1);
587   TABLE *table_5= share_1.create_table(thd_2);
588   TABLE *table_6= share_3.create_table(thd_2);
589 
590   table_cache_manager.lock_all_and_tdc();
591 
592   table_cache_1->add_used_table(thd_1, table_1);
593   table_cache_1->add_used_table(thd_1, table_2);
594   table_cache_1->add_used_table(thd_1, table_3);
595   table_cache_1->add_used_table(thd_1, table_4);
596   table_cache_2->add_used_table(thd_2, table_5);
597   table_cache_2->add_used_table(thd_2, table_6);
598 
599   EXPECT_EQ(4U, table_cache_1->cached_tables());
600   EXPECT_EQ(2U, table_cache_2->cached_tables());
601   EXPECT_EQ(6U, table_cache_manager.cached_tables());
602 
603   table_cache_manager.free_all_unused_tables();
604 
605   // All TABLE instances should stay around in caches as
606   // all of them are used.
607   EXPECT_EQ(4U, table_cache_1->cached_tables());
608   EXPECT_EQ(2U, table_cache_2->cached_tables());
609   EXPECT_EQ(6U, table_cache_manager.cached_tables());
610 
611   table_cache_1->release_table(thd_1, table_1);
612 
613   table_cache_manager.free_all_unused_tables();
614 
615   // One table should be freed. So there should be 3 + 2 TABLE instances.
616   EXPECT_EQ(3U, table_cache_1->cached_tables());
617   EXPECT_EQ(2U, table_cache_2->cached_tables());
618   EXPECT_EQ(5U, table_cache_manager.cached_tables());
619 
620   table_cache_1->release_table(thd_1, table_2);
621   table_cache_1->release_table(thd_1, table_3);
622   table_cache_2->release_table(thd_2, table_5);
623 
624   table_cache_manager.free_all_unused_tables();
625 
626   // Now there should be 1 + 1 used TABLE instances left.
627   EXPECT_EQ(1U, table_cache_1->cached_tables());
628   EXPECT_EQ(1U, table_cache_2->cached_tables());
629   EXPECT_EQ(2U, table_cache_manager.cached_tables());
630 
631   table_cache_1->release_table(thd_1, table_4);
632 
633   table_cache_manager.free_all_unused_tables();
634 
635   // There should be 0 + 1 TABLE instances around.
636   EXPECT_EQ(0U, table_cache_1->cached_tables());
637   EXPECT_EQ(1U, table_cache_2->cached_tables());
638   EXPECT_EQ(1U, table_cache_manager.cached_tables());
639 
640   table_cache_2->release_table(thd_2, table_6);
641 
642   table_cache_manager.free_all_unused_tables();
643 
644   // All caches should become empty.
645   EXPECT_EQ(0U, table_cache_1->cached_tables());
646   EXPECT_EQ(0U, table_cache_2->cached_tables());
647   EXPECT_EQ(0U, table_cache_manager.cached_tables());
648 
649   table_cache_manager.unlock_all_and_tdc();
650 }
651 
652 
653 /*
654   Test for Table_cache_manager/Table_cache::cached_tables().
655 */
656 
TEST_F(TableCacheDoubleCacheTest,ManagerCachedTables)657 TEST_F(TableCacheDoubleCacheTest, ManagerCachedTables)
658 {
659   THD *thd_1= get_thd(0);
660   THD *thd_2= get_thd(1);
661 
662   Table_cache *table_cache_1= table_cache_manager.get_cache(thd_1);
663   Table_cache *table_cache_2= table_cache_manager.get_cache(thd_2);
664 
665   // There should be no TABLE instances in all cachea.
666   EXPECT_EQ(0U, table_cache_1->cached_tables());
667   EXPECT_EQ(0U, table_cache_2->cached_tables());
668   EXPECT_EQ(0U, table_cache_manager.cached_tables());
669 
670   Mock_share share_1("share_1");
671   Mock_share share_2("share_2");
672   TABLE *table_1= share_1.create_table(thd_1);
673   TABLE *table_2= share_1.create_table(thd_1);
674   TABLE *table_3= share_2.create_table(thd_1);
675   TABLE *table_4= share_1.create_table(thd_2);
676   TABLE *table_5= share_2.create_table(thd_2);
677 
678   table_cache_manager.lock_all_and_tdc();
679 
680   table_cache_1->add_used_table(thd_1, table_1);
681   table_cache_1->add_used_table(thd_1, table_2);
682   table_cache_1->add_used_table(thd_1, table_3);
683 
684   // There should be 3 + 0 TABLE objects in cache
685   EXPECT_EQ(3U, table_cache_1->cached_tables());
686   EXPECT_EQ(0U, table_cache_2->cached_tables());
687   EXPECT_EQ(3U, table_cache_manager.cached_tables());
688 
689   table_cache_2->add_used_table(thd_2, table_4);
690   table_cache_2->add_used_table(thd_2, table_5);
691 
692   // There should be 3 + 2 TABLE objects in cache
693   EXPECT_EQ(3U, table_cache_1->cached_tables());
694   EXPECT_EQ(2U, table_cache_2->cached_tables());
695   EXPECT_EQ(5U, table_cache_manager.cached_tables());
696 
697   table_cache_1->release_table(thd_1, table_1);
698   table_cache_2->release_table(thd_2, table_4);
699 
700   // There should be the same number of TABLE objects - 3 + 2
701   EXPECT_EQ(3U, table_cache_1->cached_tables());
702   EXPECT_EQ(2U, table_cache_2->cached_tables());
703   EXPECT_EQ(5U, table_cache_manager.cached_tables());
704 
705   table_cache_2->remove_table(table_5);
706 
707   // There should be 3 + 1 TABLE objects in cache
708   EXPECT_EQ(3U, table_cache_1->cached_tables());
709   EXPECT_EQ(1U, table_cache_2->cached_tables());
710   EXPECT_EQ(4U, table_cache_manager.cached_tables());
711 
712   table_cache_1->remove_table(table_1);
713   table_cache_2->remove_table(table_4);
714 
715   // There should be 2 + 0 TABLE objects in cache
716   EXPECT_EQ(2U, table_cache_1->cached_tables());
717   EXPECT_EQ(0U, table_cache_2->cached_tables());
718   EXPECT_EQ(2U, table_cache_manager.cached_tables());
719 
720   table_cache_1->remove_table(table_2);
721   table_cache_1->remove_table(table_3);
722 
723   // Caches should be empty
724   EXPECT_EQ(0U, table_cache_1->cached_tables());
725   EXPECT_EQ(0U, table_cache_2->cached_tables());
726   EXPECT_EQ(0U, table_cache_manager.cached_tables());
727 
728   table_cache_manager.unlock_all_and_tdc();
729 
730   share_1.destroy_table(table_1);
731   share_1.destroy_table(table_2);
732   share_2.destroy_table(table_3);
733   share_1.destroy_table(table_4);
734   share_2.destroy_table(table_5);
735 }
736 
737 
738 /*
739   Coverage for lock and unlock methods of Table_cache_manager class.
740 */
741 
TEST_F(TableCacheDoubleCacheDeathTest,ManagerLockAndUnlock)742 TEST_F(TableCacheDoubleCacheDeathTest, ManagerLockAndUnlock)
743 {
744   // Nor caches nor LOCK_open should not be locked after initialization
745 #ifdef SAFE_MUTEX
746   MY_EXPECT_DEATH_IF_SUPPORTED(table_cache_manager.assert_owner_all(),
747                             ".*Assertion.*count > 0.*pthread_equal.*");
748   MY_EXPECT_DEATH_IF_SUPPORTED(table_cache_manager.assert_owner_all_and_tdc(),
749                             ".*Assertion.*count > 0.*pthread_equal.*");
750 #endif
751 
752   // And get locked after we call its lock_all_and_tdc() method.
753   table_cache_manager.lock_all_and_tdc();
754   table_cache_manager.assert_owner_all();
755   table_cache_manager.assert_owner_all_and_tdc();
756 
757   // In addition to Table_cache_manager method we check this by
758   // calling Table_cache methods and asserting state of LOCK_open.
759   Table_cache *cache_1= table_cache_manager.get_cache(get_thd(0));
760   Table_cache *cache_2= table_cache_manager.get_cache(get_thd(1));
761 
762   cache_1->assert_owner();
763   cache_2->assert_owner();
764   mysql_mutex_assert_owner(&LOCK_open);
765 
766   // Locks should be unlocked after we call unlock method
767   table_cache_manager.unlock_all_and_tdc();
768 
769 #ifdef SAFE_MUTEX
770   MY_EXPECT_DEATH_IF_SUPPORTED(table_cache_manager.assert_owner_all(),
771                             ".*Assertion.*count > 0.*pthread_equal.*");
772   MY_EXPECT_DEATH_IF_SUPPORTED(table_cache_manager.assert_owner_all_and_tdc(),
773                             ".*Assertion.*count > 0.*pthread_equal.*");
774 #endif
775 }
776 
777 
778 /*
779   Coverage for Table_cache_manager::free_table();
780 */
781 
TEST_F(TableCacheDoubleCacheDeathTest,ManagerFreeTable)782 TEST_F(TableCacheDoubleCacheDeathTest, ManagerFreeTable)
783 {
784   THD *thd_1= get_thd(0);
785   THD *thd_2= get_thd(1);
786 
787   Table_cache *table_cache_1= table_cache_manager.get_cache(thd_1);
788   Table_cache *table_cache_2= table_cache_manager.get_cache(thd_2);
789 
790   Mock_share share_1("share_1");
791   Mock_share share_2("share_2");
792   TABLE *table_1= share_1.create_table(thd_1);
793   TABLE *table_2= share_1.create_table(thd_1);
794   TABLE *table_3= share_2.create_table(thd_1);
795   TABLE *table_4= share_1.create_table(thd_2);
796   TABLE *table_5= share_2.create_table(thd_2);
797 
798   table_cache_manager.lock_all_and_tdc();
799 
800   /*
801     Coverage for TDC_RT_REMOVE_ALL case.
802   */
803   table_cache_1->add_used_table(thd_1, table_1);
804   table_cache_1->add_used_table(thd_1, table_2);
805   table_cache_1->release_table(thd_1, table_2);
806   table_cache_1->add_used_table(thd_1, table_3);
807   table_cache_2->add_used_table(thd_2, table_4);
808   table_cache_2->add_used_table(thd_2, table_5);
809 
810   EXPECT_EQ(5U, table_cache_manager.cached_tables());
811 
812   // There should be assert failure since we are trying
813   // to free all tables for share_1, while some tables
814   // are in use.
815 #ifndef DBUG_OFF
816   MY_EXPECT_DEATH_IF_SUPPORTED(table_cache_manager.free_table(thd_1,
817                                                            TDC_RT_REMOVE_ALL,
818                                                            &share_1),
819                             ".*Assertion.*is_empty.*");
820 #endif
821 
822   table_cache_1->release_table(thd_1, table_1);
823   table_cache_2->release_table(thd_2, table_4);
824 
825   // After all tables for share_1 marked as unused freeing
826   // all tables should succeed.
827   table_cache_manager.free_table(thd_1, TDC_RT_REMOVE_ALL, &share_1);
828 
829   // We still should have 2 TABLE objects for share_2.
830   EXPECT_EQ(2U, table_cache_manager.cached_tables());
831 
832   /*
833     Coverage for TDC_RT_REMOVE_NOT_OWN case.
834   */
835   table_1= share_1.create_table(thd_1);
836   table_2= share_1.create_table(thd_1);
837   table_4= share_1.create_table(thd_2);
838 
839   table_cache_1->add_used_table(thd_1, table_1);
840   table_cache_1->add_used_table(thd_1, table_2);
841   table_cache_1->release_table(thd_1, table_2);
842   table_cache_2->add_used_table(thd_2, table_4);
843 
844   EXPECT_EQ(5U, table_cache_manager.cached_tables());
845 
846   // There should be assert failure since we are trying
847   // to free all not own TABLEs for share_1, while thd_2
848   // has a TABLE object for it in used
849 #ifndef DBUG_OFF
850   MY_EXPECT_DEATH_IF_SUPPORTED(table_cache_manager.free_table(thd_1,
851                                                            TDC_RT_REMOVE_NOT_OWN,
852                                                            &share_1),
853                             ".*Assertion.*0.*");
854 #endif
855 
856   table_cache_2->release_table(thd_2, table_4);
857 
858   // After TABLE owned by thd_2 is marked as unused, the below
859   // call should succeed.
860   table_cache_manager.free_table(thd_1, TDC_RT_REMOVE_NOT_OWN, &share_1);
861 
862   // We still have 1 TABLE object for share_1 in thd_1 and
863   // 2 TABLE objects for share_2.
864   EXPECT_EQ(3U, table_cache_manager.cached_tables());
865 
866   /*
867     Coverage for TDC_RT_REMOVE_UNUSED case.
868   */
869   table_2= share_1.create_table(thd_1);
870   table_4= share_1.create_table(thd_2);
871 
872   table_cache_1->add_used_table(thd_1, table_2);
873   table_cache_1->release_table(thd_1, table_2);
874   table_cache_2->add_used_table(thd_2, table_4);
875 
876   EXPECT_EQ(5U, table_cache_manager.cached_tables());
877 
878   table_cache_manager.free_table(thd_1, TDC_RT_REMOVE_UNUSED, &share_1);
879 
880   // The above call should have been freed only 1 table.
881   EXPECT_EQ(4U, table_cache_manager.cached_tables());
882 
883   // Mark all remaining TABLE objects for share_1 as unused
884   table_cache_1->release_table(thd_1, table_1);
885   table_cache_2->release_table(thd_2, table_4);
886 
887   table_cache_manager.free_table(thd_1, TDC_RT_REMOVE_UNUSED, &share_1);
888 
889   // The above call should free all unused TABLE objects for share_1.
890   // Therefore only 2 objects for share_2 should be remaining
891   EXPECT_EQ(2U, table_cache_manager.cached_tables());
892 
893   // Clean-up.
894   table_cache_1->remove_table(table_3);
895   table_cache_2->remove_table(table_5);
896 
897   share_2.destroy_table(table_3);
898   share_2.destroy_table(table_5);
899 
900   table_cache_manager.unlock_all_and_tdc();
901 }
902 
903 
904 /*
905   Coverage for Table_cache_iterator
906 */
907 
TEST_F(TableCacheDoubleCacheTest,Iterator)908 TEST_F(TableCacheDoubleCacheTest, Iterator)
909 {
910   THD *thd_1= get_thd(0);
911   THD *thd_2= get_thd(1);
912 
913   table_cache_manager.lock_all_and_tdc();
914 
915   Mock_share share_1("share_1");
916   Mock_share share_2("share_2");
917 
918   // There is no TABLE objects for share_1 so the below iterator
919   // should not find anything.
920   Table_cache_iterator it(&share_1);
921   EXPECT_TRUE(it++ == NULL);
922   // Attempt to iterate behind the end should not give anything.
923   EXPECT_TRUE(it++ == NULL);
924 
925   Table_cache *table_cache_1= table_cache_manager.get_cache(thd_1);
926   Table_cache *table_cache_2= table_cache_manager.get_cache(thd_2);
927   TABLE *table_1= share_1.create_table(thd_1);
928   TABLE *table_2= share_1.create_table(thd_1);
929   TABLE *table_3= share_2.create_table(thd_1);
930   TABLE *table_4= share_1.create_table(thd_2);
931   TABLE *table_5= share_2.create_table(thd_2);
932 
933   table_cache_2->add_used_table(thd_2, table_4);
934 
935   // Now the iterato should see table_4.
936   it.rewind();
937   TABLE *table_r1= it++;
938   EXPECT_TRUE(table_r1 == table_4);
939   // But only it.
940   EXPECT_TRUE(it++ == NULL);
941   EXPECT_TRUE(it++ == NULL);
942 
943   table_cache_1->add_used_table(thd_1, table_1);
944 
945   // Now we should see two tables:
946   it.rewind();
947   table_r1= it++;
948   EXPECT_TRUE(table_r1 != NULL);
949   TABLE *table_r2= it++;
950   EXPECT_TRUE(table_r2 != NULL);
951   EXPECT_TRUE(table_r1 != table_r2);
952   EXPECT_TRUE(it++ == NULL);
953   EXPECT_TRUE(it++ == NULL);
954 
955   table_cache_1->add_used_table(thd_1, table_2);
956 
957   // And now three !
958   it.rewind();
959   table_r1= it++;
960   EXPECT_TRUE(table_r1 != NULL);
961   table_r2= it++;
962   EXPECT_TRUE(table_r2 != NULL);
963   TABLE *table_r3= it++;
964   EXPECT_TRUE(table_r3 != NULL);
965   EXPECT_TRUE(table_r1 != table_r2 && table_r1 != table_r3 && table_r2 != table_r3);
966   EXPECT_TRUE(it++ == NULL);
967   EXPECT_TRUE(it++ == NULL);
968 
969   table_cache_1->release_table(thd_1, table_1);
970 
971   // We should be seeing only used TABLE objects, so two tables now
972   it.rewind();
973   table_r1= it++;
974   EXPECT_TRUE(table_r1 != NULL);
975   table_r2= it++;
976   EXPECT_TRUE(table_r2 != NULL);
977   EXPECT_TRUE(table_r1 != table_r2);
978   EXPECT_TRUE(it++ == NULL);
979   EXPECT_TRUE(it++ == NULL);
980 
981   table_cache_1->add_used_table(thd_1, table_3);
982   table_cache_2->add_used_table(thd_2, table_5);
983 
984   // We also should not be seeing TABLE objects for share_2
985   it.rewind();
986   table_r1= it++;
987   EXPECT_TRUE(table_r1 != NULL);
988   table_r2= it++;
989   EXPECT_TRUE(table_r2 != NULL);
990   EXPECT_TRUE(table_r1 != table_r2);
991   EXPECT_TRUE(it++ == NULL);
992   EXPECT_TRUE(it++ == NULL);
993 
994   table_cache_1->remove_table(table_2);
995 
996   // Now we should se only one used TABLE
997   it.rewind();
998   table_r1= it++;
999   EXPECT_TRUE(table_r1 == table_4);
1000   EXPECT_TRUE(it++ == NULL);
1001   EXPECT_TRUE(it++ == NULL);
1002 
1003   table_cache_1->remove_table(table_4);
1004 
1005   // And now no used TABLE objects for share_1 at all
1006   it.rewind();
1007   EXPECT_TRUE(it++ == NULL);
1008   EXPECT_TRUE(it++ == NULL);
1009 
1010   table_cache_1->remove_table(table_1);
1011 
1012   // Still the same
1013   it.rewind();
1014   EXPECT_TRUE(it++ == NULL);
1015   EXPECT_TRUE(it++ == NULL);
1016 
1017   table_cache_1->remove_table(table_3);
1018   table_cache_2->remove_table(table_5);
1019 
1020   // Cache is empty so iterator should not show any TABLE objects.
1021   it.rewind();
1022   EXPECT_TRUE(it++ == NULL);
1023   EXPECT_TRUE(it++ == NULL);
1024 
1025   table_cache_manager.unlock_all_and_tdc();
1026 
1027   share_1.destroy_table(table_1);
1028   share_1.destroy_table(table_2);
1029   share_2.destroy_table(table_3);
1030   share_1.destroy_table(table_4);
1031   share_2.destroy_table(table_5);
1032 }
1033 
1034 }
1035