Add MessageLimiter class and test.

This commit is contained in:
Atgeirr Flø Rasmussen 2016-05-18 12:11:26 +02:00
parent 214e45e497
commit 9c84967734
4 changed files with 193 additions and 0 deletions

View File

@ -36,6 +36,7 @@ list (APPEND TEST_SOURCE_FILES
tests/test_SimulationDataContainer.cpp tests/test_SimulationDataContainer.cpp
tests/test_cmp.cpp tests/test_cmp.cpp
tests/test_OpmLog.cpp tests/test_OpmLog.cpp
tests/test_messagelimiter.cpp
) )
list (APPEND TEST_DATA_FILES list (APPEND TEST_DATA_FILES
@ -60,6 +61,7 @@ list( APPEND PUBLIC_HEADER_FILES
opm/common/OpmLog/Logger.hpp opm/common/OpmLog/Logger.hpp
opm/common/OpmLog/LogUtil.hpp opm/common/OpmLog/LogUtil.hpp
opm/common/OpmLog/MessageFormatter.hpp opm/common/OpmLog/MessageFormatter.hpp
opm/common/OpmLog/MessageLimiter.hpp
opm/common/OpmLog/OpmLog.hpp opm/common/OpmLog/OpmLog.hpp
opm/common/OpmLog/StreamLog.hpp opm/common/OpmLog/StreamLog.hpp
opm/common/OpmLog/TimerLog.hpp opm/common/OpmLog/TimerLog.hpp

View File

@ -22,6 +22,7 @@
#define OPM_LOGBACKEND_HPP #define OPM_LOGBACKEND_HPP
#include <opm/common/OpmLog/MessageFormatter.hpp> #include <opm/common/OpmLog/MessageFormatter.hpp>
#include <opm/common/OpmLog/MessageLimiter.hpp>
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <memory> #include <memory>

View File

@ -0,0 +1,111 @@
/*
Copyright 2016 SINTEF ICT, Applied Mathematics.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPM_MESSAGELIMITER_HEADER_INCLUDED
#define OPM_MESSAGELIMITER_HEADER_INCLUDED
#include <string>
#include <unordered_map>
namespace Opm
{
/// Handles limiting the number of messages with the same tag.
class MessageLimiter
{
public:
/// Used to indicate no message number limit.
enum { NoLimit = -1 };
/// Default constructor, no limit to the number of messages.
MessageLimiter()
: message_limit_(NoLimit)
{
}
/// Construct with given limit to number of messages with the
/// same tag.
///
/// Negative limits (including NoLimit) are interpreted as
/// NoLimit, but the default constructor is the preferred way
/// to obtain that behaviour.
explicit MessageLimiter(const int message_limit)
: message_limit_(message_limit < 0 ? NoLimit : message_limit)
{
}
/// The message limit (same for all tags).
int messageLimit() const
{
return message_limit_;
}
/// Used for encounteredMessage() return type (see that
/// function).
enum class Response
{
PrintMessage, JustOverLimit, OverLimit
};
/// If a tag is empty, there is no message limit or for that
/// tag (count <= limit), respond PrintMessage.
/// If (count == limit + 1), respond JustOverLimit.
/// If (count > limit + 1), respond OverLimit.
Response encounteredMessage(const std::string& tag)
{
if (tag.empty() || message_limit_ == NoLimit) {
return Response::PrintMessage;
} else {
// See if tag already encountered.
auto it = tag_counts_.find(tag);
if (it != tag_counts_.end()) {
// Already encountered this tag. Increment its count.
const int count = ++it->second;
return countBasedResponse(count);
} else {
// First encounter of this tag. Insert 1.
tag_counts_.insert({tag, 1});
return countBasedResponse(1);
}
}
}
private:
Response countBasedResponse(const int count)
{
if (count <= message_limit_) {
return Response::PrintMessage;
} else if (count == message_limit_ + 1) {
return Response::JustOverLimit;
} else {
return Response::OverLimit;
}
}
int message_limit_;
std::unordered_map<std::string, int> tag_counts_;
};
} // namespace Opm
#endif // OPM_MESSAGELIMITER_HEADER_INCLUDED

View File

@ -0,0 +1,79 @@
/*
Copyright 2016 SINTEF ICT, Applied Mathematics.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE MESSAGELIMITER_TESTS
#include <opm/common/utility/platform_dependent/disable_warnings.h>
#include <boost/test/unit_test.hpp>
#include <opm/common/utility/platform_dependent/reenable_warnings.h>
#include <opm/common/OpmLog/MessageLimiter.hpp>
using namespace Opm;
BOOST_AUTO_TEST_CASE(ConstructionAndLimits)
{
MessageLimiter m1;
BOOST_CHECK_EQUAL(m1.messageLimit(), MessageLimiter::NoLimit);
MessageLimiter m2(0);
BOOST_CHECK_EQUAL(m2.messageLimit(), 0);
MessageLimiter m3(1);
BOOST_CHECK_EQUAL(m3.messageLimit(), 1);
MessageLimiter m4(-4);
BOOST_CHECK_EQUAL(m4.messageLimit(), MessageLimiter::NoLimit);
}
BOOST_AUTO_TEST_CASE(Response)
{
{
// No limits.
MessageLimiter m;
BOOST_CHECK(m.encounteredMessage("tag1") == MessageLimiter::Response::PrintMessage);
BOOST_CHECK(m.encounteredMessage("tag2") == MessageLimiter::Response::PrintMessage);
BOOST_CHECK(m.encounteredMessage("tag1") == MessageLimiter::Response::PrintMessage);
BOOST_CHECK(m.encounteredMessage("tag2") == MessageLimiter::Response::PrintMessage);
BOOST_CHECK(m.encounteredMessage("tag1") == MessageLimiter::Response::PrintMessage);
BOOST_CHECK(m.encounteredMessage("tag2") == MessageLimiter::Response::PrintMessage);
}
{
// Limit == 0.
MessageLimiter m(0);
BOOST_CHECK(m.encounteredMessage("tag1") == MessageLimiter::Response::JustOverLimit);
BOOST_CHECK(m.encounteredMessage("tag2") == MessageLimiter::Response::JustOverLimit);
BOOST_CHECK(m.encounteredMessage("tag1") == MessageLimiter::Response::OverLimit);
BOOST_CHECK(m.encounteredMessage("tag2") == MessageLimiter::Response::OverLimit);
BOOST_CHECK(m.encounteredMessage("tag1") == MessageLimiter::Response::OverLimit);
BOOST_CHECK(m.encounteredMessage("tag2") == MessageLimiter::Response::OverLimit);
}
{
// Limit == 1.
MessageLimiter m(1);
BOOST_CHECK(m.encounteredMessage("tag1") == MessageLimiter::Response::PrintMessage);
BOOST_CHECK(m.encounteredMessage("tag2") == MessageLimiter::Response::PrintMessage);
BOOST_CHECK(m.encounteredMessage("tag1") == MessageLimiter::Response::JustOverLimit);
BOOST_CHECK(m.encounteredMessage("tag2") == MessageLimiter::Response::JustOverLimit);
BOOST_CHECK(m.encounteredMessage("tag1") == MessageLimiter::Response::OverLimit);
BOOST_CHECK(m.encounteredMessage("tag2") == MessageLimiter::Response::OverLimit);
}
}