Adding means to inject values via stub function pointer to test subject. Resulting stubs are not backward compatible. If stubbed functions contain pointer as parameter the tests need to be addapted.

This commit is contained in:
2018-08-30 09:14:34 +00:00
parent b148884185
commit 335b74a844
2 changed files with 137 additions and 15 deletions

View File

@@ -14,6 +14,7 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#include <dirent.h> #include <dirent.h>
#include <regex.h> #include <regex.h>
#include <sys/stat.h> #include <sys/stat.h>
@@ -160,21 +161,55 @@ STATIC void createVariableSpecificCheck(FILE *aFile, cfile_variable_t *aVariable
STATIC void createParameterSpecificCheck(FILE *aFile, cfunction_t *aFunction, cfunction_parameter_t *aParameter, char aParameterIndex) STATIC void createParameterSpecificCheck(FILE *aFile, cfunction_t *aFunction, cfunction_parameter_t *aParameter, char aParameterIndex)
{ {
if (NULL != strstr(aParameter->dataType, "*") && NULL != strstr(aParameter->dataType, "char")) if (CPARAMETER_TYPE_FUNCPTR == aParameter->type)
{ {
fprintf(aFile, "\tCU_ASSERT_MEMORY_CHECK(\"%s(%s)\", ", aFunction->name, aParameter->name); // function pointer
fprintf(aFile, STUBINIT_PARAM_PARAMETER_S1", "STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_PARAM_S1, aParameterIndex, aFunction->name,
aFunction->name, aParameterIndex);
fprintf(aFile, ", strlen("STUBINIT_PARAM_PARAMETER_S1"));"NEWLINES, aParameterIndex);
}
else if (NULL != strstr(aParameter->dataType, "*") || NULL != aParameter->array)
{
// matches also function pointer (array containing function pointer parameter list)
fprintf(aFile, "\tCU_ASSERT_PTR_EQUAL("); fprintf(aFile, "\tCU_ASSERT_PTR_EQUAL(");
fprintf(aFile, STUBINIT_PARAM_PARAMETER_S1", "STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_PARAM_S1, aParameterIndex, aFunction->name, fprintf(aFile, STUBINIT_PARAM_PARAMETER_S1", "STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_PARAM_S1, aParameterIndex, aFunction->name,
aFunction->name, aParameterIndex); aFunction->name, aParameterIndex);
fprintf(aFile, ");"NEWLINES); fprintf(aFile, ");"NEWLINES);
} }
else if (NULL != strstr(aParameter->dataType, "*") && NULL != strstr(aParameter->dataType, "char"))
{
fprintf(aFile,
"\tif ("STUBPARAMETER_POINTERHANDLING_ADDRESS_S " == " STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_POINTERHANDLING_S")" NEWLINES "\t{" NEWLINES,
aFunction->name, aFunction->name);
fprintf(aFile, "\t\tCU_ASSERT_MEMORY_CHECK(\"%s(%s)\", ", aFunction->name, aParameter->name);
fprintf(aFile, STUBINIT_PARAM_PARAMETER_S1", "STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_PARAM_S1, aParameterIndex, aFunction->name,
aFunction->name, aParameterIndex);
fprintf(aFile, ", strlen("STUBINIT_PARAM_PARAMETER_S1"));"NEWLINES, aParameterIndex);
fprintf(aFile, "\t}" NEWLINES);
if (NULL == strstr(aParameter->dataType, "const"))
{
fprintf(aFile, "\telse" NEWLINES "\t{" NEWLINES);
fprintf(aFile, "\t\tmemcpy(" STUBINIT_PARAM_PARAMETER_S1 ", "STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_PARAM_S1", " //
STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_PARAM_S1"_size",//
aParameterIndex, aFunction->name, aFunction->name, aParameterIndex, aFunction->name, aFunction->name, aParameterIndex);
fprintf(aFile, ");" NEWLINES);
fprintf(aFile, "\t}" NEWLINES);
}
}
else if (NULL != strstr(aParameter->dataType, "*") || NULL != aParameter->array)
{
// pointer
fprintf(aFile,
"\tif ("STUBPARAMETER_POINTERHANDLING_ADDRESS_S " == " STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_POINTERHANDLING_S")" NEWLINES "\t{" NEWLINES,
aFunction->name, aFunction->name);
fprintf(aFile, "\t\tCU_ASSERT_PTR_EQUAL(");
fprintf(aFile, STUBINIT_PARAM_PARAMETER_S1", "STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_PARAM_S1, aParameterIndex, aFunction->name,
aFunction->name, aParameterIndex);
fprintf(aFile, ");" NEWLINES);
fprintf(aFile, "\t}" NEWLINES);
if (NULL == strstr(aParameter->dataType, "const"))
{
fprintf(aFile, "\telse" NEWLINES "\t{" NEWLINES);
fprintf(aFile, "\t\tmemcpy(" STUBINIT_PARAM_PARAMETER_S1 ", "STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_PARAM_S1", " //
STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_PARAM_S1"_size",//
aParameterIndex, aFunction->name, aFunction->name, aParameterIndex, aFunction->name, aFunction->name, aParameterIndex);
fprintf(aFile, ");" NEWLINES);
fprintf(aFile, "\t}" NEWLINES);
}
}
else if (isDatatypeStandard(aParameter->dataType)) else if (isDatatypeStandard(aParameter->dataType))
{ {
fprintf(aFile, "\tCU_ASSERT_EQUAL("); fprintf(aFile, "\tCU_ASSERT_EQUAL(");
@@ -327,6 +362,18 @@ STATIC int8_t createStubFunctionBlock(FILE *aFile, FILE *aHeader, cfunction_t *a
{ {
cfunction_parameter_t *parameter = NULL; cfunction_parameter_t *parameter = NULL;
char parameterIndex = 'a'; char parameterIndex = 'a';
bool pointerAvailable = false;
parameter = aFunction->parameter.head;
while (parameter)
{
if (NULL != strstr(parameter->dataType, "*") || parameter->array)
{
pointerAvailable = true;
break;
}
parameter = parameter->next;
}
if (NULL == aFile || NULL == aHeader || NULL == aFunction) if (NULL == aFile || NULL == aHeader || NULL == aFunction)
{ {
@@ -349,10 +396,14 @@ STATIC int8_t createStubFunctionBlock(FILE *aFile, FILE *aHeader, cfunction_t *a
fprintf(aFile, "// Expected parameter and return value structures" NEWLINES); fprintf(aFile, "// Expected parameter and return value structures" NEWLINES);
fprintf(aFile, "typedef struct _STUBPARAMETER_%s" NEWLINES, aFunction->name); fprintf(aFile, "typedef struct _STUBPARAMETER_%s" NEWLINES, aFunction->name);
fprintf(aFile, "{" NEWLINES); fprintf(aFile, "{" NEWLINES);
fprintf(aFile, "\tuint8_t "STUBPARAMETER_CALLTEST_S"; /**< @brief If stub call is a STUB_CALL_PASS or STUB_CALL_FAIL */" NEWLINES); fprintf(aFile, "\tuint8_t "STUBPARAMETER_CALLTEST_S"; /*!< @brief If stub call is a STUB_CALL_PASS or STUB_CALL_FAIL */" NEWLINES);
if (pointerAvailable)
{
fprintf(aFile, "\t%s "STUBPARAMETER_POINTERHANDLING_S"; /*!< @brief pointer handling */" NEWLINES, STUBPARAMETER_POINTERHANDLING_ENUM_S);
}
if (!isDatatypeVoid(aFunction->dataType)) if (!isDatatypeVoid(aFunction->dataType))
{ {
fprintf(aFile, "\t%s "STUBPARAMETER_RETURN_S"; /**< @brief return value */" NEWLINES, aFunction->dataType); fprintf(aFile, "\t%s "STUBPARAMETER_RETURN_S"; /*!< @brief return value */" NEWLINES, aFunction->dataType);
} }
parameter = aFunction->parameter.head; parameter = aFunction->parameter.head;
parameterIndex = 'a'; parameterIndex = 'a';
@@ -365,7 +416,15 @@ STATIC int8_t createStubFunctionBlock(FILE *aFile, FILE *aHeader, cfunction_t *a
} }
else if (parameter->array) else if (parameter->array)
{ {
fprintf(aFile, "\t%s *"STUBPARAMETER_PARAM_S1"; /*!< @brief %s */" NEWLINES, NCHECK(parameter->dataType), parameterIndex++, NCHECK(parameter->name)); fprintf(aFile, "\t%s *"STUBPARAMETER_PARAM_S1"; /*!< @brief %s */" NEWLINES, NCHECK(parameter->dataType), parameterIndex, NCHECK(parameter->name));
fprintf(aFile, "\tuint32_t "STUBPARAMETER_PARAM_S1"_size; /*!< @brief %s size to copy in case of parameter injection */" NEWLINES, parameterIndex++,
NCHECK(parameter->name));
}
else if (NULL != strstr(parameter->dataType, "*"))
{
fprintf(aFile, "\t%s "STUBPARAMETER_PARAM_S1"; /*!< @brief %s */" NEWLINES, NCHECK(parameter->dataType), parameterIndex, NCHECK(parameter->name));
fprintf(aFile, "\tuint32_t "STUBPARAMETER_PARAM_S1"_size; /*!< @brief %s size to copy in case of parameter injection */" NEWLINES, parameterIndex++,
NCHECK(parameter->name));
} }
else if (CPARAMETER_TYPE_REGULAR == parameter->type) else if (CPARAMETER_TYPE_REGULAR == parameter->type)
{ {
@@ -379,7 +438,7 @@ STATIC int8_t createStubFunctionBlock(FILE *aFile, FILE *aHeader, cfunction_t *a
// Instance counter // Instance counter
fprintf(aFile, "// Instance counter for stub functions" NEWLINES); fprintf(aFile, "// Instance counter for stub functions" NEWLINES);
fprintf(aFile, "uint8_t "STUBINSTANCE_S1" = 0;" NEWLINES, aFunction->name); fprintf(aFile, STUBINSTANCE_DATATYPE_S" "STUBINSTANCE_S1" = 0;" NEWLINES, aFunction->name);
NEWLINE(aFile); NEWLINE(aFile);
// expected parameter // expected parameter
@@ -388,8 +447,40 @@ STATIC int8_t createStubFunctionBlock(FILE *aFile, FILE *aHeader, cfunction_t *a
aFunction->name); aFunction->name);
NEWLINE(aFile); NEWLINE(aFile);
// stub function init header; function comment
fprintf(aHeader, "/*! @brief Stub initialization of init_%s" NEWLINES, aFunction->name);
fprintf(aHeader, " * @param " STUBINIT_PARAM_INSTANCE_S " Which stub call to initialize" NEWLINES);
fprintf(aHeader, " * @param " STUBINIT_PARAM_CALLTEST_S " Is stub call allowed (STUB_CALL_FAIL, STUB_CALL_PASS)" NEWLINES);
if (pointerAvailable)
{
fprintf(aHeader,
" * @param " STUBINIT_PARAM_POINTERHANDLING_S " How to handle pointer to data (STUB_PARAMETER_POINTER_HANDLING_ADDRESS, STUB_PARAMETER_POINTER_HANDLING_INJECT" NEWLINES);
}
if (!isDatatypeVoid(aFunction->dataType))
{
fprintf(aHeader, " * @param " STUBINIT_PARAM_RETURN_S " Return value to inject" NEWLINES);
}
parameter = aFunction->parameter.head;
parameterIndex = 'a';
while (parameter)
{
if (NULL != strstr(parameter->dataType, "*") || parameter->array)
{
fprintf(aHeader,
" * @param " STUBINIT_PARAM_PARAMETER_S1 "_size Use injection size 0 to ignore pointer (e.g. test subject references to internal variables)" NEWLINES,
parameterIndex);
}
parameterIndex++;
parameter = parameter->next;
}
fprintf(aHeader, " */" NEWLINES);
// stub function init header // stub function init header
fprintf(aHeader, "void init_%s(uint8_t "STUBINIT_PARAM_INSTANCE_S", uint8_t "STUBINIT_PARAM_CALLTEST_S, aFunction->name); fprintf(aHeader, "void init_%s("STUBINSTANCE_DATATYPE_S " " STUBINIT_PARAM_INSTANCE_S", uint8_t "STUBINIT_PARAM_CALLTEST_S, aFunction->name);
if (pointerAvailable)
{
fprintf(aHeader, ", %s "STUBINIT_PARAM_POINTERHANDLING_S, STUBPARAMETER_POINTERHANDLING_ENUM_S);
}
if (!isDatatypeVoid(aFunction->dataType)) if (!isDatatypeVoid(aFunction->dataType))
{ {
fprintf(aHeader, ", %s "STUBINIT_PARAM_RETURN_S, aFunction->dataType); fprintf(aHeader, ", %s "STUBINIT_PARAM_RETURN_S, aFunction->dataType);
@@ -402,6 +493,11 @@ STATIC int8_t createStubFunctionBlock(FILE *aFile, FILE *aHeader, cfunction_t *a
{ {
fprintf(aHeader, ", %s (*"STUBINIT_PARAM_PARAMETER_S1")%s", NCHECK(parameter->dataType), parameterIndex++, NCHECK(parameter->array)); fprintf(aHeader, ", %s (*"STUBINIT_PARAM_PARAMETER_S1")%s", NCHECK(parameter->dataType), parameterIndex++, NCHECK(parameter->array));
} }
else if (NULL != strstr(parameter->dataType, "*") || parameter->array)
{
fprintf(aHeader, ", %s "STUBINIT_PARAM_PARAMETER_S1"%s", NCHECK(parameter->dataType), parameterIndex, NCHECK(parameter->array));
fprintf(aHeader, ", uint32_t "STUBINIT_PARAM_PARAMETER_S1"_size", parameterIndex++);
}
else else
{ {
fprintf(aHeader, ", %s "STUBINIT_PARAM_PARAMETER_S1"%s", NCHECK(parameter->dataType), parameterIndex++, NCHECK(parameter->array)); fprintf(aHeader, ", %s "STUBINIT_PARAM_PARAMETER_S1"%s", NCHECK(parameter->dataType), parameterIndex++, NCHECK(parameter->array));
@@ -411,7 +507,11 @@ STATIC int8_t createStubFunctionBlock(FILE *aFile, FILE *aHeader, cfunction_t *a
fprintf(aHeader, ");" NEWLINES); fprintf(aHeader, ");" NEWLINES);
// stub function init // stub function init
fprintf(aFile, "void init_%s(uint8_t "STUBINIT_PARAM_INSTANCE_S", uint8_t "STUBINIT_PARAM_CALLTEST_S, aFunction->name); fprintf(aFile, "void init_%s("STUBINSTANCE_DATATYPE_S " " STUBINIT_PARAM_INSTANCE_S", uint8_t "STUBINIT_PARAM_CALLTEST_S, aFunction->name);
if (pointerAvailable)
{
fprintf(aFile, ", %s "STUBINIT_PARAM_POINTERHANDLING_S, STUBPARAMETER_POINTERHANDLING_ENUM_S);
}
if (!isDatatypeVoid(aFunction->dataType)) if (!isDatatypeVoid(aFunction->dataType))
{ {
fprintf(aFile, ", %s "STUBINIT_PARAM_RETURN_S, aFunction->dataType); fprintf(aFile, ", %s "STUBINIT_PARAM_RETURN_S, aFunction->dataType);
@@ -424,6 +524,11 @@ STATIC int8_t createStubFunctionBlock(FILE *aFile, FILE *aHeader, cfunction_t *a
{ {
fprintf(aFile, ", %s (*"STUBINIT_PARAM_PARAMETER_S1")%s", NCHECK(parameter->dataType), parameterIndex++, NCHECK(parameter->array)); fprintf(aFile, ", %s (*"STUBINIT_PARAM_PARAMETER_S1")%s", NCHECK(parameter->dataType), parameterIndex++, NCHECK(parameter->array));
} }
else if (NULL != strstr(parameter->dataType, "*") || parameter->array)
{
fprintf(aFile, ", %s "STUBINIT_PARAM_PARAMETER_S1"%s", NCHECK(parameter->dataType), parameterIndex, NCHECK(parameter->array));
fprintf(aFile, ", uint32_t "STUBINIT_PARAM_PARAMETER_S1"_size", parameterIndex++);
}
else else
{ {
fprintf(aFile, ", %s "STUBINIT_PARAM_PARAMETER_S1"%s", NCHECK(parameter->dataType), parameterIndex++, NCHECK(parameter->array)); fprintf(aFile, ", %s "STUBINIT_PARAM_PARAMETER_S1"%s", NCHECK(parameter->dataType), parameterIndex++, NCHECK(parameter->array));
@@ -439,6 +544,12 @@ STATIC int8_t createStubFunctionBlock(FILE *aFile, FILE *aHeader, cfunction_t *a
fprintf(aFile, "\t"STUBINSTANCE_S1" = 0;" NEWLINES, aFunction->name); fprintf(aFile, "\t"STUBINSTANCE_S1" = 0;" NEWLINES, aFunction->name);
fprintf(aFile, "\t"STUBPARAMETER_STRUCT_S1"["STUBINIT_PARAM_INSTANCE_S"]."STUBPARAMETER_CALLTEST_S" = "STUBINIT_PARAM_CALLTEST_S";" NEWLINES, fprintf(aFile, "\t"STUBPARAMETER_STRUCT_S1"["STUBINIT_PARAM_INSTANCE_S"]."STUBPARAMETER_CALLTEST_S" = "STUBINIT_PARAM_CALLTEST_S";" NEWLINES,
aFunction->name); aFunction->name);
if (pointerAvailable)
{
fprintf(aFile,
"\t"STUBPARAMETER_STRUCT_S1"["STUBINIT_PARAM_INSTANCE_S"]."STUBPARAMETER_POINTERHANDLING_S" = "STUBINIT_PARAM_POINTERHANDLING_S";" NEWLINES,
aFunction->name);
}
if (!isDatatypeVoid(aFunction->dataType)) if (!isDatatypeVoid(aFunction->dataType))
{ {
fprintf(aFile, "\t"STUBPARAMETER_STRUCT_S1"["STUBINIT_PARAM_INSTANCE_S"]."STUBPARAMETER_RETURN_S" = "STUBINIT_PARAM_RETURN_S";" NEWLINES, fprintf(aFile, "\t"STUBPARAMETER_STRUCT_S1"["STUBINIT_PARAM_INSTANCE_S"]."STUBPARAMETER_RETURN_S" = "STUBINIT_PARAM_RETURN_S";" NEWLINES,
@@ -450,6 +561,11 @@ STATIC int8_t createStubFunctionBlock(FILE *aFile, FILE *aHeader, cfunction_t *a
{ {
fprintf(aFile, "\t"STUBPARAMETER_STRUCT_S1"["STUBINIT_PARAM_INSTANCE_S"]."STUBPARAMETER_PARAM_S1" = "STUBINIT_PARAM_PARAMETER_S1";" NEWLINES, fprintf(aFile, "\t"STUBPARAMETER_STRUCT_S1"["STUBINIT_PARAM_INSTANCE_S"]."STUBPARAMETER_PARAM_S1" = "STUBINIT_PARAM_PARAMETER_S1";" NEWLINES,
aFunction->name, parameterIndex, parameterIndex); aFunction->name, parameterIndex, parameterIndex);
if ((NULL != strstr(parameter->dataType, "*") || parameter->array) && CPARAMETER_TYPE_FUNCPTR != parameter->type)
{
fprintf(aFile, "\t"STUBPARAMETER_STRUCT_S1"["STUBINIT_PARAM_INSTANCE_S"]."STUBPARAMETER_PARAM_S1"_size = "STUBINIT_PARAM_PARAMETER_S1"_size;" NEWLINES,
aFunction->name, parameterIndex, parameterIndex);
}
++parameterIndex; ++parameterIndex;
parameter = parameter->next; parameter = parameter->next;
} }

View File

@@ -31,12 +31,18 @@
#define STUBPARAMETER_STRUCT_S1 "stubparameter_%s" // stubparameter_modulfunction_1 #define STUBPARAMETER_STRUCT_S1 "stubparameter_%s" // stubparameter_modulfunction_1
#define STUBPARAMETER_PARAM_S1 "parameter_%c" // "stubparameter_modulfunction_1".parameter_a #define STUBPARAMETER_PARAM_S1 "parameter_%c" // "stubparameter_modulfunction_1".parameter_a
#define STUBPARAMETER_CALLTEST_S "stubCallTest" #define STUBPARAMETER_CALLTEST_S "stubCallTest"
#define STUBPARAMETER_POINTERHANDLING_S "stubPointerHandling"
#define STUBPARAMETER_POINTERHANDLING_ENUM_S "stub_parameter_pointer_handling_t"
#define STUBPARAMETER_POINTERHANDLING_ADDRESS_S "STUB_PARAMETER_POINTER_HANDLING_ADDRESS"
#define STUBPARAMETER_POINTERHANDLING_INJECT_S "STUB_PARAMETER_POINTER_HANDLING_INJECT"
#define STUBPARAMETER_RETURN_S "returnValue" // "stubparameter_modulfunction_1".returnValue #define STUBPARAMETER_RETURN_S "returnValue" // "stubparameter_modulfunction_1".returnValue
#define STUBINSTANCE_S1 "stubInstance_%s" // stubInstance_modulfunction_1 #define STUBINSTANCE_S1 "stubInstance_%s" // stubInstance_modulfunction_1
#define STUBINSTANCE_DATATYPE_S "uint8_t"
#define STUBINIT_PARAM_INSTANCE_S "aInstance" #define STUBINIT_PARAM_INSTANCE_S "aInstance"
#define STUBINIT_PARAM_CALLTEST_S "aStubCallTest" #define STUBINIT_PARAM_CALLTEST_S "aStubCallTest"
#define STUBINIT_PARAM_PARAMETER_S1 "aParameter_%c" // aParameter_a #define STUBINIT_PARAM_PARAMETER_S1 "aParameter_%c" // aParameter_a
#define STUBINIT_PARAM_RETURN_S "aReturnValue" #define STUBINIT_PARAM_RETURN_S "aReturnValue"
#define STUBINIT_PARAM_POINTERHANDLING_S "aPointerHandling"
#define STUBFUNCTION_USER_INITEXPECTED_S1 "stub_%s_user_initExpected" // stub_testfunction_initExpected #define STUBFUNCTION_USER_INITEXPECTED_S1 "stub_%s_user_initExpected" // stub_testfunction_initExpected
#define STUBFUNCTION_USER_INITGLOBALS_S1 "stub_%s_user_initGlobals" // stub_testfunction_initGlobals #define STUBFUNCTION_USER_INITGLOBALS_S1 "stub_%s_user_initGlobals" // stub_testfunction_initGlobals