greenplumn redzone_handler_test 源码
greenplumn redzone_handler_test 代码
文件路径:/src/backend/utils/mmgr/test/redzone_handler_test.c
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include "cmockery.h"
#include "../redzone_handler.c"
#define EXPECT_EREPORT(LOG_LEVEL)     \
	expect_any(errstart, elevel); \
	expect_any(errstart, domain); \
	if (LOG_LEVEL < ERROR) \
	{ \
    	will_return(errstart, false); \
	} \
    else \
    { \
    	will_return_with_sideeffect(errstart, false, &_ExceptionalCondition, NULL);\
    } \
/* isRunawayDetector assumes the address of this variable */
static uint32 fakeIsRunawayDetector = 0;
extern bool sessionStateInited;
#undef PG_RE_THROW
#define PG_RE_THROW() siglongjmp(*PG_exception_stack, 1)
/*
 * This method will emulate the real ExceptionalCondition
 * function by re-throwing the exception, essentially falling
 * back to the next available PG_CATCH();
 */
static void
_ExceptionalCondition()
{
     PG_RE_THROW();
}
/* Creates a SessionStateArray of the specified number of entry */
static void
CreateSessionStateArray(int numEntries)
{
	MaxBackends = numEntries;
	IsUnderPostmaster = false;
	assert_true(NULL == AllSessionStateEntries);
	SessionStateArray *fakeSessionStateArray = NULL;
	fakeSessionStateArray = malloc(SessionState_ShmemSize());
	bool found = false;
	will_return(ShmemInitStruct, fakeSessionStateArray);
	will_assign_value(ShmemInitStruct, foundPtr, found);
	expect_any_count(ShmemInitStruct, name, 1);
	expect_any_count(ShmemInitStruct, size, 1);
	expect_any_count(ShmemInitStruct, foundPtr, 1);
	SessionState_ShmemInit();
	/* The lookup should always work, whether under postmaster or not */
	assert_true(AllSessionStateEntries == fakeSessionStateArray);
}
/* Frees a previously created SessionStateArray */
static void
DestroySessionStateArray()
{
	assert_true(NULL != AllSessionStateEntries);
	free((void *) AllSessionStateEntries);
	AllSessionStateEntries = NULL;
}
/*
 * Acquires a SessionState entry for the specified sessionid. If an existing entry
 * is found, this method reuses that entry
 */
static SessionState *
AcquireSessionState(int sessionId, int vmem, int activeProcessCount)
{
	will_be_called_count(LWLockAcquire, 1);
	will_be_called_count(LWLockRelease, 1);
	expect_any_count(LWLockAcquire, lock, 1);
	expect_any_count(LWLockAcquire, mode, 1);
	expect_any_count(LWLockRelease, lock, 1);
	/* Keep the assertions happy */
	gp_session_id = sessionId;
	sessionStateInited = false;
	MySessionState = NULL;
	EXPECT_EREPORT(gp_sessionstate_loglevel);
	SessionState_Init();
	if (vmem >= 0)
	{
		MySessionState->sessionVmem = vmem;
	}
	if (activeProcessCount >= 0)
	{
		MySessionState->activeProcessCount = activeProcessCount;
	}
	return (SessionState *) MySessionState;
}
/*
 * Checks if RedZoneHandler_ShmemInit() properly initializes the global variables
 * as the postmaster
 */
static void
test__RedZoneHandler_ShmemInit__InitializesGlobalVarsWhenPostmaster(void **state)
{
	vmemTrackerInited = false;
	IsUnderPostmaster = false;
	/* Assign weird value to test the re-initialization */
	fakeIsRunawayDetector = 1234;
	isRunawayDetector = NULL;
	expect_any_count(ShmemInitStruct, name, 3);
	expect_any_count(ShmemInitStruct, size, 3);
	expect_any_count(ShmemInitStruct, foundPtr, 3);
	will_assign_value(ShmemInitStruct, foundPtr, (bool) false);
	will_assign_value(ShmemInitStruct, foundPtr, (bool) false);
	will_assign_value(ShmemInitStruct, foundPtr, (bool) false);
	will_return_count(ShmemInitStruct, &fakeIsRunawayDetector, 3);
	will_return(VmemTracker_ConvertVmemMBToChunks, 0);
	expect_any(VmemTracker_ConvertVmemMBToChunks, mb);
	/*
	 * When vmem limit is not activated or runaway_detector_activation_percent is
	 * set to 0, red zone should be very high (i.e., red-zone will be disabled).
	 */
	runaway_detector_activation_percent = 0;
	RedZoneHandler_ShmemInit();
	assert_true(isRunawayDetector == &fakeIsRunawayDetector);
	assert_true(redZoneChunks == INT32_MAX);
	assert_true(*isRunawayDetector == 0);
	/*
	 * When the activation percent is set to 100, we will not even attempt calculating
	 * the redZoneChunks and instead assign INT32_MAX directly. Note, we don't even
	 * call VmemTracker_ConvertVmemMBToChunks()
	 */
	runaway_detector_activation_percent = 100;
	redZoneChunks = 0;
	RedZoneHandler_ShmemInit();
	assert_true(redZoneChunks == INT32_MAX);
	runaway_detector_activation_percent = 80;
	RedZoneHandler_ShmemInit();
}
/*
 * Checks if RedZoneHandler_ShmemInit() properly initializes the global variables
 * when under postmaster
 */
static void
test__RedZoneHandler_ShmemInit__InitializesUnderPostmaster(void **state)
{
	vmemTrackerInited = false;
	IsUnderPostmaster = true;
	/* Assign weird value to test the re-initialization */
	fakeIsRunawayDetector = 1234;
	isRunawayDetector = NULL;
	expect_any(ShmemInitStruct, name);
	expect_any(ShmemInitStruct, size);
	expect_any(ShmemInitStruct, foundPtr);
	will_assign_value(ShmemInitStruct, foundPtr, (bool) true);
	will_return(ShmemInitStruct, &fakeIsRunawayDetector);
	/* For testing that we don't change this value */
	redZoneChunks = 1234;
	RedZoneHandler_ShmemInit();
	assert_true(isRunawayDetector == &fakeIsRunawayDetector);
	assert_true(redZoneChunks == 1234);
	assert_true(*isRunawayDetector == 1234);
}
/*
 * Checks if RedZoneHandler_IsVmemRedZone() properly identifies red zone
 */
static void
test__RedZoneHandler_IsVmemRedZone__ProperlyIdentifiesRedZone(void **state)
{
	vmemTrackerInited = false;
	/* No red zone detection if vmem tracker is not initialized */
	assert_false(RedZoneHandler_IsVmemRedZone());
	vmemTrackerInited = true;
	static int32 fakeSegmentVmemChunks = 0;
	segmentVmemChunks = &fakeSegmentVmemChunks;
	redZoneChunks = INT32_MAX;
	*segmentVmemChunks = INT32_MAX;
	/* Both segment vmem and red zone is INT32_MAX. It's not a red-zone */
	assert_false(RedZoneHandler_IsVmemRedZone());
	/* 100 chunks */
	*segmentVmemChunks = 100;
	redZoneChunks = 80;
	/* segmentVmemChunks exceeds redZoneChunks. So, should be red zone */
	assert_true(RedZoneHandler_IsVmemRedZone());
	vmemTrackerInited = false;
	/*
	 * segmentVmemChunks exceeds redZoneChunks. But vmem tracker is not
	 * initialized. Therefore, no red zone detection
	 */
	assert_false(RedZoneHandler_IsVmemRedZone());
}
/*
 * Checks if RedZoneHandler_FlagTopConsumer() allows only one detector
 * at a time
 */
static void
test__RedZoneHandler_FlagTopConsumer__SingletonDetector(void **state)
{
	/* Make sure the code is exercised */
	vmemTrackerInited = true;
	/* Ensure non-null MySessionState */
	MySessionState = (SessionState *) 0x1234;
	static uint32 fakeIsRunawayDetector = 0;
	isRunawayDetector = &fakeIsRunawayDetector;
	/* We already have a runaway detector */
	*isRunawayDetector = 1;
	/*
	 * This will return without attempting to detecting any runaway session.
	 * This is tested from the fact that it is not trying to call LWLocAcquire
	 */
	RedZoneHandler_FlagTopConsumer();
}
/*
 * Checks if RedZoneHandler_FlagTopConsumer() finds the top consumer
 */
static void
test__RedZoneHandler_FlagTopConsumer__FindsTopConsumer(void **state)
{
	/* Make sure the RedZoneHandler_FlagTopConsumer code is exercised */
	vmemTrackerInited = true;
	CreateSessionStateArray(4);
	/* Make sure MySessionState is valid */
	SessionState *one = AcquireSessionState(1 /* sessionId */, 100 /* vmem */, 1 /* activeProcessCount */);
	SessionState *two = AcquireSessionState(2, 101, 1);
	SessionState *three = AcquireSessionState(3, 101, 1);
	SessionState *four = AcquireSessionState(4, 99, 1);
	/* Ensure we can detect runaway sessions */
	*isRunawayDetector = 0;
	will_be_called_count(LWLockAcquire, 1);
	will_be_called_count(LWLockRelease, 1);
	expect_any_count(LWLockAcquire, lock, 1);
	expect_any_count(LWLockAcquire, mode, 1);
	expect_any_count(LWLockRelease, lock, 1);
	static EventVersion fakeLatestRunawayVersion = 0;
	static EventVersion fakeCurrentVersion = 1;
	latestRunawayVersion = &fakeLatestRunawayVersion;
	CurrentVersion = &fakeCurrentVersion;
	RedZoneHandler_FlagTopConsumer();
	assert_true(one->runawayStatus == RunawayStatus_NotRunaway &&
			two->runawayStatus  == RunawayStatus_NotRunaway /* three is tied with two. So, won't be flagged */ &&
			three->runawayStatus  == RunawayStatus_PrimaryRunawaySession /* First detected max consumer is
			flagged (note the usedList is reversed, so "three" will be ahead of "two") */ &&
			four->runawayStatus == RunawayStatus_NotRunaway);
	DestroySessionStateArray();
}
/*
 * Checks if RedZoneHandler_FlagTopConsumer() ignores the idle sessions
 * even if they are the top consumer
 */
static void
test__RedZoneHandler_FlagTopConsumer__IgnoresIdleSession(void **state)
{
	/* Make sure the RedZoneHandler_FlagTopConsumer code is exercised */
	vmemTrackerInited = true;
	CreateSessionStateArray(4);
	/* Make sure MySessionState is valid */
	SessionState *one = AcquireSessionState(1 /* sessionId */, 100 /* vmem */, 1 /* activeProcessCount */);
	SessionState *two = AcquireSessionState(2, 101, 0);
	SessionState *three = AcquireSessionState(3, 100, 0);
	SessionState *four = AcquireSessionState(4, 99, 1);
	/* Ensure we can detect runaway sessions */
	*isRunawayDetector = 0;
	will_be_called_count(LWLockAcquire, 1);
	will_be_called_count(LWLockRelease, 1);
	expect_any_count(LWLockAcquire, lock, 1);
	expect_any_count(LWLockAcquire, mode, 1);
	expect_any_count(LWLockRelease, lock, 1);
	static EventVersion fakeLatestRunawayVersion = 0;
	static EventVersion fakeCurrentVersion = 1;
	latestRunawayVersion = &fakeLatestRunawayVersion;
	CurrentVersion = &fakeCurrentVersion;
	RedZoneHandler_FlagTopConsumer();
	assert_true(one->runawayStatus  == RunawayStatus_SecondaryRunawaySession &&
			two->runawayStatus == RunawayStatus_NotRunaway &&
			three->runawayStatus  == RunawayStatus_NotRunaway /* We will encounter three first, but it
				doesn't have active process. So, RDT will ignore it. */ &&
			four->runawayStatus == RunawayStatus_NotRunaway);
	DestroySessionStateArray();
}
/*
 * Checks if RedZoneHandler_FlagTopConsumer() reactivates the runaway detector
 * if there is no active session
 */
static void
test__RedZoneHandler_FlagTopConsumer__ReactivatesDetectorIfNoActiveSession(void **state)
{
	/* Make sure the RedZoneHandler_FlagTopConsumer code is exercised */
	vmemTrackerInited = true;
	CreateSessionStateArray(4);
	/* Make sure MySessionState is valid */
	SessionState *one = AcquireSessionState(1 /* sessionId */, 100 /* vmem */, 0 /* activeProcessCount */);
	SessionState *two = AcquireSessionState(2, 101, 0);
	SessionState *three = AcquireSessionState(3, 100, 0);
	SessionState *four = AcquireSessionState(4, 99, 0);
	/* Ensure we can detect runaway sessions */
	*isRunawayDetector = 0;
	will_be_called_count(LWLockAcquire, 1);
	will_be_called_count(LWLockRelease, 1);
	expect_any_count(LWLockAcquire, lock, 1);
	expect_any_count(LWLockAcquire, mode, 1);
	expect_any_count(LWLockRelease, lock, 1);
	static EventVersion fakeLatestRunawayVersion = 0;
	static EventVersion fakeCurrentVersion = 1;
	latestRunawayVersion = &fakeLatestRunawayVersion;
	CurrentVersion = &fakeCurrentVersion;
	RedZoneHandler_FlagTopConsumer();
	/* None of them could be detected as runaway as all of them are inactive sessions */
	assert_true(one->runawayStatus == RunawayStatus_NotRunaway && two->runawayStatus == RunawayStatus_NotRunaway &&
			three->runawayStatus == RunawayStatus_NotRunaway && four->runawayStatus == RunawayStatus_NotRunaway);
	assert_true(*isRunawayDetector == 0);
	DestroySessionStateArray();
}
/*
 * Checks if RedZoneHandler_FlagTopConsumer() updates the CurrentVersion and
 * latestRunawayVersion
 */
static void
test__RedZoneHandler_FlagTopConsumer__UpdatesEventVersions(void **state)
{
	/* Make sure the RedZoneHandler_FlagTopConsumer code is exercised */
	vmemTrackerInited = true;
	CreateSessionStateArray(1);
	/* Make sure MySessionState is valid */
	SessionState *one = AcquireSessionState(1 /* sessionId */, 100 /* vmem */, 1 /* activeProcessCount */);
	/* Ensure we can detect runaway sessions */
	*isRunawayDetector = 0;
	will_be_called_count(LWLockAcquire, 1);
	will_be_called_count(LWLockRelease, 1);
	expect_any_count(LWLockAcquire, lock, 1);
	expect_any_count(LWLockAcquire, mode, 1);
	expect_any_count(LWLockRelease, lock, 1);
	static EventVersion fakeLatestRunawayVersion = 0;
	static EventVersion fakeCurrentVersion = 1;
	latestRunawayVersion = &fakeLatestRunawayVersion;
	CurrentVersion = &fakeCurrentVersion;
	RedZoneHandler_FlagTopConsumer();
	assert_true(one->runawayStatus == RunawayStatus_PrimaryRunawaySession);
	/* Verify that the event versions were properly updated */
	assert_true(*CurrentVersion == 3 && *latestRunawayVersion == 2);
	DestroySessionStateArray();
}
int
main(int argc, char* argv[])
{
	cmockery_parse_arguments(argc, argv);
	const UnitTest tests[] = {
		unit_test(test__RedZoneHandler_ShmemInit__InitializesGlobalVarsWhenPostmaster),
		unit_test(test__RedZoneHandler_ShmemInit__InitializesUnderPostmaster),
		unit_test(test__RedZoneHandler_IsVmemRedZone__ProperlyIdentifiesRedZone),
		unit_test(test__RedZoneHandler_FlagTopConsumer__SingletonDetector),
		unit_test(test__RedZoneHandler_FlagTopConsumer__FindsTopConsumer),
		unit_test(test__RedZoneHandler_FlagTopConsumer__IgnoresIdleSession),
		unit_test(test__RedZoneHandler_FlagTopConsumer__ReactivatesDetectorIfNoActiveSession),
		unit_test(test__RedZoneHandler_FlagTopConsumer__UpdatesEventVersions),
	};
	return run_tests(tests);
}
相关信息
相关文章
greenplumn event_version_test 源码
greenplumn idle_tracker_test 源码
                        
                            0
                        
                        
                             赞
                        
                    
                    
                热门推荐
- 
                        2、 - 优质文章
 - 
                        3、 gate.io
 - 
                        7、 openharmony
 - 
                        9、 golang