Commit d35d47be authored by Peter Hutterer's avatar Peter Hutterer
Browse files

xserver: add default X IO error handler



Once a server is started, set the X IO error handler to throw an exception.
This way our test cases will survive a server crash and googletest will just
continue with the next test case instead of exiting the process completely.
Signed-off-by: Peter Hutterer's avatarPeter Hutterer <peter.hutterer@who-t.net>
parent ef25a6b6
......@@ -33,10 +33,28 @@
#include <gtest/gtest.h>
#include <xorg/gtest/xorg-gtest.h>
#include <X11/Xlib.h>
#include <stdexcept>
namespace xorg {
namespace testing {
/**
* @class XIOError
*
* Exception thrown if the display connection encounters an IO error and
* calls the XIOErrorHandler function.
*
* This exception requires an XIOErrorHandler to be registered.
* XServer::Start() will register this error handler. For tests that do not
* use the provided XServer object, call XServer::RegisterXIOErrorHandler()
* instead.
*/
class XIOError : public std::runtime_error {
public:
/** Create a new XIOError with the given message */
XIOError(const std::string& msg) : std::runtime_error(msg) {}
};
/**
* @class XServer xorg-gtest-xserver.h xorg/gtest/xorg-gtest-xserver.h
*
......@@ -55,6 +73,9 @@ namespace testing {
* std::cerr << "Problem killing server" << std::endl;
* }
* @endcode
*
* Once a XServer is started, a default XIOErrorHandler is installed and
* subsequent IO errors on the display connection will throw an XIOError.
*/
class XServer : public xorg::testing::Process {
public:
......@@ -221,6 +242,19 @@ class XServer : public xorg::testing::Process {
*/
static bool WaitForEventOfType(::Display *display, int type, int extension, int evtype, time_t timeout = 1000);
/**
* Install a default XIOErrorHandler. That error handler will throw an
* xorg::testing::XIOError when encountered.
*
* This function is called automatically by XServer::Start(). Usually,
* you will not need to call this function unless your test does not
* instantiate and Start() an XServer object.
*
* This function will only install a new error handler if the currently
* installed XIOErrorHandler is not the default handler used by Xlib.
*/
static void RegisterXIOErrorHandler();
private:
struct Private;
std::auto_ptr<Private> d_;
......
......@@ -45,6 +45,7 @@
#include <fstream>
#include <X11/Xlib.h>
#include <X11/Xlibint.h>
#include <X11/extensions/XInput2.h>
struct xorg::testing::XServer::Private {
......@@ -295,6 +296,20 @@ const std::string& xorg::testing::XServer::GetVersion(void) {
return d_->version;
}
static int _x_io_error_handler(Display *dpy)
{
throw xorg::testing::XIOError("Connection to X Server lost. Possible server crash.");
}
void xorg::testing::XServer::RegisterXIOErrorHandler()
{
XIOErrorHandler old_handler;
old_handler = XSetIOErrorHandler(_x_io_error_handler);
if (old_handler != _XDefaultIOError)
XSetIOErrorHandler(old_handler);
}
void xorg::testing::XServer::Start(const std::string &program) {
TestStartup();
......@@ -351,6 +366,8 @@ void xorg::testing::XServer::Start(const std::string &program) {
sigemptyset(&sig_mask);
sigaddset(&sig_mask, SIGCHLD);
sigprocmask(SIG_UNBLOCK, &sig_mask, NULL);
RegisterXIOErrorHandler();
}
bool xorg::testing::XServer::Terminate(unsigned int timeout) {
......
......@@ -3,6 +3,7 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <fstream>
#include <stdexcept>
#include <xorg/gtest/xorg-gtest.h>
......@@ -71,6 +72,22 @@ TEST(XServer, WaitForSIGUSR1)
}
}
TEST(XServer, IOErrorException)
{
ASSERT_THROW({
XServer server;
server.SetOption("-logfile", "/tmp/xorg-io-error-test.log");
server.SetOption("-noreset", "");
server.Start();
ASSERT_EQ(server.GetState(), Process::RUNNING);
::Display *dpy = XOpenDisplay(server.GetDisplayString().c_str());
ASSERT_TRUE(dpy != NULL);
close(ConnectionNumber(dpy));
XSync(dpy, False);
}, XIOError);
}
int main(int argc, char *argv[]) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment