libeventベースのアプリケーションをテストする

libevent(Fast portable non-blocking network programming with Libevent)で回ってるようなアプリのテストって悩ましいよね。
event_dispatchをしてしまうと、Testのコードに戻れないし!
そんな悩める少年少女に送る云々

つまるところは、event_base_loop(or event_loop?)を回せばいいのさジョニー

	typedef std::shared_ptr<struct event_base> pevenv_t;
	event_base * ptr = event_base_new();
	BOOST_CHECK(ptr != NULL);
	pevenv_t pevenv(ptr, event_base_free);
	...
	BOOST_CHECK(event_base_loop(pevenv.get(), EVLOOP_ONCE) == 0);

ものは試し、inotify(inotify を使ってファイルシステムのアクティビティーを監視する)と合わせて簡単なテストを書いてみようそうしよう

#include <event.h>
#include <iostream>
#include <memory>
#include <boost/test/minimal.hpp>
#include <sys/inotify.h>
#include <sys/ioctl.h>

void on_notify(int fd, short event, void * arg)
{
	int len, vpos = 0;

	ioctl(fd, FIONREAD, &len);
	std::shared_ptr<char> buf((char *)malloc(len), free);
	read(fd, buf.get(), len);

	while(vpos < len) {
		inotify_event * piev((inotify_event *)(buf.get() + vpos));
		std::cout << "Event:";
		if(piev->mask == IN_CREATE)
			std::cout<< "CREATE" << std::endl;
		else if(piev->mask == IN_MODIFY)
			std::cout<< "MODIFY" << std::endl;
		else
			std::cout<< "???" << std::endl;

		std::cout << "Name:" << std::string(piev->name, piev->len) << std::endl;
		vpos += (sizeof(inotify_event) + piev->len);
	}
}

int test_main(int, char **)
{
	typedef std::shared_ptr<struct event_base> pevenv_t;

	event_base * ptr = event_base_new();
	BOOST_REQUIRE(ptr != NULL);

	pevenv_t pevenv(ptr, event_base_free);

	int fd;
	std::shared_ptr<struct event> pev(new event, event_del);
	{
		fd = inotify_init();

		if(inotify_add_watch(fd, "./", IN_CREATE|IN_MODIFY) == -1) {
			close(fd);
			return 1;
		}

		event_set(pev.get(), fd, EV_READ | EV_PERSIST, on_notify, NULL);
		event_base_set(pevenv.get(), pev.get());
		event_add(pev.get(), NULL);
	}

	BOOST_REQUIRE(system("echo >> temp.txt") != -1);
	BOOST_REQUIRE(event_base_loop(pevenv.get(), EVLOOP_ONCE) == 0);

	std::cout << "Main!" << std::endl;
	return 0;
}
% g++ test.cpp -std=c++0x -I/usr/local/include/boost-1_39 -levent
% ./a.out
Event:CREATE
Name:temp.txt
Event:MODIFY
Name:temp.txt
Main!

**** no errors detected
%