Files
openGauss-server/src/test/whitebox/knl_whitebox_test.cpp
2021-09-23 15:19:37 +08:00

284 lines
10 KiB
C++

/*
* -------------------------------------------------------------------------
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*
* knl_uheaptest.cpp
* Implementation for uheap test framework.
*
* IDENTIFICATION
* src/gausskernel/cbb/utils/debug/knl_uheaptest.cpp
*
* -------------------------------------------------------------------------
*/
#include "knl/knl_variable.h"
#include "utils/builtins.h"
#include "access/ustore/knl_whitebox_test.h"
#include "port.h"
const uint32 BUFSIZE = 1024;
bool VerifyBeforeTest (const char* newval)
{
if (g_instance.whitebox_test_param_instance &&
strcmp(newval, g_instance.whitebox_test_param_instance->test_file_name) == 0) {
elog(LOG, "AssignUstoreUnitTest: g_instance.whitebox_test_param_instance is already initialized");
return false;
}
if (!g_instance.whitebox_test_param_instance) {
g_instance.whitebox_test_param_instance =
(WhiteboxTestParam *)palloc(sizeof(WhiteboxTestParam) * (MAX_UNIT_TEST));
}
g_instance.whitebox_test_param_instance->elevel = WARNING;
int rc = sprintf_s(g_instance.whitebox_test_param_instance->test_file_name, MAX_NAME_STR_LEN, "%s", newval);
securec_check_ss_c(rc, "\0", "\0");
if (strcmp(newval, "") == 0) {
g_instance.whitebox_test_param_instance->num_testcase = 0;
elog(LOG, "AssignUstoreUnitTest: ustore_unit_test is empty");
return false;
}
return true;
}
void AssignUStoreUnitTest(const char* newval, const void* extra)
{
FILE *fp;
char buffer[BUFSIZE];
int i = 0;
bool ret = false;
ret = VerifyBeforeTest(newval);
if (!ret) {
return;
}
fp = fopen(newval, PG_BINARY_RW);
if (!fp) {
g_instance.whitebox_test_param_instance->num_testcase = 0;
elog(LOG, "AssignUstoreUnitTest: ustore_unit_test does not exist");
return;
}
while (fgets(buffer, BUFSIZE, fp) != NULL) {
char* ptoken = NULL;
char* psave = NULL;
char* ptype = NULL;
char* pvalue = NULL;
const char* pcomma = ",";
const char* pequal = "=";
// skip comment
if (!buffer || buffer[0] == '#') {
continue;
}
elog(LOG, "ustore_unit_test: %s", buffer);
// expand array of test param
g_instance.whitebox_test_param_instance->num_testcase = i + 1;
// test stub name
ptoken = strtok_r(buffer, pcomma, &psave);
int rc = sprintf_s(g_instance.whitebox_test_param_instance[i].test_stub_name, MAX_NAME_STR_LEN, "%s", ptoken);
securec_check_ss_c(rc, "\0", "\0");
// test stub type
ptoken = strtok_r(NULL, pcomma, &psave);
if (strcmp(ptoken, "PRINT") == 0) {
g_instance.whitebox_test_param_instance[i].type = WHITEBOX_PRINT;
} else if (strcmp(ptoken, "SLEEP") == 0) {
g_instance.whitebox_test_param_instance[i].type = WHITEBOX_SLEEP;
} else if (strcmp(ptoken, "SUSPEND") == 0) {
g_instance.whitebox_test_param_instance[i].type = WHITEBOX_SUSPEND;
} else if (strcmp(ptoken, "ENABLE") == 0) {
g_instance.whitebox_test_param_instance[i].type = WHITEBOX_ENABLE;
} else if (strcmp(ptoken, "DISABLE") == 0) {
g_instance.whitebox_test_param_instance[i].type = WHITEBOX_DISABLE;
} else if (strcmp(ptoken, "ERROR") == 0) {
g_instance.whitebox_test_param_instance[i].type = WHITEBOX_ERROR;
}
// test stub attributes
ptoken = strtok_r(NULL, pcomma, &psave);
while (ptoken) {
ptype = TrimStr(strtok_r(ptoken, pequal, &pvalue));
if (!ptype || !pvalue) {
break;
}
if (strcmp(ptype, "TIMEOUT") == 0) {
g_instance.whitebox_test_param_instance[i].attributes.timeout = pg_strtoint32(pvalue);
} else if (strcmp(ptype, "ENABLED") == 0) {
g_instance.whitebox_test_param_instance[i].attributes.enabled = (bool) pg_strtoint32(pvalue);
} else if (strcmp(ptype, "SKIP_ITERATION") == 0) {
g_instance.whitebox_test_param_instance[i].attributes.skip_iteration = pg_strtoint32(pvalue);
} else if (strcmp(ptype, "TARGET_TEST_STUB") == 0) {
rc = sprintf_s(g_instance.whitebox_test_param_instance[i].attributes.target_test_stub, MAX_NAME_STR_LEN,
"%s", TrimStr(pvalue));
securec_check_ss_c(rc, "\0", "\0");
}
ptoken = strtok_r(NULL, pcomma, &psave);
}
g_instance.whitebox_test_param_instance[i].attributes.hit_count = 0;
i++;
}
fclose(fp);
}
/**
* @Description: check whether the test stub can be activated.
* @in name - the white-box single-point fault fire tag, is a string defined in GUC
* @in function - callback function
* @return - true if one or more breakpoints have been activated; false otherwise
*/
bool WhiteboxTestStubActivator(const char* name, whitebox_stub_callback function)
{
bool result = false;
if (g_instance.whitebox_test_param_instance == NULL) {
return false;
}
if (t_thrd.proc_cxt.proc_exit_inprogress) {
return false;
}
if (g_instance.whitebox_test_param_instance->num_testcase > MAX_UNIT_TEST) {
return false;
}
for (int i = 0; i < g_instance.whitebox_test_param_instance->num_testcase; i++) {
if (pg_strcasecmp(name, g_instance.whitebox_test_param_instance[i].test_stub_name) == 0) {
result = result || (*function)(g_instance.whitebox_test_param_instance[i]);
}
}
return result;
}
/**
* @Description: default uheap-error emit callback function.
* @in - a reference to test parameters
* @return - true if one or more breakpoints have been activated; false otherwise
*/
bool WhiteboxDefaultErrorEmit(WhiteboxTestParam& uheapTestParamInstance)
{
bool result = false;
if (g_instance.whitebox_test_param_instance->elevel == PANIC) {
exit(0);
}
switch (uheapTestParamInstance.type) {
case WHITEBOX_PRINT:
result = WhiteboxTestPrint(uheapTestParamInstance.test_stub_name);
break;
case WHITEBOX_SLEEP:
result = WhiteboxTestSleep(
uheapTestParamInstance.test_stub_name,
uheapTestParamInstance.attributes.timeout,
uheapTestParamInstance.attributes.skip_iteration,
uheapTestParamInstance.attributes.hit_count);
break;
case WHITEBOX_SUSPEND:
result = WhiteboxTestSuspend(
uheapTestParamInstance.test_stub_name,
uheapTestParamInstance.attributes.timeout,
uheapTestParamInstance.attributes.enabled);
break;
case WHITEBOX_ENABLE:
result = WhiteboxTestSetEnable(
uheapTestParamInstance.attributes.target_test_stub, true);
break;
case WHITEBOX_DISABLE:
result = WhiteboxTestSetEnable(
uheapTestParamInstance.attributes.target_test_stub, false);
break;
case WHITEBOX_ERROR:
result = WhiteboxTestSetError(
uheapTestParamInstance.test_stub_name,
uheapTestParamInstance.attributes.enabled);
break;
default:
break;
}
return false; // make it always false for now, to mute the message printing at each breakpoint
}
bool WhiteboxTestPrint(const char* functionName)
{
ereport(NOTICE, (errmsg("Hitting breakpoint %s", functionName)));
return true;
}
bool WhiteboxTestSetError(const char* functionName, const bool& enabled)
{
if (enabled) {
ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("Hitting breakpoint %s", functionName)));
return true;
} else {
return false;
}
}
bool WhiteboxTestSleep(const char* functionName, int timeout, int skipIteration, int& hitCount)
{
hitCount++;
if (hitCount > skipIteration) {
hitCount = 0;
elog(g_instance.whitebox_test_param_instance->elevel,
"Suspending at breakpoint %s timeout=%d", functionName, timeout);
pg_usleep(timeout);
return true;
} else {
return false;
}
}
bool WhiteboxTestSuspend(const char* functionName, int timeout, const bool& enabled)
{
int elapseTime = 0;
int elapseInterval = 1000; // 1/1000 second
if (enabled) {
elog(g_instance.whitebox_test_param_instance->elevel, "Suspending at breakpoint %s timeout=%d",
functionName, timeout);
while (elapseTime < timeout) {
// check for interrupts
if (!enabled) {
break;
}
elapseTime += elapseInterval;
pg_usleep(elapseInterval);
}
return true;
} else {
return false;
}
}
bool WhiteboxTestSetEnable(const char* functionName, bool enabled)
{
for (int i = 0; i < g_instance.whitebox_test_param_instance->num_testcase; i++) {
if (pg_strcasecmp(functionName, g_instance.whitebox_test_param_instance[i].test_stub_name) == 0) {
g_instance.whitebox_test_param_instance[i].attributes.enabled = enabled;
if (enabled) {
elog(g_instance.whitebox_test_param_instance->elevel, "Enabling breakpoint %s type=%d", functionName,
g_instance.whitebox_test_param_instance[i].type);
} else {
elog(g_instance.whitebox_test_param_instance->elevel, "Disabling breakpoint %s type=%d", functionName,
g_instance.whitebox_test_param_instance[i].type);
}
}
}
return true;
}