tstSeamlessX11-auto.cpp revision cf59f0d26d20b28df49bd34b4c33401e009c4fe6
/** @file
* Automated test of the X11 seamless Additions code.
* @todo Better separate test data from implementation details!
*/
/*
* Copyright (C) 2007-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#include <stdlib.h> /* exit() */
#include <iprt/initterm.h>
#include <iprt/semaphore.h>
#include "../seamless.h"
/******************************************************
* Mock X11 functions needed by the seamless X11 class *
******************************************************/
{
return 0;
}
{
return TEST_DISPLAY;
}
{
return 0;
}
enum
{
ATOM_PROP = 1,
};
{
return (Atom) ATOM_DESKTOP_PROP;
AssertFailed();
return (Atom)0;
}
/** The window (if any) on which the WM_TYPE_PROP property is set to the
* WM_TYPE_DESKTOP_PROP atom. */
static Window g_hSmlsDesktopWindow = 0;
long long_offset, long long_length,
int *actual_format_return,
unsigned long *nitems_return,
unsigned long *bytes_after_return,
unsigned char **prop_return);
int *actual_format_return,
unsigned long *nitems_return,
unsigned long *bytes_after_return,
unsigned char **prop_return)
{
/* We only handle things we expect. */
0xffff);
*nitems_return = 0;
*bytes_after_return = sizeof(Atom);
*prop_return = NULL;
if ((w != g_hSmlsDesktopWindow) || (g_hSmlsDesktopWindow == 0))
return Success;
AssertReturn(long_offset == 0, 0);
AssertReturn(delProp == false, 0);
unsigned char *pProp;
sizeof(atomTypeDesktop));
*nitems_return = 1;
*prop_return = pProp;
*bytes_after_return = 0;
return 0;
}
/** Sets the current set of properties for all mock X11 windows */
{
}
int *error_basep);
{
return true;
}
/* We silently ignore this for now. */
{
return 0;
}
/* We silently ignore this for now. */
unsigned long event_mask);
{
}
{
return TEST_ROOT;
}
static unsigned g_cSmlsWindows = 0;
static const char **g_papszSmlsWinNames = NULL;
unsigned int *nchildren_return);
unsigned int *nchildren_return)
{
if (root_return)
*root_return = TEST_ROOT;
if (parent_return)
g_cSmlsWindows * sizeof(Window));
if (nchildren_return)
return (g_cSmlsWindows != 0);
}
{
return win;
}
{
for (unsigned i = 0; i < g_cSmlsWindows; ++i)
if (g_paSmlsWindows[i] == w)
{
return 1;
}
return 0;
}
long *supplied_return);
{
return 1;
}
const char **paNames)
{
}
static Window g_SmlsShapedWindow = 0;
static int g_cSmlsShapeRectangles = 0;
int *ordering);
{
return NULL; /* Probably not correct, but works for us. */
*ordering = 0;
sizeof(XRectangle)
}
{
}
static int g_SmlsEventType = 0;
static Window g_SmlsEventWindow = 0;
/* This should not be needed in the bits of the code we test. */
{
return True;
}
{
}
/* This should not be needed in the bits of the code we test. */
{
}
/* This should not be needed in the bits of the code we test. */
{
}
/** Dummy host class */
class testHost: public SeamlessHostProxy
{
bool mfNotified;
public:
testHost() : mfNotified(false) {}
{
mfNotified = true;
}
virtual ~testHost() {}
bool isNotified(void) { return mfNotified; }
};
/*****************************
* The actual tests to be run *
*****************************/
/** The name of the unit test */
static const char *g_pszTestName = NULL;
/*** Test fixture data and data structures ***/
/** A structure describing a test fixture to be run through. Each fixture
* describes the state of the windows visible (and unmapped) on the X server
* before and after a particular event is delivered, and the expected
* on-screen positions of all interesting visible windows at the end of the
* fixture as reported by the code (currently in the order it is likely to
* report them in, @todo sort this). We expect that the set of visible
* windows will be the same whether we start the code before the event and
* handle it or start the code after the event.
*/
struct SMLSFIXTURE
{
/** The number of windows visible before the event */
unsigned cWindowsBefore;
/** An array of Window IDs for the visible and unmapped windows before
* the event */
/** The window attributes matching the windows in @a paWindowsBefore */
/** The window names matching the windows in @a paWindowsBefore */
const char **papszNamesBefore;
/** The shaped window before the event - we allow at most one of these.
* Zero for none. */
/** The number of rectangles in the shaped window before the event. */
int cShapeRectsBefore;
/** The rectangles in the shaped window before the event */
/** The number of windows visible after the event */
unsigned cWindowsAfter;
/** An array of Window IDs for the visible and unmapped windows after
* the event */
/** The window attributes matching the windows in @a paWindowsAfter */
/** The window names matching the windows in @a paWindowsAfter */
const char **papszNamesAfter;
/** The shaped window after the event - we allow at most one of these.
* Zero for none. */
/** The number of rectangles in the shaped window after the event. */
int cShapeRectsAfter;
/** The rectangles in the shaped window after the event */
/** The event to delivered */
int x11EventType;
/** The window for which the event in @enmEvent is delivered */
/** The number of windows expected to be reported at the end of the
* fixture */
unsigned cReportedRects;
/** The onscreen positions of those windows. */
};
/*** Test fixture to test the code against X11 configure (move) events ***/
static XWindowAttributes g_aAttrib1Before[] =
};
static XRectangle g_aRectangle1[] =
{
{ 0, 0, 50, 50 },
{ 50, 50, 150, 250 }
};
static XWindowAttributes g_aAttrib1After[] =
};
static const char *g_apszNames1[] = { "Test Window" };
{
{ 200, 300, 250, 350 },
{ 250, 350, 400, 600 }
};
static SMLSFIXTURE g_testMove =
{
20,
20,
20,
};
/*** Test fixture to test the code against X11 configure (resize) events ***/
static XWindowAttributes g_aAttrib2Before[] =
};
static XRectangle g_aRectangle2Before[] =
{
{ 0, 0, 50, 50 },
{ 50, 50, 100, 100 }
};
static SMLSFIXTURE g_testResize =
{
20,
20,
20,
};
/*** Test fixture to test the code against X11 map events ***/
static XWindowAttributes g_aAttrib3Before[] =
};
static SMLSFIXTURE g_testMap =
{
20,
20,
20,
};
/*** Test fixtures to test the code against X11 unmap events ***/
static XWindowAttributes g_aAttrib4After[] =
};
static SMLSFIXTURE g_testUnmap =
{
20,
20,
20,
0,
};
/*** A window we are not monitoring has been unmapped. Nothing should
*** happen, especially nothing bad. ***/
{
{ 100, 200, 150, 250 },
{ 150, 250, 300, 500 }
};
static SMLSFIXTURE g_testUnmapOther =
{
20,
20,
21,
};
/*** Test fixture to test the code against X11 shape events ***/
static XRectangle g_aRectangle5Before[] =
{
{ 0, 0, 200, 200 }
};
static SMLSFIXTURE g_testShape =
{
20,
20,
20,
};
/*** And the test code proper ***/
/** Compare two RTRECT structures */
{
}
{
RTPrintf(" Expected: %d, %d, %d, %d. Got: %d, %d, %d, %d\n",
}
/** Run through a test fixture */
{
unsigned cErrs = 0;
{
RTPrintf("%s: fixture: %s. Notification was set before the first event!!!\n",
++cErrs;
}
if (!host.isNotified())
{
RTPrintf("%s: fixture: %s. No notification was sent for the initial window tree rebuild.\n",
++cErrs;
}
smlsSetNextEvent(0, 0);
if (!host.isNotified())
{
RTPrintf("%s: fixture: %s. No notification was sent after the event.\n",
++cErrs;
}
{
RTPrintf("%s: fixture: %s. Wrong number of rectangles reported after processing event (expected %u, got %u).\n",
cRects);
++cErrs;
}
else
for (unsigned i = 0; i < cRects; ++i)
{
RTPrintf("%s: fixture: %s. Rectangle %u wrong after processing event.\n",
g_pszTestName, pszDesc, i);
&pRects[i]);
++cErrs;
break;
}
{
RTPrintf("%s: fixture: %s. Wrong number of rectangles reported without processing event (expected %u, got %u).\n",
cRects);
++cErrs;
}
else
for (unsigned i = 0; i < cRects; ++i)
{
RTPrintf("%s: fixture: %s. Rectangle %u wrong without processing event.\n",
g_pszTestName, pszDesc, i);
&pRects[i]);
++cErrs;
break;
}
return cErrs;
}
{
unsigned cErrs = 0;
"ConfigureNotify event (window moved)");
// Currently not working
"ConfigureNotify event (window resized)");
"UnmapNotify event for unmonitored window");
if (cErrs > 0)
return cErrs == 0 ? 0 : 1;
}