Add unittests to cover uncovered code in MemoryManager ADEF_ and REF_… (#1483)

* Add unittests to cover uncovered code in MemoryManager ADEF_ and REF_ parsers.

* Remove the second production of the 'user_defined_type' target
because it is superfluous, and impossible to reach. This is
because the NAME token is defined as pattern : '[_a-zA-Z][_a-zA-Z0-9:]*'.
This pattern will always match a string of colon separated names.
Note that the NAME itoken is used for colon separated type-name as well as
colon separated variable names.

* Add a test to MM_declare_var_unittest that covers the HEX token in adef_parser.l.

* Add a unittest for MemoryManager_JSON_Intf.cpp.

* Tweak MM_JSON_Intf.cc to get better code-coverage.
This commit is contained in:
jmpenn 2023-04-27 14:57:55 -05:00 committed by GitHub
parent 6c685d8400
commit 9438bd559b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 307 additions and 57 deletions

View File

@ -26,7 +26,7 @@
using namespace std;
int ADEF_lex( YYSTYPE* lvalp, YYLTYPE* llocp, void* scanner );
void ADEF_error( YYLTYPE* locp, Trick::ADefParseContext* context, const char* err) {
std::stringstream message;
message << "adef_parser PARSE-ERROR " << locp->first_line << ": " << err << ".";
@ -56,13 +56,13 @@
%type <value_list> dim_list
%type <ival> pointers
%type <sval> opt_name user_defined_type
%type <sval> opt_name user_type_name
%%
alloc_definition: TYPE pointers opt_name dim_list {
context->type = (TRICK_TYPE)$1;
context->type = (TRICK_TYPE)$1;
context->user_type_name = "";
context->n_stars = $2;
if ($3 == NULL) {
@ -72,8 +72,8 @@ alloc_definition: TYPE pointers opt_name dim_list {
free($3) ;
}
}
| user_defined_type pointers opt_name dim_list {
| user_type_name pointers opt_name dim_list {
// TRICK_OPAQUE_TYPE means that the type is a user-defined type,
// the details of which will be determined later.
context->type = TRICK_OPAQUE_TYPE;
@ -105,32 +105,21 @@ pointers: {
}
;
user_defined_type: NAME {
$$ = $1;
}
| user_defined_type ':' ':' NAME {
size_t len;
len = strlen($1) + strlen($4) + (size_t)3;
$$ = (char*)malloc( (size_t)len);
strcpy($$, $1);
strcat($$, "::");
strcat($$, $4);
free($1);
free($4);
}
;
user_type_name: NAME {
$$ = $1;
};
dim_list: {
/*
* These two rules handle C style array indexing. This rule
* handles no indexes, the second rule handles one or more other
* indexes.
* indexes.
*/
int ii ;
context->n_cdims = 0;
for ( ii = 0 ; ii < TRICK_MAX_INDEX ; ii++ ) {
context->cdims[ii] = 0;
}
}
}
| dim_list '[' I_CON ']' {
if (context->n_cdims >= TRICK_MAX_INDEX ) {
@ -142,5 +131,3 @@ dim_list: {
};
%%

View File

@ -0,0 +1,139 @@
#include <gtest/gtest.h>
#include "MM_test.hh"
#include "MM_user_defined_types.hh"
/*
This tests the allocation of user-defined types using MemoryManager::declare_var().
*/
class MM_JSON_intf : public ::testing::Test {
protected:
Trick::MemoryManager *memmgr;
MM_JSON_intf() {
try {
memmgr = new Trick::MemoryManager;
} catch (std::logic_error e) {
memmgr = NULL;
}
}
~MM_JSON_intf() {
delete memmgr;
}
void SetUp() {}
void TearDown() {}
};
/*
The tests.
*/
TEST_F(MM_JSON_intf, Write_Named_Local_C_Alloc_Info ) {
std::stringstream ss;
std::string s;
double *d_p = (double*)memmgr->declare_var("double foo[2]");
ALLOC_INFO* alloc_info = memmgr->get_alloc_info_of(d_p);
memmgr->write_JSON_alloc_info(ss, alloc_info);
s = ss.str();
std::size_t pos;
bool found = true;
pos = s.find("name");
if (pos == std::string::npos) found = false;
pos = s.find("foo");
if (pos == std::string::npos) found = false;
pos = s.find("start");
if (pos == std::string::npos) found = false;
pos = s.find("end");
if (pos == std::string::npos) found = false;
pos = s.find("num");
if (pos == std::string::npos) found = false;
pos = s.find("size");
if (pos == std::string::npos) found = false;
pos = s.find("type");
if (pos == std::string::npos) found = false;
pos = s.find("stcl");
if (pos == std::string::npos) found = false;
pos = s.find("TRICK_LOCAL");
if (pos == std::string::npos) found = false;
pos = s.find("language");
if (pos == std::string::npos) found = false;
pos = s.find("Language_C");
if (pos == std::string::npos) found = false;
pos = s.find("index");
if (pos == std::string::npos) found = false;
EXPECT_EQ(found, true);
}
TEST_F(MM_JSON_intf, Write_Anon_Extern_CPP_Alloc_Info ) {
std::stringstream ss;
std::string s;
UDT1 test_var;
UDT1 *test_var_p = (UDT1 *)memmgr->declare_extern_var(&test_var, "UDT1");
ALLOC_INFO* alloc_info = memmgr->get_alloc_info_of(test_var_p);
//memmgr->write_JSON_alloc_info(std::cout, alloc_info);
memmgr->write_JSON_alloc_info(ss, alloc_info);
s = ss.str();
std::size_t pos;
bool found = true;
pos = s.find("name");
if (pos == std::string::npos) found = false;
pos = s.find("start");
if (pos == std::string::npos) found = false;
pos = s.find("end");
if (pos == std::string::npos) found = false;
pos = s.find("num");
if (pos == std::string::npos) found = false;
pos = s.find("size");
if (pos == std::string::npos) found = false;
pos = s.find("type");
if (pos == std::string::npos) found = false;
pos = s.find("stcl");
if (pos == std::string::npos) found = false;
pos = s.find("TRICK_EXTERN");
if (pos == std::string::npos) found = false;
pos = s.find("language");
if (pos == std::string::npos) found = false;
pos = s.find("Language_CPP");
if (pos == std::string::npos) found = false;
pos = s.find("index");
if (pos == std::string::npos) found = false;
EXPECT_EQ(found, true);
}
TEST_F(MM_JSON_intf, Write_Alloc_Info_List ) {
std::stringstream ss;
std::string s;
void *ptr;
ptr = memmgr->declare_var("double apple");
ptr = memmgr->declare_var("double banana");
ptr = memmgr->declare_var("double cherry");
ptr = memmgr->declare_var("double date");
ptr = memmgr->declare_var("double elderberry");
memmgr->write_JSON_alloc_list(std::cout, 0, 2);
memmgr->write_JSON_alloc_list(ss, 0, 2);
s = ss.str();
std::size_t pos;
bool found = true;
pos = s.find("alloc_total");
if (pos >= std::string::npos) found = false;
pos = s.find("chunk_size");
if (pos >= std::string::npos) found = false;
pos = s.find("chunk_start");
if (pos >= std::string::npos) found = false;
pos = s.find("alloc_list");
if (pos == std::string::npos) found = false;
EXPECT_EQ(found, true);
}

View File

@ -39,7 +39,6 @@ void validate_alloc_info_local(Trick::MemoryManager *memmgr,
"Storage class (stcl) for a var created with var_declare should always be TRICK_LOCAL.";
}
/* ================================================================================
Test Cases
================================================================================
@ -50,46 +49,117 @@ TEST_F(MM_declare_var, Character) {
validate_alloc_info_local(memmgr, test_var, TRICK_CHARACTER, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, UnsignedCharacter) {
unsigned char *test_var = (unsigned char *)memmgr->declare_var("unsigned char");
validate_alloc_info_local(memmgr, test_var, TRICK_UNSIGNED_CHARACTER, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, String) {
std::string *test_var = (std::string *)memmgr->declare_var("std::string");
validate_alloc_info_local(memmgr, test_var, TRICK_STRING, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, wchar) {
wchar_t *test_var = (wchar_t *)memmgr->declare_var("wchar");
validate_alloc_info_local(memmgr, test_var, TRICK_WCHAR, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, SignedCharacter) {
unsigned char *test_var = (unsigned char *)memmgr->declare_var("signed char");
validate_alloc_info_local(memmgr, test_var, TRICK_CHARACTER, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, INT8_T) {
unsigned char *test_var = (unsigned char *)memmgr->declare_var("int8_t");
validate_alloc_info_local(memmgr, test_var, TRICK_CHARACTER, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, UnsignedCharacter) {
unsigned char *test_var = (unsigned char *)memmgr->declare_var("unsigned char");
validate_alloc_info_local(memmgr, test_var, TRICK_UNSIGNED_CHARACTER, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, UINT8_T) {
unsigned char *test_var = (unsigned char *)memmgr->declare_var("uint8_t");
validate_alloc_info_local(memmgr, test_var, TRICK_UNSIGNED_CHARACTER, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, Short) {
short *test_var = (short *)memmgr->declare_var("short");
validate_alloc_info_local(memmgr, test_var, TRICK_SHORT, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, SignedShort) {
short *test_var = (short *)memmgr->declare_var("signed short");
validate_alloc_info_local(memmgr, test_var, TRICK_SHORT, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, INT16_T) {
short *test_var = (short *)memmgr->declare_var("int16_t");
validate_alloc_info_local(memmgr, test_var, TRICK_SHORT, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, UnsignedShort) {
unsigned short *test_var = (unsigned short *)memmgr->declare_var("unsigned short");
validate_alloc_info_local(memmgr, test_var, TRICK_UNSIGNED_SHORT, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, UINT16_T) {
short *test_var = (short *)memmgr->declare_var("uint16_t");
validate_alloc_info_local(memmgr, test_var, TRICK_UNSIGNED_SHORT, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, Integer) {
int *test_var = (int *)memmgr->declare_var("int");
validate_alloc_info_local(memmgr, test_var, TRICK_INTEGER, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, SignedInteger) {
int *test_var = (int *)memmgr->declare_var("signed int");
validate_alloc_info_local(memmgr, test_var, TRICK_INTEGER, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, INT32_T) {
int *test_var = (int *)memmgr->declare_var("int32_t");
validate_alloc_info_local(memmgr, test_var, TRICK_INTEGER, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, UnsignedInteger) {
unsigned int *test_var = (unsigned int *)memmgr->declare_var("unsigned int");
validate_alloc_info_local(memmgr, test_var, TRICK_UNSIGNED_INTEGER, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, UINT32_T) {
unsigned int *test_var = (unsigned int *)memmgr->declare_var("uint32_t");
validate_alloc_info_local(memmgr, test_var, TRICK_UNSIGNED_INTEGER, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, INT64_T) {
long *test_var = (long *)memmgr->declare_var("int64_t");
validate_alloc_info_local(memmgr, test_var, TRICK_INT64, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, UINT64_T) {
unsigned long *test_var = (unsigned long *)memmgr->declare_var("uint64_t");
validate_alloc_info_local(memmgr, test_var, TRICK_UINT64, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, Long) {
long *test_var = (long *)memmgr->declare_var("long");
validate_alloc_info_local(memmgr, test_var, TRICK_LONG, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, SignedLong) {
long *test_var = (long *)memmgr->declare_var("signed long");
validate_alloc_info_local(memmgr, test_var, TRICK_LONG, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, UnsignedLong) {
unsigned long *test_var = (unsigned long *)memmgr->declare_var("unsigned long");
validate_alloc_info_local(memmgr, test_var, TRICK_UNSIGNED_LONG, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, SignedLongLong) {
long long *test_var = (long long *)memmgr->declare_var("signed long long");
validate_alloc_info_local(memmgr, test_var, TRICK_LONG_LONG, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, Float) {
float *test_var = (float *)memmgr->declare_var("float");
validate_alloc_info_local(memmgr, test_var, TRICK_FLOAT, NULL, NULL, 1, 0, NULL);
@ -112,6 +182,17 @@ TEST_F(MM_declare_var, UnsignedLongLong) {
validate_alloc_info_local(memmgr, test_var, TRICK_UNSIGNED_LONG_LONG, NULL, NULL, 1, 0, NULL);
}
TEST_F(MM_declare_var, DELIBERATE_SYNTAX_ERROR_IN_LEXER) {
std::cout << ISO_6429_White_Background
<< ISO_6429_Blue_Foreground
<< ISO_6429_Underline
<< "NOTE: An error message is expected in this test."
<< ISO_6429_Restore_Default
<< std::endl;
float *test_var = (float *)memmgr->declare_var("??");
ASSERT_TRUE(test_var == NULL);
}
// Hmmm. What to do with the silly TRICK_FILE_POINTER type.
TEST_F(MM_declare_var, Boolean) {
@ -124,6 +205,11 @@ TEST_F(MM_declare_var, WideCharacter) {
validate_alloc_info_local(memmgr, test_var, TRICK_WCHAR, NULL, NULL, 1, 0, NULL);
}
// Named Variables
TEST_F(MM_declare_var, NamedVariable) {
double *test_var = (double *)memmgr->declare_var("double force");
validate_alloc_info_local(memmgr, test_var, TRICK_DOUBLE, NULL, "force", 1, 0, NULL);
}
// Intrinsic Type Arrays
@ -139,6 +225,12 @@ TEST_F(MM_declare_var, NamedOneDimDoubleArray) {
validate_alloc_info_local(memmgr, test_var, TRICK_DOUBLE, NULL, "myarray", 5, 1, extents);
}
TEST_F(MM_declare_var, NamedOneDimDoubleArrayHexIndex) {
double *test_var = (double *)memmgr->declare_var("double myarray[0x05]");
int extents[8] = {5,0,0,0,0,0,0,0};
validate_alloc_info_local(memmgr, test_var, TRICK_DOUBLE, NULL, "myarray", 5, 1, extents);
}
TEST_F(MM_declare_var, AnonOneDimDoublePtrArray) {
double **test_var = (double **)memmgr->declare_var("double*[5]");
int extents[8] = {5,0,0,0,0,0,0,0};
@ -157,6 +249,17 @@ TEST_F(MM_declare_var, AnonThreeDimDoubleArray) {
validate_alloc_info_local(memmgr, test_var, TRICK_DOUBLE, NULL, NULL, 24, 3, extents);
}
TEST_F(MM_declare_var, TooManyDimensions) {
std::cout << ISO_6429_White_Background
<< ISO_6429_Blue_Foreground
<< ISO_6429_Underline
<< "NOTE: An error message is expected in this test."
<< ISO_6429_Restore_Default
<< std::endl;
double *test_var = (double *)memmgr->declare_var("double[2][2][2][2][2][2][2][2][2]");
ASSERT_TRUE(test_var == NULL);
}
// User-defined types
TEST_F(MM_declare_var, UserDefinedSingleton) {
@ -175,4 +278,3 @@ TEST_F(MM_declare_var, UserDefinedTwoDimArray) {
int extents[8] = {3,4,0,0,0,0,0,0};
validate_alloc_info_local(memmgr, test_var, TRICK_STRUCTURED, "UDT1", NULL, 12, 2, extents);
}

View File

@ -107,6 +107,13 @@ TEST_F(MM_ref_attributes, NormalCases) {
EXPECT_EQ( &udt3.C[5], ref->address);
free( ref);
// Same as above but with HEX index.
std::cout << "Case of: \"udt3.C[0x05]\"" << std::endl;
ref = memmgr->ref_attributes("udt3.C[0x05]");
ASSERT_TRUE(ref != NULL);
EXPECT_EQ( &udt3.C[5], ref->address);
free( ref);
std::cout << "Case of: \"udt3.N.A\"" << std::endl;
ref = memmgr->ref_attributes("udt3.N.A");
ASSERT_TRUE(ref != NULL);
@ -141,30 +148,43 @@ TEST_F(MM_ref_attributes, NormalCases) {
}
TEST_F(MM_ref_attributes, FailureCases) {
REF2 *ref;
UDT1 udt1;
UDT2 udt2;
UDT3 udt3;
REF2 *ref;
UDT1 udt1;
UDT2 udt2;
UDT3 udt3;
udt3.udt1_p = &udt1;
udt3.udt2_p = &udt2;
udt2.udt1_p = &udt1;
udt3.udt1_p = &udt1;
udt3.udt2_p = &udt2;
udt2.udt1_p = &udt1;
UDT3* udt3_p = (UDT3*)memmgr->declare_extern_var(&udt3, "UDT3 udt3");
ASSERT_TRUE(udt3_p != NULL);
UDT3* udt3_p = (UDT3*)memmgr->declare_extern_var(&udt3, "UDT3 udt3");
ASSERT_TRUE(udt3_p != NULL);
// Failure cases.
ref = memmgr->ref_attributes("udt3.idontexist");
ASSERT_TRUE(ref == NULL);
// Failure cases.
ref = memmgr->ref_attributes("udt3.idontexist");
ASSERT_TRUE(ref == NULL);
std::cout << ISO_6429_White_Background
<< ISO_6429_Blue_Foreground
<< ISO_6429_Underline
<< "NOTE: An error message is expected in this test."
<< ISO_6429_Restore_Default
<< std::endl;
// Failure cases.
ref = memmgr->ref_attributes("udt3!syntax_error");
ASSERT_TRUE(ref == NULL);
std::cout << ISO_6429_White_Background
<< ISO_6429_Blue_Foreground
<< ISO_6429_Underline
<< "NOTE: An error message is expected in this test."
<< ISO_6429_Restore_Default
<< std::endl;
ref = memmgr->ref_attributes("udt3.M2[4][7]");
ASSERT_TRUE(ref == NULL);
std::cout << ISO_6429_White_Background
<< ISO_6429_Blue_Foreground
<< ISO_6429_Underline
<< "NOTE: An error message is expected in this test."
<< ISO_6429_Restore_Default
<< std::endl;
ref = memmgr->ref_attributes("udt3.M2[4][7]");
ASSERT_TRUE(ref == NULL);
}

View File

@ -26,8 +26,8 @@ TESTS = MM_creation_unittest \
MM_declare_extern_var_unittest \
MM_delete_var_unittest \
MM_ref_attributes_unittest \
MM_resize_array_unittest \
MM_strdup_unittest \
MM_resize_array_unittest \
MM_strdup_unittest \
MM_write_var_unittest \
MM_sizeof_type_unittest\
MM_read_checkpoint\
@ -35,12 +35,13 @@ TESTS = MM_creation_unittest \
MM_alloc_deps\
MM_write_checkpoint\
MM_write_checkpoint_hexfloat \
MM_get_enumerated\
MM_ref_name_from_address \
MM_get_enumerated\
MM_ref_name_from_address \
Bitfield_tests \
MM_stl_checkpoint \
MM_stl_restore \
MM_trick_type_char_string
MM_stl_checkpoint \
MM_stl_restore \
MM_trick_type_char_string \
MM_JSON_Intf
# List of XML files produced by the tests.
unittest_results = $(patsubst %,%.xml,$(TESTS))
@ -127,6 +128,7 @@ MM_write_var_unittest : io_MM_user_defined_types.o
MM_sizeof_type_unittest : io_MM_user_defined_types.o
MM_read_checkpoint : io_MM_user_defined_types.o
MM_clear_var_unittest : io_MM_user_defined_types.o
MM_JSON_Intf : io_MM_user_defined_types.o
MM_alloc_deps : io_MM_alloc_deps.o
MM_write_checkpoint : io_MM_write_checkpoint.o
MM_ref_name_from_address : io_MM_ref_name_from_address.o