Skip to content

Commit

Permalink
pocoproject#3507: Added regression tests and fix another issue in bin…
Browse files Browse the repository at this point in the history
…ding().
  • Loading branch information
kblaschke committed Jan 31, 2022
1 parent e08c9f5 commit 231b5a4
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 26 deletions.
7 changes: 5 additions & 2 deletions Util/src/Option.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,11 @@ Option& Option::binding(const std::string& propertyName)
Option& Option::binding(const std::string& propertyName, AbstractConfiguration* pConfig)
{
_binding = propertyName;
_pConfig = pConfig;
if (_pConfig) _pConfig->duplicate();
if (pConfig != _pConfig)
{
_pConfig = pConfig;
if (_pConfig) _pConfig->duplicate();
}
return *this;
}

Expand Down
204 changes: 180 additions & 24 deletions Util/testsuite/src/OptionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "OptionTest.h"
#include "CppUnit/TestCaller.h"
#include "CppUnit/TestSuite.h"
#include "Poco/Util/MapConfiguration.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionException.h"

Expand All @@ -34,33 +35,33 @@ void OptionTest::testOption()
.required(false)
.repeatable(true)
.argument("path");

Option libOpt = Option("library-dir", "L", "specify a library search path", false)
.repeatable(true)
.argument("path");

Option outOpt = Option("output", "o", "specify the output file", true)
.argument("file", true);

Option vrbOpt = Option("verbose", "v")
.description("enable verbose mode")
.required(false)
.repeatable(false);

Option optOpt = Option("optimize", "O")
.description("enable optimization")
.required(false)
.repeatable(false)
.argument("level", false);

assertTrue (incOpt.shortName() == "I");
assertTrue (incOpt.fullName() == "include-dir");
assertTrue (incOpt.repeatable());
assertTrue (!incOpt.required());
assertTrue (incOpt.argumentName() == "path");
assertTrue (incOpt.argumentRequired());
assertTrue (incOpt.takesArgument());

assertTrue (libOpt.shortName() == "L");
assertTrue (libOpt.fullName() == "library-dir");
assertTrue (libOpt.repeatable());
Expand Down Expand Up @@ -100,7 +101,7 @@ void OptionTest::testMatches1()
.required(false)
.repeatable(true)
.argument("path");

assertTrue (incOpt.matchesShort("Iinclude"));
assertTrue (incOpt.matchesPartial("include:include"));
assertTrue (incOpt.matchesPartial("include-dir:include"));
Expand All @@ -109,12 +110,12 @@ void OptionTest::testMatches1()
assertTrue (incOpt.matchesPartial("include"));
assertTrue (incOpt.matchesShort("I"));
assertTrue (incOpt.matchesPartial("i"));

assertTrue (incOpt.matchesFull("include-dir:include"));
assertTrue (incOpt.matchesFull("INClude-dir:include"));
assertTrue (!incOpt.matchesFull("include:include"));
assertTrue (!incOpt.matchesFull("include-dir2:include"));

assertTrue (!incOpt.matchesPartial("include-dir2=include"));
assertTrue (!incOpt.matchesShort("linclude"));
}
Expand All @@ -126,20 +127,20 @@ void OptionTest::testMatches2()
.required(false)
.repeatable(true)
.argument("path");

assertTrue (!incOpt.matchesShort("Iinclude"));
assertTrue (incOpt.matchesPartial("include:include"));
assertTrue (incOpt.matchesPartial("include-dir:include"));
assertTrue (incOpt.matchesPartial("inc=include"));
assertTrue (incOpt.matchesPartial("INCLUDE=include"));
assertTrue (incOpt.matchesPartial("I"));
assertTrue (incOpt.matchesPartial("i"));

assertTrue (incOpt.matchesFull("include-dir:include"));
assertTrue (incOpt.matchesFull("INClude-dir:include"));
assertTrue (!incOpt.matchesFull("include:include"));
assertTrue (!incOpt.matchesFull("include-dir2:include"));

assertTrue (!incOpt.matchesFull("include-dir2=include"));
assertTrue (!incOpt.matchesShort("linclude"));
}
Expand All @@ -165,7 +166,7 @@ void OptionTest::testProcess1()
assertTrue (arg == "/usr/include");
incOpt.process("Include-dir:/proj/include", arg);
assertTrue (arg == "/proj/include");

try
{
incOpt.process("I", arg);
Expand All @@ -183,7 +184,7 @@ void OptionTest::testProcess1()
catch (Poco::Util::MissingArgumentException&)
{
}

try
{
incOpt.process("Llib", arg);
Expand All @@ -192,17 +193,17 @@ void OptionTest::testProcess1()
catch (Poco::Util::UnknownOptionException&)
{
}

Option vrbOpt = Option("verbose", "v")
.description("enable verbose mode")
.required(false)
.repeatable(false);

vrbOpt.process("v", arg);
assertTrue (arg.empty());
vrbOpt.process("verbose", arg);
assertTrue (arg.empty());

try
{
vrbOpt.process("v2", arg);
Expand All @@ -220,13 +221,13 @@ void OptionTest::testProcess1()
catch (Poco::Util::UnexpectedArgumentException&)
{
}

Option optOpt = Option("optimize", "O")
.description("enable optimization")
.required(false)
.repeatable(false)
.argument("level", false);

optOpt.process("O", arg);
assertTrue (arg.empty());
optOpt.process("O2", arg);
Expand Down Expand Up @@ -258,7 +259,7 @@ void OptionTest::testProcess2()
assertTrue (arg == "/usr/include");
incOpt.process("Include-dir:/proj/include", arg);
assertTrue (arg == "/proj/include");

try
{
incOpt.process("Iinclude", arg);
Expand All @@ -267,7 +268,7 @@ void OptionTest::testProcess2()
catch (Poco::Util::UnknownOptionException&)
{
}

try
{
incOpt.process("I", arg);
Expand All @@ -285,7 +286,7 @@ void OptionTest::testProcess2()
catch (Poco::Util::MissingArgumentException&)
{
}

try
{
incOpt.process("Llib", arg);
Expand All @@ -294,17 +295,17 @@ void OptionTest::testProcess2()
catch (Poco::Util::UnknownOptionException&)
{
}

Option vrbOpt = Option("verbose", "")
.description("enable verbose mode")
.required(false)
.repeatable(false);

vrbOpt.process("v", arg);
assertTrue (arg.empty());
vrbOpt.process("verbose", arg);
assertTrue (arg.empty());

try
{
vrbOpt.process("v2", arg);
Expand All @@ -324,6 +325,157 @@ void OptionTest::testProcess2()
}
}

void OptionTest::testBindingRefCountingSingleBind()
{
Poco::Util::MapConfiguration::Ptr mapConfiguration = Poco::makeAuto<Poco::Util::MapConfiguration>();

// Increment refcounter by 4 to prevent crashes-
mapConfiguration.duplicate();
mapConfiguration.duplicate();
mapConfiguration.duplicate();
mapConfiguration.duplicate();

assertTrue(mapConfiguration->referenceCount() == 5);

{
Option incOpt = Option("include-dir", "I", "specify an include search path")
.binding("includeDir", mapConfiguration);

assertTrue(mapConfiguration->referenceCount() == 6);
}

assertTrue(mapConfiguration->referenceCount() == 5);

while (mapConfiguration->referenceCount() > 1)
{
mapConfiguration->release();
}

mapConfiguration.reset();
}

void OptionTest::testBindingRefCountingCopyWithBinding()
{
Poco::Util::MapConfiguration::Ptr mapConfiguration = Poco::makeAuto<Poco::Util::MapConfiguration>();

// Increment refcounter by 4 to prevent crashes-
mapConfiguration.duplicate();
mapConfiguration.duplicate();
mapConfiguration.duplicate();
mapConfiguration.duplicate();

assertTrue(mapConfiguration->referenceCount() == 5);

{
Option incOpt = Option("include-dir", "I", "specify an include search path")
.binding("includeDir", mapConfiguration);

assertTrue(mapConfiguration->referenceCount() == 6);

{
Option incOpt2 = incOpt;

assertTrue(mapConfiguration->referenceCount() == 7);

Option incOpt3 = incOpt;

assertTrue(mapConfiguration->referenceCount() == 8);
}

assertTrue(mapConfiguration->referenceCount() == 6);
}

assertTrue(mapConfiguration->referenceCount() == 5);

while (mapConfiguration->referenceCount() > 1)
{
mapConfiguration->release();
}

mapConfiguration.reset();
}

void OptionTest::testBindingRefCountingMultipleBinds1()
{

Poco::Util::MapConfiguration::Ptr mapConfiguration = Poco::makeAuto<Poco::Util::MapConfiguration>();

// Increment refcounter by 4 to prevent crashes
mapConfiguration.duplicate();
mapConfiguration.duplicate();
mapConfiguration.duplicate();
mapConfiguration.duplicate();

assertTrue(mapConfiguration->referenceCount() == 5);

{
Option incOpt = Option("include-dir", "I", "specify an include search path")
.binding("includeDir", mapConfiguration);

assertTrue(mapConfiguration->referenceCount() == 6);

incOpt.binding("includeDir", mapConfiguration);

assertTrue(mapConfiguration->referenceCount() == 6);
}

assertTrue(mapConfiguration->referenceCount() == 5);

while (mapConfiguration->referenceCount() > 1)
{
mapConfiguration->release();
}

mapConfiguration.reset();
}


void OptionTest::testBindingRefCountingMultipleBinds2()
{

Poco::Util::MapConfiguration::Ptr mapConfiguration1 = Poco::makeAuto<Poco::Util::MapConfiguration>();
Poco::Util::MapConfiguration::Ptr mapConfiguration2 = Poco::makeAuto<Poco::Util::MapConfiguration>();

// Increment refcounters by 4 to prevent crashes
for (int i = 0; i < 4; i++)
{
mapConfiguration1.duplicate();
mapConfiguration2.duplicate();
}

assertTrue(mapConfiguration1->referenceCount() == 5);
assertTrue(mapConfiguration2->referenceCount() == 5);

{
Option incOpt = Option("include-dir", "I", "specify an include search path")
.binding("includeDir", mapConfiguration1);

assertTrue(mapConfiguration1->referenceCount() == 6);
assertTrue(mapConfiguration2->referenceCount() == 5);

incOpt.binding("includeDir", mapConfiguration2);

assertTrue(mapConfiguration1->referenceCount() == 5);
assertTrue(mapConfiguration2->referenceCount() == 6);
}

assertTrue(mapConfiguration1->referenceCount() == 5);
assertTrue(mapConfiguration2->referenceCount() == 5);

while (mapConfiguration1->referenceCount() > 1)
{
mapConfiguration1->release();
}

while (mapConfiguration2->referenceCount() > 1)
{
mapConfiguration2->release();
}

mapConfiguration1.reset();
mapConfiguration2.reset();
}


void OptionTest::setUp()
{
Expand All @@ -344,6 +496,10 @@ CppUnit::Test* OptionTest::suite()
CppUnit_addTest(pSuite, OptionTest, testMatches2);
CppUnit_addTest(pSuite, OptionTest, testProcess1);
CppUnit_addTest(pSuite, OptionTest, testProcess2);
CppUnit_addTest(pSuite, OptionTest, testBindingRefCountingSingleBind);
CppUnit_addTest(pSuite, OptionTest, testBindingRefCountingCopyWithBinding);
CppUnit_addTest(pSuite, OptionTest, testBindingRefCountingMultipleBinds1);
CppUnit_addTest(pSuite, OptionTest, testBindingRefCountingMultipleBinds2);

return pSuite;
}
4 changes: 4 additions & 0 deletions Util/testsuite/src/OptionTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ class OptionTest: public CppUnit::TestCase
void testMatches2();
void testProcess1();
void testProcess2();
void testBindingRefCountingSingleBind();
void testBindingRefCountingCopyWithBinding();
void testBindingRefCountingMultipleBinds1();
void testBindingRefCountingMultipleBinds2();

void setUp();
void tearDown();
Expand Down

0 comments on commit 231b5a4

Please sign in to comment.