Beispiel #1
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();
}
Beispiel #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();
}
Beispiel #3
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();
}
Beispiel #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();
}
Beispiel #5
0
/*
 * Checks if SessionState_ShmemInit initializes the usedList and freeList
 * properly
 */
void
test__SessionState_ShmemInit__LinkedListSanity(void **state)
{
	/* Only 3 entries to test the linked list sanity */
	CreateSessionStateArray(3);

	assert_true(AllSessionStateEntries->usedList == NULL &&
			AllSessionStateEntries->freeList ==  &AllSessionStateEntries->sessions[0] &&
			AllSessionStateEntries->sessions[0].next == &AllSessionStateEntries->sessions[1] &&
			AllSessionStateEntries->sessions[1].next == &AllSessionStateEntries->sessions[2] &&
			AllSessionStateEntries->sessions[2].next == NULL);

	DestroySessionStateArray();
}
Beispiel #6
0
/*
 * Checks if SessionState_ShmemInit initializes the SessionState entries
 * when postmaster
 */
void
test__SessionState_ShmemInit__InitializesWhenPostmaster(void **state)
{
	IsUnderPostmaster = false;

	/* The intention is that MAX_BACKENDS here would match the value in guc.c */
#define MAX_BACKENDS 0x7fffff

	int allMaxBackends[] = {1, 100, MAX_BACKENDS};

	for (int i = 0; i < sizeof(allMaxBackends) / sizeof(int); i++)
	{
		CreateSessionStateArray(allMaxBackends[i]);

		/* All the struct properties should be unchanged */
		assert_true(AllSessionStateEntries->maxSession == MaxBackends);
		assert_true(AllSessionStateEntries->numSession == 0);
		assert_true(AllSessionStateEntries->freeList == AllSessionStateEntries->sessions &&
				AllSessionStateEntries->usedList == NULL);

		SessionState *prev = NULL;
		for (int j = 0; j < MaxBackends; j++)
		{
			SessionState *cur = &AllSessionStateEntries->sessions[j];
			assert_true(cur->sessionId == INVALID_SESSION_ID);
			assert_true(cur->cleanupCountdown == CLEANUP_COUNTDOWN_BEFORE_RUNAWAY);
			assert_true(cur->runawayStatus == RunawayStatus_NotRunaway);
			assert_true(cur->pinCount == 0);
			assert_true(cur->activeProcessCount == 0);
			assert_true(cur->idle_start == 0);
			assert_true(cur->sessionVmem == 0);
			assert_true(cur->spinLock == 0);

			if (prev != NULL)
			{
				assert_true(prev->next == cur);
			}

			prev = cur;
		}

		assert_true(prev->next == NULL);

		DestroySessionStateArray();
	}
}
Beispiel #7
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();
}
Beispiel #8
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();
}
Beispiel #9
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();
}
Beispiel #10
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();
}
Beispiel #11
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();
}
Beispiel #12
0
/*
 * Checks if SessionState_Init initializes the global variables
 * such as MySessionState and sessionStateInited properly
 */
void
test__SessionState_Init__TestSideffects(void **state)
{
	/* Only 2 entry to test initialization */
	CreateSessionStateArray(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);

	assert_true(MySessionState == NULL);
	assert_true(sessionStateInited == false);

	EXPECT_EREPORT(gp_sessionstate_loglevel);
	SessionState_Init();

	assert_true(NULL != MySessionState);
	assert_true(sessionStateInited);

	DestroySessionStateArray();
}