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>();
|
||||
|
||||
if (json->type != cJSON_Object)
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("JSON type must be cJSON_Object."));
|
||||
ASSERT(json->type == cJSON_Object);
|
||||
|
||||
for (cJSON *i = json->child; i != NULL; i = i->next) {
|
||||
dictionary->Set(i->string, Value::FromJson(i));
|
||||
|
|
|
@ -26,20 +26,19 @@
|
|||
#include <boost/bind.hpp>
|
||||
#include <boost/exception/diagnostic_information.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/chrono/duration.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
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++)
|
||||
SpawnWorker();
|
||||
|
||||
boost::thread managerThread(boost::bind(&ThreadPool::ManagerThreadProc, this));
|
||||
managerThread.detach();
|
||||
|
||||
boost::thread statsThread(boost::bind(&ThreadPool::StatsThreadProc, this));
|
||||
statsThread.detach();
|
||||
m_ManagerThread = boost::thread(boost::bind(&ThreadPool::ManagerThreadProc, this));
|
||||
m_StatsThread = boost::thread(boost::bind(&ThreadPool::StatsThreadProc, this));
|
||||
}
|
||||
|
||||
ThreadPool::~ThreadPool(void)
|
||||
|
@ -52,7 +51,8 @@ void ThreadPool::Stop(void)
|
|||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
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);
|
||||
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);
|
||||
|
||||
while (m_WorkItems.empty() && !m_Stopped && m_ThreadDeaths == 0)
|
||||
m_CV.wait(lock);
|
||||
m_WorkCV.wait(lock);
|
||||
|
||||
if (m_ThreadDeaths > 0) {
|
||||
m_ThreadDeaths--;
|
||||
|
@ -190,7 +211,7 @@ void ThreadPool::Post(const ThreadPool::WorkFunction& callback)
|
|||
wi.Timestamp = Utility::GetTime();
|
||||
|
||||
m_WorkItems.push_back(wi);
|
||||
m_CV.notify_one();
|
||||
m_WorkCV.notify_one();
|
||||
}
|
||||
|
||||
void ThreadPool::ManagerThreadProc(void)
|
||||
|
@ -200,16 +221,18 @@ void ThreadPool::ManagerThreadProc(void)
|
|||
Utility::SetThreadName(idbuf.str());
|
||||
|
||||
for (;;) {
|
||||
Utility::Sleep(5);
|
||||
|
||||
double now = Utility::GetTime();
|
||||
|
||||
int pending, alive;
|
||||
double avg_latency, max_latency;
|
||||
double utilization = 0;
|
||||
|
||||
{
|
||||
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();
|
||||
|
||||
alive = 0;
|
||||
|
@ -299,15 +322,16 @@ void ThreadPool::StatsThreadProc(void)
|
|||
Utility::SetThreadName(idbuf.str());
|
||||
|
||||
for (;;) {
|
||||
Utility::Sleep(0.25);
|
||||
|
||||
{
|
||||
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++)
|
||||
UpdateThreadUtilization(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -71,6 +71,9 @@ private:
|
|||
ThreadStats m_ThreadStats[512];
|
||||
int m_ThreadDeaths;
|
||||
|
||||
boost::thread m_ManagerThread;
|
||||
boost::thread m_StatsThread;
|
||||
|
||||
double m_WaitTime;
|
||||
double m_ServiceTime;
|
||||
int m_TaskCount;
|
||||
|
@ -78,7 +81,8 @@ private:
|
|||
double m_MaxLatency;
|
||||
|
||||
boost::mutex m_Mutex;
|
||||
boost::condition_variable m_CV;
|
||||
boost::condition_variable m_WorkCV;
|
||||
boost::condition_variable m_MgmtCV;
|
||||
|
||||
bool m_Stopped;
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "base/timer.h"
|
||||
#include "base/application.h"
|
||||
#include "base/utility.h"
|
||||
#include "base/logger_fwd.h"
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
@ -300,6 +301,6 @@ void Timer::TimerThreadProc(void)
|
|||
lock.unlock();
|
||||
|
||||
/* 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-fifo.cpp \
|
||||
base-object.cpp \
|
||||
base-shellescape.cpp
|
||||
base-shellescape.cpp \
|
||||
base-timer.cpp
|
||||
|
||||
icinga2_test_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