blob: dad090cf8810a37e02bb2bc312135ad19e392ac0 [file]
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include "cmockery.h"
#include "postgres.h"
#include "utils/memutils.h"
#include "../cdbappendonlyxlog.c"
#include "access/transam.h"
#include "catalog/pg_tablespace.h"
static int
check_relfilelocator_function(const LargestIntegralType arg1, const LargestIntegralType arg2)
{
const RelFileLocator *value = (const RelFileLocator *) arg1;
const RelFileLocator *check_value = (const RelFileLocator *) arg2;
return RelFileLocatorEquals(*value, *check_value);
}
/*
* Test that XLogAOSegmentFile will be called when we cannot find the AO
* segment file.
*/
static void
ao_invalid_segment_file_test(uint8 xl_info)
{
RelFileLocator relfilelocator;
XLogReaderState *mockrecord;
xl_ao_target xlaotarget;
xl_ao_insert xlaoinsert;
xl_ao_truncate xlaotruncate;
/* create mock transaction log */
relfilelocator.spcOid = DEFAULTTABLESPACE_OID;
relfilelocator.dbOid = 12087 /* postgres database */;
relfilelocator.relNumber = FirstNormalObjectId;
xlaotarget.node = relfilelocator;
xlaotarget.segment_filenum = 2;
xlaotarget.offset = 12345;
mockrecord = XLogReaderAllocate(DEFAULT_XLOG_SEG_SIZE, NULL, XL_ROUTINE(), NULL);
mockrecord->record = palloc0(sizeof(DecodedXLogRecord));
if (xl_info == XLOG_APPENDONLY_INSERT)
{
xlaoinsert.target = xlaotarget;
XLogRecGetData(mockrecord) = (char *) &xlaoinsert;
}
else if (xl_info == XLOG_APPENDONLY_TRUNCATE)
{
xlaotruncate.target = xlaotarget;
XLogRecGetData(mockrecord) = (char *) &xlaotruncate;
}
/* mock to not find AO segment file */
expect_any(PathNameOpenFile, fileName);
expect_any(PathNameOpenFile, fileFlags);
will_return(PathNameOpenFile, -1);
/* XLogAOSegmentFile should be called with our mock relfilelocator and segment file number */
expect_check(XLogAOSegmentFile, &rnode, check_relfilelocator_function, &relfilelocator);
expect_value(XLogAOSegmentFile, segmentFileNum, xlaotarget.segment_filenum);
will_be_called(XLogAOSegmentFile);
/* run test */
if (xl_info == XLOG_APPENDONLY_INSERT)
ao_insert_replay(mockrecord);
else if (xl_info == XLOG_APPENDONLY_TRUNCATE)
ao_truncate_replay(mockrecord);
}
/*
* Test that ao_insert_replay will call XLogAOSegmentFile when we cannot find
* the AO segment file.
*/
static void
test_ao_insert_replay_invalid_segment_file(void **state)
{
ao_invalid_segment_file_test(XLOG_APPENDONLY_INSERT);
}
/*
* Test that ao_truncate_replay will call XLogAOSegmentFile when we cannot find
* the AO segment file.
*/
static void
test_ao_truncate_replay_invalid_segment_file(void **state)
{
ao_invalid_segment_file_test(XLOG_APPENDONLY_TRUNCATE);
}
int
main(int argc, char* argv[])
{
cmockery_parse_arguments(argc, argv);
const UnitTest tests[] = {
unit_test(test_ao_insert_replay_invalid_segment_file),
unit_test(test_ao_truncate_replay_invalid_segment_file)
};
MemoryContextInit();
return run_tests(tests);
}