Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormike <michael.jmontcalm@gmail.com>2009-11-17 00:04:23 (GMT)
committer mike <michael.jmontcalm@gmail.com>2009-11-17 00:04:23 (GMT)
commit7f82e474b4eaaef2795fb39539330f5ff6221922 (patch)
tree8aa8fc679c67e1285cf40b50264eb63cf880976a
parentc86bf110f49a6d293cbebede3ec10c552b92fb8c (diff)
WIP for Engine with Resourcestotal_merge
-rw-r--r--tests/probetests.py15
-rw-r--r--tutorius/TProbe.py70
-rw-r--r--tutorius/dbustools.py21
-rw-r--r--tutorius/engine.py26
-rw-r--r--tutorius/tutorial.py8
5 files changed, 122 insertions, 18 deletions
diff --git a/tests/probetests.py b/tests/probetests.py
index 8321e19..67132ff 100644
--- a/tests/probetests.py
+++ b/tests/probetests.py
@@ -223,11 +223,13 @@ class ProbeTest(unittest.TestCase):
del self.activity
def test_ping(self):
+ print "test_ping"
#Test ping()
res = self.probe.ping()
assert res == "alive", "Probe should be alive"
def test_action(self):
+ print "test_action"
global message_box
action = MockAddon()
action.i, action.s = (5,"woot")
@@ -271,6 +273,7 @@ class ProbeTest(unittest.TestCase):
assert message_box == "Test", "undo should not have happened again"
def test_events(self):
+ print "test_events"
global message_box
global event_box
@@ -319,6 +322,7 @@ class ProbeManagerTest(unittest.TestCase):
self._registered_actions = {}
def test_register_probe(self):
+ print "test_register_probe"
assert len(self.probeManager.get_registered_probes_list()) == 0
self.probeManager.register_probe("act1", "unique_id_1")
@@ -334,6 +338,7 @@ class ProbeManagerTest(unittest.TestCase):
assert self.probeManager.get_registered_probes_list("act2")[0][0] == "unique_id_2"
def test_register_multiple_probes(self):
+ print "test_register_multiple_probes"
assert len(self.probeManager.get_registered_probes_list()) == 0
self.probeManager.register_probe("act1", "unique_id_1")
@@ -344,6 +349,7 @@ class ProbeManagerTest(unittest.TestCase):
assert self.probeManager.get_registered_probes_list("act1")[1][0] == "unique_id_2"
def test_unregister_probe(self):
+ print "test_unregister_probe"
assert len(self.probeManager.get_registered_probes_list()) == 0
self.probeManager.register_probe("act1", "unique_id_1")
self.probeManager.register_probe("act1","unique_id_2")
@@ -360,6 +366,7 @@ class ProbeManagerTest(unittest.TestCase):
self._registered_actions[action_name] = action_address
def test_actions(self):
+ print "test_actions"
self.probeManager.register_probe("act1", "unique_id_1")
self.probeManager.register_probe("act2", "unique_id_2")
act1 = self.probeManager.get_registered_probes_list("act1")[0][1]
@@ -393,6 +400,7 @@ class ProbeManagerTest(unittest.TestCase):
assert act1.MockAction is None, "Action should be uninstalled"
def test_events(self):
+ print "test_events"
self.probeManager.register_probe("act1", "unique_id_1")
self.probeManager.register_probe("act2", "unique_id_2")
act1 = self.probeManager.get_registered_probes_list("act1")[0][1]
@@ -425,6 +433,10 @@ class ProbeManagerTest(unittest.TestCase):
class ProbeProxyTest(unittest.TestCase):
def setUp(self):
+ #Set a default dbus mainloop
+ m = DBusGMainLoop(set_as_default=True)
+ dbus.set_default_main_loop(m)
+
dbus.SessionBus = MockSessionBus
self.mockObj = MockProxyObject("unittest.TestCase", "/tutorius/Probe/unique_id_1")
@@ -437,6 +449,7 @@ class ProbeProxyTest(unittest.TestCase):
MockProxyObject._MockProxyObjects = {}
def test_Alive(self):
+ print "test_Alive"
self.mockObj.MockRet["ping"] = "alive"
assert self.probeProxy.isAlive() == True, "Alive should return True"
@@ -447,6 +460,7 @@ class ProbeProxyTest(unittest.TestCase):
self._registered_actions[action_name] = action_address
def test_actions(self):
+ print "test_Actions"
action = MockAddon()
action.i, action.s = 5, "action"
action2 = MockAddon()
@@ -478,6 +492,7 @@ class ProbeProxyTest(unittest.TestCase):
assert self.mockObj.MockCall["uninstall"]["args"][0] == address, "1 argument, the action address"
def test_events(self):
+ print "test_events"
event = MockAddon()
event.i, event.s = 5, "event"
event2 = MockAddon()
diff --git a/tutorius/TProbe.py b/tutorius/TProbe.py
index cfa734b..1bfa5e8 100644
--- a/tutorius/TProbe.py
+++ b/tutorius/TProbe.py
@@ -1,3 +1,18 @@
+# Copyright (C) 2009, Tutorius.org
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import logging
LOGGER = logging.getLogger("sugar.tutorius.TProbe")
import os
@@ -8,12 +23,11 @@ import dbus
import dbus.service
import cPickle as pickle
-
from . import addon
from .services import ObjectStore
from .properties import TPropContainer
-from .dbustools import remote_call, save_args
+from .dbustools import remote_call, save_args, Future, logError
import copy
"""
@@ -125,6 +139,8 @@ class TProbe(dbus.service.Object):
address = self._generate_action_reference(action)
+ LOGGER.debug("Installing action with name : %s"%address)
+
self._installedActions[address] = action
if action._props:
@@ -143,6 +159,7 @@ class TProbe(dbus.service.Object):
@param action_props pickled action properties
@return None
"""
+ LOGGER.debug("Updating action at address : %s"%address)
action = self._installedActions[address]
if action._props:
@@ -160,6 +177,7 @@ class TProbe(dbus.service.Object):
@return None
"""
if self._installedActions.has_key(address):
+ LOGGER.debug("Uninstalling action : %s"%address)
action = self._installedActions[address]
action.undo()
self._installedActions.pop(address)
@@ -190,6 +208,7 @@ class TProbe(dbus.service.Object):
name = self._generate_event_reference(eventfilter)
self._subscribedEvents[name] = eventfilter
+ LOGGER.debug("Subscribed to event %s"%name)
return name
@dbus.service.method("org.tutorius.ProbeInterface",
@@ -202,6 +221,7 @@ class TProbe(dbus.service.Object):
"""
if self._subscribedEvents.has_key(address):
+ LOGGER.debug("Unsubscribing event at address : %s"%address)
eventfilter = self._subscribedEvents[address]
eventfilter.remove_handlers()
self._subscribedEvents.pop(address)
@@ -312,9 +332,15 @@ class ProbeProxy:
@param block Force a synchroneous dbus call if True
@return None
"""
- return remote_call(self._probe.install, (pickle.dumps(action),),
- save_args(self.__update_action, action, callback),
- block=block)
+ LOGGER.debug("ProbeProxy :: installing a new action %s"%str(action))
+ action_address = Future("action_install")
+ #remote_call(self._probe.install, (pickle.dumps(action),),
+ # action_address._set, block)
+ self._probe.install(pickle.dumps(action), reply_handler=action_address._set, error_handler=logError)
+ # Get the value from the future!
+ address_name = action_address.get()
+ callback(address_name)
+ return address_name
def update(self, action_address, newaction, block=False):
"""
@@ -328,7 +354,14 @@ class ProbeProxy:
if not action_address in self._actions.keys():
raise RuntimeWarning("Action not installed")
#TODO Check error handling
- return remote_call(self._probe.update, (self._actions[action_address], pickle.dumps(newaction._props)), block=block)
+ LOGGER.debug("ProbeProxy :: Updating action at address %s"%action_address)
+ future_address = Future("action_update")
+ # Call the update method
+ remote_call(self._probe.update, (self._actions[action_address], pickle.dumps(newaction._props)),
+ save_args(future_address._set, action_address), block=block)
+ # Wait for the callback to be completed
+ future_address.get()
+ return None
def uninstall(self, action_address, block=False):
"""
@@ -337,7 +370,12 @@ class ProbeProxy:
@param block Force a synchroneous dbus call if True
"""
if action_name in self._actions.keys():
- remote_call(self._probe.uninstall,(self._actions.pop(action_name),), block=block)
+ LOGGER.debug("ProbeProxy :: Uninstalling action at %s"%action_address)
+ future_uninstall = Future("action_uninstall")
+ remote_call(self._probe.uninstall, (self._actions.pop(action_name),),
+ save_args(future_uninstall._set, action_address), block=block)
+ future_uninstall.get()
+ LOGGER.debug("ProbeProxy :: Uninstall complete for action at %s"%action_address)
def __update_event(self, event, callback, address):
LOGGER.debug("ProbeProxy :: Registered event %s with address %s", str(hash(event)), str(address))
@@ -402,9 +440,13 @@ class ProbeProxy:
# TODO elavoie 2009-07-25 When we will allow for patterns both
# for event types and sources, we will need to revise the lookup
# mechanism for which callback function to call
- return remote_call(self._probe.subscribe, (pickle.dumps(event),),
- save_args(self.__update_event, event, callback),
- block=block)
+
+ # TODO : Remove all the block(s) from the dbus stack
+ future_subscribe = Future("event_subscribe")
+ self._probe.subscribe(pickle.dumps(event), reply_handler=future_subscribe._set, error_handler=logError)
+ event_address = future_subscribe.get()
+ LOGGER.debug("ProbeProxy :: Registering of event %s complete"%str(hash(event)))
+ return self.__update_event(event, callback, event_address)
def unsubscribe(self, address, block=True):
"""
@@ -415,9 +457,13 @@ class ProbeProxy:
"""
LOGGER.debug("ProbeProxy :: Unregister adress %s issued", str(address))
if address in self._subscribedEvents.keys():
+ future_unsubscribe = Future("event_subscribe")
remote_call(self._probe.unsubscribe, (address,),
- return_cb=save_args(self.__clear_event, address),
+ return_cb=save_args(future_unsubscribe._set, address),
block=block)
+ future_unsubscribe.get()
+ self.__clear_event(address)
+ LOGGER.debug("ProbeProxy :: Unsubscribing from address %s complete"%str(address))
else:
LOGGER.debug("ProbeProxy :: unsubscribe address %s failed : not registered", address)
@@ -426,11 +472,13 @@ class ProbeProxy:
Detach the ProbeProxy from it's TProbe. All installed actions and
subscribed events should be removed.
"""
+ LOGGER.debug("ProbeProxy :: detaching...")
for action_addr in self._actions.keys():
self.uninstall(action_addr, block)
for address in self._subscribedEvents.keys():
self.unsubscribe(address, block)
+ LOGGER.debug("ProbeProxy :: detaching complete")
class ProbeManager(object):
diff --git a/tutorius/dbustools.py b/tutorius/dbustools.py
index 02acd3d..d96594e 100644
--- a/tutorius/dbustools.py
+++ b/tutorius/dbustools.py
@@ -1,3 +1,18 @@
+# Copyright (C) 2009, Tutorius.org
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import logging
import gobject
@@ -43,13 +58,15 @@ def remote_call(callable, args, return_cb=None, error_cb=None, block=False):
callable(*args, reply_handler=reply_cb, error_handler=errhandler_cb)
class Future(object):
- def __init__(self):
+ def __init__(self, log_name="default_Future"):
self._value = None
+ self._log_name = log_name
def get(self):
context = gobject.MainLoop().get_context()
while self._value == None and context.iteration(True):
- pass
+ LOGGER.debug("Future variable %s executed event loop while waiting for its value"%str(self._log_name))
+ LOGGER.debug("Future variable %s has received its value"%self._log_name)
return self._value
def _set(self, value):
diff --git a/tutorius/engine.py b/tutorius/engine.py
index ec281b3..e102406 100644
--- a/tutorius/engine.py
+++ b/tutorius/engine.py
@@ -1,3 +1,18 @@
+# Copyright (C) 2009, Tutorius.org
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import logging
import dbus.mainloop.glib
from jarabe.model import shell
@@ -10,6 +25,8 @@ from .tutorial import Tutorial, AutomaticTransitionEvent
from .translator import ResourceTranslator
+LOGGER = logging.getLogger("TutorialRunner")
+
class TutorialRunner(object):
"""
Driver for the execution of one tutorial
@@ -37,13 +54,16 @@ class TutorialRunner(object):
def start(self):
self.setCurrentActivity() #Temp Hack until activity in events/actions
+ LOGGER.debug("Starting tutorial : %s"%self._tutorial.name)
self.enterState(self._tutorial.INIT)
def stop(self):
self.setCurrentActivity() #Temp Hack until activity in events/actions
+ LOGGER.debug("Stopping tutorial execution for tutorial : %s"%self._tutorial.name)
self.enterState(self._tutorial.END)
self._teardownState()
self._state = None
+ LOGGER.debug("Teardown complete for tutorial : %s"%self._tutorial.name)
def _handleEvent(self, next_state, event):
#FIXME sanity check, log event that was not installed and ignore
@@ -87,7 +107,7 @@ class TutorialRunner(object):
# Install all the actions first
for (action_name, action) in actions.items():
- self._pM.install(action, save_args(self.__save_address, action_name), block=True)
+ self._pM.install(action, save_args(self.__save_address, action_name))
# Install the event filters
for (event, next_state) in transitions.values():
@@ -107,11 +127,13 @@ class TutorialRunner(object):
@param state_name The name of the state to enter in
"""
+ LOGGER.debug("Tutorial %s moving into state : %s"%(self._tutorial.name, state_name))
self.setCurrentActivity() #Temp Hack until activity in events/actions
# Recursive base case
if state_name == self._state:
#Nothing to do
+ LOGGER.debug("Installation of state %s completed"%state_name)
return
self._teardownState()
@@ -142,8 +164,10 @@ class Engine:
@param tutorialID unique tutorial identifier used to retrieve it from the disk
"""
if self._tutorial:
+ LOGGER.debug("Stopping old tutorial : %s"%self._tutorial.name)
self.stop()
+ LOGGER.debug("Starting new tutorial with ID : %s"%str(tutorialID))
# Insert the resource translation layer into the
translator_layer = ResourceTranslator(self._probeManager, tutorialID)
self._tutorial = TutorialRunner(Vault.loadTutorial(tutorialID), translator_layer)
diff --git a/tutorius/tutorial.py b/tutorius/tutorial.py
index 793d6f2..c933df7 100644
--- a/tutorius/tutorial.py
+++ b/tutorius/tutorial.py
@@ -88,7 +88,7 @@ class Tutorial(object):
self._state_name_nb = 0
- def add_state(self, action_dict={}, transition_list=()):
+ def add_state(self, action_list=[], transition_list=()):
"""
Add a new state to the state machine. The state is
initialized with the action list and transition list
@@ -98,19 +98,19 @@ class Tutorial(object):
The transitions are added using add_transition.
- @param action_dict The dictionary of valid action_name:actions for this state
+ @param action_list The list of actions for this state
@param transition_list The list of valid transitions
@return unique name for this state
"""
name = self._generate_unique_state_name()
- for (action_name, action) in action_dict.items():
+ for action in action_list:
self._validate_action(action)
for transition in transition_list:
self._validate_transition(transition)
- state = State(name, action_dict, transition_list)
+ state = State(name, action_list, transition_list)
self._state_dict[name] = state