mirror of https://github.com/Icinga/icinga2.git
Even more unit tests.
This commit is contained in:
parent
d0113e33da
commit
fcdb690b48
|
@ -271,8 +271,7 @@ Dictionary::Ptr Dictionary::FromJson(cJSON *json)
|
||||||
{
|
{
|
||||||
Dictionary::Ptr dictionary = boost::make_shared<Dictionary>();
|
Dictionary::Ptr dictionary = boost::make_shared<Dictionary>();
|
||||||
|
|
||||||
if (json->type != cJSON_Object)
|
ASSERT(json->type == cJSON_Object);
|
||||||
BOOST_THROW_EXCEPTION(std::invalid_argument("JSON type must be cJSON_Object."));
|
|
||||||
|
|
||||||
for (cJSON *i = json->child; i != NULL; i = i->next) {
|
for (cJSON *i = json->child; i != NULL; i = i->next) {
|
||||||
dictionary->Set(i->string, Value::FromJson(i));
|
dictionary->Set(i->string, Value::FromJson(i));
|
||||||
|
|
|
@ -26,20 +26,19 @@
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <boost/exception/diagnostic_information.hpp>
|
#include <boost/exception/diagnostic_information.hpp>
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
#include <boost/chrono/duration.hpp>
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
ThreadPool::ThreadPool(void)
|
ThreadPool::ThreadPool(void)
|
||||||
: m_Stopped(false), m_ThreadDeaths(0), m_WaitTime(0), m_ServiceTime(0), m_TaskCount(0)
|
: m_Stopped(false), m_ThreadDeaths(0), m_WaitTime(0),
|
||||||
|
m_ServiceTime(0), m_TaskCount(0)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
SpawnWorker();
|
SpawnWorker();
|
||||||
|
|
||||||
boost::thread managerThread(boost::bind(&ThreadPool::ManagerThreadProc, this));
|
m_ManagerThread = boost::thread(boost::bind(&ThreadPool::ManagerThreadProc, this));
|
||||||
managerThread.detach();
|
m_StatsThread = boost::thread(boost::bind(&ThreadPool::StatsThreadProc, this));
|
||||||
|
|
||||||
boost::thread statsThread(boost::bind(&ThreadPool::StatsThreadProc, this));
|
|
||||||
statsThread.detach();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadPool::~ThreadPool(void)
|
ThreadPool::~ThreadPool(void)
|
||||||
|
@ -52,7 +51,8 @@ void ThreadPool::Stop(void)
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
m_Stopped = true;
|
m_Stopped = true;
|
||||||
m_CV.notify_all();
|
m_WorkCV.notify_all();
|
||||||
|
m_MgmtCV.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,6 +67,27 @@ void ThreadPool::Join(void)
|
||||||
Utility::Sleep(0.5);
|
Utility::Sleep(0.5);
|
||||||
lock.lock();
|
lock.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int alive;
|
||||||
|
|
||||||
|
do {
|
||||||
|
alive = 0;
|
||||||
|
for (int i = 0; i < sizeof(m_ThreadStats) / sizeof(m_ThreadStats[0]); i++) {
|
||||||
|
if (m_ThreadStats[i].State != ThreadDead) {
|
||||||
|
alive++;
|
||||||
|
KillWorker();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alive > 0) {
|
||||||
|
lock.unlock();
|
||||||
|
Utility::Sleep(0.5);
|
||||||
|
lock.lock();
|
||||||
|
}
|
||||||
|
} while (alive > 0);
|
||||||
|
|
||||||
|
m_ManagerThread.join();
|
||||||
|
m_StatsThread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,7 +108,7 @@ void ThreadPool::QueueThreadProc(int tid)
|
||||||
UpdateThreadUtilization(tid, ThreadIdle);
|
UpdateThreadUtilization(tid, ThreadIdle);
|
||||||
|
|
||||||
while (m_WorkItems.empty() && !m_Stopped && m_ThreadDeaths == 0)
|
while (m_WorkItems.empty() && !m_Stopped && m_ThreadDeaths == 0)
|
||||||
m_CV.wait(lock);
|
m_WorkCV.wait(lock);
|
||||||
|
|
||||||
if (m_ThreadDeaths > 0) {
|
if (m_ThreadDeaths > 0) {
|
||||||
m_ThreadDeaths--;
|
m_ThreadDeaths--;
|
||||||
|
@ -190,7 +211,7 @@ void ThreadPool::Post(const ThreadPool::WorkFunction& callback)
|
||||||
wi.Timestamp = Utility::GetTime();
|
wi.Timestamp = Utility::GetTime();
|
||||||
|
|
||||||
m_WorkItems.push_back(wi);
|
m_WorkItems.push_back(wi);
|
||||||
m_CV.notify_one();
|
m_WorkCV.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadPool::ManagerThreadProc(void)
|
void ThreadPool::ManagerThreadProc(void)
|
||||||
|
@ -200,16 +221,18 @@ void ThreadPool::ManagerThreadProc(void)
|
||||||
Utility::SetThreadName(idbuf.str());
|
Utility::SetThreadName(idbuf.str());
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
Utility::Sleep(5);
|
|
||||||
|
|
||||||
double now = Utility::GetTime();
|
|
||||||
|
|
||||||
int pending, alive;
|
int pending, alive;
|
||||||
double avg_latency, max_latency;
|
double avg_latency, max_latency;
|
||||||
double utilization = 0;
|
double utilization = 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
|
||||||
|
m_MgmtCV.timed_wait(lock, boost::posix_time::seconds(5));
|
||||||
|
|
||||||
|
if (m_Stopped)
|
||||||
|
break;
|
||||||
|
|
||||||
pending = m_WorkItems.size();
|
pending = m_WorkItems.size();
|
||||||
|
|
||||||
alive = 0;
|
alive = 0;
|
||||||
|
@ -299,16 +322,17 @@ void ThreadPool::StatsThreadProc(void)
|
||||||
Utility::SetThreadName(idbuf.str());
|
Utility::SetThreadName(idbuf.str());
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
Utility::Sleep(0.25);
|
|
||||||
|
|
||||||
{
|
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
|
||||||
|
m_MgmtCV.timed_wait(lock, boost::posix_time::milliseconds(250));
|
||||||
|
|
||||||
|
if (m_Stopped)
|
||||||
|
break;
|
||||||
|
|
||||||
for (int i = 0; i < sizeof(m_ThreadStats) / sizeof(m_ThreadStats[0]); i++)
|
for (int i = 0; i < sizeof(m_ThreadStats) / sizeof(m_ThreadStats[0]); i++)
|
||||||
UpdateThreadUtilization(i);
|
UpdateThreadUtilization(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: Caller must hold m_Mutex.
|
* Note: Caller must hold m_Mutex.
|
||||||
|
|
|
@ -71,6 +71,9 @@ private:
|
||||||
ThreadStats m_ThreadStats[512];
|
ThreadStats m_ThreadStats[512];
|
||||||
int m_ThreadDeaths;
|
int m_ThreadDeaths;
|
||||||
|
|
||||||
|
boost::thread m_ManagerThread;
|
||||||
|
boost::thread m_StatsThread;
|
||||||
|
|
||||||
double m_WaitTime;
|
double m_WaitTime;
|
||||||
double m_ServiceTime;
|
double m_ServiceTime;
|
||||||
int m_TaskCount;
|
int m_TaskCount;
|
||||||
|
@ -78,7 +81,8 @@ private:
|
||||||
double m_MaxLatency;
|
double m_MaxLatency;
|
||||||
|
|
||||||
boost::mutex m_Mutex;
|
boost::mutex m_Mutex;
|
||||||
boost::condition_variable m_CV;
|
boost::condition_variable m_WorkCV;
|
||||||
|
boost::condition_variable m_MgmtCV;
|
||||||
|
|
||||||
bool m_Stopped;
|
bool m_Stopped;
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "base/timer.h"
|
#include "base/timer.h"
|
||||||
#include "base/application.h"
|
#include "base/application.h"
|
||||||
#include "base/utility.h"
|
#include "base/utility.h"
|
||||||
|
#include "base/logger_fwd.h"
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <boost/thread/thread.hpp>
|
#include <boost/thread/thread.hpp>
|
||||||
#include <boost/thread/mutex.hpp>
|
#include <boost/thread/mutex.hpp>
|
||||||
|
@ -300,6 +301,6 @@ void Timer::TimerThreadProc(void)
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
/* Asynchronously call the timer. */
|
/* Asynchronously call the timer. */
|
||||||
Application::GetTP().Post(boost::bind(&Timer::Call, timer));
|
Utility::QueueAsyncCallback(boost::bind(&Timer::Call, timer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,8 @@ icinga2_test_SOURCES = \
|
||||||
base-dictionary.cpp \
|
base-dictionary.cpp \
|
||||||
base-fifo.cpp \
|
base-fifo.cpp \
|
||||||
base-object.cpp \
|
base-object.cpp \
|
||||||
base-shellescape.cpp
|
base-shellescape.cpp \
|
||||||
|
base-timer.cpp
|
||||||
|
|
||||||
icinga2_test_CPPFLAGS = \
|
icinga2_test_CPPFLAGS = \
|
||||||
$(BOOST_CPPFLAGS) \
|
$(BOOST_CPPFLAGS) \
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* Icinga 2 *
|
||||||
|
* Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
|
||||||
|
* *
|
||||||
|
* This program 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 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation *
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "base/timer.h"
|
||||||
|
#include "base/utility.h"
|
||||||
|
#include "base/application.h"
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#include <boost/smart_ptr/make_shared.hpp>
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace icinga;
|
||||||
|
|
||||||
|
struct TimerFixture
|
||||||
|
{
|
||||||
|
TimerFixture(void)
|
||||||
|
{
|
||||||
|
Timer::Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
~TimerFixture(void)
|
||||||
|
{
|
||||||
|
Timer::Uninitialize();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BOOST_FIXTURE_TEST_SUITE(base_timer, TimerFixture)
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(construct)
|
||||||
|
{
|
||||||
|
Timer::Ptr timer = boost::make_shared<Timer>();
|
||||||
|
BOOST_CHECK(timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(interval)
|
||||||
|
{
|
||||||
|
Timer::Ptr timer = boost::make_shared<Timer>();
|
||||||
|
timer->SetInterval(1.5);
|
||||||
|
BOOST_CHECK(timer->GetInterval() == 1.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Callback(int *counter)
|
||||||
|
{
|
||||||
|
(*counter)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(invoke)
|
||||||
|
{
|
||||||
|
int counter;
|
||||||
|
Timer::Ptr timer = boost::make_shared<Timer>();
|
||||||
|
timer->OnTimerExpired.connect(boost::bind(&Callback, &counter));
|
||||||
|
timer->SetInterval(1);
|
||||||
|
|
||||||
|
counter = 0;
|
||||||
|
timer->Start();
|
||||||
|
Utility::Sleep(5.5);
|
||||||
|
timer->Stop();
|
||||||
|
|
||||||
|
std::cout << counter << std::endl;
|
||||||
|
BOOST_CHECK(counter >= 4 && counter <= 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(scope)
|
||||||
|
{
|
||||||
|
int counter;
|
||||||
|
Timer::Ptr timer = boost::make_shared<Timer>();
|
||||||
|
timer->OnTimerExpired.connect(boost::bind(&Callback, &counter));
|
||||||
|
timer->SetInterval(1);
|
||||||
|
|
||||||
|
counter = 0;
|
||||||
|
timer->Start();
|
||||||
|
Utility::Sleep(5.5);
|
||||||
|
timer.reset();
|
||||||
|
Utility::Sleep(5.5);
|
||||||
|
|
||||||
|
std::cout << counter << std::endl;
|
||||||
|
BOOST_CHECK(counter >= 4 && counter <= 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE_END()
|
Loading…
Reference in New Issue