[rhmessaging-commits] rhmessaging commits: r3632 - in mgmt/trunk: cumin/python/cumin/account and 5 other directories.

rhmessaging-commits at lists.jboss.org rhmessaging-commits at lists.jboss.org
Mon Sep 14 16:15:31 EDT 2009


Author: justi9
Date: 2009-09-14 16:15:30 -0400 (Mon, 14 Sep 2009)
New Revision: 3632

Added:
   mgmt/trunk/cumin/python/cumin/grid/test.py
   mgmt/trunk/cumin/python/cumin/messaging/test.py
   mgmt/trunk/parsley/python/parsley/test.py
Modified:
   mgmt/trunk/cumin/python/cumin/account/main.py
   mgmt/trunk/cumin/python/cumin/grid/main.py
   mgmt/trunk/cumin/python/cumin/grid/scheduler.py
   mgmt/trunk/cumin/python/cumin/inventory/main.py
   mgmt/trunk/cumin/python/cumin/messaging/main.py
   mgmt/trunk/cumin/python/cumin/test.py
   mgmt/trunk/cumin/python/cumin/tools.py
   mgmt/trunk/cumin/python/cumin/usergrid/main.py
   mgmt/trunk/cumin/python/cumin/util.py
Log:
Improve tests

 * Introduce a way to initialize tests

 * Move the test framework to the parsley module so stuff other than
   cumin can use it

 * Use a common module superclass

 * Translate a handful of tests from the old plan to the new; this
   will be ongoing


Modified: mgmt/trunk/cumin/python/cumin/account/main.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/account/main.py	2009-09-14 20:13:26 UTC (rev 3631)
+++ mgmt/trunk/cumin/python/cumin/account/main.py	2009-09-14 20:15:30 UTC (rev 3632)
@@ -3,7 +3,7 @@
 
 from model import *
 
-class AccountModule(object):
+class AccountModule(CuminModule):
     def init(self, app):
         subject = app.model.subject
 

Modified: mgmt/trunk/cumin/python/cumin/grid/main.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/main.py	2009-09-14 20:13:26 UTC (rev 3631)
+++ mgmt/trunk/cumin/python/cumin/grid/main.py	2009-09-14 20:15:30 UTC (rev 3632)
@@ -6,10 +6,11 @@
 
 from model import *
 from pool import *
+from test import *
 
 strings = StringCatalog(__file__)
 
-class GridModule(object):
+class GridModule(CuminModule):
     def init(self, app):
         self.see_pools = SeePoolsTask(app, None)
 
@@ -57,6 +58,9 @@
         self.pool_slots_page = PoolSlotMapPage(app, "poolslots.png")
         app.add_page(self.pool_slots_page)
 
+    def init_test(self, test):
+        GridTest("grid", test)
+
 module = GridModule()
 
 class GridFrame(CuminFrame):

Modified: mgmt/trunk/cumin/python/cumin/grid/scheduler.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/scheduler.py	2009-09-14 20:13:26 UTC (rev 3631)
+++ mgmt/trunk/cumin/python/cumin/grid/scheduler.py	2009-09-14 20:15:30 UTC (rev 3632)
@@ -104,8 +104,15 @@
         self.add_child(self.schedulers)
 
     def get(self, session):
-        return self.param.get(session)
+        scheduler = self.param.get(session)
 
+        if not scheduler:
+            for item in self.schedulers.get_items(session):
+                scheduler = item
+                break
+
+        return scheduler
+
     def render_title(self, session):
         return "Scheduler"
 
@@ -115,8 +122,10 @@
     class SchedulerOptions(OptionInputSet):
         def do_get_items(self, session):
             pool = self.parent.pool.get(session)
-            return list(Scheduler.selectBy(Pool=pool.id))
+            schedulers = list(Scheduler.selectBy(Pool=pool.id))
 
+            return schedulers
+
         def render_item_value(self, session, item):
             return item.id
 

Added: mgmt/trunk/cumin/python/cumin/grid/test.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/test.py	                        (rev 0)
+++ mgmt/trunk/cumin/python/cumin/grid/test.py	2009-09-14 20:15:30 UTC (rev 3632)
@@ -0,0 +1,52 @@
+from mint import *
+from wooly import *
+
+from cumin.test import *
+
+import main
+
+from cumin.model import Pool
+from wooly import Session
+
+class GridTest(Test):
+    def __init__(self, name, parent):
+        super(GridTest, self).__init__(name, parent)
+
+        self.pool = None
+        self.scheduler = None
+
+        SubmissionTest("Submission", self)
+
+    def do_run(self, session):
+        collector = check_get_object(Collector)
+
+        self.pool = Pool(collector.Pool)
+
+        self.scheduler = check_get_object(Scheduler)
+
+        super(GridTest, self).do_run(session)
+
+class SubmissionTest(Test):
+    def __init__(self, name, parent):
+        super(SubmissionTest, self).__init__(name, parent)
+
+        self.submission = None
+
+    def do_run(self, session):
+        s = MainPageSession(self.harness)
+
+        task = main.module.submission_add
+
+        ns = task.enter(s, self.parent.pool)
+
+        check_render(ns)
+
+        task.form.description.set(ns, session.id)
+        task.form.command.set(ns, "/bin/sleep")
+        task.form.args.set(ns, "5m")
+
+        check_submit_form(ns, task.form)
+
+        self.submission = check_get_object(Submission, Name=session.id)
+
+        super(SubmissionTest, self).do_run(session)

Modified: mgmt/trunk/cumin/python/cumin/inventory/main.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/inventory/main.py	2009-09-14 20:13:26 UTC (rev 3631)
+++ mgmt/trunk/cumin/python/cumin/inventory/main.py	2009-09-14 20:15:30 UTC (rev 3632)
@@ -8,10 +8,7 @@
 
 strings = StringCatalog(__file__)
 
-class InventoryModule(object):
-    def __init__(self):
-        self.frame = None
-
+class InventoryModule(CuminModule):
     def init(self, app):
         self.frame = InventoryFrame(app, "inventory")
         app.main_page.main.inventory = self.frame

Modified: mgmt/trunk/cumin/python/cumin/messaging/main.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/messaging/main.py	2009-09-14 20:13:26 UTC (rev 3631)
+++ mgmt/trunk/cumin/python/cumin/messaging/main.py	2009-09-14 20:15:30 UTC (rev 3632)
@@ -7,10 +7,11 @@
 from broker import *
 from brokergroup import *
 from model import *
+from test import *
 
 strings = StringCatalog(__file__)
 
-class MessagingModule(object):
+class MessagingModule(CuminModule):
     def init(self, app):
         broker = app.model.broker
 
@@ -70,6 +71,9 @@
         app.main_page.main.messaging = self.frame
         app.main_page.main.add_tab(self.frame)
 
+    def init_test(self, test):
+        MessagingTest("messaging", test)
+
 module = MessagingModule()
 
 class MessagingFrame(CuminFrame):

Added: mgmt/trunk/cumin/python/cumin/messaging/test.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/messaging/test.py	                        (rev 0)
+++ mgmt/trunk/cumin/python/cumin/messaging/test.py	2009-09-14 20:15:30 UTC (rev 3632)
@@ -0,0 +1,603 @@
+from mint import *
+from mint.schema import *
+
+from cumin.test import *
+from cumin.util import *
+
+import main
+
+log = logging.getLogger("cumin.messaging.test")
+
+class MessagingTest(Test):
+    def __init__(self, name, parent):
+        super(MessagingTest, self).__init__(name, parent)
+
+        BrokerGroupTest("BrokerGroup", self, main.module.broker_group_add)
+
+class BrokerGroupTest(TaskFormTest):
+    def __init__(self, name, parent, task):
+        super(BrokerGroupTest, self).__init__(name, parent, task)
+
+        self.group = None
+
+        self.Edit("edit", self, main.module.broker_group_edit)
+        self.Remove("remove", self, main.module.broker_group_remove)
+
+    def add_input(self, session, s):
+        self.task.form.group_name.set(s, session.id)
+
+    def check(self, session, s):
+        self.group = check_get_object(BrokerGroup, name=session.id)
+
+    class Edit(TaskFormTest):
+        def enter(self, session, s):
+            return self.task.enter(s, self.parent.group)
+
+        def add_input(self, session, s):
+            name = self.task.form.group_name.get(s)
+            
+            self.altered_name = name + "%;&#\\"
+
+            self.task.form.group_name.set(s, self.altered_name)
+
+        def check(self, session, s):
+            assert self.parent.group.name == self.altered_name
+
+    class Remove(TaskFormTest):
+        def enter(self, session, s):
+            return self.task.enter(s, self.parent.group)
+
+        def check(self, session, s):
+            check_removed(BrokerGroup, id=self.parent.group.id)
+
+# XXX The tests below are as yet unconverted
+
+class BrokerLinkTest(Test):
+    def __init__(self, harness, parent):
+        super(BrokerLinkTest, self).__init__(harness, parent)
+
+        RouteTest(harness, self)
+        self.LinkRemove(harness, self)
+
+    def do_run(self, session):
+        p, s = self.harness.page_and_session()
+
+        p.main.broker.set_object(s, self.harness.broker)
+
+        form = p.main.broker.link_add
+        form.show(s)
+
+        form.host.set(s, "localhost")
+        form.port.set(s, "9991")
+        form.submit(s)
+
+        p.process(s)
+
+        self.harness.check_redirect(p, s)
+
+        vhost = self.harness.vhost
+
+        def predicate():
+            for item in Link.selectBy(vhost=vhost, host="localhost", port=9991):
+                self.harness.link = item
+                return True
+
+        wait(predicate)
+
+        self.run_children(session)
+
+    class LinkRemove(Test):
+        def do_run(self, session):
+            p, s = self.harness.page_and_session()
+
+            p.main.broker.set_object(s, self.harness.broker)
+
+            form = p.main.broker.links_close
+            form.show(s)
+            form.ids.set(s, [self.harness.link.id])
+            form.submit(s)
+
+            p.process(s)
+
+            self.harness.check_redirect(p, s)
+
+            def predicate():
+                return self.harness.link.qmfDeleteTime
+
+            wait(predicate)
+
+class RouteTest(Test):
+    def __init__(self, harness, parent):
+        super(RouteTest, self).__init__(harness, parent)
+
+        self.Add(harness, self)
+        self.Remove(harness, self)
+
+    def do_run(self, session):
+        self.run_children(session)
+
+    class Add(Test):
+        def do_run(self, session):
+            p, s = self.harness.page_and_session()
+
+            p.main.broker.set_object(s, self.harness.broker)
+            p.main.broker.link.set_object(s, self.harness.link)
+
+            form = p.main.broker.link.bridge_add
+            form.show(s)
+
+            vhost = self.harness.vhost
+            exchange = Exchange.selectBy \
+                (vhost=vhost, name=self.harness.broker_exchange.name)[0]
+            form.exchange.set(s, str(exchange.id))
+
+            form.key.set(s, "cumin.key")
+            form.tag.set(s, "cumin.tag")
+            form.excludes.set(s, "cumin.tag")
+
+            form.submit(s)
+
+            p.process(s)
+
+            self.harness.check_redirect(p, s)
+
+            def predicate():
+                for item in Bridge.selectBy \
+                        (link=self.harness.link,
+                         dest=self.harness.broker_exchange.name,
+                         key="cumin.key"):
+                    self.harness.bridge = item
+                    return True
+
+            wait(predicate)
+
+    class Remove(Test):
+        def do_run(self, session):
+            p, s = self.harness.page_and_session()
+
+            p.main.broker.set_object(s, self.harness.broker)
+            p.main.broker.link.set_object(s, self.evn.link)
+
+            form = p.main.broker.link.routes_close
+            form.show(s)
+            form.ids.set(s, [self.harness.bridge.id])
+            form.submit(s)
+
+            p.process(s)
+
+            self.harness.check_redirect(p, s)
+
+            def predicate():
+                return self.harness.bridge.qmfDeleteTime
+
+            wait(predicate)
+
+class BrokerTest(Test):
+    def __init__(self, harness, parent):
+        super(BrokerTest, self).__init__(harness, parent)
+
+        VhostTest(harness, self)
+
+    def do_run(self, session):
+        try:
+            sleep(10)
+            self.harness.broker = Broker.select()[0]
+        except IndexError:
+            raise Exception("Broker not found")
+
+        self.run_children(session)
+
+class VhostTest(Test):
+    def __init__(self, harness, parent):
+        super(VhostTest, self).__init__(harness, parent)
+
+        QueueTest(harness, self)
+        ExchangeTest(harness, self)
+        ConnectionTest(harness, self)
+        BrokerLinkTest(harness, self)
+
+    def do_run(self, session):
+        def predicate():
+            for item in Vhost.selectBy(broker=self.harness.broker, name="/"):
+                return True
+
+        wait(predicate)
+
+        try:
+            self.harness.vhost = Vhost.selectBy \
+                (broker=self.harness.broker, name="/")[0]
+        except IndexError:
+            raise Exception("Vhost not found")
+
+        self.run_children(session)
+
+class BindQueueTest(Test):
+    def __init__(self, harness, parent):
+        super(BindQueueTest, self).__init__(harness, parent)
+
+        self.BindDirect(harness, self)
+        self.BindTopic(harness, self)
+        self.BindFanout(harness, self)
+        self.BindHeaders(harness, self)
+
+    def do_run(self, session):
+        self.run_children(session)
+
+    class BindDirect(Test):
+        def __init__(self, harness, parent):
+            super(BindQueueTest.BindDirect, self).__init__(harness, parent)
+
+            self.RemoveBindDirect(harness, self)
+
+        def do_run(self, session):
+            p, s = self.harness.page_and_session()
+
+            p.main.broker.set_object(s, self.harness.broker.registration)
+            p.main.broker.queue.set_object(s, self.harness.queue)
+
+            form = p.main.broker.queue.binding_add
+            form.show(s)
+
+            binding = dict()
+            binding["test"] = {}
+            direct = binding["test"]
+            direct["name"] = "amq.direct"
+            direct["type"] = "direct"
+            direct["key"] = "amq.direct.key"
+
+            form.bindings.dict_param.set(s, binding)
+
+            form.submit(s)
+
+            p.process(s)
+
+            self.harness.check_redirect(p, s)
+
+            def predicate():
+                for item in Binding.selectBy(queue=self.harness.queue, bindingKey=self.harness.queue.name):
+                    self.harness.binding_direct = item
+                    return True
+
+            wait(predicate)
+
+        class RemoveBindDirect(Test):
+            def do_run(self, session):
+                p, s = self.harness.page_and_session()
+
+                p.main.broker.set_object(s, self.harness.broker)
+
+                form = p.main.broker.bindings_remove.show(s)
+                form.ids.set([self.harness.binding_direct.id])
+                form.submit(s)
+
+                p.process(s)
+
+                self.harness.check_redirect(p, s)
+
+                def predicate():
+                    return self.harness.binding_direct.qmfDeleteTime
+
+                wait(predicate)
+
+    class BindTopic(Test):
+        def __init__(self, harness, parent):
+            super(BindQueueTest.BindTopic, self).__init__(harness, parent)
+
+            self.RemoveBindTopic(harness, self)
+
+        def do_run(self, session):
+            p, s = self.harness.page_and_session()
+
+            p.main.broker.set_object(s, self.harness.broker.registration)
+            p.main.broker.queue.set_object(s, self.harness.queue)
+
+            form = p.main.broker.queue.binding_add
+            form.show(s)
+
+            binding = dict()
+            binding["test"] = {}
+            direct = binding["test"]
+            direct["name"] = "amq.topic"
+            direct["type"] = "topic"
+            direct["key"] = "topic.key"
+            form.bindings.dict_param.set(s, binding)
+
+            form.submit(s)
+            p.process(s)
+
+            self.harness.check_redirect(p, s)
+
+            def predicate():
+                for item in Binding.selectBy(queue=self.harness.queue, bindingKey="topic.key"):
+                    self.harness.binding_topic = item
+                    return True
+
+            wait(predicate)
+
+        class RemoveBindTopic(Test):
+            def do_run(self, session):
+                p, s = self.harness.page_and_session()
+
+                p.main.broker.set_object(s, self.harness.broker)
+
+                form = p.main.broker.bindings_remove.show(s)
+                form.ids.set([self.harness.binding_topic.id])
+                form.submit(s)
+
+                p.process(s)
+
+                self.harness.check_redirect(p, s)
+
+                def predicate():
+                    return self.harness.binding_topic.qmfDeleteTime
+
+                wait(predicate)
+
+    class BindFanout(Test):
+        def __init__(self, harness, parent):
+            super(BindQueueTest.BindFanout, self).__init__(harness, parent)
+
+            self.RemoveBindFanout(harness, self)
+
+        def do_run(self, session):
+            p, s = self.harness.page_and_session()
+
+            p.main.broker.set_object(s, self.harness.broker.registration)
+            p.main.broker.queue.set_object(s, self.harness.queue)
+
+            form = p.main.broker.queue.binding_add
+            form.show(s)
+
+            binding = dict()
+            binding["test"] = {}
+            direct = binding["test"]
+            direct["name"] = "amq.fanout"
+            direct["type"] = "fanout"
+            form.bindings.dict_param.set(s, binding)
+
+            form.submit(s)
+            p.process(s)
+
+            self.harness.check_redirect(p, s)
+
+            def predicate():
+                for item in Binding.selectBy(queue=self.harness.queue):
+                    if item.exchange.name == "amq.fanout":
+                        self.harness.binding_fanout = item
+                        return True
+
+            wait(predicate)
+
+        class RemoveBindFanout(Test):
+            def do_run(self, session):
+                p, s = self.harness.page_and_session()
+
+                p.main.broker.set_object(s, self.harness.broker)
+
+                form = p.main.broker.bindings_remove.show(s)
+                form.ids.set([self.harness.binding_fanout.id])
+                form.submit(s)
+
+                p.process(s)
+
+                self.harness.check_redirect(p, s)
+
+                def predicate():
+                    return self.harness.binding_fanout.qmfDeleteTime
+
+                wait(predicate)
+
+    class BindHeaders(Test):
+        def do_run(self, session):
+            p, s = self.harness.page_and_session()
+
+            p.main.broker.set_object(s, self.harness.broker.registration)
+            p.main.broker.queue.set_object(s, self.harness.queue)
+
+            form = p.main.broker.queue.binding_add
+            form.show(s)
+
+            binding = dict()
+            binding["test"] = {}
+            direct = binding["test"]
+            direct["name"] = "amq.match"
+            direct["type"] = "headers"
+            direct["key"] = "headers.key"
+            direct["x-match"] = "all"
+            direct["mkey.1"] = "key1"
+            direct["mkey.1.nv"] = "name.value.1"
+            form.bindings.dict_param.set(s, binding)
+
+            form.submit(s)
+            p.process(s)
+
+            self.harness.check_redirect(p, s)
+
+            def predicate():
+                for item in Binding.selectBy(queue=self.harness.queue, bindingKey="headers.key"):
+                    return True
+
+            wait(predicate)
+
+            # if it timed out, raise an exception
+            try:
+                Binding.selectBy(queue=self.harness.queue, bindingKey="headers.key")[0]
+            except IndexError:
+                raise Exception("Headers Binding not added")
+
+class AddQueueTest(Test):
+    def __init__(self, harness, parent):
+        super(AddQueueTest, self).__init__(harness, parent)
+
+        BindQueueTest(harness, self)
+
+    def do_run(self, session):
+        name = "cumin.queue.%s" % session.id
+        p, s = self.harness.page_and_session()
+
+        p.main.broker.set_object(s, self.harness.broker)
+
+        form = p.main.broker.queue_add
+        form.show(s)
+        form.namef.set(s, name)
+        form.submit(s)
+
+        p.process(s)
+
+        self.harness.check_redirect(p, s)
+
+        vhost = self.harness.vhost
+
+        # wait for newly created queue to show up
+        def predicate():
+            for item in Queue.selectBy(vhost=vhost, name=name):
+                return True
+
+        wait(predicate)
+
+        # if it timed out, raise an exception
+        try:
+            self.harness.queue = Queue.selectBy(vhost=vhost, name=name)[0]
+        except IndexError:
+            raise Exception("Queue %s not added" % name)
+
+        self.run_children(session)
+
+
+class QueueTest(Test):
+    def __init__(self, harness, parent):
+        super(QueueTest, self).__init__(harness, parent)
+
+        AddQueueTest(harness, self)
+        self.Remove(harness, self)
+
+    def do_run(self, session):
+        vhost = self.harness.vhost
+        name = self.harness.broker_queue.name
+
+        def predicate():
+            for item in Queue.selectBy(vhost=vhost, name=name):
+                self.harness.broker_queue = item
+                return True
+
+        wait(predicate)
+
+        self.run_children(session)
+
+    class Remove(Test):
+        def do_run(self, session):
+            p, s = self.harness.page_and_session()
+
+            p.main.broker.set_object(s, self.harness.broker)
+
+            form = p.main.broker.queues_remove
+            form.show(s)
+            form.ids.set(s, [self.harness.queue.id])
+            form.submit(s)
+
+            p.process(s)
+
+            self.harness.check_redirect(p, s)
+
+            # wait for newly created queue to get marked as deleted
+            def predicate():
+                return self.harness.queue.qmfDeleteTime
+
+            wait(predicate)
+
+class AddExchangeTest(Test):
+    def do_run(self, session):
+        name = "cumin.exchange.%s" % session.id
+        p, s = self.harness.page_and_session()
+
+        p.main.broker.set_object(s, self.harness.broker)
+
+        form = p.main.broker.exchange_add
+        form.show(s)
+
+        form.exchange_name.set(s, name)
+        form.exchange_type.set(s, "topic")
+        form.submit(s)
+
+        p.process(s)
+
+        self.harness.check_redirect(p, s)
+
+        vhost = self.harness.vhost
+        # wait for newly created exchange to show up
+        def predicate():
+            for item in Exchange.selectBy(vhost=vhost, name=name):
+                self.harness.added_exchange = item
+                return True
+
+        wait(predicate)
+
+class ExchangeTest(Test):
+    def __init__(self, harness, parent):
+        super(ExchangeTest, self).__init__(harness, parent)
+
+        AddExchangeTest(harness, self)
+        self.Remove(harness, self)
+
+    def do_run(self, session):
+        vhost = self.harness.vhost
+        name = self.harness.broker_exchange.name
+
+        def predicate():
+            for item in Exchange.selectBy(vhost=vhost, name=name):
+                self.harness.broker_exchange = item
+                return True
+
+        wait(predicate)
+
+        self.run_children(session)
+
+    class Remove(Test):
+        def do_run(self, session):
+            # try to delete it
+            p, s = self.harness.page_and_session()
+
+            p.main.broker.set_object(s, self.harness.broker)
+
+            form = p.main.broker.exchanges_remove
+            form.show(s)
+            form.ids.set(s, [self.harness.added_exchange.id])
+            form.submit(s)
+
+            p.process(s)
+
+            self.harness.check_redirect(p, s)
+
+            # wait for newly created exchange to get marked as deleted
+            def predicate():
+                return self.harness.added_exchange.qmfDeleteTime
+
+            wait(predicate)
+
+class ConnectionTest(Test):
+    def do_run(self, session):
+        raise Exception("Not implemented")
+
+        vhost = self.harness.vhost
+        address = self.harness.broker_conn.host + ":" + \
+            str(self.harness.broker_conn.port)
+
+        try:
+            self.harness.conn = ClientConnection.selectBy \
+                (vhost=vhost, address=address)[0]
+        except IndexError:
+            raise Exception("ClientConnection not found")
+
+        self.run_children(session)
+
+def wait(predicate, timeout=30):
+    start = time()
+
+    while True:
+        if predicate():
+            return
+
+        if time() - start > timeout:
+            raise Exception("Operation timed out")
+
+        sleep(1)

Modified: mgmt/trunk/cumin/python/cumin/test.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/test.py	2009-09-14 20:13:26 UTC (rev 3631)
+++ mgmt/trunk/cumin/python/cumin/test.py	2009-09-14 20:15:30 UTC (rev 3632)
@@ -1,877 +1,127 @@
-import sys, os, signal
-from mint import *
-from mint.schema import *
-from traceback import print_exc, extract_tb
-from datetime import datetime
-from threading import Thread
-from popen2 import Popen4
-from shutil import copyfileobj
-from tempfile import mkdtemp
-import qpid, quirk, wooly
+from parsley.test import *
+from wooly import *
 
-from cumin import Cumin
 from util import *
-import time
 
-class TestBroker(Thread):
-    def __init__(self, path, port):
-        super(TestBroker, self).__init__()
+log = logging.getLogger("cumin.test")
 
-        self.path = path
-        self.port = port
+class CuminTest(Test):
+    def __init__(self, app):
+        super(CuminTest, self).__init__("cumin", None)
 
-        self.temp_dir = mkdtemp()
-        self.data_dir = os.path.join(self.temp_dir, "data")
-
-        self.command = (path,
-                        "--port", str(port),
-                        "--auth", "no",
-                        "--trace",
-                        "--data-dir", self.data_dir)
-
-        self.output_path = os.path.join(self.temp_dir, "output")
-
-        self.setDaemon(True)
-
-    def run(self):
-        print "Saving qpidd output to %s" % self.temp_dir
-
-        out = open(self.output_path, "w")
-
-        try:
-            pop = Popen4(self.command)
-            copyfileobj(pop.fromchild, out)
-            exit_code = pop.wait()
-            print exit_code
-        finally:
-            if pop:
-                os.kill(pop.pid, signal.SIGKILL)
-
-            kpid, stat = os.waitpid(pop.pid, os.WNOHANG)
-
-            if kpid == 0:
-                print "Test qpidd wouldn't die"
-
-class TestEnvironment(object):
-    def __init__(self, app, broker_host, broker_port, spec_path):
         self.app = app
-        self.broker_host = broker_host
-        self.broker_port = broker_port
 
-        broker = TestBroker("qpidd", self.broker_port)
-
-        self.broker_conn = quirk.Connection \
-            (self.broker_host, self.broker_port, spec_path)
-        self.broker_queue = quirk.Queue("cumin.queue")
-        self.broker_exchange = quirk.Exchange("cumin.exchange")
-
-        self.broker = None
-        self.vhost = None
-        self.queue = None
-        self.exchange = None
-        self.broker_group = None
-
     def init(self):
-        name = "test-%s-%s" % (self.broker_host, self.broker_port)
-        url = "amqp://%s:%s" % (self.broker_host, self.broker_port)
+        for module in self.app.modules:
+            module.init_test(self)
 
-        print "Connecting to qmf server at %s" % url
+        super(CuminTest, self).init()
 
-        if not BrokerRegistration.selectBy(name=name, url=url).count():
-            reg = BrokerRegistration(name=name, url=url)
-
-        ready = False
-
-        print "Waiting for the broker to show up...",
-
-        while not ready:
-            time.sleep(1)
-
-            for broker in Broker.select():
-                print "got it."
-                ready = True
-                break
-
-            print ".",
-
-        self.broker_conn.open()
-
-        session = quirk.Session(self.broker_conn, "test")
-        session.open()
-
-        try:
-            self.broker_queue.declare(session)
-            self.broker_exchange.declare(session)
-        finally:
-            session.close()
-
-    def run_test(self, test):
-        session = TestSession(self)
-        test.run(session)
-        return session
-
-    def page_and_session(self, page=None):
-        if page is None:
-            page = self.app.main_page
-
-        s = wooly.Session(page)
-
-        return page, s
-
-    def check_redirect(self, p, s):
-        redirect = p.get_redirect_url(s)
-
-        if redirect is None:
-            raise Exception("Expected redirect")
-
-        s = wooly.Session.unmarshal(p.app, redirect)
-        p = s.page
-
-        p.process(s)
-        p.render(s)
-
-class TestSession(object):
-    def __init__(self, env):
-        self.env = env
-        self.id = short_id()
-
-        self.stack = list()
-        self.passed = list()
-        self.failed = list()
-
-    def report(self, out):
-        out.write("Tests:")
-        out.write(os.linesep)
-        out.write(os.linesep)
-
-        self.stack[0].report(sys.stdout, 1)
-        out.write(os.linesep)
-
-        out.write("Failures:")
-        out.write(os.linesep)
-        out.write(os.linesep)
-
-        if self.failed:
-            for call in self.failed:
-                out.write("  %s: %s" % \
-                              (call.test.path(), call.get_exception_text()))
-                out.write(os.linesep)
-
-                for spec in extract_tb(call.traceback):
-                    file, line, func, text = spec
-                    out.write("    File \"%s\", line %i, in %s" % spec[:3])
-                    out.write(os.linesep)
-                    out.write("      %s" % spec[3])
-                    out.write(os.linesep)
-
-                out.write(os.linesep)
-        else:
-            out.write("  None")
-            out.write(os.linesep)
-            out.write(os.linesep)
-
-        out.write("Summary:")
-        out.write(os.linesep)
-        out.write(os.linesep)
-
-        passed, failed = len(self.passed), len(self.failed)
-        out.write("  %i passed, %i failed" % (passed, failed))
-        out.write(os.linesep)
-
-class Test(object):
-    def __init__(self, env, parent):
-        self.env = env
-        self.name = self.__class__.__name__
-        self.parent = parent
-        self.children = list()
-
-        if parent:
-            self.parent.children.append(self)
-
-    def path(self):
-        if self.parent is None:
-            return self.name
-        else:
-            return self.parent.path() + "/" + self.name
-
-    def run(self, session):
-        call = TestCall(session, self)
-        call.open()
-        try:
-            try:
-                self.do_run(session)
-                session.passed.append(call)
-            except Exception, e:
-                call.exception = e
-                call.traceback = sys.exc_info()[2]
-                session.failed.append(call)
-        finally:
-            call.close()
-
     def do_run(self, session):
-        self.run_children(session)
+        log.info("Waiting for the broker to connect")
 
-    def run_children(self, session):
-        for child in self.children:
-            child.run(session)
-
-    def __repr__(self):
-        return self.__class__.__name__
-
-class TestCall(object):
-    def __init__(self, session, test):
-        self.session = session
-        self.test = test
-        self.exception = None
-        self.traceback = None
-
-        self.caller = None
-        self.callees = list()
-
-        self.start = None
-        self.end = None
-
-    def open(self):
-        if self.session.stack:
-            self.caller = self.session.stack[-1]
-            self.caller.callees.append(self)
-
-        self.session.stack.append(self)
-
-        self.start = time.clock()
-
-    def close(self):
-        self.end = time.clock()
-
-        if len(self.session.stack) > 1:
-            self.session.stack.pop()
-
-    def report(self, writer, depth):
-        entry = ("  " * depth) + str(self.test)
-        status = "-"
-
-        if self.exception:
-            status = self.get_exception_text()
-
-        writer.write("%-40s %s" % (entry, status))
-        writer.write(os.linesep)
-
-        for call in self.callees:
-            call.report(writer, depth + 1)
-
-    def get_exception_text(self):
-        if self.exception:
-            message = self.exception.__class__.__name__
-
-            if hasattr(self.exception, "message"):
-                message = message + ": " + self.exception.message
-
-            return message
-
-class MainTest(Test):
-    def __init__(self, env):
-        super(MainTest, self).__init__(env, None)
-
-        BrokerTest(env, self)
-        BrokerGroupTest(env, self)
-
-class BrokerLinkTest(Test):
-    def __init__(self, env, parent):
-        super(BrokerLinkTest, self).__init__(env, parent)
-
-        RouteTest(env, self)
-        self.LinkRemove(env, self)
-
-    def do_run(self, session):
-        p, s = self.env.page_and_session()
-
-        p.main.broker.set_object(s, self.env.broker)
-
-        form = p.main.broker.link_add
-        form.show(s)
-
-        form.host.set(s, "localhost")
-        form.port.set(s, "9991")
-        form.submit(s)
-
-        p.process(s)
-
-        self.env.check_redirect(p, s)
-
-        vhost = self.env.vhost
-
-        def predicate():
-            for item in Link.selectBy(vhost=vhost, host="localhost", port=9991):
-                self.env.link = item
+        def connect():
+            if self.app.model.mint.model.isConnected():
+                log.info("The broker is connected")
                 return True
 
-        wait(predicate)
+        connected = retry(connect)
 
-        self.run_children(session)
+        if not connected:
+            raise Exception("Failed to connect to broker")
 
-    class LinkRemove(Test):
-        def do_run(self, session):
-            p, s = self.env.page_and_session()
+        super(CuminTest, self).do_run(session)
 
-            p.main.broker.set_object(s, self.env.broker)
+class TaskFormTest(Test):
+    def __init__(self, name, parent, task):
+        super(TaskFormTest, self).__init__(name, parent)
 
-            form = p.main.broker.links_close
-            form.show(s)
-            form.ids.set(s, [self.env.link.id])
-            form.submit(s)
+        self.task = task
 
-            p.process(s)
+    def enter(self, session, s):
+        return self.task.enter(s, None)
 
-            self.env.check_redirect(p, s)
+    def add_input(self, session, s):
+        pass
 
-            def predicate():
-                return self.env.link.qmfDeleteTime
+    def check(self, session, s):
+        pass
 
-            wait(predicate)
-
-class RouteTest(Test):
-    def __init__(self, env, parent):
-        super(RouteTest, self).__init__(env, parent)
-
-        self.Add(env, self)
-        self.Remove(env, self)
-
     def do_run(self, session):
-        self.run_children(session)
+        s = MainPageSession(self.harness)
 
-    class Add(Test):
-        def do_run(self, session):
-            p, s = self.env.page_and_session()
+        s = self.enter(session, s)
 
-            p.main.broker.set_object(s, self.env.broker)
-            p.main.broker.link.set_object(s, self.env.link)
+        check_render(s)
 
-            form = p.main.broker.link.bridge_add
-            form.show(s)
+        self.add_input(session, s)
 
-            vhost = self.env.vhost
-            exchange = Exchange.selectBy(vhost=vhost, name=self.env.broker_exchange.name)[0]
-            form.exchange.set(s, str(exchange.id))
+        check_submit_form(s, self.task.form)
 
-            form.key.set(s, "cumin.key")
-            form.tag.set(s, "cumin.tag")
-            form.excludes.set(s, "cumin.tag")
+        self.check(session, s)
 
-            form.submit(s)
+        super(TaskFormTest, self).do_run(session)
+    
+class MainPageSession(Session):
+    def __init__(self, harness):
+        super(MainPageSession, self).__init__(harness.test.app.main_page)
 
-            p.process(s)
+def retry(fn):
+    result = None
 
-            self.env.check_redirect(p, s)
+    for i in range(10):
+        result = fn()
 
-            def predicate():
-                for item in Bridge.selectBy(link=self.env.link, dest=self.env.broker_exchange.name, key="cumin.key"):
-                    self.env.bridge = item
-                    return True
+        if result:
+            break
 
-            wait(predicate)
+        sleep(1)
 
-    class Remove(Test):
-        def do_run(self, session):
-            p, s = self.env.page_and_session()
+    return result
 
-            p.main.broker.set_object(s, self.env.broker)
-            p.main.broker.link.set_object(s, self.evn.link)
+def check_render(session):
+    session.page.process(session)
+    session.page.render(session)
 
-            form = p.main.broker.link.routes_close
-            form.show(s)
-            form.ids.set(s, [self.env.bridge.id])
-            form.submit(s)
+def check_submit_form(session, form):
+    form.submit(session)
 
-            p.process(s)
+    session.page.process(session)
 
-            self.env.check_redirect(p, s)
+    redirect = session.page.redirect.get(session)
 
-            def predicate():
-                return self.env.bridge.qmfDeleteTime
+    if redirect is None:
+        errors = task.form.errors.get(ns)
 
-            wait(predicate)
+        if errors:
+            raise Exception("Unexpected form input errors")
 
-class BrokerGroupTest(Test):
-    def __init__(self, env, parent):
-        super(BrokerGroupTest, self).__init__(env, parent)
+    nsession = Session.unmarshal(session.page.app, redirect)
 
-        self.Edit(env, self)
-        self.Remove(env, self)
+    check_render(nsession)
 
-    def do_run(self, session):
-        p, s = self.env.page_and_session()
+def check_get_object(cls, **criteria):
+    def get():
+        for obj in cls.selectBy(**criteria):
+            return obj
 
-        form = p.main.broker_group.add
-        form.show(s)
-        form.group_name.set(s, session.id)
-        form.submit(s)
+    obj = retry(get)
 
-        p.process(s)
+    if not obj:
+        args = (cls.__name__, criteria)
+        raise Exception("Object %s(%s) not found" % args)
 
-        self.env.check_redirect(p, s)
+    return obj
 
-        try:
-            self.env.broker_group = BrokerGroup.selectBy(name=session.id)[0]
-        except IndexError:
-            raise Exception("Broker group not found")
-
-        self.run_children(session)
-
-    class Edit(Test):
-        def do_run(self, session):
-            p, s = self.env.page_and_session()
-
-            p.main.broker_group.set_object(s, self.env.broker_group)
-
-            form = p.main.broker_group.edit
-            form.show(s)
-            form.group_name.set(s, session.id + "%;&#\\")
-            form.submit(s)
-
-            p.process(s)
-
-            self.env.check_redirect(p, s)
-
-    class Remove(Test):
-        def do_run(self, session):
-            p, s = self.env.page_and_session()
-
-            p.main.broker_group.set_object(s, self.env.broker_group)
-
-            form = p.main.broker_group.remove
-            form.show(s)
-            form.submit(s)
-
-            p.process(s)
-
-            self.env.check_redirect(p, s)
-
-class BrokerTest(Test):
-    def __init__(self, env, parent):
-        super(BrokerTest, self).__init__(env, parent)
-
-        VhostTest(env, self)
-
-    def do_run(self, session):
-        try:
-            time.sleep(10)
-            self.env.broker = Broker.select()[0]
-        except IndexError:
-            raise Exception("Broker not found")
-
-        self.run_children(session)
-
-class VhostTest(Test):
-    def __init__(self, env, parent):
-        super(VhostTest, self).__init__(env, parent)
-
-        QueueTest(env, self)
-        ExchangeTest(env, self)
-        ConnectionTest(env, self)
-        BrokerLinkTest(env, self)
-
-    def do_run(self, session):
-        def predicate():
-            for item in Vhost.selectBy(broker=self.env.broker, name="/"):
-                return True
-
-        wait(predicate)
-
-        try:
-            self.env.vhost = Vhost.selectBy \
-                (broker=self.env.broker, name="/")[0]
-        except IndexError:
-            raise Exception("Vhost not found")
-
-        self.run_children(session)
-
-class BindQueueTest(Test):
-    def __init__(self, env, parent):
-        super(BindQueueTest, self).__init__(env, parent)
-
-        self.BindDirect(env, self)
-        self.BindTopic(env, self)
-        self.BindFanout(env, self)
-        self.BindHeaders(env, self)
-
-    def do_run(self, session):
-        self.run_children(session)
-
-    class BindDirect(Test):
-        def __init__(self, env, parent):
-            super(BindQueueTest.BindDirect, self).__init__(env, parent)
-
-            self.RemoveBindDirect(env, self)
-
-        def do_run(self, session):
-            p, s = self.env.page_and_session()
-
-            p.main.broker.set_object(s, self.env.broker.registration)
-            p.main.broker.queue.set_object(s, self.env.queue)
-
-            form = p.main.broker.queue.binding_add
-            form.show(s)
-
-            binding = dict()
-            binding["test"] = {}
-            direct = binding["test"]
-            direct["name"] = "amq.direct"
-            direct["type"] = "direct"
-            direct["key"] = "amq.direct.key"
-
-            form.bindings.dict_param.set(s, binding)
-
-            form.submit(s)
-
-            p.process(s)
-
-            self.env.check_redirect(p, s)
-
-            def predicate():
-                for item in Binding.selectBy(queue=self.env.queue, bindingKey=self.env.queue.name):
-                    self.env.binding_direct = item
-                    return True
-
-            wait(predicate)
-
-        class RemoveBindDirect(Test):
-            def do_run(self, session):
-                p, s = self.env.page_and_session()
-
-                p.main.broker.set_object(s, self.env.broker)
-
-                form = p.main.broker.bindings_remove.show(s)
-                form.ids.set([self.env.binding_direct.id])
-                form.submit(s)
-
-                p.process(s)
-
-                self.env.check_redirect(p, s)
-
-                def predicate():
-                    return self.env.binding_direct.qmfDeleteTime
-
-                wait(predicate)
-
-    class BindTopic(Test):
-        def __init__(self, env, parent):
-            super(BindQueueTest.BindTopic, self).__init__(env, parent)
-
-            self.RemoveBindTopic(env, self)
-
-        def do_run(self, session):
-            p, s = self.env.page_and_session()
-
-            p.main.broker.set_object(s, self.env.broker.registration)
-            p.main.broker.queue.set_object(s, self.env.queue)
-
-            form = p.main.broker.queue.binding_add
-            form.show(s)
-
-            binding = dict()
-            binding["test"] = {}
-            direct = binding["test"]
-            direct["name"] = "amq.topic"
-            direct["type"] = "topic"
-            direct["key"] = "topic.key"
-            form.bindings.dict_param.set(s, binding)
-
-            form.submit(s)
-            p.process(s)
-
-            self.env.check_redirect(p, s)
-
-            def predicate():
-                for item in Binding.selectBy(queue=self.env.queue, bindingKey="topic.key"):
-                    self.env.binding_topic = item
-                    return True
-
-            wait(predicate)
-
-        class RemoveBindTopic(Test):
-            def do_run(self, session):
-                p, s = self.env.page_and_session()
-
-                p.main.broker.set_object(s, self.env.broker)
-
-                form = p.main.broker.bindings_remove.show(s)
-                form.ids.set([self.env.binding_topic.id])
-                form.submit(s)
-
-                p.process(s)
-
-                self.env.check_redirect(p, s)
-
-                def predicate():
-                    return self.env.binding_topic.qmfDeleteTime
-
-                wait(predicate)
-
-    class BindFanout(Test):
-        def __init__(self, env, parent):
-            super(BindQueueTest.BindFanout, self).__init__(env, parent)
-
-            self.RemoveBindFanout(env, self)
-
-        def do_run(self, session):
-            p, s = self.env.page_and_session()
-
-            p.main.broker.set_object(s, self.env.broker.registration)
-            p.main.broker.queue.set_object(s, self.env.queue)
-
-            form = p.main.broker.queue.binding_add
-            form.show(s)
-
-            binding = dict()
-            binding["test"] = {}
-            direct = binding["test"]
-            direct["name"] = "amq.fanout"
-            direct["type"] = "fanout"
-            form.bindings.dict_param.set(s, binding)
-
-            form.submit(s)
-            p.process(s)
-
-            self.env.check_redirect(p, s)
-
-            def predicate():
-                for item in Binding.selectBy(queue=self.env.queue):
-                    if item.exchange.name == "amq.fanout":
-                        self.env.binding_fanout = item
-                        return True
-
-            wait(predicate)
-
-        class RemoveBindFanout(Test):
-            def do_run(self, session):
-                p, s = self.env.page_and_session()
-
-                p.main.broker.set_object(s, self.env.broker)
-
-                form = p.main.broker.bindings_remove.show(s)
-                form.ids.set([self.env.binding_fanout.id])
-                form.submit(s)
-
-                p.process(s)
-
-                self.env.check_redirect(p, s)
-
-                def predicate():
-                    return self.env.binding_fanout.qmfDeleteTime
-
-                wait(predicate)
-
-    class BindHeaders(Test):
-        def do_run(self, session):
-            p, s = self.env.page_and_session()
-
-            p.main.broker.set_object(s, self.env.broker.registration)
-            p.main.broker.queue.set_object(s, self.env.queue)
-
-            form = p.main.broker.queue.binding_add
-            form.show(s)
-
-            binding = dict()
-            binding["test"] = {}
-            direct = binding["test"]
-            direct["name"] = "amq.match"
-            direct["type"] = "headers"
-            direct["key"] = "headers.key"
-            direct["x-match"] = "all"
-            direct["mkey.1"] = "key1"
-            direct["mkey.1.nv"] = "name.value.1"
-            form.bindings.dict_param.set(s, binding)
-
-            form.submit(s)
-            p.process(s)
-
-            self.env.check_redirect(p, s)
-
-            def predicate():
-                for item in Binding.selectBy(queue=self.env.queue, bindingKey="headers.key"):
-                    return True
-
-            wait(predicate)
-
-            # if it timed out, raise an exception
-            try:
-                Binding.selectBy(queue=self.env.queue, bindingKey="headers.key")[0]
-            except IndexError:
-                raise Exception("Headers Binding not added")
-
-class AddQueueTest(Test):
-    def __init__(self, env, parent):
-        super(AddQueueTest, self).__init__(env, parent)
-
-        BindQueueTest(env, self)
-
-    def do_run(self, session):
-        name = "cumin.queue.%s" % session.id
-        p, s = self.env.page_and_session()
-
-        p.main.broker.set_object(s, self.env.broker)
-
-        form = p.main.broker.queue_add
-        form.show(s)
-        form.namef.set(s, name)
-        form.submit(s)
-
-        p.process(s)
-
-        self.env.check_redirect(p, s)
-
-        vhost = self.env.vhost
-
-        # wait for newly created queue to show up
-        def predicate():
-            for item in Queue.selectBy(vhost=vhost, name=name):
-                return True
-
-        wait(predicate)
-
-        # if it timed out, raise an exception
-        try:
-            self.env.queue = Queue.selectBy(vhost=vhost, name=name)[0]
-        except IndexError:
-            raise Exception("Queue %s not added" % name)
-
-        self.run_children(session)
-
-
-class QueueTest(Test):
-    def __init__(self, env, parent):
-        super(QueueTest, self).__init__(env, parent)
-
-        AddQueueTest(env, self)
-        self.Remove(env, self)
-
-    def do_run(self, session):
-        vhost = self.env.vhost
-        name = self.env.broker_queue.name
-
-        def predicate():
-            for item in Queue.selectBy(vhost=vhost, name=name):
-                self.env.broker_queue = item
-                return True
-
-        wait(predicate)
-
-        self.run_children(session)
-
-    class Remove(Test):
-        def do_run(self, session):
-            p, s = self.env.page_and_session()
-
-            p.main.broker.set_object(s, self.env.broker)
-
-            form = p.main.broker.queues_remove
-            form.show(s)
-            form.ids.set(s, [self.env.queue.id])
-            form.submit(s)
-
-            p.process(s)
-
-            self.env.check_redirect(p, s)
-
-            # wait for newly created queue to get marked as deleted
-            def predicate():
-                return self.env.queue.qmfDeleteTime
-
-            wait(predicate)
-
-class AddExchangeTest(Test):
-    def do_run(self, session):
-        name = "cumin.exchange.%s" % session.id
-        p, s = self.env.page_and_session()
-
-        p.main.broker.set_object(s, self.env.broker)
-
-        form = p.main.broker.exchange_add
-        form.show(s)
-
-        form.exchange_name.set(s, name)
-        form.exchange_type.set(s, "topic")
-        form.submit(s)
-
-        p.process(s)
-
-        self.env.check_redirect(p, s)
-
-        vhost = self.env.vhost
-        # wait for newly created exchange to show up
-        def predicate():
-            for item in Exchange.selectBy(vhost=vhost, name=name):
-                self.env.added_exchange = item
-                return True
-
-        wait(predicate)
-
-class ExchangeTest(Test):
-    def __init__(self, env, parent):
-        super(ExchangeTest, self).__init__(env, parent)
-
-        AddExchangeTest(env, self)
-        self.Remove(env, self)
-
-    def do_run(self, session):
-        vhost = self.env.vhost
-        name = self.env.broker_exchange.name
-
-        def predicate():
-            for item in Exchange.selectBy(vhost=vhost, name=name):
-                self.env.broker_exchange = item
-                return True
-
-        wait(predicate)
-
-        self.run_children(session)
-
-    class Remove(Test):
-        def do_run(self, session):
-            # try to delete it
-            p, s = self.env.page_and_session()
-
-            p.main.broker.set_object(s, self.env.broker)
-
-            form = p.main.broker.exchanges_remove
-            form.show(s)
-            form.ids.set(s, [self.env.added_exchange.id])
-            form.submit(s)
-
-            p.process(s)
-
-            self.env.check_redirect(p, s)
-
-            # wait for newly created exchange to get marked as deleted
-            def predicate():
-                return self.env.added_exchange.qmfDeleteTime
-
-            wait(predicate)
-
-class ConnectionTest(Test):
-    def do_run(self, session):
-        raise Exception("Not implemented")
-
-        vhost = self.env.vhost
-        address = self.env.broker_conn.host + ":" + \
-            str(self.env.broker_conn.port)
-
-        try:
-            self.env.conn = ClientConnection.selectBy \
-                (vhost=vhost, address=address)[0]
-        except IndexError:
-            raise Exception("ClientConnection not found")
-
-        self.run_children(session)
-
-def wait(predicate, timeout=30):
-    start = time.time()
-
-    while True:
-        if predicate():
+def check_removed(cls, **criteria):
+    def find():
+        for obj in cls.selectBy(**criteria):
             return
 
-        if time.time() - start > timeout:
-            raise Exception("Operation timed out")
+        return True
 
-        time.sleep(1)
+    removed = retry(find)
+
+    if not removed:
+        args = (cls.__name__, criteria)
+        raise Exception("Object %s(%s) not removed" % args)

Modified: mgmt/trunk/cumin/python/cumin/tools.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/tools.py	2009-09-14 20:13:26 UTC (rev 3631)
+++ mgmt/trunk/cumin/python/cumin/tools.py	2009-09-14 20:15:30 UTC (rev 3632)
@@ -156,10 +156,6 @@
 
         self.description = "Cumin test tool"
 
-        opt = CommandOption(self, "broker")
-        opt.argument = "ADDR"
-        opt.description = "Use existing broker at ADDR"
-
     def do_run(self, opts, args):
         app = Cumin(self.config)
 
@@ -170,28 +166,25 @@
 
             sys.exit(1)
 
-        usr_sbin = "/usr/sbin"
-        if usr_sbin not in sys.path:
-            sys.path.append(usr_sbin)
-
         app.init()
+        app.start()
 
-        if "broker" in opts:
-            host, port = parse_broker_addr(opts["broker"])
-        else:
-            host, port = "localhost", randint(49152, 65535)
+        try:
+            test = CuminTest(app)
 
-            broker = TestBroker("qpidd", port)
-            broker.start()
+            harness = TestHarness(test)
 
-        env = TestEnvironment(app, host, port, self.config.spec)
-        env.init();
+            if len(args) < 2:
+                harness.include.append("*")
+            else:
+                for pattern in args[1:]:
+                    harness.include.append(pattern)
 
-        app.start()
+            harness.init()
 
-        try:
-            session = env.run_test(MainTest(env))
-            session.report(sys.stdout)
+            session = harness.run()
+
+            session.report()
         finally:
             app.stop()
 
@@ -211,6 +204,10 @@
         opt = CommandOption(self, "check-xml")
         opt.description = "Check that page output is well-formed xml"
 
+        opt = CommandOption(self, "broker")
+        opt.argument = "ADDR"
+        opt.description = "Use existing broker at ADDR"
+
     def do_run(self, opts, args):
         app = Cumin(self.config)
 

Modified: mgmt/trunk/cumin/python/cumin/usergrid/main.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/usergrid/main.py	2009-09-14 20:13:26 UTC (rev 3631)
+++ mgmt/trunk/cumin/python/cumin/usergrid/main.py	2009-09-14 20:15:30 UTC (rev 3632)
@@ -9,7 +9,7 @@
 
 strings = StringCatalog(__file__)
 
-class UserGridModule(object):
+class UserGridModule(CuminModule):
     def init(self, app):
         app.user_grid_page = MainPage(app, "usergrid.html")
         app.add_page(app.user_grid_page)

Modified: mgmt/trunk/cumin/python/cumin/util.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/util.py	2009-09-14 20:13:26 UTC (rev 3631)
+++ mgmt/trunk/cumin/python/cumin/util.py	2009-09-14 20:15:30 UTC (rev 3632)
@@ -173,3 +173,10 @@
     @classmethod
     def get_zipped_colors(cls):
         return zip(cls.stat_strings, cls.stat_colors)
+
+class CuminModule(object):
+    def init(self, app):
+        pass
+
+    def init_test(self, test):
+        pass

Added: mgmt/trunk/parsley/python/parsley/test.py
===================================================================
--- mgmt/trunk/parsley/python/parsley/test.py	                        (rev 0)
+++ mgmt/trunk/parsley/python/parsley/test.py	2009-09-14 20:15:30 UTC (rev 3632)
@@ -0,0 +1,261 @@
+import logging
+import sys
+import os
+
+from fnmatch import fnmatchcase
+from random import randint
+from traceback import print_exc, extract_tb
+from datetime import datetime
+from threading import Thread
+from time import clock, sleep, time
+
+log = logging.getLogger("parsley.test")
+
+class TestHarness(object):
+    def __init__(self, test):
+        self.test = test
+        self.test.harness = self
+
+        self.tests = list()
+
+        self.include = list()
+        self.exclude = list()
+
+        self.initialized = False
+
+    def init(self):
+        assert not self.initialized
+        assert isinstance(self.test, Test)
+
+        self.test.init()
+
+        self.initialized = True
+
+    def run(self):
+        assert self.initialized
+        assert isinstance(self.test, Test)
+
+        session = TestSession(self)
+
+        self.test.run(session)
+
+        return session
+
+class TestSession(object):
+    def __init__(self, harness):
+        self.harness = harness
+        self.id = short_id()
+
+        self.test_calls_by_test = dict()
+
+    def report(self, out=sys.stdout):
+        enabled = 0
+        disabled = 0
+        passed = 0
+        failed = 0
+        skipped = 0
+
+        failed_calls = list()
+
+        out.write("Tests:")
+        out.write(os.linesep)
+        out.write(os.linesep)
+
+        for test in self.harness.tests:
+            status = None
+            elaboration = None
+
+            if test.enabled:
+                enabled += 1
+
+                call = self.test_calls_by_test.get(test)
+
+                if call:
+                    if call.exception:
+                        failed += 1
+                        failed_calls.append(call)
+                        status = "failed"
+                        elaboration = call.get_exception_text()
+                    else:
+                        passed += 1
+                        status = "passed"
+                else:
+                    skipped += 1
+                    status = "skipped"
+            else:
+                disabled += 1
+                status = "disabled"
+
+            out.write("  %-38s %s" % (test.path, status))
+            out.write(os.linesep)
+
+            if elaboration:
+                out.write("    %s" % elaboration)
+                out.write(os.linesep)
+
+        out.write(os.linesep)
+
+        out.write("Failures:")
+        out.write(os.linesep)
+        out.write(os.linesep)
+
+        if failed_calls:
+            for call in failed_calls:
+                out.write("  %s: %s" % \
+                              (call.test.path, call.get_exception_text()))
+                out.write(os.linesep)
+                out.write(os.linesep)
+
+                for spec in extract_tb(call.traceback):
+                    file, line, func, text = spec
+                    out.write("    %s:%i:%s" % spec[:3])
+                    out.write(os.linesep)
+                    out.write("      %s" % spec[3])
+                    out.write(os.linesep)
+
+                out.write(os.linesep)
+        else:
+            out.write("  None")
+            out.write(os.linesep)
+            out.write(os.linesep)
+
+        out.write("Summary:")
+        out.write(os.linesep)
+        out.write(os.linesep)
+
+        out.write("  %i tests" % len(self.harness.tests))
+        out.write(os.linesep)
+
+        out.write("    %i disabled" % disabled)
+        out.write(os.linesep)
+
+        out.write("    %i enabled" % enabled)
+        out.write(os.linesep)
+
+        out.write("      %i passed" % passed)
+        out.write(os.linesep)
+
+        out.write("      %i failed" % failed)
+        out.write(os.linesep)
+
+        out.write("      %i skipped" % skipped)
+        out.write(os.linesep)
+        out.write(os.linesep)
+
+class Test(object):
+    def __init__(self, name, parent):
+        assert isinstance(name, str)
+
+        if parent:
+            assert isinstance(parent, Test)
+
+        self.name = name
+        self.parent = parent
+        self.children = list()
+        self.ancestors = list()
+
+        self.harness = None
+        self.path = None
+        self.enabled = None
+
+        if parent:
+            self.parent.children.append(self)
+
+    def init(self):
+        log.debug("Initializing %s", self)
+
+        if self.parent is None:
+            self.path = self.name
+        else:
+            self.harness = self.parent.harness
+            self.path = "%s.%s" % (self.parent.path, self.name)
+
+            ancestor = self.parent
+
+            while ancestor:
+                self.ancestors.append(ancestor)
+                ancestor = ancestor.parent
+
+        self.harness.tests.append(self)
+
+        for pattern in self.harness.include:
+            if fnmatchcase(self.path, pattern):
+                self.enabled = True
+
+                for ancestor in self.ancestors:
+                    ancestor.enabled = True
+
+                break
+
+        for pattern in self.harness.exclude:
+            if fnmatchcase(self.path, pattern):
+                self.enabled = False
+
+                break
+
+        if not self.enabled:
+            log.debug("%s is disabled", self)
+
+        for child in self.children:
+            child.init()
+
+    def run(self, session):
+        if not self.enabled:
+            return
+
+        log.debug("Running %s", self)
+
+        call = TestCall(session, self)
+
+        call.open()
+
+        try:
+            try:
+                self.do_run(session)
+            except Exception, e:
+                call.exception = e
+                call.traceback = sys.exc_info()[2]
+        finally:
+            call.close()
+
+    def do_run(self, session):
+        self.run_children(session)
+
+    def run_children(self, session):
+        for child in self.children:
+            child.run(session)
+
+    def __repr__(self):
+        return "%s(%s)" % (self.__class__.__name__, self.path)
+
+class TestCall(object):
+    def __init__(self, session, test):
+        self.session = session
+        self.test = test
+        self.exception = None
+        self.traceback = None
+
+        self.start = None
+        self.end = None
+
+        self.session.test_calls_by_test[test] = self
+
+    def open(self):
+        self.start = clock()
+
+    def close(self):
+        self.end = clock()
+
+    def get_exception_text(self):
+        if self.exception:
+            return str(self.exception)
+
+class PassTest(Test):
+    pass
+
+class FailTest(Test):
+    def do_run(self, session):
+        raise Exception("!")
+
+def short_id():
+    return "%08x" % randint(0, sys.maxint)



More information about the rhmessaging-commits mailing list