Skip to content

Fix #1219 copy on expect with output parameter returning #1222

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Fix #1219.
On expect .withOutputParameterReturning() store content of
output parameter.
  • Loading branch information
asgeroverby committed Jun 5, 2019
commit c4a8c08295401d0a530da612ca1b5fa22d25b44a
2 changes: 1 addition & 1 deletion include/CppUTestExt/MockCheckedExpectedCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class MockCheckedExpectedCall : public MockExpectedCall
virtual MockExpectedCall& onObject(void* objectPtr) _override;

virtual MockNamedValue getInputParameter(const SimpleString& name);
virtual MockNamedValue getOutputParameter(const SimpleString& name);
virtual MockNamedValue* getOutputParameter(const SimpleString& name);
virtual SimpleString getInputParameterType(const SimpleString& name);
virtual SimpleString getInputParameterValueString(const SimpleString& name);

Expand Down
3 changes: 3 additions & 0 deletions include/CppUTestExt/MockNamedValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ class MockNamedValue
DEFAULT_COPY_CONSTRUCTOR(MockNamedValue)
virtual ~MockNamedValue();

virtual void copyValue(const void* value, size_t size);

virtual void setValue(bool value);
virtual void setValue(int value);
virtual void setValue(unsigned int value);
Expand Down Expand Up @@ -185,6 +187,7 @@ class MockNamedValue
void* objectPointerValue_;
const void* outputPointerValue_;
} value_;
uint8_t* membuf_;
size_t size_;
MockNamedValueComparator* comparator_;
MockNamedValueCopier* copier_;
Expand Down
36 changes: 21 additions & 15 deletions src/CppUTestExt/MockActualCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,24 +83,30 @@ void MockCheckedActualCall::copyOutputParameters(MockCheckedExpectedCall* expect
{
for (MockOutputParametersListNode* p = outputParameterExpectations_; p; p = p->next_)
{
MockNamedValue outputParameter = expectedCall->getOutputParameter(p->name_);
MockNamedValueCopier* copier = outputParameter.getCopier();
if (copier)
MockNamedValue dummy = MockNamedValue("");
MockNamedValue* outputParameter = expectedCall->getOutputParameter(p->name_);
if (outputParameter == NULLPTR)
{
outputParameter = &dummy;
}
MockNamedValueCopier* copier = outputParameter->getCopier();

if (copier)
{
copier->copy(p->ptr_, outputParameter->getConstObjectPointer());
}
else if ((outputParameter->getType() == "const void*") && (p->type_ == "void*"))
{
const void* data = outputParameter->getConstPointerValue();
size_t size = outputParameter->getSize();
PlatformSpecificMemCpy(p->ptr_, data, size);
}
else if (outputParameter->getName() != "")
{
copier->copy(p->ptr_, outputParameter.getConstObjectPointer());
}
else if ((outputParameter.getType() == "const void*") && (p->type_ == "void*"))
{
const void* data = outputParameter.getConstPointerValue();
size_t size = outputParameter.getSize();
PlatformSpecificMemCpy(p->ptr_, data, size);
}
else if (outputParameter.getName() != "")
{
SimpleString type = expectedCall->getOutputParameter(p->name_).getType();
SimpleString type = expectedCall->getOutputParameter(p->name_)->getType();
MockNoWayToCopyCustomTypeFailure failure(getTest(), type);
failTest(failure);
}
}
}
}

Expand Down
8 changes: 3 additions & 5 deletions src/CppUTestExt/MockExpectedCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,7 @@ MockExpectedCall& MockCheckedExpectedCall::withOutputParameterReturning(const Si
{
MockNamedValue* newParameter = new MockExpectedFunctionParameter(name);
outputParameters_->add(newParameter);
newParameter->setValue(value);
newParameter->setSize(size);
newParameter->copyValue(value, size);
return *this;
}

Expand Down Expand Up @@ -264,10 +263,9 @@ MockNamedValue MockCheckedExpectedCall::getInputParameter(const SimpleString& na
return (p) ? *p : MockNamedValue("");
}

MockNamedValue MockCheckedExpectedCall::getOutputParameter(const SimpleString& name)
MockNamedValue* MockCheckedExpectedCall::getOutputParameter(const SimpleString& name)
{
MockNamedValue * p = outputParameters_->getValueByName(name);
return (p) ? *p : MockNamedValue("");
return outputParameters_->getValueByName(name);
}

bool MockCheckedExpectedCall::areParametersMatchingActualCall()
Expand Down
17 changes: 16 additions & 1 deletion src/CppUTestExt/MockNamedValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,17 @@ void MockNamedValue::setDefaultComparatorsAndCopiersRepository(MockNamedValueCom
defaultRepository_ = repository;
}

MockNamedValue::MockNamedValue(const SimpleString& name) : name_(name), type_("int"), size_(0), comparator_(NULLPTR), copier_(NULLPTR)
MockNamedValue::MockNamedValue(const SimpleString& name) : name_(name), type_("int"), membuf_(NULL), size_(0), comparator_(NULLPTR), copier_(NULLPTR)
{
value_.intValue_ = 0;
}

MockNamedValue::~MockNamedValue()
{
if ( (membuf_ != NULL)) {
delete [] membuf_;
membuf_ = NULL;
}
}

void MockNamedValue::setValue(bool value)
Expand Down Expand Up @@ -129,6 +133,17 @@ void MockNamedValue::setValue(const void* value)
value_.constPointerValue_ = value;
}

void MockNamedValue::copyValue(const void* value, size_t size)
{
type_ = "const void*";
if (membuf_ == NULL) {
membuf_ = new uint8_t[size];
}
memcpy(membuf_, value, size);
value_.constPointerValue_ = (const void*) membuf_;
size_ = size;
}

void MockNamedValue::setValue(void (*value)())
{
type_ = "void (*)()";
Expand Down
22 changes: 21 additions & 1 deletion tests/CppUTestExt/MockParameterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,27 @@ TEST(MockParameterTest, outputParameterSucceeds)
mock().checkExpectations();
}

TEST(MockParameterTest, outputParameterIsCopiedOnExpect)
{
int param = 1;
int retval = 2;

/*
The mock method .withOutputParameterReturning() should copied
on .expectOneCall(), but is actually dereference on
.actualCall(). This will allow the memory pointed to by
.withOutputParameterReturning() to be changed between calls.
*/

mock().expectOneCall("function").withOutputParameterReturning("parameterName", &retval, sizeof(retval));
retval = 7;

mock().actualCall("function").withOutputParameter("parameterName", &param);
CHECK_EQUAL(param, 2); // Check fails !!!

mock().checkExpectations();
}

TEST(MockParameterTest, noActualCallForOutputParameter)
{
MockFailureReporterInstaller failureReporterInstaller;
Expand Down Expand Up @@ -904,4 +925,3 @@ TEST(MockParameterTest, expectMultipleMultipleCallsWithParameters)

mock().checkExpectations();
}