greenplumn aomd_filehandler_test 源码

  • 2022-08-18
  • 浏览 (508)

greenplumn aomd_filehandler_test 代码

文件路径:/src/backend/access/appendonly/test/aomd_filehandler_test.c

#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include "cmockery.h"


#include "postgres.h"
#include "utils/memutils.h"
#include "access/aomd.h"
#include "access/appendonlytid.h"
#include "access/appendonlywriter.h"

/*
 * ACHTUNG  This module is trickier than you might initially have expected
 *  because not all combinations of present files are in fact valid GPDB
 *  ao tables.  See the comment in ao_foreach_extent_file() to understand
 *  what valid combinations are.  We do NOT attempt to test invalid
 *  combinations here as that is a higher-level test than this unit test.
 */

#define MAX_SEGNO_FILES (MAX_AOREL_CONCURRENCY * MaxHeapAttributeNumber)
typedef struct {
	bool present[MAX_SEGNO_FILES];
	bool call_result[MAX_SEGNO_FILES];
	bool call_expected[MAX_SEGNO_FILES];
	int num_called;
} aomd_filehandler_callback_ctx;

static void
setup_test_structures(aomd_filehandler_callback_ctx *ctx)
{
	memset(ctx->present, false, sizeof(ctx->present));
	memset(ctx->call_result, false, sizeof(ctx->call_result));
	memset(ctx->call_expected, false, sizeof(ctx->call_expected));
	ctx->num_called = 0;

    /* these files get checked for presence in the foreach() */
    ctx->call_expected[AOTupleId_MultiplierSegmentFileNum] = true;
    for (int segno = 1; segno < MAX_AOREL_CONCURRENCY; segno++)
        ctx->call_expected[segno] = true;
}

/*
 * This is meant to be called in sorted order from lowest segno to
 *  highest segno.  Since [.0,.127] is called by foreach(), we need
 *  not set call_expected on the called in segno, just the next one.
 *  This is because, for instance, .129 can only be called if .1 is present.
 */
static void
set_ctx_for_present_file(aomd_filehandler_callback_ctx *ctx, int segno)
{
	ctx->present[segno] = true;
	if (segno < (MAX_SEGNO_FILES - MAX_AOREL_CONCURRENCY))
		ctx->call_expected[segno + MAX_AOREL_CONCURRENCY] = true;
}

static int
compareSegnoFiles(bool *expected, bool *result)
{
	size_t numDiffer = 0;
	bool printedOneDiff = false;

	/*
	 * We had two choices for the initialization value of segno:
	 *   A). 0 since ao tables have a 0 segno file
	 *   B). 1 since the foreach() function we are testing here does not
	 *              actually touch segno 0.
	 * We opt for A). since callers of foreach() need to handle that case
	 *  properly, so we want our tests to model that.
	 */
	for (size_t segno=0;segno<MAX_SEGNO_FILES;segno++) {
		if (expected[segno] != result[segno]) {
			numDiffer++;
			/* print only the first error to avoid printing thousands of them */
			if (!printedOneDiff) {
				printedOneDiff = true;
				print_error("MISMATCH for segno: %ld expected: %d got: %d (%s)\n",
							(long)segno, expected[segno], result[segno],
							result[segno] ? "called but should not have been" :
							"not called but should have been");
			}
		}
	}

	return numDiffer;
}

static bool
file_callback(int segno, void *ctx) {
	aomd_filehandler_callback_ctx *myctx = ctx;

	assert_true(segno < MAX_SEGNO_FILES);

	myctx->num_called++;
	myctx->call_result[segno] = true;

	return myctx->present[segno];
}

static void
test_no_files_present(void **state)
{
    aomd_filehandler_callback_ctx ctx;
    setup_test_structures(&ctx);

    ao_foreach_extent_file(file_callback, &ctx);

    assert_int_equal(ctx.num_called, MAX_AOREL_CONCURRENCY);
    assert_int_equal(compareSegnoFiles(ctx.call_expected, ctx.call_result), 0);
}

/* concurrency = 1 num_columns = 1 */
static void
test_co_1_column_1_concurrency(void **state)
{
    aomd_filehandler_callback_ctx ctx;
    setup_test_structures(&ctx);

    for (int col = 0; col < 1; col++)
        set_ctx_for_present_file(&ctx, 1 + col * AOTupleId_MultiplierSegmentFileNum);

    ao_foreach_extent_file(file_callback, &ctx);

    assert_int_equal(ctx.num_called, MAX_AOREL_CONCURRENCY + 1*1);
    assert_int_equal(compareSegnoFiles(ctx.call_expected, ctx.call_result), 0);
}

/* concurrency = 1 num_columns = 4 */
static void
test_co_4_columns_1_concurrency(void **state)
{
    aomd_filehandler_callback_ctx ctx;
    setup_test_structures(&ctx);

    for (int col = 0; col < 4; col++)
        set_ctx_for_present_file(&ctx, 1 + col * AOTupleId_MultiplierSegmentFileNum);

    ao_foreach_extent_file(file_callback, &ctx);

    assert_int_equal(ctx.num_called, MAX_AOREL_CONCURRENCY + 4*1);
    assert_int_equal(compareSegnoFiles(ctx.call_expected, ctx.call_result), 0);
}

/* concurrency = 1,5 num_columns = 3 */
static void
test_co_3_columns_2_concurrency(void **state)
{
    aomd_filehandler_callback_ctx ctx;
    setup_test_structures(&ctx);

    for (int col = 0; col < 3; col++)
    {
        set_ctx_for_present_file(&ctx, 1 + col * AOTupleId_MultiplierSegmentFileNum);
        set_ctx_for_present_file(&ctx, 5 + col * AOTupleId_MultiplierSegmentFileNum);
    }

    ao_foreach_extent_file(file_callback, &ctx);

    assert_int_equal(ctx.num_called, MAX_AOREL_CONCURRENCY + 3*2);
    assert_int_equal(compareSegnoFiles(ctx.call_expected, ctx.call_result), 0);
}

/* concurrency = [1,127] num_columns = 1 */
static void
test_co_1_column_127_concurrency(void **state)
{
    aomd_filehandler_callback_ctx ctx;
    setup_test_structures(&ctx);

    for (int concurrency = 1; concurrency < MAX_AOREL_CONCURRENCY; concurrency++)
        set_ctx_for_present_file(&ctx, concurrency);

    ao_foreach_extent_file(file_callback, &ctx);

    assert_int_equal(ctx.num_called, MAX_AOREL_CONCURRENCY + 1*127);
    assert_int_equal(compareSegnoFiles(ctx.call_expected, ctx.call_result), 0);
}

/* concurrency = 0 num_columns = MaxHeapAttributeNumber  */
static void
test_co_max_columns_0th_concurrency(void **state)
{
    aomd_filehandler_callback_ctx ctx;
    setup_test_structures(&ctx);

    for (int col = 0; col < MaxHeapAttributeNumber; col++)
        set_ctx_for_present_file(&ctx, col * MAX_AOREL_CONCURRENCY);

    ao_foreach_extent_file(file_callback, &ctx);

    /* 0th file already acccounted for, hence the -1 */
    assert_int_equal(ctx.num_called, (MAX_AOREL_CONCURRENCY-1) + (MaxHeapAttributeNumber * 1 - 1));
    assert_int_equal(compareSegnoFiles(ctx.call_expected, ctx.call_result), 0);
}

/* concurrency = 1 num_columns = (MaxHeapAttributeNumber + 1) */
static void
test_co_max_columns_0_1_concurrency(void **state)
{
    aomd_filehandler_callback_ctx ctx;
    setup_test_structures(&ctx);

    for (int col = 0; col < MaxHeapAttributeNumber; col++) {
        set_ctx_for_present_file(&ctx, col * MAX_AOREL_CONCURRENCY);
        set_ctx_for_present_file(&ctx, col * MAX_AOREL_CONCURRENCY + 1);
    }

    ao_foreach_extent_file(file_callback, &ctx);

    /* 0th file already acccount for, hence the -1 */
    assert_int_equal(ctx.num_called, (MAX_AOREL_CONCURRENCY-1) + (MaxHeapAttributeNumber - 1) * 2);
    assert_int_equal(compareSegnoFiles(ctx.call_expected, ctx.call_result), 0);
}

static void
test_different_number_of_columns_per_concurrency_level(void **state)
{
    aomd_filehandler_callback_ctx ctx;
    setup_test_structures(&ctx);

    set_ctx_for_present_file(&ctx, 1);
    set_ctx_for_present_file(&ctx, 129);
    set_ctx_for_present_file(&ctx, 2);
    set_ctx_for_present_file(&ctx, 130);
    set_ctx_for_present_file(&ctx, 258);

    ao_foreach_extent_file(file_callback, &ctx);

    assert_int_equal(ctx.num_called, MAX_AOREL_CONCURRENCY + 5);
    assert_int_equal(compareSegnoFiles(ctx.call_expected, ctx.call_result), 0);
}

static void
test_all_files_present(void **state)
{
	aomd_filehandler_callback_ctx ctx;
	setup_test_structures(&ctx);

	memset(ctx.present, true, sizeof(ctx.present));
	memset(ctx.call_expected, true, sizeof(ctx.call_expected));

	ctx.call_expected[0] = false;  /* caller must deal with .0 file */
	ao_foreach_extent_file(file_callback, &ctx);

	assert_int_equal(ctx.num_called, MAX_SEGNO_FILES - 1);
	assert_int_equal(compareSegnoFiles(ctx.call_expected, ctx.call_result), 0);

	return;
}

int
main(int argc, char *argv[])
{
	cmockery_parse_arguments(argc, argv);

	const		UnitTest tests[] = {
		unit_test(test_no_files_present),
        unit_test(test_co_1_column_1_concurrency),
        unit_test(test_co_4_columns_1_concurrency),
        unit_test(test_co_3_columns_2_concurrency),
        unit_test(test_co_1_column_127_concurrency),
        unit_test(test_co_max_columns_0th_concurrency),
        unit_test(test_co_max_columns_0_1_concurrency),
        unit_test(test_different_number_of_columns_per_concurrency_level),
		unit_test(test_all_files_present),
	};

	MemoryContextInit();

	return run_tests(tests);
}

相关信息

greenplumn 源码目录

相关文章

greenplumn aomd_test 源码

greenplumn aosegfiles_test 源码

greenplumn appendonly_visimap_entry_test 源码

greenplumn appendonly_visimap_test 源码

0  赞