~jlukas79/+junk/mysql-server

« back to all changes in this revision

Viewing changes to storage/maria/unittest/ma_control_file-t.c

manual merge 6.0-main --> 6.0-bka-review

Show diffs side-by-side

added added

removed removed

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