Right, but it seems to have one error handling mechanism in xorg-gtest, and another in xorg-integration-tests, especially with your commit message of "other clients will have to install their own error handlers"<br>
<div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Nov 7, 2012 at 12:55 AM, Peter Hutterer <span dir="ltr"><<a href="mailto:peter.hutterer@who-t.net" target="_blank">peter.hutterer@who-t.net</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Wed, Nov 07, 2012 at 12:36:16AM -0500, Jasper St. Pierre wrote:<br>
> I wonder if we should move the error trap system into xorg-gtest.<br>
<br>
</div>yes, it would be useful have a unified error system for (both?) xorg-gtest<br>
users.<br>
<br>
this is largely orthogonal to this commit though. the error trap system is<br>
useful to trap specific errors that are expected, but not general errors<br>
that may occur accidentally - which is what this patch addresses.<br>
<br>
Cheers,<br>
   Peter<br>
<div class="HOEnZb"><div class="h5"><br>
> On Tue, Nov 6, 2012 at 10:57 PM, Peter Hutterer <<a href="mailto:peter.hutterer@who-t.net">peter.hutterer@who-t.net</a>>wrote:<br>
><br>
> > Xlib's default error handler prints the error and calls exit(1). Tests that<br>
> > accidentally trigger an error thus quit without cleaning up properly.<br>
> ><br>
> > Install a default error handler that prints the basic info and continue<br>
> > with<br>
> > the test. Clients that expect to trigger errors should set a custom error<br>
> > handler.<br>
> ><br>
> > Signed-off-by: Peter Hutterer <<a href="mailto:peter.hutterer@who-t.net">peter.hutterer@who-t.net</a>><br>
> > ---<br>
> >  include/xorg/gtest/xorg-gtest-xserver.h | 13 ++++++<br>
> >  src/xserver.cpp                         | 54 +++++++++++++++++++++++-<br>
> >  test/xserver-test.cpp                   | 73<br>
> > +++++++++++++++++++++++++++++++++<br>
> >  3 files changed, 139 insertions(+), 1 deletion(-)<br>
> ><br>
> > diff --git a/include/xorg/gtest/xorg-gtest-xserver.h<br>
> > b/include/xorg/gtest/xorg-gtest-xserver.h<br>
> > index 8bf7996..11fc93d 100644<br>
> > --- a/include/xorg/gtest/xorg-gtest-xserver.h<br>
> > +++ b/include/xorg/gtest/xorg-gtest-xserver.h<br>
> > @@ -265,6 +265,19 @@ class XServer : public xorg::testing::Process {<br>
> >       */<br>
> >      static void RegisterXIOErrorHandler();<br>
> ><br>
> > +    /**<br>
> > +     * Install a default XErrorHandler. That error handler will cause a<br>
> > test<br>
> > +     * failure if called.<br>
> > +     *<br>
> > +     * This function is called automatically by XServer::Start(). Usually,<br>
> > +     * you will not need to call this function unless your test does not<br>
> > +     * instantiate and Start() an XServer object.<br>
> > +     *<br>
> > +     * This function will only install a new error handler if the<br>
> > currently<br>
> > +     * installed XErrorHandler is not the default handler used by Xlib.<br>
> > +     */<br>
> > +    static void RegisterXErrorHandler();<br>
> > +<br>
> >    private:<br>
> >      struct Private;<br>
> >      std::auto_ptr<Private> d_;<br>
> > diff --git a/src/xserver.cpp b/src/xserver.cpp<br>
> > index ad018a1..4faa8e9 100644<br>
> > --- a/src/xserver.cpp<br>
> > +++ b/src/xserver.cpp<br>
> > @@ -394,6 +394,40 @@ const std::string&<br>
> > xorg::testing::XServer::GetVersion(void) {<br>
> >    return d_->version;<br>
> >  }<br>
> ><br>
> > +static int _x_error_handler(Display *dpy, XErrorEvent *err)<br>
> > +{<br>
> > +  std::stringstream error;<br>
> > +  switch(err->error_code) {<br>
> > +    case BadRequest: error << "BadRequest"; break;<br>
> > +    case BadValue: error << "BadValue"; break;<br>
> > +    case BadWindow: error << "BadWindow"; break;<br>
> > +    case BadPixmap: error << "BadPixmap"; break;<br>
> > +    case BadAtom: error << "BadAtom"; break;<br>
> > +    case BadCursor: error << "BadCursor"; break;<br>
> > +    case BadFont: error << "BadFont"; break;<br>
> > +    case BadMatch: error << "BadMatch"; break;<br>
> > +    case BadDrawable: error << "BadDrawable"; break;<br>
> > +    case BadAccess: error << "BadAccess"; break;<br>
> > +    case BadAlloc: error << "BadAlloc"; break;<br>
> > +    case BadColor: error << "BadColor"; break;<br>
> > +    case BadGC: error << "BadGC"; break;<br>
> > +    case BadIDChoice: error << "BadIDChoice"; break;<br>
> > +    case BadName: error << "BadName"; break;<br>
> > +    case BadLength: error << "BadLength"; break;<br>
> > +    case BadImplementation: error << "BadImplementation"; break;<br>
> > +    default:<br>
> > +      error << err->error_code;<br>
> > +      break;<br>
> > +  }<br>
> > +<br>
> > +  ADD_FAILURE() << "XError received: " << error.str() << ", request " <<<br>
> > +    (int)err->request_code << "(" << (int)err->minor_code << "), detail: "<br>
> > +    << err->resourceid << "\nThis error handler is likely to be triggered<br>
> > "<br>
> > +    "more than once.\nCheck the first error for the real error";<br>
> > +  return 0;<br>
> > +}<br>
> > +<br>
> > +<br>
> >  static int _x_io_error_handler(Display *dpy) _X_NORETURN;<br>
> >  static int _x_io_error_handler(Display *dpy)<br>
> >  {<br>
> > @@ -409,6 +443,15 @@ void xorg::testing::XServer::RegisterXIOErrorHandler()<br>
> >      XSetIOErrorHandler(old_handler);<br>
> >  }<br>
> ><br>
> > +void xorg::testing::XServer::RegisterXErrorHandler()<br>
> > +{<br>
> > +  XErrorHandler old_handler;<br>
> > +  old_handler = XSetErrorHandler(_x_error_handler);<br>
> > +<br>
> > +  if (old_handler != _XDefaultError)<br>
> > +    XSetErrorHandler(old_handler);<br>
> > +}<br>
> > +<br>
> >  void xorg::testing::XServer::Start(const std::string &program) {<br>
> >    TestStartup();<br>
> ><br>
> > @@ -464,7 +507,15 @@ void xorg::testing::XServer::Start(const std::string<br>
> > &program) {<br>
> >          args.push_back(it->second);<br>
> >      }<br>
> ><br>
> > -    Process::Start(program.empty() ? d_->path_to_server : program, args);<br>
> > +    std::string server_binary = program.empty() ? d_->path_to_server :<br>
> > program;<br>
> > +<br>
> > +    if (getenv("XORG_GTEST_XSERVER_USE_VALGRIND")) {<br>
> > +      args.insert(args.begin(), server_binary);<br>
> > +      server_binary = "valgrind";<br>
> > +      args.insert(args.begin(), "--leak-check=full");<br>
> > +    }<br>
> > +<br>
> > +    Process::Start(server_binary, args);<br>
> >      /* noreturn */<br>
> ><br>
> >    }<br>
> > @@ -494,6 +545,7 @@ void xorg::testing::XServer::Start(const std::string<br>
> > &program) {<br>
> >    signal(SIGUSR1 ,SIG_IGN);<br>
> ><br>
> >    RegisterXIOErrorHandler();<br>
> > +  RegisterXErrorHandler();<br>
> >  }<br>
> ><br>
> >  bool xorg::testing::XServer::Terminate(unsigned int timeout) {<br>
> > diff --git a/test/xserver-test.cpp b/test/xserver-test.cpp<br>
> > index cdf0bd9..32792e6 100644<br>
> > --- a/test/xserver-test.cpp<br>
> > +++ b/test/xserver-test.cpp<br>
> > @@ -6,6 +6,7 @@<br>
> >  #include <stdexcept><br>
> ><br>
> >  #include <xorg/gtest/xorg-gtest.h><br>
> > +#include <gtest/gtest-spi.h><br>
> >  #include <X11/extensions/XInput2.h><br>
> ><br>
> >  using namespace xorg::testing;<br>
> > @@ -213,6 +214,78 @@ TEST(XServer, IOErrorException)<br>
> >    }, XIOError);<br>
> >  }<br>
> ><br>
> > +TEST(XServer, ErrorHandler)<br>
> > +{<br>
> > +  XORG_TESTCASE("Start a server, trigger a BadColor error and expect a "<br>
> > +                 "failure from the default error handler\n");<br>
> > +<br>
> > +  pid_t pid = fork();<br>
> > +<br>
> > +  if (pid == 0) {<br>
> > +    EXPECT_NONFATAL_FAILURE({<br>
> > +      XServer server;<br>
> > +      server.SetOption("-logfile", LOGFILE_DIR<br>
> > "/xorg-error-handler-test.log");<br>
> > +      server.SetOption("-config", DUMMY_CONF_PATH);<br>
> > +      server.SetOption("-noreset", "");<br>
> > +      server.Start();<br>
> > +      ASSERT_EQ(server.GetState(), Process::RUNNING);<br>
> > +      ::Display *dpy = XOpenDisplay(server.GetDisplayString().c_str());<br>
> > +      ASSERT_TRUE(dpy != NULL);<br>
> > +      XColor color;<br>
> > +      XQueryColor(dpy, 0, &color);<br>
> > +      XSync(dpy, False);<br>
> > +    }, "BadColor");<br>
> > +    exit(0);<br>
> > +  }<br>
> > +<br>
> > +  /* if the Xlib default error handler triggers, child calls exit(1) */<br>
> > +  int status;<br>
> > +  ASSERT_EQ(waitpid(pid, &status, 0), pid);<br>
> > +  ASSERT_TRUE(WIFEXITED(status));<br>
> > +  ASSERT_EQ(WEXITSTATUS(status), 0);<br>
> > +}<br>
> > +<br>
> > +static bool error_handler_triggered = false;<br>
> > +<br>
> > +static int _test_error_handler(Display *dpy, XErrorEvent *error) {<br>
> > +  error_handler_triggered = true;<br>
> > +  if (error->error_code != BadColor)<br>
> > +    ADD_FAILURE() << "Error handler triggered with wrong error code\n";<br>
> > +  return 0;<br>
> > +}<br>
> > +<br>
> > +TEST(XServer, NondefaultErrorHandler)<br>
> > +{<br>
> > +  XORG_TESTCASE("Set a custom error handler, start a server, trigger a "<br>
> > +                "BadColor error and expect the custom error handler to be<br>
> > "<br>
> > +                "triggered\n");<br>
> > +<br>
> > +  pid_t pid = fork();<br>
> > +<br>
> > +  if (pid == 0) {<br>
> > +    XSetErrorHandler(_test_error_handler);<br>
> > +<br>
> > +    XServer server;<br>
> > +    server.SetOption("-logfile", LOGFILE_DIR<br>
> > "/xorg-error-handler-test.log");<br>
> > +    server.SetOption("-config", DUMMY_CONF_PATH);<br>
> > +    server.SetOption("-noreset", "");<br>
> > +    server.Start();<br>
> > +    ASSERT_EQ(server.GetState(), Process::RUNNING);<br>
> > +    ::Display *dpy = XOpenDisplay(server.GetDisplayString().c_str());<br>
> > +    ASSERT_TRUE(dpy != NULL);<br>
> > +    XColor color;<br>
> > +    XQueryColor(dpy, 0, &color);<br>
> > +    XSync(dpy, False);<br>
> > +    exit(error_handler_triggered ? 0 : 1);<br>
> > +  }<br>
> > +<br>
> > +  /* if the Xlib default error handler triggers, child calls exit(1) */<br>
> > +  int status;<br>
> > +  ASSERT_EQ(waitpid(pid, &status, 0), pid);<br>
> > +  ASSERT_TRUE(WIFEXITED(status));<br>
> > +  ASSERT_EQ(WEXITSTATUS(status), 0);<br>
> > +}<br>
> > +<br>
> >  TEST(XServer, KeepAlive)<br>
> >  {<br>
> >    XORG_TESTCASE("If XORG_GTEST_XSERVER_KEEPALIVE is set,\n"<br>
> > --<br>
> > 1.7.11.7<br>
> ><br>
> > _______________________________________________<br>
> > <a href="mailto:xorg-devel@lists.x.org">xorg-devel@lists.x.org</a>: X.Org development<br>
> > Archives: <a href="http://lists.x.org/archives/xorg-devel" target="_blank">http://lists.x.org/archives/xorg-devel</a><br>
> > Info: <a href="http://lists.x.org/mailman/listinfo/xorg-devel" target="_blank">http://lists.x.org/mailman/listinfo/xorg-devel</a><br>
> ><br>
><br>
><br>
><br>
> --<br>
>   Jasper<br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br>  Jasper<br><br>
</div>