LTP GCOV extension - code coverage report
Current view: directory - storage/maria/unittest - ma_pagecache_single.c
Test: mtr_and_unit.info
Date: 2009-03-05 Instrumented lines: 277
Code covered: 77.3 % Executed lines: 214

       1                 : /* Copyright (C) 2006-2008 MySQL AB
       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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
      15                 : 
      16                 : /*
      17                 :   TODO: use pthread_join instead of wait_for_thread_count_to_be_zero, like in
      18                 :   my_atomic-t.c (see BUG#22320).
      19                 :   Use diag() instead of fprintf(stderr).
      20                 : */
      21                 : #include <tap.h>
      22                 : #include <my_sys.h>
      23                 : #include <m_string.h>
      24                 : #include "test_file.h"
      25                 : #include <tap.h>
      26                 : 
      27                 : #define PCACHE_SIZE (TEST_PAGE_SIZE*1024*10)
      28                 : 
      29                 : #ifndef DBUG_OFF
      30                 : static const char* default_dbug_option;
      31                 : #endif
      32                 : 
      33                 : #ifndef BIG
      34                 : #undef SKIP_BIG_TESTS
      35                 : #define SKIP_BIG_TESTS(X) /* no-op */
      36                 : #endif
      37                 : 
      38                 : static char *file1_name= (char*)"page_cache_test_file_1";
      39                 : static char *file2_name= (char*)"page_cache_test_file_2";
      40                 : static PAGECACHE_FILE file1;
      41                 : static pthread_cond_t COND_thread_count;
      42                 : static pthread_mutex_t LOCK_thread_count;
      43                 : static uint thread_count;
      44                 : static PAGECACHE pagecache;
      45                 : 
      46                 : /*
      47                 :   File contance descriptors
      48                 : */
      49                 : static struct file_desc simple_read_write_test_file[]=
      50                 : {
      51                 :   { TEST_PAGE_SIZE, '\1'},
      52                 :   {0, 0}
      53                 : };
      54                 : static struct file_desc simple_read_change_write_read_test_file[]=
      55                 : {
      56                 :   { TEST_PAGE_SIZE/2, '\65'},
      57                 :   { TEST_PAGE_SIZE/2, '\1'},
      58                 :   {0, 0}
      59                 : };
      60                 : static struct file_desc simple_pin_test_file1[]=
      61                 : {
      62                 :   { TEST_PAGE_SIZE*2, '\1'},
      63                 :   {0, 0}
      64                 : };
      65                 : static struct file_desc simple_pin_test_file2[]=
      66                 : {
      67                 :   { TEST_PAGE_SIZE/2, '\1'},
      68                 :   { TEST_PAGE_SIZE/2, (unsigned char)129},
      69                 :   { TEST_PAGE_SIZE, '\1'},
      70                 :   {0, 0}
      71                 : };
      72                 : static struct file_desc simple_pin_no_lock_test_file1[]=
      73                 : {
      74                 :   { TEST_PAGE_SIZE, '\4'},
      75                 :   {0, 0}
      76                 : };
      77                 : static struct file_desc simple_pin_no_lock_test_file2[]=
      78                 : {
      79                 :   { TEST_PAGE_SIZE, '\5'},
      80                 :   {0, 0}
      81                 : };
      82                 : static struct file_desc simple_pin_no_lock_test_file3[]=
      83                 : {
      84                 :   { TEST_PAGE_SIZE, '\6'},
      85                 :   {0, 0}
      86                 : };
      87                 : static struct file_desc simple_delete_forget_test_file[]=
      88                 : {
      89                 :   { TEST_PAGE_SIZE, '\1'},
      90                 :   {0, 0}
      91                 : };
      92                 : static struct file_desc simple_delete_flush_test_file[]=
      93                 : {
      94                 :   { TEST_PAGE_SIZE, '\2'},
      95                 :   {0, 0}
      96                 : };
      97                 : 
      98                 : 
      99                 : /**
     100                 :   @brief Dummy pagecache callback.
     101                 : */
     102                 : 
     103                 : static my_bool
     104                 : dummy_callback(uchar *page __attribute__((unused)),
     105                 :                pgcache_page_no_t page_no __attribute__((unused)),
     106                 :                uchar* data_ptr __attribute__((unused)))
     107          134170 : {
     108          134170 :   return 0;
     109                 : }
     110                 : 
     111                 : 
     112                 : /**
     113                 :   @brief Dummy pagecache callback.
     114                 : */
     115                 : 
     116                 : static void
     117                 : dummy_fail_callback(uchar* data_ptr __attribute__((unused)))
     118               0 : {
     119                 :   return;
     120                 : }
     121                 : 
     122                 : 
     123                 : /*
     124                 :   Recreate and reopen a file for test
     125                 : 
     126                 :   SYNOPSIS
     127                 :     reset_file()
     128                 :     file                 File to reset
     129                 :     file_name            Path (and name) of file which should be reset
     130                 : */
     131                 : 
     132                 : void reset_file(PAGECACHE_FILE *file, const char *file_name)
     133              14 : {
     134              14 :   flush_pagecache_blocks(&pagecache, file, FLUSH_RELEASE);
     135              14 :   if (my_close(file->file, MYF(MY_WME)))
     136               0 :     exit(1);
     137              14 :   my_delete(file_name, MYF(MY_WME));
     138              14 :   if ((file->file= my_open(file_name,
     139                 :                            O_CREAT | O_TRUNC | O_RDWR, MYF(0))) == -1)
     140                 :   {
     141               0 :     diag("Got error during %s creation from open() (errno: %d)\n",
     142                 :          file_name, my_errno);
     143               0 :     exit(1);
     144                 :   }
     145                 : }
     146                 : 
     147                 : /*
     148                 :   Write then read page, check file on disk
     149                 : */
     150                 : 
     151                 : int simple_read_write_test()
     152               2 : {
     153               2 :   unsigned char *buffw= malloc(TEST_PAGE_SIZE);
     154               2 :   unsigned char *buffr= malloc(TEST_PAGE_SIZE);
     155                 :   int res;
     156               2 :   DBUG_ENTER("simple_read_write_test");
     157               2 :   bfill(buffw, TEST_PAGE_SIZE, '\1');
     158               2 :   pagecache_write(&pagecache, &file1, 0, 3, buffw,
     159                 :                   PAGECACHE_PLAIN_PAGE,
     160                 :                   PAGECACHE_LOCK_LEFT_UNLOCKED,
     161                 :                   PAGECACHE_PIN_LEFT_UNPINNED,
     162                 :                   PAGECACHE_WRITE_DELAY,
     163                 :                   0, LSN_IMPOSSIBLE);
     164               2 :   pagecache_read(&pagecache, &file1, 0, 3, buffr,
     165                 :                  PAGECACHE_PLAIN_PAGE,
     166                 :                  PAGECACHE_LOCK_LEFT_UNLOCKED,
     167                 :                  0);
     168               2 :   ok((res= test(memcmp(buffr, buffw, TEST_PAGE_SIZE) == 0)),
     169                 :      "Simple write-read page ");
     170               2 :   if (flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE))
     171                 :   {
     172               0 :     diag("Got error during flushing pagecache\n");
     173               0 :     exit(1);
     174                 :   }
     175               2 :   ok((res&= test(test_file(file1, file1_name, TEST_PAGE_SIZE, TEST_PAGE_SIZE,
     176                 :                            simple_read_write_test_file))),
     177                 :      "Simple write-read page file");
     178               2 :   if (res)
     179               2 :     reset_file(&file1, file1_name);
     180               2 :   free(buffw);
     181               2 :   free(buffr);
     182               2 :   DBUG_RETURN(res);
     183                 : }
     184                 : 
     185                 : 
     186                 : /*
     187                 :   Prepare page, then read (and lock), change (write new value and unlock),
     188                 :   then check the page in the cache and on the disk
     189                 : */
     190                 : int simple_read_change_write_read_test()
     191               2 : {
     192               2 :   unsigned char *buffw= malloc(TEST_PAGE_SIZE);
     193               2 :   unsigned char *buffr= malloc(TEST_PAGE_SIZE);
     194                 :   int res, res2;
     195               2 :   DBUG_ENTER("simple_read_change_write_read_test");
     196                 : 
     197                 :   /* prepare the file */
     198               2 :   bfill(buffw, TEST_PAGE_SIZE, '\1');
     199               2 :   pagecache_write(&pagecache, &file1, 0, 3, buffw,
     200                 :                   PAGECACHE_PLAIN_PAGE,
     201                 :                   PAGECACHE_LOCK_LEFT_UNLOCKED,
     202                 :                   PAGECACHE_PIN_LEFT_UNPINNED,
     203                 :                   PAGECACHE_WRITE_DELAY,
     204                 :                   0, LSN_IMPOSSIBLE);
     205               2 :   if (flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE))
     206                 :   {
     207               0 :     diag("Got error during flushing pagecache\n");
     208               0 :     exit(1);
     209                 :   }
     210                 :   /* test */
     211               2 :   pagecache_read(&pagecache, &file1, 0, 3, buffw,
     212                 :                  PAGECACHE_PLAIN_PAGE,
     213                 :                  PAGECACHE_LOCK_WRITE,
     214                 :                  0);
     215               2 :   bfill(buffw, TEST_PAGE_SIZE/2, '\65');
     216               2 :   pagecache_write(&pagecache, &file1, 0, 3, buffw,
     217                 :                   PAGECACHE_PLAIN_PAGE,
     218                 :                   PAGECACHE_LOCK_WRITE_UNLOCK,
     219                 :                   PAGECACHE_UNPIN,
     220                 :                   PAGECACHE_WRITE_DELAY,
     221                 :                   0, LSN_IMPOSSIBLE);
     222                 : 
     223               2 :   pagecache_read(&pagecache, &file1, 0, 3, buffr,
     224                 :                  PAGECACHE_PLAIN_PAGE,
     225                 :                  PAGECACHE_LOCK_LEFT_UNLOCKED,
     226                 :                  0);
     227               2 :   ok((res= test(memcmp(buffr, buffw, TEST_PAGE_SIZE) == 0)),
     228                 :      "Simple read-change-write-read page ");
     229               2 :   DBUG_ASSERT(pagecache.blocks_changed == 1);
     230               2 :   if (flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE))
     231                 :   {
     232               0 :     diag("Got error during flushing pagecache\n");
     233               0 :     exit(1);
     234                 :   }
     235               2 :   DBUG_ASSERT(pagecache.blocks_changed == 0);
     236               2 :   ok((res2= test(test_file(file1, file1_name, TEST_PAGE_SIZE, TEST_PAGE_SIZE,
     237                 :                            simple_read_change_write_read_test_file))),
     238                 :      "Simple read-change-write-read page file");
     239               2 :   if (res && res2)
     240               2 :     reset_file(&file1, file1_name);
     241               2 :   free(buffw);
     242               2 :   free(buffr);
     243               2 :   DBUG_RETURN(res && res2);
     244                 : }
     245                 : 
     246                 : 
     247                 : /*
     248                 :   Prepare page, read page 0 (and pin) then write page 1 and page 0.
     249                 :   Flush the file (shold flush only page 1 and return 1 (page 0 is
     250                 :   still pinned).
     251                 :   Check file on the disk.
     252                 :   Unpin and flush.
     253                 :   Check file on the disk.
     254                 : */
     255                 : int simple_pin_test()
     256               2 : {
     257               2 :   unsigned char *buffw= malloc(TEST_PAGE_SIZE);
     258                 :   int res;
     259               2 :   DBUG_ENTER("simple_pin_test");
     260                 :   /* prepare the file */
     261               2 :   bfill(buffw, TEST_PAGE_SIZE, '\1');
     262               2 :   pagecache_write(&pagecache, &file1, 0, 3, buffw,
     263                 :                   PAGECACHE_PLAIN_PAGE,
     264                 :                   PAGECACHE_LOCK_LEFT_UNLOCKED,
     265                 :                   PAGECACHE_PIN_LEFT_UNPINNED,
     266                 :                   PAGECACHE_WRITE_DELAY,
     267                 :                   0, LSN_IMPOSSIBLE);
     268                 :   /* test */
     269               2 :   if (flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE))
     270                 :   {
     271               0 :     diag("Got error during flushing pagecache\n");
     272               0 :     exit(1);
     273                 :   }
     274               2 :   pagecache_read(&pagecache, &file1, 0, 3, buffw,
     275                 :                  PAGECACHE_PLAIN_PAGE,
     276                 :                  PAGECACHE_LOCK_WRITE,
     277                 :                  0);
     278               2 :   pagecache_write(&pagecache, &file1, 1, 3, buffw,
     279                 :                   PAGECACHE_PLAIN_PAGE,
     280                 :                   PAGECACHE_LOCK_LEFT_UNLOCKED,
     281                 :                   PAGECACHE_PIN_LEFT_UNPINNED,
     282                 :                   PAGECACHE_WRITE_DELAY,
     283                 :                   0, LSN_IMPOSSIBLE);
     284               2 :   bfill(buffw + TEST_PAGE_SIZE/2, TEST_PAGE_SIZE/2, ((unsigned char) 129));
     285               2 :   pagecache_write(&pagecache, &file1, 0, 3, buffw,
     286                 :                   PAGECACHE_PLAIN_PAGE,
     287                 :                   PAGECACHE_LOCK_WRITE_TO_READ,
     288                 :                   PAGECACHE_PIN_LEFT_PINNED,
     289                 :                   PAGECACHE_WRITE_DELAY,
     290                 :                   0, LSN_IMPOSSIBLE);
     291                 :   /*
     292                 :     We have to get error because one page of the file is pinned,
     293                 :     other page should be flushed
     294                 :   */
     295               2 :   if (!flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE))
     296                 :   {
     297               0 :     diag("Did not get error in flush_pagecache_blocks\n");
     298               0 :     res= 0;
     299               0 :     goto err;
     300                 :   }
     301               2 :   ok((res= test(test_file(file1, file1_name, TEST_PAGE_SIZE*2, TEST_PAGE_SIZE*2,
     302                 :                            simple_pin_test_file1))),
     303                 :      "Simple pin page file with pin");
     304               2 :   pagecache_unlock(&pagecache,
     305                 :                    &file1,
     306                 :                    0,
     307                 :                    PAGECACHE_LOCK_READ_UNLOCK,
     308                 :                    PAGECACHE_UNPIN,
     309                 :                    0, 0, 0);
     310               2 :   if (flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE))
     311                 :   {
     312               0 :     diag("Got error in flush_pagecache_blocks\n");
     313               0 :     res= 0;
     314               0 :     goto err;
     315                 :   }
     316               2 :   ok((res&= test(test_file(file1, file1_name, TEST_PAGE_SIZE*2, TEST_PAGE_SIZE,
     317                 :                            simple_pin_test_file2))),
     318                 :      "Simple pin page result file");
     319               2 :   if (res)
     320               2 :     reset_file(&file1, file1_name);
     321               2 : err:
     322               2 :   free(buffw);
     323               2 :   DBUG_RETURN(res);
     324                 : }
     325                 : 
     326                 : /*
     327                 :   Checks pins without lock.
     328                 : */
     329                 : int simple_pin_no_lock_test()
     330               2 : {
     331               2 :   unsigned char *buffw= malloc(TEST_PAGE_SIZE);
     332                 :   PAGECACHE_BLOCK_LINK *link;
     333                 :   int res;
     334               2 :   DBUG_ENTER("simple_pin_no_lock_test");
     335                 :   /* prepare the file */
     336               2 :   bfill(buffw, TEST_PAGE_SIZE, '\4');
     337               2 :   pagecache_write(&pagecache, &file1, 0, 3, buffw,
     338                 :                   PAGECACHE_PLAIN_PAGE,
     339                 :                   PAGECACHE_LOCK_LEFT_UNLOCKED,
     340                 :                   PAGECACHE_PIN_LEFT_UNPINNED,
     341                 :                   PAGECACHE_WRITE_DELAY,
     342                 :                   0, LSN_IMPOSSIBLE);
     343                 :   /* test */
     344               2 :   if (flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE))
     345                 :   {
     346               0 :     diag("Got error during flushing pagecache 2\n");
     347               0 :     exit(1);
     348                 :   }
     349               2 :   bfill(buffw, TEST_PAGE_SIZE, '\5');
     350               2 :   pagecache_write(&pagecache, &file1, 0, 3, buffw,
     351                 :                   PAGECACHE_PLAIN_PAGE,
     352                 :                   PAGECACHE_LOCK_LEFT_UNLOCKED,
     353                 :                   PAGECACHE_PIN,
     354                 :                   PAGECACHE_WRITE_DELAY,
     355                 :                   0, LSN_IMPOSSIBLE);
     356                 :   /*
     357                 :     We have to get error because one page of the file is pinned,
     358                 :     other page should be flushed
     359                 :   */
     360               2 :   if (!flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE))
     361                 :   {
     362               0 :     diag("Did not get error in flush_pagecache_blocks 2\n");
     363               0 :     res= 0;
     364               0 :     goto err;
     365                 :   }
     366               2 :   ok((res= test(test_file(file1, file1_name, TEST_PAGE_SIZE, TEST_PAGE_SIZE,
     367                 :                            simple_pin_no_lock_test_file1))),
     368                 :      "Simple pin (no lock) page file with pin 2");
     369               2 :   pagecache_unlock(&pagecache,
     370                 :                    &file1,
     371                 :                    0,
     372                 :                    PAGECACHE_LOCK_LEFT_UNLOCKED,
     373                 :                    PAGECACHE_UNPIN,
     374                 :                    0, 0, 0);
     375               2 :   if (flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE))
     376                 :   {
     377               0 :     diag("Got error in flush_pagecache_blocks 2\n");
     378               0 :     res= 0;
     379               0 :     goto err;
     380                 :   }
     381               2 :   ok((res&= test(test_file(file1, file1_name, TEST_PAGE_SIZE, TEST_PAGE_SIZE,
     382                 :                            simple_pin_no_lock_test_file2))),
     383                 :      "Simple pin (no lock) page result file 2");
     384                 : 
     385               2 :   bfill(buffw, TEST_PAGE_SIZE, '\6');
     386               2 :   pagecache_write(&pagecache, &file1, 0, 3, buffw,
     387                 :                   PAGECACHE_PLAIN_PAGE,
     388                 :                   PAGECACHE_LOCK_WRITE,
     389                 :                   PAGECACHE_PIN,
     390                 :                   PAGECACHE_WRITE_DELAY,
     391                 :                   &link, LSN_IMPOSSIBLE);
     392               2 :   pagecache_unlock_by_link(&pagecache, link,
     393                 :                            PAGECACHE_LOCK_WRITE_UNLOCK,
     394                 :                            PAGECACHE_PIN_LEFT_PINNED, 0, 0, 1, FALSE);
     395               2 :   if (!flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE))
     396                 :   {
     397               0 :     diag("Did not get error in flush_pagecache_blocks 3\n");
     398               0 :     res= 0;
     399               0 :     goto err;
     400                 :   }
     401               2 :   ok((res= test(test_file(file1, file1_name, TEST_PAGE_SIZE, TEST_PAGE_SIZE,
     402                 :                            simple_pin_no_lock_test_file2))),
     403                 :      "Simple pin (no lock) page file with pin 3");
     404               2 :   pagecache_unpin_by_link(&pagecache, link, 0);
     405               2 :   if (flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE))
     406                 :   {
     407               0 :     diag("Got error in flush_pagecache_blocks 3\n");
     408               0 :     res= 0;
     409               0 :     goto err;
     410                 :   }
     411               2 :   ok((res&= test(test_file(file1, file1_name, TEST_PAGE_SIZE, TEST_PAGE_SIZE,
     412                 :                            simple_pin_no_lock_test_file3))),
     413                 :      "Simple pin (no lock) page result file 3");
     414               2 :   if (res)
     415               2 :     reset_file(&file1, file1_name);
     416               2 : err:
     417               2 :   free(buffw);
     418               2 :   DBUG_RETURN(res);
     419                 : }
     420                 : /*
     421                 :   Prepare page, write new value, then delete page from cache without flush,
     422                 :   on the disk should be page with old content written during preparation
     423                 : */
     424                 : 
     425                 : int simple_delete_forget_test()
     426               2 : {
     427               2 :   unsigned char *buffw= malloc(TEST_PAGE_SIZE);
     428               2 :   unsigned char *buffr= malloc(TEST_PAGE_SIZE);
     429                 :   int res;
     430               2 :   DBUG_ENTER("simple_delete_forget_test");
     431                 :   /* prepare the file */
     432               2 :   bfill(buffw, TEST_PAGE_SIZE, '\1');
     433               2 :   pagecache_write(&pagecache, &file1, 0, 3, buffw,
     434                 :                   PAGECACHE_PLAIN_PAGE,
     435                 :                   PAGECACHE_LOCK_LEFT_UNLOCKED,
     436                 :                   PAGECACHE_PIN_LEFT_UNPINNED,
     437                 :                   PAGECACHE_WRITE_DELAY,
     438                 :                   0, LSN_IMPOSSIBLE);
     439               2 :   flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE);
     440                 :   /* test */
     441               2 :   bfill(buffw, TEST_PAGE_SIZE, '\2');
     442               2 :   pagecache_write(&pagecache, &file1, 0, 3, buffw,
     443                 :                   PAGECACHE_PLAIN_PAGE,
     444                 :                   PAGECACHE_LOCK_LEFT_UNLOCKED,
     445                 :                   PAGECACHE_PIN_LEFT_UNPINNED,
     446                 :                   PAGECACHE_WRITE_DELAY,
     447                 :                   0, LSN_IMPOSSIBLE);
     448               2 :   pagecache_delete(&pagecache, &file1, 0,
     449                 :                    PAGECACHE_LOCK_WRITE, 0);
     450               2 :   flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE);
     451               2 :   ok((res= test(test_file(file1, file1_name, TEST_PAGE_SIZE, TEST_PAGE_SIZE,
     452                 :                           simple_delete_forget_test_file))),
     453                 :      "Simple delete-forget page file");
     454               2 :   if (res)
     455               2 :     reset_file(&file1, file1_name);
     456               2 :   free(buffw);
     457               2 :   free(buffr);
     458               2 :   DBUG_RETURN(res);
     459                 : }
     460                 : 
     461                 : /*
     462                 :   Prepare page with locking, write new content to the page,
     463                 :   delete page with flush and on existing lock,
     464                 :   check that page on disk contain new value.
     465                 : */
     466                 : 
     467                 : int simple_delete_flush_test()
     468               2 : {
     469               2 :   unsigned char *buffw= malloc(TEST_PAGE_SIZE);
     470               2 :   unsigned char *buffr= malloc(TEST_PAGE_SIZE);
     471                 :   PAGECACHE_BLOCK_LINK *link;
     472                 :   int res;
     473               2 :   DBUG_ENTER("simple_delete_flush_test");
     474                 :   /* prepare the file */
     475               2 :   bfill(buffw, TEST_PAGE_SIZE, '\1');
     476               2 :   pagecache_write(&pagecache, &file1, 0, 3, buffw,
     477                 :                   PAGECACHE_PLAIN_PAGE,
     478                 :                   PAGECACHE_LOCK_WRITE,
     479                 :                   PAGECACHE_PIN,
     480                 :                   PAGECACHE_WRITE_DELAY,
     481                 :                   &link, LSN_IMPOSSIBLE);
     482               2 :   flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE);
     483                 :   /* test */
     484               2 :   bfill(buffw, TEST_PAGE_SIZE, '\2');
     485               2 :   pagecache_write(&pagecache, &file1, 0, 3, buffw,
     486                 :                   PAGECACHE_PLAIN_PAGE,
     487                 :                   PAGECACHE_LOCK_LEFT_WRITELOCKED,
     488                 :                   PAGECACHE_PIN_LEFT_PINNED,
     489                 :                   PAGECACHE_WRITE_DELAY,
     490                 :                   0, LSN_IMPOSSIBLE);
     491               2 :   if (pagecache_delete_by_link(&pagecache, link,
     492                 :                                PAGECACHE_LOCK_LEFT_WRITELOCKED, 1))
     493                 :   {
     494               0 :     diag("simple_delete_flush_test: error during delete");
     495               0 :     exit(1);
     496                 :   }
     497               2 :   flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE);
     498               2 :   ok((res= test(test_file(file1, file1_name, TEST_PAGE_SIZE, TEST_PAGE_SIZE,
     499                 :                           simple_delete_flush_test_file))),
     500                 :      "Simple delete flush (link) page file");
     501               2 :   if (res)
     502               2 :     reset_file(&file1, file1_name);
     503               2 :   free(buffw);
     504               2 :   free(buffr);
     505               2 :   DBUG_RETURN(res);
     506                 : }
     507                 : 
     508                 : 
     509                 : /*
     510                 :   write then read file bigger then cache
     511                 : */
     512                 : 
     513                 : int simple_big_test()
     514               2 : {
     515               2 :   unsigned char *buffw= (unsigned char *) my_malloc(TEST_PAGE_SIZE, MYF(MY_WME));
     516               2 :   unsigned char *buffr= (unsigned char *) my_malloc(TEST_PAGE_SIZE, MYF(MY_WME));
     517                 :   struct file_desc *desc= ((struct file_desc *)
     518               2 :                            my_malloc((PCACHE_SIZE/(TEST_PAGE_SIZE/2) + 1) *
     519                 :                                      sizeof(struct file_desc), MYF(MY_WME)));
     520                 :   int res, i;
     521               2 :   DBUG_ENTER("simple_big_test");
     522                 : 
     523                 :   /* prepare the file twice larger then cache */
     524           40962 :   for (i= 0; i < PCACHE_SIZE/(TEST_PAGE_SIZE/2); i++)
     525                 :   {
     526           40960 :     bfill(buffw, TEST_PAGE_SIZE, (unsigned char) (i & 0xff));
     527           40960 :     desc[i].length= TEST_PAGE_SIZE;
     528           40960 :     desc[i].content= (i & 0xff);
     529           40960 :     pagecache_write(&pagecache, &file1, i, 3, buffw,
     530                 :                     PAGECACHE_PLAIN_PAGE,
     531                 :                     PAGECACHE_LOCK_LEFT_UNLOCKED,
     532                 :                     PAGECACHE_PIN_LEFT_UNPINNED,
     533                 :                     PAGECACHE_WRITE_DELAY,
     534                 :                     0, LSN_IMPOSSIBLE);
     535                 :   }
     536               2 :   desc[i].length= 0;
     537               2 :   desc[i].content= '\0';
     538               2 :   ok(1, "Simple big file write");
     539                 :   /* check written pages sequentally read */
     540           40962 :   for (i= 0; i < PCACHE_SIZE/(TEST_PAGE_SIZE/2); i++)
     541                 :   {
     542                 :     int j;
     543           40960 :     pagecache_read(&pagecache, &file1, i, 3, buffr,
     544                 :                    PAGECACHE_PLAIN_PAGE,
     545                 :                    PAGECACHE_LOCK_LEFT_UNLOCKED,
     546                 :                    0);
     547       188784640 :     for(j= 0; j < TEST_PAGE_SIZE; j++)
     548                 :     {
     549       188743680 :       if (buffr[j] != (i & 0xff))
     550                 :       {
     551               0 :         diag("simple_big_test seq: page %u byte %u mismatch\n", i, j);
     552               0 :         res= 0;
     553               0 :         goto err;
     554                 :       }
     555                 :     }
     556                 :   }
     557               2 :   ok(1, "Simple big file sequential read");
     558                 :   /* chack random reads */
     559           20482 :   for (i= 0; i < PCACHE_SIZE/(TEST_PAGE_SIZE); i++)
     560                 :   {
     561                 :     int j, page;
     562           20480 :     page= rand() % (PCACHE_SIZE/(TEST_PAGE_SIZE/2));
     563           20480 :     pagecache_read(&pagecache, &file1, page, 3, buffr,
     564                 :                    PAGECACHE_PLAIN_PAGE,
     565                 :                    PAGECACHE_LOCK_LEFT_UNLOCKED,
     566                 :                    0);
     567        94392320 :     for(j= 0; j < TEST_PAGE_SIZE; j++)
     568                 :     {
     569        94371840 :       if (buffr[j] != (page & 0xff))
     570                 :       {
     571               0 :         diag("simple_big_test rnd: page %u byte %u mismatch\n", page, j);
     572               0 :         res= 0;
     573               0 :         goto err;
     574                 :       }
     575                 :     }
     576                 :   }
     577               2 :   ok(1, "Simple big file random read");
     578               2 :   flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE);
     579                 : 
     580               2 :   ok((res= test(test_file(file1, file1_name, PCACHE_SIZE*2, TEST_PAGE_SIZE,
     581                 :                           desc))),
     582                 :      "Simple big file");
     583               2 :   if (res)
     584               2 :     reset_file(&file1, file1_name);
     585                 : 
     586               2 : err:
     587               2 :   my_free(buffw, 0);
     588               2 :   my_free(buffr, 0);
     589               2 :   my_free(desc, 0);
     590               2 :   DBUG_RETURN(res);
     591                 : }
     592                 : 
     593                 : 
     594                 : /*
     595                 :   Thread function
     596                 : */
     597                 : 
     598                 : static void *test_thread(void *arg)
     599               2 : {
     600                 : #ifndef DBUG_OFF
     601               2 :   int param= *((int*) arg);
     602                 : #endif
     603                 : 
     604               2 :   my_thread_init();
     605                 :   {
     606               2 :   DBUG_ENTER("test_thread");
     607               2 :   DBUG_PRINT("enter", ("param: %d", param));
     608                 : 
     609               2 :   if (!simple_read_write_test() ||
     610                 :       !simple_read_change_write_read_test() ||
     611                 :       !simple_pin_test() ||
     612                 :       !simple_pin_no_lock_test() ||
     613                 :       !simple_delete_forget_test() ||
     614                 :       !simple_delete_flush_test())
     615               0 :     exit(1);
     616                 : 
     617               0 :   SKIP_BIG_TESTS(4)
     618                 :   {
     619               2 :     if (!simple_big_test())
     620               0 :       exit(1);
     621                 :   }
     622                 : 
     623               2 :   DBUG_PRINT("info", ("Thread %s ended\n", my_thread_name()));
     624               2 :   pthread_mutex_lock(&LOCK_thread_count);
     625               2 :   thread_count--;
     626               2 :   VOID(pthread_cond_signal(&COND_thread_count)); /* Tell main we are ready */
     627               2 :   pthread_mutex_unlock(&LOCK_thread_count);
     628               2 :   free((uchar*) arg);
     629               2 :   my_thread_end();
     630               2 :   DBUG_RETURN(0);
     631                 :   }
     632                 : }
     633                 : 
     634                 : 
     635                 : int main(int argc __attribute__((unused)),
     636                 :          char **argv __attribute__((unused)))
     637               3 : {
     638                 :   pthread_t tid;
     639                 :   pthread_attr_t thr_attr;
     640                 :   int *param, error, pagen;
     641                 :   File tmp_file;
     642               3 :   MY_INIT(argv[0]);
     643                 : 
     644                 : #ifndef DBUG_OFF
     645                 : #if defined(__WIN__)
     646                 :   default_dbug_option= "d:t:i:O,\\test_pagecache_single.trace";
     647                 : #else
     648               3 :   default_dbug_option= "d:t:i:o,/tmp/test_pagecache_single.trace";
     649                 : #endif
     650               3 :   if (argc > 1)
     651                 :   {
     652               0 :     DBUG_SET(default_dbug_option);
     653               0 :     DBUG_SET_INITIAL(default_dbug_option);
     654                 :   }
     655                 : #endif
     656                 :   {
     657               3 :   DBUG_ENTER("main");
     658               3 :   DBUG_PRINT("info", ("Main thread: %s\n", my_thread_name()));
     659                 : 
     660               3 :   plan(16);
     661               1 :   SKIP_BIG_TESTS(16)
     662                 :   {
     663                 : 
     664               2 :   if ((tmp_file= my_open(file2_name, O_CREAT | O_TRUNC | O_RDWR,
     665                 :                          MYF(MY_WME))) < 0)
     666               0 :     exit(1);
     667                 : 
     668               2 :   if ((file1.file= my_open(file1_name,
     669                 :                            O_CREAT | O_TRUNC | O_RDWR, MYF(0))) == -1)
     670                 :   {
     671               0 :     fprintf(stderr, "Got error during file1 creation from open() (errno: %d)\n",
     672                 :             errno);
     673               0 :     exit(1);
     674                 :   }
     675               2 :   pagecache_file_init(file1, &dummy_callback, &dummy_callback,
     676                 :                       &dummy_fail_callback, &dummy_callback, NULL);
     677               2 :   my_close(tmp_file, MYF(0));
     678               2 :   my_delete(file2_name, MYF(0));
     679                 : 
     680               2 :   DBUG_PRINT("info", ("file1: %d", file1.file));
     681               2 :   if (my_chmod(file1_name, S_IRWXU | S_IRWXG | S_IRWXO, MYF(MY_WME)))
     682               0 :     exit(1);
     683               2 :   my_pwrite(file1.file, (const uchar*)"test file", 9, 0, MYF(MY_WME));
     684                 : 
     685               2 :   if ((error= pthread_cond_init(&COND_thread_count, NULL)))
     686                 :   {
     687               0 :     fprintf(stderr, "Got error: %d from pthread_cond_init (errno: %d)\n",
     688                 :             error, errno);
     689               0 :     exit(1);
     690                 :   }
     691               2 :   if ((error= pthread_mutex_init(&LOCK_thread_count, MY_MUTEX_INIT_FAST)))
     692                 :   {
     693               0 :     fprintf(stderr, "Got error: %d from pthread_cond_init (errno: %d)\n",
     694                 :             error, errno);
     695               0 :     exit(1);
     696                 :   }
     697                 : 
     698               2 :   if ((error= pthread_attr_init(&thr_attr)))
     699                 :   {
     700               0 :     fprintf(stderr,"Got error: %d from pthread_attr_init (errno: %d)\n",
     701                 :             error,errno);
     702               0 :     exit(1);
     703                 :   }
     704               2 :   if ((error= pthread_attr_setdetachstate(&thr_attr, PTHREAD_CREATE_DETACHED)))
     705                 :   {
     706               0 :     fprintf(stderr,
     707                 :             "Got error: %d from pthread_attr_setdetachstate (errno: %d)\n",
     708                 :             error,errno);
     709               0 :     exit(1);
     710                 :   }
     711                 : 
     712                 : #ifdef HAVE_THR_SETCONCURRENCY
     713                 :   VOID(thr_setconcurrency(2));
     714                 : #endif
     715                 : 
     716               2 :   if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
     717                 :                              TEST_PAGE_SIZE, MYF(MY_WME))) == 0)
     718                 :   {
     719               0 :     fprintf(stderr,"Got error: init_pagecache() (errno: %d)\n",
     720                 :             errno);
     721               0 :     exit(1);
     722                 :   }
     723               2 :   DBUG_PRINT("info", ("Page cache %d pages", pagen));
     724                 : 
     725               2 :   pthread_mutex_lock(&LOCK_thread_count);
     726               2 :   param=(int*) malloc(sizeof(int));
     727               2 :   *param= 1;
     728               2 :   if ((error= pthread_create(&tid, &thr_attr, test_thread, (void*) param)))
     729                 :   {
     730               0 :     fprintf(stderr,"Got error: %d from pthread_create (errno: %d)\n",
     731                 :             error,errno);
     732               0 :     exit(1);
     733                 :   }
     734               2 :   thread_count++;
     735               2 :   DBUG_PRINT("info", ("Thread started"));
     736               2 :   pthread_mutex_unlock(&LOCK_thread_count);
     737                 : 
     738               2 :   pthread_attr_destroy(&thr_attr);
     739                 : 
     740               2 :   pthread_mutex_lock(&LOCK_thread_count);
     741               6 :   while (thread_count)
     742                 :   {
     743               2 :     if ((error= pthread_cond_wait(&COND_thread_count,&LOCK_thread_count)))
     744               0 :       fprintf(stderr,"Got error: %d from pthread_cond_wait\n",error);
     745                 :   }
     746               2 :   pthread_mutex_unlock(&LOCK_thread_count);
     747               2 :   DBUG_PRINT("info", ("thread ended"));
     748                 : 
     749               2 :   end_pagecache(&pagecache, 1);
     750               2 :   DBUG_PRINT("info", ("Page cache ended"));
     751                 : 
     752               2 :   if (my_close(file1.file, MYF(MY_WME)))
     753               0 :     exit(1);
     754                 : 
     755               2 :   my_delete(file1_name, MYF(0));
     756                 : 
     757                 :   } /* SKIP_BIG_TESTS */
     758               3 :   DBUG_PRINT("info", ("file1 (%d) closed", file1.file));
     759               3 :   DBUG_PRINT("info", ("Program end"));
     760                 : 
     761               3 :   my_end(0);
     762                 : 
     763                 :   }
     764               3 :   return exit_status();
     765                 : }

Generated by: LTP GCOV extension version 1.4