LTP GCOV extension - code coverage report
Current view: directory - storage/maria/unittest - ma_control_file-t.c
Test: maria-unit-test.html
Date: 2009-03-04 Instrumented lines: 217
Code covered: 92.2 % Executed lines: 200

       1                 : /* Copyright (C) 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult 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                 : /* Unit test of the control file module of the Maria engine WL#3234 */
      17                 : 
      18                 : /*
      19                 :   Note that it is not possible to test the durability of the write (can't
      20                 :   pull the plug programmatically :)
      21                 : */
      22                 : 
      23                 : #include <my_global.h>
      24                 : #include <my_sys.h>
      25                 : #include <tap.h>
      26                 : 
      27                 : #ifndef WITH_MARIA_STORAGE_ENGINE
      28                 : /*
      29                 :   If Maria is not compiled in, normally we don't come to building this test.
      30                 : */
      31                 : #error "Maria engine is not compiled in, test cannot be built"
      32                 : #endif
      33                 : 
      34                 : #include "maria.h"
      35                 : #include "../../../storage/maria/maria_def.h"
      36                 : #include <my_getopt.h>
      37                 : 
      38                 : #define EXTRACT_DEFINITIONS
      39                 : #include "../ma_control_file.c"
      40                 : #undef EXTRACT_DEFINITIONS
      41                 : 
      42                 : char file_name[FN_REFLEN];
      43                 : 
      44                 : /* The values we'll set and expect the control file module to return */
      45                 : LSN    expect_checkpoint_lsn;
      46                 : uint32 expect_logno;
      47                 : TrID   expect_max_trid;
      48                 : uint8  expect_recovery_failures;
      49                 : 
      50                 : static int delete_file(myf my_flags);
      51                 : /*
      52                 :   Those are test-specific wrappers around the module's API functions: after
      53                 :   calling the module's API functions they perform checks on the result.
      54                 : */
      55                 : static int close_file(void); /* wraps ma_control_file_end */
      56                 : /* wraps ma_control_file_open_or_create */
      57                 : static int open_file(void);
      58                 : /* wraps ma_control_file_write_and_force */
      59                 : static int write_file(LSN checkpoint_lsn, uint32 logno, TrID trid,
      60                 :                       uint8 rec_failures);
      61                 : 
      62                 : /* Tests */
      63                 : static int test_one_log_and_recovery_failures(void);
      64                 : static int test_five_logs_and_max_trid(void);
      65                 : static int test_3_checkpoints_and_2_logs(void);
      66                 : static int test_binary_content(void);
      67                 : static int test_start_stop(void);
      68                 : static int test_2_open_and_2_close(void);
      69                 : static int test_bad_magic_string(void);
      70                 : static int test_bad_checksum(void);
      71                 : static int test_bad_hchecksum(void);
      72                 : static int test_future_size(void);
      73                 : static int test_bad_blocksize(void);
      74                 : static int test_bad_size(void);
      75                 : 
      76                 : /* Utility */
      77                 : static int verify_module_values_match_expected(void);
      78                 : static int verify_module_values_are_impossible(void);
      79                 : static void usage(void);
      80                 : static void get_options(int argc, char *argv[]);
      81                 : 
      82                 : /*
      83                 :   If "expr" is FALSE, this macro will make the function print a diagnostic
      84                 :   message and immediately return 1.
      85                 :   This is inspired from assert() but does not crash the binary (sometimes we
      86                 :   may want to see how other tests go even if one fails).
      87                 :   RET_ERR means "return error".
      88                 : */
      89                 : 
      90                 : #define RET_ERR_UNLESS(expr) \
      91                 :   {if (!(expr)) {diag("line %d: failure: '%s'", __LINE__, #expr); assert(0);return 1;}}
      92                 : 
      93                 : 
      94                 : /* Used to ignore error messages from ma_control_file_open() */
      95                 : 
      96                 : static int my_ignore_message(uint error __attribute__((unused)),
      97                 :                              const char *str __attribute__((unused)),
      98                 :                              myf MyFlags __attribute__((unused)))
      99               6 : {
     100               6 :   DBUG_ENTER("my_message_no_curses");
     101               6 :   DBUG_PRINT("enter",("message: %s",str));
     102               6 :   DBUG_RETURN(0);
     103                 : }
     104                 : 
     105                 : int (*default_error_handler_hook)(uint my_err, const char *str,
     106                 :                                   myf MyFlags) = 0;
     107                 : 
     108                 : 
     109                 : /* like ma_control_file_open(), but without error messages */
     110                 : 
     111                 : static CONTROL_FILE_ERROR local_ma_control_file_open(void)
     112              22 : {
     113                 :   CONTROL_FILE_ERROR error;
     114              22 :   error_handler_hook= my_ignore_message;
     115              22 :   error= ma_control_file_open(TRUE, TRUE);
     116              22 :   error_handler_hook= default_error_handler_hook;
     117              22 :   return error;
     118                 : }
     119                 : 
     120                 : 
     121                 : 
     122                 : int main(int argc,char *argv[])
     123               1 : {
     124               1 :   MY_INIT(argv[0]);
     125               1 :   my_init();
     126                 : 
     127               1 :   maria_data_root= (char *)".";
     128               1 :   default_error_handler_hook= error_handler_hook;
     129                 : 
     130               1 :   plan(12);
     131                 : 
     132               1 :   diag("Unit tests for control file");
     133                 : 
     134               1 :   get_options(argc,argv);
     135                 : 
     136               1 :   diag("Deleting control file at startup, if there is an old one");
     137               1 :   RET_ERR_UNLESS(0 == delete_file(0)); /* if fails, can't continue */
     138                 : 
     139               1 :   diag("Tests of normal conditions");
     140               1 :   ok(0 == test_one_log_and_recovery_failures(),
     141                 :      "test of creating one log and recording recovery failures");
     142               1 :   ok(0 == test_five_logs_and_max_trid(),
     143                 :      "test of creating five logs and many transactions");
     144               1 :   ok(0 == test_3_checkpoints_and_2_logs(),
     145                 :      "test of creating three checkpoints and two logs");
     146               1 :   ok(0 == test_binary_content(), "test of the binary content of the file");
     147               1 :   ok(0 == test_start_stop(), "test of multiple starts and stops");
     148               1 :   diag("Tests of abnormal conditions");
     149               1 :   ok(0 == test_2_open_and_2_close(),
     150                 :      "test of two open and two close (strange call sequence)");
     151               1 :   ok(0 == test_bad_magic_string(), "test of bad magic string");
     152               1 :   ok(0 == test_bad_checksum(), "test of bad checksum");
     153               1 :   ok(0 == test_bad_hchecksum(), "test of bad hchecksum");
     154               1 :   ok(0 == test_future_size(), "test of ability to handlr future versions");
     155               1 :   ok(0 == test_bad_blocksize(), "test of bad blocksize");
     156               1 :   ok(0 == test_bad_size(), "test of too small/big file");
     157                 : 
     158               1 :   return exit_status();
     159                 : }
     160                 : 
     161                 : 
     162                 : static int delete_file(myf my_flags)
     163               3 : {
     164               3 :   RET_ERR_UNLESS(fn_format(file_name, CONTROL_FILE_BASE_NAME,
     165                 :                            maria_data_root, "", MYF(MY_WME)) != NullS);
     166                 :   /*
     167                 :     Maybe file does not exist, ignore error.
     168                 :     The error will however be printed on stderr.
     169                 :   */
     170               3 :   my_delete(file_name, my_flags);
     171               3 :   expect_checkpoint_lsn= LSN_IMPOSSIBLE;
     172               3 :   expect_logno= FILENO_IMPOSSIBLE;
     173               3 :   expect_max_trid= expect_recovery_failures= 0;
     174                 : 
     175               3 :   return 0;
     176                 : }
     177                 : 
     178                 : /*
     179                 :   Verifies that global values last_checkpoint_lsn, last_logno,
     180                 :   max_trid_in_control_file (belonging to the module) match what we expect.
     181                 : */
     182                 : static int verify_module_values_match_expected(void)
     183              28 : {
     184              28 :   RET_ERR_UNLESS(last_logno == expect_logno);
     185              28 :   RET_ERR_UNLESS(last_checkpoint_lsn == expect_checkpoint_lsn);
     186              28 :   RET_ERR_UNLESS(max_trid_in_control_file == expect_max_trid);
     187              28 :   RET_ERR_UNLESS(recovery_failures == expect_recovery_failures);
     188              28 :   return 0;
     189                 : }
     190                 : 
     191                 : 
     192                 : /*
     193                 :   Verifies that global values last_checkpoint_lsn and last_logno (belonging
     194                 :   to the module) are impossible (this is used when the file has been closed).
     195                 : */
     196                 : static int verify_module_values_are_impossible(void)
     197              16 : {
     198              16 :   RET_ERR_UNLESS(last_logno == FILENO_IMPOSSIBLE);
     199              16 :   RET_ERR_UNLESS(last_checkpoint_lsn == LSN_IMPOSSIBLE);
     200              16 :   RET_ERR_UNLESS(max_trid_in_control_file == 0);
     201              16 :   return 0;
     202                 : }
     203                 : 
     204                 : 
     205                 : static int close_file(void)
     206              16 : {
     207                 :   /* Simulate shutdown */
     208              16 :   ma_control_file_end();
     209                 :   /* Verify amnesia */
     210              16 :   RET_ERR_UNLESS(verify_module_values_are_impossible() == 0);
     211              16 :   return 0;
     212                 : }
     213                 : 
     214                 : static int open_file(void)
     215              16 : {
     216              16 :   RET_ERR_UNLESS(local_ma_control_file_open() == CONTROL_FILE_OK);
     217                 :   /* Check that the module reports expected information */
     218              16 :   RET_ERR_UNLESS(verify_module_values_match_expected() == 0);
     219              16 :   return 0;
     220                 : }
     221                 : 
     222                 : static int write_file(LSN checkpoint_lsn, uint32 logno, TrID trid,
     223                 :                       uint8 rec_failures)
     224              12 : {
     225              12 :   RET_ERR_UNLESS(ma_control_file_write_and_force(checkpoint_lsn, logno, trid,
     226                 :                                                  rec_failures)
     227                 :                  == 0);
     228                 :   /* Check that the module reports expected information */
     229              12 :   RET_ERR_UNLESS(verify_module_values_match_expected() == 0);
     230              12 :   return 0;
     231                 : }
     232                 : 
     233                 : static int test_one_log_and_recovery_failures(void)
     234               1 : {
     235               1 :   RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
     236               1 :   expect_logno= 123;
     237               1 :   RET_ERR_UNLESS(write_file(last_checkpoint_lsn, expect_logno,
     238                 :                             max_trid_in_control_file,
     239                 :                             recovery_failures) == 0);
     240               1 :   expect_recovery_failures= 158;
     241               1 :   RET_ERR_UNLESS(write_file(last_checkpoint_lsn, expect_logno,
     242                 :                             max_trid_in_control_file,
     243                 :                             expect_recovery_failures) == 0);
     244               1 :   RET_ERR_UNLESS(close_file() == 0);
     245               1 :   return 0;
     246                 : }
     247                 : 
     248                 : static int test_five_logs_and_max_trid(void)
     249               1 : {
     250                 :   uint i;
     251                 : 
     252               1 :   RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
     253               1 :   expect_logno= 100;
     254               1 :   expect_max_trid= ULL(14111978111);
     255               6 :   for (i= 0; i<5; i++)
     256                 :   {
     257               5 :     expect_logno*= 3;
     258               5 :     RET_ERR_UNLESS(write_file(last_checkpoint_lsn, expect_logno,
     259                 :                               expect_max_trid,
     260                 :                               recovery_failures) == 0);
     261                 :   }
     262               1 :   RET_ERR_UNLESS(close_file() == 0);
     263               1 :   return 0;
     264                 : }
     265                 : 
     266                 : static int test_3_checkpoints_and_2_logs(void)
     267               1 : {
     268                 :   /*
     269                 :     Simulate one checkpoint, one log creation, two checkpoints, one
     270                 :     log creation.
     271                 :   */
     272               1 :   RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
     273               1 :   expect_checkpoint_lsn= MAKE_LSN(5, 10000);
     274               1 :   RET_ERR_UNLESS(write_file(expect_checkpoint_lsn, expect_logno,
     275                 :                             max_trid_in_control_file,
     276                 :                             recovery_failures) == 0);
     277                 : 
     278               1 :   expect_logno= 17;
     279               1 :   RET_ERR_UNLESS(write_file(expect_checkpoint_lsn, expect_logno,
     280                 :                             max_trid_in_control_file,
     281                 :                             recovery_failures) == 0);
     282                 : 
     283               1 :   expect_checkpoint_lsn= MAKE_LSN(17, 20000);
     284               1 :   RET_ERR_UNLESS(write_file(expect_checkpoint_lsn, expect_logno,
     285                 :                             max_trid_in_control_file,
     286                 :                             recovery_failures) == 0);
     287                 : 
     288               1 :   expect_checkpoint_lsn= MAKE_LSN(17, 45000);
     289               1 :   RET_ERR_UNLESS(write_file(expect_checkpoint_lsn, expect_logno,
     290                 :                             max_trid_in_control_file,
     291                 :                             recovery_failures) == 0);
     292                 : 
     293               1 :   expect_logno= 19;
     294               1 :   RET_ERR_UNLESS(write_file(expect_checkpoint_lsn, expect_logno,
     295                 :                             max_trid_in_control_file,
     296                 :                             recovery_failures) == 0);
     297               1 :   RET_ERR_UNLESS(close_file() == 0);
     298               1 :   return 0;
     299                 : }
     300                 : 
     301                 : static int test_binary_content(void)
     302               1 : {
     303                 :   uint i;
     304                 :   int fd;
     305                 : 
     306                 :   /*
     307                 :     TEST4: actually check by ourselves the content of the file.
     308                 :     Note that constants (offsets) are hard-coded here, precisely to prevent
     309                 :     someone from changing them in the control file module and breaking
     310                 :     backward-compatibility.
     311                 :     TODO: when we reach the format-freeze state, we may even just do a
     312                 :     comparison with a raw binary string, to not depend on any uint4korr
     313                 :     future change/breakage.
     314                 :   */
     315                 : 
     316                 :   uchar buffer[45];
     317               1 :   RET_ERR_UNLESS((fd= my_open(file_name,
     318                 :                           O_BINARY | O_RDWR,
     319                 :                           MYF(MY_WME))) >= 0);
     320               1 :   RET_ERR_UNLESS(my_read(fd, buffer, 45, MYF(MY_FNABP |  MY_WME)) == 0);
     321               1 :   RET_ERR_UNLESS(my_close(fd, MYF(MY_WME)) == 0);
     322               1 :   RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
     323               1 :   i= uint3korr(buffer + 34 );
     324               1 :   RET_ERR_UNLESS(i == LSN_FILE_NO(last_checkpoint_lsn));
     325               1 :   i= uint4korr(buffer + 37);
     326               1 :   RET_ERR_UNLESS(i == LSN_OFFSET(last_checkpoint_lsn));
     327               1 :   i= uint4korr(buffer + 41);
     328               1 :   RET_ERR_UNLESS(i == last_logno);
     329               1 :   RET_ERR_UNLESS(close_file() == 0);
     330               1 :   return 0;
     331                 : }
     332                 : 
     333                 : static int test_start_stop(void)
     334               1 : {
     335                 :   /* TEST5: Simulate start/nothing/stop/start/nothing/stop/start */
     336                 : 
     337               1 :   RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
     338               1 :   RET_ERR_UNLESS(close_file() == 0);
     339               1 :   RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
     340               1 :   RET_ERR_UNLESS(close_file() == 0);
     341               1 :   RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
     342               1 :   RET_ERR_UNLESS(close_file() == 0);
     343               1 :   return 0;
     344                 : }
     345                 : 
     346                 : static int test_2_open_and_2_close(void)
     347               1 : {
     348               1 :   RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
     349               1 :   RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
     350               1 :   RET_ERR_UNLESS(close_file() == 0);
     351               1 :   RET_ERR_UNLESS(close_file() == 0);
     352               1 :   return 0;
     353                 : }
     354                 : 
     355                 : 
     356                 : static int test_bad_magic_string(void)
     357               1 : {
     358                 :   uchar buffer[4];
     359                 :   int fd;
     360                 : 
     361               1 :   RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
     362               1 :   RET_ERR_UNLESS(close_file() == 0);
     363                 : 
     364                 :   /* Corrupt magic string */
     365               1 :   RET_ERR_UNLESS((fd= my_open(file_name,
     366                 :                           O_BINARY | O_RDWR,
     367                 :                           MYF(MY_WME))) >= 0);
     368               1 :   RET_ERR_UNLESS(my_pread(fd, buffer, 4, 0, MYF(MY_FNABP |  MY_WME)) == 0);
     369               1 :   RET_ERR_UNLESS(my_pwrite(fd, (const uchar *)"papa", 4, 0,
     370                 :                            MYF(MY_FNABP |  MY_WME)) == 0);
     371                 : 
     372                 :   /* Check that control file module sees the problem */
     373               1 :   RET_ERR_UNLESS(local_ma_control_file_open() ==
     374                 :              CONTROL_FILE_BAD_MAGIC_STRING);
     375                 :   /* Restore magic string */
     376               1 :   RET_ERR_UNLESS(my_pwrite(fd, buffer, 4, 0, MYF(MY_FNABP |  MY_WME)) == 0);
     377               1 :   RET_ERR_UNLESS(my_close(fd, MYF(MY_WME)) == 0);
     378               1 :   RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
     379               1 :   RET_ERR_UNLESS(close_file() == 0);
     380               1 :   return 0;
     381                 : }
     382                 : 
     383                 : static int test_bad_checksum(void)
     384               1 : {
     385                 :   uchar buffer[4];
     386                 :   int fd;
     387                 : 
     388               1 :   RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
     389               1 :   RET_ERR_UNLESS(close_file() == 0);
     390                 : 
     391                 :   /* Corrupt checksum */
     392               1 :   RET_ERR_UNLESS((fd= my_open(file_name,
     393                 :                           O_BINARY | O_RDWR,
     394                 :                           MYF(MY_WME))) >= 0);
     395               1 :   RET_ERR_UNLESS(my_pread(fd, buffer, 1, 30, MYF(MY_FNABP |  MY_WME)) == 0);
     396               1 :   buffer[0]+= 3; /* mangle checksum */
     397               1 :   RET_ERR_UNLESS(my_pwrite(fd, buffer, 1, 30, MYF(MY_FNABP |  MY_WME)) == 0);
     398                 :   /* Check that control file module sees the problem */
     399               1 :   RET_ERR_UNLESS(local_ma_control_file_open() ==
     400                 :                  CONTROL_FILE_BAD_CHECKSUM);
     401                 :   /* Restore checksum */
     402               1 :   buffer[0]-= 3;
     403               1 :   RET_ERR_UNLESS(my_pwrite(fd, buffer, 1, 30, MYF(MY_FNABP |  MY_WME)) == 0);
     404               1 :   RET_ERR_UNLESS(my_close(fd, MYF(MY_WME)) == 0);
     405                 : 
     406               1 :   return 0;
     407                 : }
     408                 : 
     409                 : 
     410                 : static int test_bad_blocksize(void)
     411               1 : {
     412               1 :   maria_block_size<<= 1;
     413                 :   /* Check that control file module sees the problem */
     414               1 :   RET_ERR_UNLESS(local_ma_control_file_open() ==
     415                 :                  CONTROL_FILE_WRONG_BLOCKSIZE);
     416                 :   /* Restore blocksize */
     417               1 :   maria_block_size>>= 1;
     418                 : 
     419               1 :   RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
     420               1 :   RET_ERR_UNLESS(close_file() == 0);
     421               1 :   return 0;
     422                 : }
     423                 : 
     424                 : 
     425                 : static int test_future_size(void)
     426               1 : {
     427                 :   /*
     428                 :     Here we check ability to add fields only so we can use
     429                 :     defined constants
     430                 :   */
     431                 :   uint32 sum;
     432                 :   int fd;
     433                 :   uchar buffer[CF_CREATE_TIME_TOTAL_SIZE + CF_CHANGEABLE_TOTAL_SIZE + 2];
     434               1 :   RET_ERR_UNLESS((fd= my_open(file_name,
     435                 :                           O_BINARY | O_RDWR,
     436                 :                           MYF(MY_WME))) >= 0);
     437               1 :   RET_ERR_UNLESS(my_read(fd, buffer,
     438                 :                          CF_CREATE_TIME_TOTAL_SIZE + CF_CHANGEABLE_TOTAL_SIZE,
     439                 :                          MYF(MY_FNABP |  MY_WME)) == 0);
     440               1 :   RET_ERR_UNLESS(my_close(fd, MYF(MY_WME)) == 0);
     441                 :   /* "add" new field of 1 byte (value 1) to header and variable part */
     442               1 :   memmove(buffer + CF_CREATE_TIME_TOTAL_SIZE + 1,
     443                 :           buffer + CF_CREATE_TIME_TOTAL_SIZE,
     444                 :           CF_CHANGEABLE_TOTAL_SIZE);
     445               1 :   buffer[CF_CREATE_TIME_TOTAL_SIZE - CF_CHECKSUM_SIZE]= '\1';
     446               1 :   buffer[CF_CREATE_TIME_TOTAL_SIZE + CF_CHANGEABLE_TOTAL_SIZE + 1]= '\1';
     447                 :   /* fix lengths */
     448               1 :   int2store(buffer + CF_CREATE_TIME_SIZE_OFFSET, CF_CREATE_TIME_TOTAL_SIZE + 1);
     449               1 :   int2store(buffer + CF_CHANGEABLE_SIZE_OFFSET, CF_CHANGEABLE_TOTAL_SIZE + 1);
     450                 :   /* recalculete checksums */
     451               1 :   sum= (uint32) my_checksum(0, buffer, CF_CREATE_TIME_TOTAL_SIZE -
     452                 :                             CF_CHECKSUM_SIZE + 1);
     453               1 :   int4store(buffer + CF_CREATE_TIME_TOTAL_SIZE - CF_CHECKSUM_SIZE + 1, sum);
     454               1 :   sum= (uint32) my_checksum(0, buffer +  CF_CREATE_TIME_TOTAL_SIZE + 1 +
     455                 :                             CF_CHECKSUM_SIZE,
     456                 :                             CF_CHANGEABLE_TOTAL_SIZE - CF_CHECKSUM_SIZE + 1);
     457               1 :   int4store(buffer + CF_CREATE_TIME_TOTAL_SIZE + 1, sum);
     458                 :   /* write new file and check it */
     459               1 :   RET_ERR_UNLESS((fd= my_open(file_name,
     460                 :                           O_BINARY | O_RDWR,
     461                 :                           MYF(MY_WME))) >= 0);
     462               1 :   RET_ERR_UNLESS(my_pwrite(fd, buffer,
     463                 :                            CF_CREATE_TIME_TOTAL_SIZE +
     464                 :                            CF_CHANGEABLE_TOTAL_SIZE + 2,
     465                 :                            0, MYF(MY_FNABP |  MY_WME)) == 0);
     466               1 :   RET_ERR_UNLESS(my_close(fd, MYF(MY_WME)) == 0);
     467               1 :   RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
     468               1 :   RET_ERR_UNLESS(close_file() == 0);
     469                 : 
     470               1 :   return(0);
     471                 : }
     472                 : 
     473                 : static int test_bad_hchecksum(void)
     474               1 : {
     475                 :   uchar buffer[4];
     476                 :   int fd;
     477                 : 
     478               1 :   RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
     479               1 :   RET_ERR_UNLESS(close_file() == 0);
     480                 : 
     481                 :   /* Corrupt checksum */
     482               1 :   RET_ERR_UNLESS((fd= my_open(file_name,
     483                 :                           O_BINARY | O_RDWR,
     484                 :                           MYF(MY_WME))) >= 0);
     485               1 :   RET_ERR_UNLESS(my_pread(fd, buffer, 1, 26, MYF(MY_FNABP |  MY_WME)) == 0);
     486               1 :   buffer[0]+= 3; /* mangle checksum */
     487               1 :   RET_ERR_UNLESS(my_pwrite(fd, buffer, 1, 26, MYF(MY_FNABP |  MY_WME)) == 0);
     488                 :   /* Check that control file module sees the problem */
     489               1 :   RET_ERR_UNLESS(local_ma_control_file_open() ==
     490                 :                  CONTROL_FILE_BAD_HEAD_CHECKSUM);
     491                 :   /* Restore checksum */
     492               1 :   buffer[0]-= 3;
     493               1 :   RET_ERR_UNLESS(my_pwrite(fd, buffer, 1, 26, MYF(MY_FNABP |  MY_WME)) == 0);
     494               1 :   RET_ERR_UNLESS(my_close(fd, MYF(MY_WME)) == 0);
     495                 : 
     496               1 :   return 0;
     497                 : }
     498                 : 
     499                 : 
     500                 : static int test_bad_size(void)
     501               1 : {
     502                 :   uchar buffer[]=
     503               1 :     "123456789012345678901234567890123456789012345678901234567890123456";
     504                 :   int fd, i;
     505                 : 
     506                 :   /* A too short file */
     507               1 :   RET_ERR_UNLESS(delete_file(MYF(MY_WME)) == 0);
     508               1 :   RET_ERR_UNLESS((fd= my_open(file_name,
     509                 :                           O_BINARY | O_RDWR | O_CREAT,
     510                 :                           MYF(MY_WME))) >= 0);
     511               1 :   RET_ERR_UNLESS(my_write(fd, buffer, 10, MYF(MY_FNABP |  MY_WME)) == 0);
     512                 :   /* Check that control file module sees the problem */
     513               1 :   RET_ERR_UNLESS(local_ma_control_file_open() ==
     514                 :                  CONTROL_FILE_TOO_SMALL);
     515               9 :   for (i= 0; i < 8; i++)
     516                 :   {
     517               8 :     RET_ERR_UNLESS(my_write(fd, buffer, 66, MYF(MY_FNABP |  MY_WME)) == 0);
     518                 :   }
     519                 :   /* Check that control file module sees the problem */
     520               1 :   RET_ERR_UNLESS(local_ma_control_file_open() ==
     521                 :                  CONTROL_FILE_TOO_BIG);
     522               1 :   RET_ERR_UNLESS(my_close(fd, MYF(MY_WME)) == 0);
     523                 : 
     524                 :   /* Leave a correct control file */
     525               1 :   RET_ERR_UNLESS(delete_file(MYF(MY_WME)) == 0);
     526               1 :   RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
     527               1 :   RET_ERR_UNLESS(close_file() == 0);
     528                 : 
     529               1 :   return 0;
     530                 : }
     531                 : 
     532                 : 
     533                 : static struct my_option my_long_options[] =
     534                 : {
     535                 : #ifndef DBUG_OFF
     536                 :   {"debug", '#', "Debug log.",
     537                 :    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
     538                 : #endif
     539                 :   {"help", '?', "Display help and exit",
     540                 :    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
     541                 :   {"version", 'V', "Print version number and exit",
     542                 :    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
     543                 :   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
     544                 : };
     545                 : 
     546                 : 
     547                 : static void version(void)
     548               0 : {
     549               0 :   printf("ma_control_file_test: unit test for the control file "
     550                 :          "module of the Maria storage engine. Ver 1.0 \n");
     551                 : }
     552                 : 
     553                 : static my_bool
     554                 : get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
     555                 :                char *argument __attribute__((unused)))
     556               0 : {
     557               0 :   switch(optid) {
     558                 :   case 'V':
     559               0 :     version();
     560               0 :     exit(0);
     561                 :   case '#':
     562               0 :     DBUG_PUSH (argument);
     563               0 :     break;
     564                 :   case '?':
     565               0 :     version();
     566               0 :     usage();
     567               0 :     exit(0);
     568                 :   }
     569               0 :   return 0;
     570                 : }
     571                 : 
     572                 : 
     573                 : /* Read options */
     574                 : 
     575                 : static void get_options(int argc, char *argv[])
     576               1 : {
     577                 :   int ho_error;
     578                 : 
     579               1 :   if ((ho_error=handle_options(&argc, &argv, my_long_options,
     580                 :                                get_one_option)))
     581               0 :     exit(ho_error);
     582                 : 
     583                 :   return;
     584                 : } /* get options */
     585                 : 
     586                 : 
     587                 : static void usage(void)
     588               0 : {
     589               0 :   printf("Usage: %s [options]\n\n", my_progname);
     590               0 :   my_print_help(my_long_options);
     591               0 :   my_print_variables(my_long_options);
     592                 : }

Generated by: LTP GCOV extension version 1.4