diff options
author | Mark Doffman <mdoff@silver-wind.(none)> | 2008-06-13 04:10:33 +0100 |
---|---|---|
committer | Mark Doffman <mdoff@silver-wind.(none)> | 2008-06-13 04:13:15 +0100 |
commit | 378f926e3fbcd81bdb2aa5065612ddddf959e2e4 (patch) | |
tree | ad9e1bfb40d607dbfc746484ff3b47f519c42f2e /tests | |
parent | ef25f02aa5044192c07e7d07b2a9c7b61582ddfe (diff) | |
download | at-spi2-atk-378f926e3fbcd81bdb2aa5065612ddddf959e2e4.tar.gz |
2008-06-13 Mark Doffman <mark.doffman@codethink.co.uk>
* atk-adaptor/bridge.c
Add command line arguments to set the D-Bus name.
For testing purposes.
* tests/*
Add the beginnings of a component test.
Add a D-Bus Test interface for syncing the
client and server processes.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Makefile.am | 12 | ||||
-rw-r--r-- | tests/apps/Makefile.am | 7 | ||||
-rw-r--r-- | tests/apps/component-app.c | 54 | ||||
-rw-r--r-- | tests/apps/noop-app.c | 12 | ||||
-rw-r--r-- | tests/apps/object-app.c | 12 | ||||
-rw-r--r-- | tests/apps/test-application.c | 149 | ||||
-rw-r--r-- | tests/clients/Makefile.am | 3 | ||||
-rw-r--r-- | tests/clients/__init__.py | 5 | ||||
-rw-r--r-- | tests/clients/accessibletest.py (renamed from tests/clients/accessibleobject.py) | 27 | ||||
-rw-r--r-- | tests/clients/componenttest.py | 82 | ||||
-rw-r--r-- | tests/clients/coretest.py | 57 | ||||
-rw-r--r-- | tests/clients/testutil.py | 43 | ||||
-rwxr-xr-x | tests/runtests.sh | 9 | ||||
-rwxr-xr-x | tests/testrunner.py | 16 |
14 files changed, 402 insertions, 86 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index dd9a234..f272bb9 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -2,11 +2,11 @@ SUBDIRS = dummyatk apps clients EXTRA_DIST = testrunner.py runtests.sh TESTS=testrunner.py -TESTS_ENVIRONMENT = PYTHONPATH=$(abs_top_srcdir)/python \ - ATSPI_INTROSPECTION_PATH=$(top_srcdir)/xml/introspection \ - testdata=$(abs_top_srcdir)/tests/data \ - atspilib=$(abs_top_srcdir)/atk-adaptor/.libs/libspiatk.so \ - testmodules=$(abs_top_srcdir)/tests/apps/.libs \ - testapp=$(abs_top_srcdir)/tests/apps/test-application +TESTS_ENVIRONMENT = PYTHONPATH=$(abs_top_srcdir)/python \ + ATSPI_INTROSPECTION_PATH=$(top_srcdir)/xml/introspection \ + TEST_DATA_DIRECTORY=$(abs_top_srcdir)/tests/data \ + TEST_ATSPI_LIBRARY=$(abs_top_srcdir)/atk-adaptor/.libs/libspiatk.so \ + TEST_MODULES_DIRECTORY=$(abs_top_srcdir)/tests/apps/.libs \ + TEST_APPLICATION=$(abs_top_srcdir)/tests/apps/test-application CLEANFILES = *.pyc diff --git a/tests/apps/Makefile.am b/tests/apps/Makefile.am index 0f0b550..9d13218 100644 --- a/tests/apps/Makefile.am +++ b/tests/apps/Makefile.am @@ -1,5 +1,5 @@ check_PROGRAMS = test-application -check_LTLIBRARIES = libnoopapp.la libobjectapp.la +check_LTLIBRARIES = libnoopapp.la libobjectapp.la libcomponentapp.la test_application_CFLAGS = $(DBUS_GLIB_CFLAGS) \ $(ATK_CFLAGS) \ @@ -26,3 +26,8 @@ libobjectapp_la_CFLAGS = $(TEST_APP_CFLAGS) $(LIB_XML_CFLAGS) libobjectapp_la_LDFLAGS = $(TEST_APP_LDFLAGS) libobjectapp_la_LIBADD = $(TEST_APP_LIBADD) $(LIB_XML_LIBS) libobjectapp_la_SOURCES = object-app.c atk-object-xml-loader.c atk-object-xml-loader.h + +libcomponentapp_la_CFLAGS = $(TEST_APP_CFLAGS) +libcomponentapp_la_LDFLAGS = $(TEST_APP_LDFLAGS) +libcomponentapp_la_LIBADD = $(TEST_APP_LIBADD) +libcomponentapp_la_SOURCES = component-app.c diff --git a/tests/apps/component-app.c b/tests/apps/component-app.c new file mode 100644 index 0000000..f395b98 --- /dev/null +++ b/tests/apps/component-app.c @@ -0,0 +1,54 @@ +#include <gmodule.h> +#include <atk/atk.h> +#include <my-atk.h> + +static gchar *tdata_path = NULL; + +static AtkComponent *comps[] = {NULL, NULL, NULL}; +static const AtkRectangle extents[] = {{0,0,30,20}, {40,30,30,40}, {0,0,70,70}}; +static const AtkLayer layers[] = {ATK_LAYER_WINDOW, ATK_LAYER_WIDGET, ATK_LAYER_MDI}; +static const guint zorders[] = {0, G_MININT, 100}; +static const gboolean extent_may_changed[] = {TRUE, FALSE, TRUE}; + +G_MODULE_EXPORT void +test_init (gchar *path) +{ + int i; + + if (path == NULL) + g_error("No test data path provided"); + tdata_path = path; + + g_type_init(); + for(i = 0; i < sizeof(comps) / sizeof(comps[0]); i++) + { + MyAtkComponent *mycomp = MY_ATK_COMPONENT(g_object_new(MY_TYPE_ATK_COMPONENT, NULL)); + + mycomp->extent = extents[i]; + mycomp->is_extent_may_changed = extent_may_changed[i]; + mycomp->layer = layers[i]; + mycomp->zorder = zorders[i]; + + comps[i] = ATK_COMPONENT(mycomp); + } + atk_object_set_parent((AtkObject*)comps[0],(AtkObject*)comps[2]); + atk_object_set_parent((AtkObject*)comps[1],(AtkObject*)comps[2]); +} + +G_MODULE_EXPORT void +test_next (int argc, char *argv[]) +{ + g_print("Moving to next stage\n"); +} + +G_MODULE_EXPORT void +test_finished (int argc, char *argv[]) +{ + g_print("Test has completed\n"); +} + +G_MODULE_EXPORT AtkObject * +test_get_root (void) +{ + return ATK_COMPONENT(comps[2]); +} diff --git a/tests/apps/noop-app.c b/tests/apps/noop-app.c index 42951eb..f2a5f51 100644 --- a/tests/apps/noop-app.c +++ b/tests/apps/noop-app.c @@ -7,6 +7,18 @@ test_init (int argc, char *argv[]) ; } +G_MODULE_EXPORT void +test_next (int argc, char *argv[]) +{ + ; +} + +G_MODULE_EXPORT void +test_finished (int argc, char *argv[]) +{ + ; +} + G_MODULE_EXPORT AtkObject * test_get_root (void) { diff --git a/tests/apps/object-app.c b/tests/apps/object-app.c index 74dabb3..07b79e6 100644 --- a/tests/apps/object-app.c +++ b/tests/apps/object-app.c @@ -24,6 +24,18 @@ test_init (gchar *path) g_free(td); } +G_MODULE_EXPORT void +test_next (int argc, char *argv[]) +{ + g_print("Moving to next stage\n"); +} + +G_MODULE_EXPORT void +test_finished (int argc, char *argv[]) +{ + g_print("Test has completed\n"); +} + G_MODULE_EXPORT AtkObject * test_get_root (void) { diff --git a/tests/apps/test-application.c b/tests/apps/test-application.c index 41118e3..0c62402 100644 --- a/tests/apps/test-application.c +++ b/tests/apps/test-application.c @@ -30,6 +30,7 @@ * all the application state for the test. */ +#include <stdlib.h> #include <glib.h> #include <gmodule.h> #include <atk/atk.h> @@ -38,6 +39,11 @@ /* The test module, GModule containing interface for an atk-test */ static GModule *test_module; static gpointer test_module_get_root; +static gpointer test_module_next; +static gpointer test_module_finished; + +static DBusConnection *dbus_bus; +static GMainLoop *mainloop; /* Test module interface */ /*************************/ @@ -51,6 +57,16 @@ get_root(void) return ((TestModuleGetRoot) test_module_get_root)(); } +typedef void (*VoidVoid) (void); + +/* Called to move to next stage of test.*/ +static void +next(void) +{ + ((VoidVoid) test_module_next)(); +} + + /*************************/ /* The AtkUtil class is called to find the root accessible and to deal @@ -66,11 +82,11 @@ setup_atk_util(void) g_type_class_unref(klass); } -typedef void (*GtkModuleInit) (int argc, char *argv[]); +typedef void (*GtkModuleInit) (int *argc, char **argv[]); /* AT-SPI is a gtk module that must be loaded and initialized */ static void -load_atspi_module(const char *path, int argc, char *argv[]) +load_atspi_module(const char *path, int *argc, char **argv[]) { GModule *bridge; gpointer init; @@ -102,9 +118,126 @@ load_test_module(const char *path, const char *tdpath) if (!g_module_symbol(test_module, "test_get_root", &test_module_get_root)) g_error("Couldn't load symbol \"test_get_root\"\n"); + if (!g_module_symbol(test_module, "test_next", &test_module_next)) + g_error("Couldn't load symbol \"test_next\"\n"); + + if (!g_module_symbol(test_module, "test_finished", &test_module_finished)) + g_error("Couldn't load symbol \"test_finished\"\n"); + ((TestModuleInit) init)((gchar *)tdpath); } +static const char* introspection_string = +"<node name=\"/org/codethink/atspi/test\">" +" <interface name=\"org.codethink.atspi.test\">" +" <method name=\"next\"/>" +" <signal name=\"started\"/>" +" </interface>" +"</node>"; + +static DBusHandlerResult +message_handler (DBusConnection *bus, DBusMessage *message, void *user_data) +{ + const char *iface = dbus_message_get_interface (message); + const char *member = dbus_message_get_member (message); + DBusHandlerResult result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + gboolean exit = FALSE; + + DBusMessage *reply = NULL; + + g_print("\nRecieved test interface message\n"); + + g_return_val_if_fail(iface != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED); + + if (!strcmp(iface, "org.codethink.atspi.test")) + { + if (!strcmp(member, "next")) + { + next(); + reply = dbus_message_new_method_return (message); + g_assert(reply != NULL); + result = DBUS_HANDLER_RESULT_HANDLED; + } + + if (!strcmp(member, "finished")) + { + ((VoidVoid) test_module_finished)(); + reply = dbus_message_new_method_return (message); + g_assert(reply != NULL); + result = DBUS_HANDLER_RESULT_HANDLED; + exit = TRUE; + } + } + + if (!strcmp(iface, "org.freedesktop.DBus.Introspectable")) + { + if (!strcmp(member, "Introspect")) + { + reply = dbus_message_new_method_return (message); + g_assert(reply != NULL); + dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection_string, + DBUS_TYPE_INVALID); + result = DBUS_HANDLER_RESULT_HANDLED; + } + } + + if (reply) + { + dbus_connection_send (bus, reply, NULL); + dbus_message_unref (reply); + } + + if (exit == TRUE) + { + dbus_connection_flush(bus); + dbus_connection_unref(bus); + g_main_loop_quit(mainloop); + abort(); + } + return result; +} + +static DBusObjectPathVTable test_vtable = +{ + NULL, + &message_handler, + NULL, NULL, NULL, NULL +}; + +static void +init_dbus_interface(void) +{ + DBusError error; + + dbus_error_init(&error); + dbus_bus = dbus_bus_get(DBUS_BUS_SESSION, &error); + g_print("\nUnique D-Bus name is: %s\n", dbus_bus_get_unique_name(dbus_bus)); + + if (!dbus_bus) + g_error("Couldn't get the session bus - %s\n", error.message); + + g_assert(dbus_connection_register_object_path(dbus_bus, + "/org/codethink/atspi/test", + &test_vtable, + NULL)); + + dbus_connection_setup_with_g_main(dbus_bus, g_main_context_default()); +} + +static void +send_started_signal(void) +{ + DBusMessage* sig; + DBusMessageIter args; + + sig = dbus_message_new_signal("/org/codethink/atspi/test", "org.codethink.atspi.test", "started"); + g_assert(sig != NULL); + if (!dbus_connection_send(dbus_bus, sig, NULL)) + g_error("Out of memory"); + dbus_connection_flush(dbus_bus); + dbus_message_unref(sig); +} + /*Command line data*/ static gchar *tmodule_path = NULL; static gchar *amodule_path = NULL; @@ -112,9 +245,9 @@ static gchar *tdata_path = NULL; static GOptionEntry optentries[] = { - {"test-module", 't', 0, G_OPTION_ARG_STRING, &tmodule_path, "Module containing test scenario", NULL}, - {"atspi-module", 'a', 0, G_OPTION_ARG_STRING, &amodule_path, "Gtk module with atk-atspi adaptor", NULL}, - {"test-data", 'd', 0, G_OPTION_ARG_STRING, &tdata_path, "Path to directory of test data", NULL}, + {"test-module", 0, 0, G_OPTION_ARG_STRING, &tmodule_path, "Module containing test scenario", NULL}, + {"test-atspi-library", 0, 0, G_OPTION_ARG_STRING, &amodule_path, "Gtk module with atk-atspi adaptor", NULL}, + {"test-data-directory", 0, 0, G_OPTION_ARG_STRING, &tdata_path, "Path to directory of test data", NULL}, {NULL} }; @@ -124,7 +257,6 @@ static GOptionEntry optentries[] = */ main(int argc, char *argv[]) { - GMainLoop *mainloop; GOptionContext *opt; GError *err = NULL; @@ -132,6 +264,7 @@ main(int argc, char *argv[]) opt = g_option_context_new(NULL); g_option_context_add_main_entries(opt, optentries, NULL); g_option_context_set_ignore_unknown_options(opt, TRUE); + if (!g_option_context_parse(opt, &argc, &argv, &err)) g_error("Option parsing failed: %s\n", err->message); @@ -144,7 +277,9 @@ main(int argc, char *argv[]) setup_atk_util(); load_test_module(tmodule_path, tdata_path); - load_atspi_module(amodule_path, argc, argv); + load_atspi_module(amodule_path, &argc, &argv); + init_dbus_interface(); + send_started_signal(); mainloop = g_main_loop_new (NULL, FALSE); g_main_loop_run (mainloop); diff --git a/tests/clients/Makefile.am b/tests/clients/Makefile.am index a0d9ea1..5c96eae 100644 --- a/tests/clients/Makefile.am +++ b/tests/clients/Makefile.am @@ -1,6 +1,7 @@ EXTRA_DIST = \ - accessibleobject.py \ __init__.py \ + accessibleobject.py \ + component.py \ testutil.py CLEANFILES = *.pyc diff --git a/tests/clients/__init__.py b/tests/clients/__init__.py index 40674f3..2b8731d 100644 --- a/tests/clients/__init__.py +++ b/tests/clients/__init__.py @@ -1,5 +1,4 @@ -from accessibleobject import AccessibleObjectTestCase +from accessibletest import AccessibleTestCase +from componenttest import ComponentTestCase import testutil - -del accessibleobject diff --git a/tests/clients/accessibleobject.py b/tests/clients/accessibletest.py index f63490d..63c8e22 100644 --- a/tests/clients/accessibleobject.py +++ b/tests/clients/accessibletest.py @@ -1,14 +1,15 @@ -import unittest import testutil import dbus import gobject import os.path +import coretest from dbus.mainloop.glib import DBusGMainLoop from accessible_cache import AccessibleCache from xml.dom import minidom +import os def createNode(accessible, parentElement): e = minidom.Element("accessible") @@ -22,30 +23,20 @@ def createNode(accessible, parentElement): parentElement.appendChild(e) -class AccessibleObjectTestCase(unittest.TestCase): - def setUp(self): - DBusGMainLoop(set_as_default=True) - self._app = testutil.runTestApp("libobjectapp.so") - - self._bus = dbus.SessionBus() - self._loop = gobject.MainLoop() - self._cache = AccessibleCache(self._bus, testutil.busname, testutil.objectpath) - - def tearDown(self): - del(self._bus) - del(self._loop) - del(self._cache) - #TODO Shut down the test application. - del(self._app) - +class AccessibleTestCase(coretest.CoreTestCase): def runTest(self): + self._app = testutil.runTestApp("libobjectapp.so", self._name) + self._loop.run() + + def post_application_test(self): root = self._cache.getRootAccessible() doc = minidom.Document() createNode(root, doc) answer = doc.toprettyxml() - correct = os.path.join(testutil.testdata, "object-test-stage1-results.xml") + correct = os.path.join(os.environ["TEST_DATA_DIRECTORY"], + "object-test-stage1-results.xml") file = open(correct) cstring = file.read() diff --git a/tests/clients/componenttest.py b/tests/clients/componenttest.py new file mode 100644 index 0000000..9a1564d --- /dev/null +++ b/tests/clients/componenttest.py @@ -0,0 +1,82 @@ +import testutil + +import dbus +import gobject +import os.path +import coretest +from dbus.mainloop.glib import DBusGMainLoop + +from accessible_cache import AccessibleCache +from accessible_cache import ATSPI_COMPONENT + +from xml.dom import minidom + +ATSPI_LAYER_WIDGET = 3 +ATSPI_LAYER_MDI = 4 +ATSPI_LAYER_WINDOW = 7 + +extents_expected = [(0,0,30,20), (40,30,30,40), (0,0,70,70)] +layers_expected = [ATSPI_LAYER_WINDOW, ATSPI_LAYER_WIDGET, ATSPI_LAYER_MDI] +zorders_expected = [0, -100, 100] + +def supportsInterface(accessible, interface): + for itf in accessible.interfaces: + if itf == interface: + return True + return False + +class ComponentTestCase(coretest.CoreTestCase): + def runTest(self): + self._app = testutil.runTestApp("libcomponentapp.so", self._name) + self._loop.run() + + def post_application_test(self): + #---------------------------------------- + comps = [None, None, None] + comps[2] = self._cache.getRootAccessible() + + self.assertEqual(comps[2].numChildren, 2, + """ + Number of child components = %d + Correct number of components = 2 + """ % comps[2].numChildren) + #---------------------------------------- + comps[0] = comps[2].getChild(0) + comps[1] = comps[2].getChild(1) + + for comp in comps: + self.assert_(supportsInterface(comp, ATSPI_COMPONENT), + """ + An accessible object provided does not support the + component interface. + """) + #---------------------------------------- + for (expected, comp) in zip(extents_expected, comps): + extents = comp.getExtents(dbus.types.UInt32(0)) + self.assertEquals(extents, expected, + """ + Extents of component do not match. + Expected: %s + Recieved: %s + """ % (str(expected), str(extents))) + #---------------------------------------- + for (expected, comp) in zip(layers_expected, comps): + layer = comp.getLayer() + self.assertEquals(layer, expected, + """ + Layer of component does not match. + Expected: %s + Recieved: %s + """ % (str(expected), str(layer))) + #---------------------------------------- + #There is no defined value for the result when the layer is not WINDOW or MDI + #for (expected, comp) in zip(zorders_expected, [comps[0], comps[2]]): + # zorder = comp.getMDIZOrder() + # print zorder, expected + # self.assertEquals(layer, expected, + # """ + # ZOrder of component does not match. + # Expected: %s + # Recieved: %s + # """ % (str(expected), str(zorder))) + #---------------------------------------- diff --git a/tests/clients/coretest.py b/tests/clients/coretest.py new file mode 100644 index 0000000..53fc879 --- /dev/null +++ b/tests/clients/coretest.py @@ -0,0 +1,57 @@ +import unittest +import testutil + +import dbus +import gobject +import os.path +from dbus.mainloop.glib import DBusGMainLoop + +from accessible_cache import AccessibleCache +from random import randint + + + +class CoreTestCase(unittest.TestCase): + def setUp(self): + DBusGMainLoop(set_as_default=True) + + self._bus = dbus.SessionBus() + self._loop = gobject.MainLoop() + self._name = "test.atspi.R" + str(randint(1, 1000)) + self._match = self._bus.add_signal_receiver(self.post_application_setup, + "started", + "org.codethink.atspi.test", + self._name) + self._started = False + + if "TEST_APP_WAIT_FOR_DEBUG" not in os.environ.keys(): + gobject.timeout_add(1000, self.application_check) + + def tearDown(self): + #Shut down the test application + self._test.finished() + + del(self._bus) + del(self._loop) + del(self._cache) + del(self._app) + del(self._test) + + def application_check(self): + if not self._started: + self.fail("Test application did not start") + + def post_application_setup(self): + self._started = True + + self._cache = AccessibleCache(self._bus, self._name, "/org/freedesktop/atspi/tree") + + test_object = self._bus.get_object(self._name, "/org/codethink/atspi/test") + self._test = dbus.Interface(test_object, "org.codethink.atspi.test") + + self.post_application_test() + + self._loop.quit() + + def post_application_test(self): + raise Exception, "No test has been defined" diff --git a/tests/clients/testutil.py b/tests/clients/testutil.py index c7d8e0f..e11302a 100644 --- a/tests/clients/testutil.py +++ b/tests/clients/testutil.py @@ -1,37 +1,30 @@ -#Bus name where test application can be found. -busname = "test.atspi.tree" -#Path of tree interface on test application. -objectpath = "/org/freedesktop/atspi/tree" - -#Directory where test data, such as XML results -#can be found. -testdata = "./" - -#Location of test application. -testapp = "../apps/test-application" - -#Directory of test application modules. -testmodules = "../apps/.libs" - -#Atk to at-spi adaptor library location. -atspilib = "../../atk-adaptor/.libs/libspiatk.so" - - -def runTestApp(module_name): +def runTestApp(module_name, dbus_name): import os from subprocess import Popen - testmodule = os.path.join(testmodules, module_name) - pop = Popen([testapp , "-a", atspilib, "-t", testmodule, "-d", testdata]) + test_data_directory = os.environ["TEST_DATA_DIRECTORY"] + test_modules_directory = os.environ["TEST_MODULES_DIRECTORY"] + test_atspi_library = os.environ["TEST_ATSPI_LIBRARY"] + test_application = os.environ["TEST_APPLICATION"] - wait_envar = "TEST_APP_WAIT_FOR_DEBUG" + test_module = os.path.join(test_modules_directory, module_name) + pop = Popen([test_application, + "--atspi-dbus-name", dbus_name, + "--test-atspi-library", test_atspi_library, + "--test-module", test_module, + "--test-data-directory", test_data_directory,]) + + print " ".join([test_application, + "--atspi-dbus-name", dbus_name, + "--test-atspi-library", test_atspi_library, + "--test-module", test_module, + "--test-data-directory", test_data_directory,]) wait_message = """ The test application %s has been started with PID %d. To continue the test press ENTER.\n\n """ - - if (wait_envar in os.environ.keys()): + if ("TEST_APP_WAIT_FOR_DEBUG" in os.environ.keys()): raw_input(wait_message % (module_name, pop.pid)) diff --git a/tests/runtests.sh b/tests/runtests.sh deleted file mode 100755 index 0cc27a1..0000000 --- a/tests/runtests.sh +++ /dev/null @@ -1,9 +0,0 @@ -export PYTHONPATH=../python -export ATSPI_INTROSPECTION_PATH=../xml/introspection - -export testdata=../tests/data -export atspilib=../atk-adaptor/.libs/libspiatk.so -export testmodules=../tests/apps/.libs -export testapp=../tests/apps/test-application - -./testrunner.py diff --git a/tests/testrunner.py b/tests/testrunner.py index feafc33..2b5be54 100755 --- a/tests/testrunner.py +++ b/tests/testrunner.py @@ -1,25 +1,10 @@ #!/usr/bin/python import sys -import os import unittest import clients -optionvars = ["testdata", - "atspilib", - "testmodules", - "testapp", - "busname", - "objectpath"] - - def main(argv): - def set_data(name): - if name in os.environ.keys(): - setattr(clients.testutil, name, os.environ[name]) - - [set_data(name) for name in optionvars] - runner = unittest.TextTestRunner() testsuite = unittest.defaultTestLoader.loadTestsFromModule(clients) result = runner.run(testsuite) @@ -29,6 +14,5 @@ def main(argv): else: return 1 - if __name__=="__main__": sys.exit(main(sys.argv)) |