예제 #1
0
/*
 * Checks if SessionState_Shutdown decrements pinCount and releases
 * SessionState entry as appropriate. The usedList, freeList and
 * sessions array are also checked for sanity
 */
void
test__SessionState_Shutdown__ReleaseSessionEntry(void **state)
{
	/* Only 3 entries to test the reuse */
	CreateSessionStateArray(3);

	/* These should be new */
	SessionState *first = AcquireSessionState(1, gp_sessionstate_loglevel);
	SessionState *second = AcquireSessionState(2, gp_sessionstate_loglevel);
	SessionState *third = AcquireSessionState(3, gp_sessionstate_loglevel);

	assert_true(first != second);
	assert_true(second != third);

	SessionState *reuseFirst = AcquireSessionState(1, gp_sessionstate_loglevel);
	assert_true(reuseFirst == first);
	assert_true(reuseFirst->pinCount == 2);
	assert_true(AllSessionStateEntries->usedList == third &&
			third->next == second && second->next == first);

	/* The entire linked list has been reversed as we shift from freeList to usedList*/
	assert_true(AllSessionStateEntries->sessions[0].next == NULL &&
			AllSessionStateEntries->sessions[1].next == &AllSessionStateEntries->sessions[0] &&
			AllSessionStateEntries->sessions[2].next == &AllSessionStateEntries->sessions[1]);
	/* The last entry is at the head of the usedList */
	assert_true(AllSessionStateEntries->usedList == &AllSessionStateEntries->sessions[2] &&
			third == &AllSessionStateEntries->sessions[2]);
	/* All 3 entries are consumed */
	assert_true(AllSessionStateEntries->freeList == NULL);

	/* Release 1 entry */
	ReleaseSessionState(2);
	assert_true(AllSessionStateEntries->freeList == second);
	assert_true(AllSessionStateEntries->numSession == 2);

	/* Entry 1 had 2 pinCount. So, we need 2 release call. */
	ReleaseSessionState(1);
	assert_true(AllSessionStateEntries->numSession == 2);
	/* Only 1 free entry */
	assert_true(AllSessionStateEntries->freeList->next == NULL);
	ReleaseSessionState(1);
	assert_true(AllSessionStateEntries->numSession == 1);
	/* Only 1 used entry */
	assert_true(AllSessionStateEntries->usedList->next == NULL);

	/* Release entry for session 3 */
	ReleaseSessionState(3);
	assert_true(AllSessionStateEntries->numSession == 0);
	/*
	 * Based on free ordering, now we have session 2 at the tail of freeList, preceeded by
	 * session 1 and preceded by session 3. Note, the indexing starts at 0, while session
	 * id starts at 1
	 */
	assert_true(AllSessionStateEntries->sessions[1].next == NULL &&
			AllSessionStateEntries->sessions[0].next == &AllSessionStateEntries->sessions[1] &&
			AllSessionStateEntries->sessions[2].next == &AllSessionStateEntries->sessions[0]);
	assert_true(AllSessionStateEntries->freeList == &AllSessionStateEntries->sessions[2]);
	assert_true(AllSessionStateEntries->usedList == NULL);
	DestroySessionStateArray();
}
예제 #2
0
/*
 * Checks if SessionState_Init fails when no more SessionState entry
 * is available to satisfy a new request
 */
void
test__SessionState_Init__FailsIfNoFreeSessionStateEntry(void **state)
{
	/* Only 3 entries to exhaust the entries */
	CreateSessionStateArray(3);

	/* These should be new */
	SessionState *first = AcquireSessionState(1, gp_sessionstate_loglevel);
	SessionState *second = AcquireSessionState(2, gp_sessionstate_loglevel);
	SessionState *third = AcquireSessionState(3, gp_sessionstate_loglevel);

	PG_TRY();
	{
		/* No more SessionState entry to satisfy this request */
		SessionState *fourth = AcquireSessionState(4, FATAL);
		assert_false("No ereport(FATAL, ...) was called");
	}
	PG_CATCH();
	{

	}
	PG_END_TRY();

	DestroySessionStateArray();
}
예제 #3
0
/*
 * Checks if RedZoneHandler_FlagTopConsumer() updates the CurrentVersion and
 * latestRunawayVersion
 */
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, l, 1);
	expect_any_count(LWLockAcquire, mode, 1);
	expect_any_count(LWLockRelease, l, 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();
}
예제 #4
0
/*
 * Checks if SessionState_Init initializes a SessionState entry after acquiring
 */
void
test__SessionState_Init__AcquiresAndInitializes(void **state)
{
	/* Only 2 entry to test initialization */
	CreateSessionStateArray(1);

	SessionState *theEntry = AllSessionStateEntries->freeList;

	theEntry->activeProcessCount = 1234;
	theEntry->idle_start = 1234;
	theEntry->cleanupCountdown = 1234;
	theEntry->runawayStatus = RunawayStatus_PrimaryRunawaySession;
	theEntry->pinCount = 1234;
	theEntry->sessionId = 1234;
	theEntry->sessionVmem = 1234;
	/* Mark it as acquired and see if it is released */
	SpinLockAcquire(&theEntry->spinLock);
	assert_true(theEntry->spinLock == 1);

	/* These should be new */
	SessionState *first = AcquireSessionState(1, gp_sessionstate_loglevel);
	assert_true(first == theEntry);

	assert_true(theEntry->activeProcessCount == 0);
	assert_true(theEntry->idle_start == 0);
	assert_true(theEntry->cleanupCountdown == CLEANUP_COUNTDOWN_BEFORE_RUNAWAY);
	assert_true(theEntry->runawayStatus == RunawayStatus_NotRunaway);
	assert_true(theEntry->pinCount == 1);
	assert_true(theEntry->sessionId == 1);
	assert_true(theEntry->sessionVmem == 0);
	assert_true(theEntry->spinLock == 0);

	DestroySessionStateArray();
}
예제 #5
0
/*
 * Checks if RedZoneHandler_FlagTopConsumer() reactivates the runaway detector
 * if there is no active session
 */
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, l, 1);
	expect_any_count(LWLockAcquire, mode, 1);
	expect_any_count(LWLockRelease, l, 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();
}
예제 #6
0
/*
 * Checks if RedZoneHandler_FlagTopConsumer() ignores the idle sessions
 * even if they are the top consumer
 */
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, l, 1);
	expect_any_count(LWLockAcquire, mode, 1);
	expect_any_count(LWLockRelease, l, 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();
}
예제 #7
0
/*
 * Checks if RedZoneHandler_FlagTopConsumer() finds the top consumer
 */
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, l, 1);
	expect_any_count(LWLockAcquire, mode, 1);
	expect_any_count(LWLockRelease, l, 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();
}
예제 #8
0
/*
 * Checks if SessionState_Shutdown marks the session clean when the pinCount
 * drops to 0 (i.e., releasing the entry back to the freeList)
 */
void
test__SessionState_Shutdown__MarksSessionCleanUponRelease(void **state)
{
	/* Only 3 entries to test the reuse */
	CreateSessionStateArray(1);

	/* These should be new */
	SessionState *first = AcquireSessionState(1, gp_sessionstate_loglevel);
	SessionState *reuseFirst = AcquireSessionState(1, gp_sessionstate_loglevel);
	SessionState *reuseAgain = AcquireSessionState(1, gp_sessionstate_loglevel);

	assert_true(reuseFirst == first && reuseAgain == first);
	assert_true(reuseFirst->pinCount == 3);

	/* Entry 1 had 2 pinCount. So, we need 3 release call. */
	ReleaseSessionState(1);
	assert_true(reuseFirst->pinCount == 2 && AllSessionStateEntries->numSession == 1);
	ReleaseSessionState(1);
	assert_true(reuseFirst->pinCount == 1 && AllSessionStateEntries->numSession == 1);

	will_be_called_count(LWLockAcquire, 1);
	will_be_called_count(LWLockRelease, 1);
	expect_any_count(LWLockAcquire, lockid, 1);
	expect_any_count(LWLockAcquire, mode, 1);
	expect_any_count(LWLockRelease, lockid, 1);

	/* Bypass assertion */
	MySessionState = first;
	sessionStateInited = true;
	will_be_called(RunawayCleaner_RunawayCleanupDoneForSession);
	EXPECT_EREPORT(gp_sessionstate_loglevel);
	/* This will finally release the entry */
	SessionState_Shutdown();

	assert_true(AllSessionStateEntries->numSession == 0);

	DestroySessionStateArray();
}
예제 #9
0
/*
 * Checks if SessionState_Init acquires a new entry as well as
 * reuse an existing entry whenever possible
 */
void
test__SessionState_Init__AcquiresWithReuse(void **state)
{
	/* Only 3 entries to test the reuse */
	CreateSessionStateArray(3);

	/* These should be new */
	SessionState *first = AcquireSessionState(1, gp_sessionstate_loglevel);
	SessionState *second = AcquireSessionState(2, gp_sessionstate_loglevel);
	SessionState *third = AcquireSessionState(3, gp_sessionstate_loglevel);

	assert_true(first != second);
	assert_true(first != third);
	assert_true(second != third);

	SessionState *reuseFirst = AcquireSessionState(1, gp_sessionstate_loglevel);
	assert_true(reuseFirst == first);
	assert_true(reuseFirst->pinCount == 2);
	assert_true(AllSessionStateEntries->usedList == third &&
			third->next == second && second->next == first);

	DestroySessionStateArray();
}
예제 #10
0
/* Releases a SessionState entry for the specified sessionId */
static void
ReleaseSessionState(int sessionId)
{
	/* We call shutdown twice */
	will_be_called_count(LWLockAcquire, 2);
	will_be_called_count(LWLockRelease, 2);

	expect_any_count(LWLockAcquire, lockid, 2);
	expect_any_count(LWLockAcquire, mode, 2);
	expect_any_count(LWLockRelease, lockid, 2);

	gp_session_id = sessionId;
	/* First find the previously allocated session state */
	SessionState *foundSessionState = AcquireSessionState(sessionId, gp_sessionstate_loglevel);

	assert_true(foundSessionState->sessionId == sessionId);
	/*
	 * It was pre-allocated and we incremented the pinCount
	 * for finding it
	 */
	assert_true(foundSessionState->pinCount > 1);
	/* Satisfy assertion */
	sessionStateInited = true;
	EXPECT_EREPORT(gp_sessionstate_loglevel);
	/* Undo for our search pinCount */
	SessionState_Shutdown();
	/* The pinCount should not drop to 0 as we just undid our own increment */
	assert_true(foundSessionState->pinCount >= 1);
	MySessionState = foundSessionState;
	sessionStateInited = true;
	/*
	 * If we are releasing this SessionState permanently, we need to ensure
	 * that RunawayCleaner_RunawayCleanupDoneForSession() will be called
	 */
	if (foundSessionState->pinCount == 1)
	{
		will_be_called(RunawayCleaner_RunawayCleanupDoneForSession);
	}

	EXPECT_EREPORT(gp_sessionstate_loglevel);
	/* Undo one more to truly undo previously acquired one */
	SessionState_Shutdown();
}