Example #1
0
class FysomRepeatedAfterEventCallbackTests(unittest.TestCase):

    def setUp(self):
        self.fired = []

        def record_event(event):
            self.fired.append(event.msg)
            return 42

        self.fsm = Fysom({
            'initial': 'notcalled',
            'events': [
                {'name': 'multiple', 'src': 'notcalled', 'dst': 'called'},
                {'name': 'multiple', 'src': 'called', 'dst': 'called'},
            ],
            'callbacks': {
                'onaftermultiple': record_event
            }
        })

    def test_should_fire_onafter_event_repeatedly(self):
        self.fsm.multiple(msg="first")
        self.fsm.multiple(msg="second")

        self.assertEqual(self.fired, ["first", "second"])
Example #2
0
class FysomEventWithStateCallbackTests(unittest.TestCase):

    def setUp(self):
        self.fired_nocalled_to_called = []
        self.fired_called_to_called = []

        def record_event_nocalled_to_called(event):
            self.fired_nocalled_to_called.append(event.msg)
            return 42

        def record_event_called_to_called(event):
            self.fired_called_to_called.append(event.msg)
            return 42

        self.fsm = Fysom({
            'initial': 'notcalled',
            'events': [
                {'name': 'multiple', 'src': 'notcalled', 'dst': 'called'},
                {'name': 'multiple', 'src': 'called', 'dst': 'called'},
            ],
            'callbacks': {
                'onaftermultiple_notcalled_called': record_event_nocalled_to_called,
                'onaftermultiple_called_called': record_event_called_to_called
            }
        })

    def test_should_fire_on_event(self):
        self.fsm.multiple(msg="first")
        self.fsm.multiple(msg="second")

        self.assertEqual(self.fired_nocalled_to_called, ["first"])
        self.assertEqual(self.fired_called_to_called, ["second"])
Example #3
0
    def __init__(self, agent):
        logger.debug("Initializing host agent state machine")

        self.agent = agent
        self.fsm = Fysom({
            "events": [("lookup", "*", "found"),
                       ("announce", "found", "announced"),
                       ("pending", "announced", "wait4init"),
                       ("ready", "wait4init", "good2go")],
            "callbacks": {
                # Can add the following to debug
                # "onchangestate":  self.print_state_change,
                "onlookup": self.lookup_agent_host,
                "onannounce": self.announce_sensor,
                "onpending": self.on_ready,
                "ongood2go": self.on_good2go
            }
        })

        self.timer = threading.Timer(1, self.fsm.lookup)
        self.timer.daemon = True
        self.timer.name = self.THREAD_NAME

        # Only start the announce process when not in Test
        if not "INSTANA_TEST" in os.environ:
            self.timer.start()
Example #4
0
 def __init__(self, name, runner, references, config, **kwargs):
     """ Create a PrePostTask.
       @param str name: unique name of the task
       @param object runner: TaskRunner that manages this task
       @param dict references: contains references to all required modules
       @param dict config: configuration parameter dictionary
     """
     _default_callbacks = {'onprerun': self._pre, 'onpostrun': self._post}
     _stateList = {
         'initial':
         'stopped',
         'events': [{
             'name': 'prerun',
             'src': 'stopped',
             'dst': 'paused'
         }, {
             'name': 'postrun',
             'src': 'paused',
             'dst': 'stopped'
         }],
         'callbacks':
         _default_callbacks
     }
     if 'PyQt5' in sys.modules:
         super().__init__(cfg=_stateList, **kwargs)
     else:
         QtCore.QObject.__init__(self)
         Fysom.__init__(self, _stateList)
     self.lock = Mutex()
     self.name = name
     self.runner = runner
     self.ref = references
     self.config = config
Example #5
0
    def __init__(self,
                 left_button=None,
                 left_led=None,
                 right_button=None,
                 right_led=None,
                 track=None,
                 strawberry_factory=None,
                 chocolate_factory=None):

        self.buttons_locked = False
        self.micro_lock = threading.Lock()

        self.pending_cookies = Queue.Queue()

        self.left_button = left_button
        self.left_button.register(self.button_pressed)
        self.left_led = left_led
        self.left_led.off()

        self.right_button = right_button
        self.right_button.register(self.button_pressed)
        self.right_led = right_led
        self.right_led.off()

        self.track = track
        self.strawberry_factory = strawberry_factory
        self.chocolate_factory = chocolate_factory

        self.evolution = Evolution()

        self._fsm = Fysom(initial='waiting',
                          events=[('reproduce', 'waiting', 'waiting')],
                          callbacks=[('on_state_waiting', self._unlock),
                                     ('onreproduce', self._reproduce)])
Example #6
0
def create_voting_fsm(tracking_id,
                      vote,
                      broadcast_vote,
                      spawn_yadtshell,
                      fold,
                      cleanup_fsm):
    fsm = Fysom({
        'initial': 'negotiating',
        'events': [
            {'name': 'call', 'src': 'negotiating', 'dst': 'negotiating'},
            {'name': 'fold', 'src': 'negotiating', 'dst': 'finish'},
            {'name': 'showdown', 'src': 'negotiating', 'dst': 'spawning'},
            {'name': 'spawned', 'src': 'spawning', 'dst': 'finish'},
            {'name': 'showdown', 'src': 'finish', 'dst': 'finish'}
        ],
        'callbacks': {
            'onnegotiating': broadcast_vote,
            'onspawning': spawn_yadtshell,
            'onfinish': cleanup_fsm,
            'onfold': fold,
        }
    })
    fsm.tracking_id = tracking_id
    fsm.vote = vote
    return fsm
Example #7
0
    def __init__(self, debuglevel=0, debugname='Log Service Base'):
        self.debuglevel = debuglevel
        self.debugname = debugname
        self._error_string = ''
        self.on_error_string_changed = []

        # Log
        self._log_channel = Publish(debuglevel=debuglevel)
        self._log_channel.debugname = '%s - %s' % (self.debugname, 'log')
        # more efficient to reuse protobuf messages
        self._log_tx = Container()

        # callbacks
        self.on_state_changed = []

        # fsm
        self._fsm = Fysom(
            {
                'initial': 'down',
                'events': [
                    {'name': 'connect', 'src': 'down', 'dst': 'up'},
                    {'name': 'disconnect', 'src': 'up', 'dst': 'down'},
                ],
            }
        )

        self._fsm.ondown = self._on_fsm_down
        self._fsm.onafterconnect = self._on_fsm_connect
        self._fsm.onup = self._on_fsm_up
        self._fsm.onafterdisconnect = self._on_fsm_disconnect
Example #8
0
    def test_pickling(self):

        fsm = Fysom({
            'initial': 'green',
            'events': [
                {'name': 'warn', 'src': 'green', 'dst': 'yellow'},
                {'name': 'panic', 'src': 'yellow', 'dst': 'red'},
                {'name': 'calm', 'src': 'red', 'dst': 'yellow'},
                {'name': 'clear', 'src': 'yellow', 'dst': 'green'}
            ]
        })

        pickled = dumps(fsm)
        assert pickled
        fsm = loads(pickled)

        self.assertTrue(isinstance(fsm, Fysom))
        self.assertEquals('green', fsm.current)

        fsm.warn()
        pickled = dumps(fsm)
        assert pickled
        fsm = loads(pickled)

        self.assertEquals('yellow', fsm.current)
Example #9
0
 def test_if_src_not_specified_then_is_wildcard(self):
     fsm = Fysom({
         'initial':
         'hungry',
         'events': [{
             'name': 'eat',
             'src': 'hungry',
             'dst': 'satisfied'
         }, {
             'name': 'eat',
             'src': 'satisfied',
             'dst': 'full'
         }, {
             'name': 'eat',
             'src': 'full',
             'dst': 'sick'
         }, {
             'name': 'rest',
             'dst': 'hungry'
         }]
     })
     fsm.eat()
     self.assertEqual(fsm.current, 'satisfied')
     fsm.rest()
     self.assertEqual(fsm.current, 'hungry')
     fsm.eat()
     fsm.eat()
     self.assertEqual(fsm.current, 'full')
     fsm.rest()
     self.assertEqual(fsm.current, 'hungry')
Example #10
0
    def __init__(self, callbacks_dict=None, interactive_callbacks=None):
        self.__NOT_IMPLEMENTED_ERROR = "Classes that inherit from KnittingPlugin should implment {0}"
        self.interactive_callbacks = {}

        if interactive_callbacks is None:
            self.register_interactive_callbacks({
                "info": BaseKnittingPlugin.__interactive_info,
                "user_action": BaseKnittingPlugin.__interactive_info,
                "warning": BaseKnittingPlugin.__interactive_warn,
                "error": BaseKnittingPlugin.__interactive_error,
                "progress": BaseKnittingPlugin.__log_progress
            })
        else:
            self.register_interactive_callbacks(interactive_callbacks)

        if callbacks_dict is None:
            callbacks_dict = {
                'onknit': self.onknit,
                'onconfigure': self.onconfigure,
                'onfinish': self.onfinish,
            }
        Fysom.__init__(self, {
            'initial': 'activated',
            'events': [  # TODO: add more states for handling error management.
                         {'name': 'configure', 'src': 'activated', 'dst': 'configured'},
                         {'name': 'configure', 'src': 'configured', 'dst': 'configured'},
                         {'name': 'configure', 'src': 'finished', 'dst': 'configured'},
                         {'name': 'configure', 'src': 'error', 'dst': 'configured'},
                         {'name': 'knit', 'src': 'configured', 'dst': 'knitting'},
                         {'name': 'finish', 'src': 'knitting', 'dst': 'finished'},
                         {'name': 'fail', 'src': 'knitting', 'dst': 'error'}],
            'callbacks': callbacks_dict
        })
Example #11
0
class FysomRepeatedAfterEventCallbackTests(unittest.TestCase):

    def setUp(self):
        self.fired = []

        def record_event(event):
            self.fired.append(event.msg)
            return 42

        self.fsm = Fysom({
            'initial': 'notcalled',
            'events': [
                {'name': 'multiple', 'src': 'notcalled', 'dst': 'called'},
                {'name': 'multiple', 'src': 'called', 'dst': 'called'},
            ],
            'callbacks': {
                'onaftermultiple': record_event
            }
        })

    def test_should_fire_onafter_event_repeatedly(self):
        self.fsm.multiple(msg="first")
        self.fsm.multiple(msg="second")

        self.assertEqual(self.fired, ["first", "second"])
Example #12
0
    def test_onchangestate_should_fire_for_all_state_changes(self):
        def on_change_state(e):
            self.current_event = e
        fsm = Fysom({
            'initial': 'foo',
            'events': [
                {'name': 'footobar', 'src': 'foo', 'dst': 'bar'},
                {'name': 'bartobaz', 'src': 'bar', 'dst': 'baz'},
            ],
            'callbacks': {
                'onchangestate': on_change_state
            }
        })

        fsm.footobar(id=123)
        self.assertEqual(self.current_event.event, 'footobar')
        self.assertEqual(self.current_event.src, 'foo')
        self.assertEqual(self.current_event.dst, 'bar')
        self.assertEqual(self.current_event.id, 123)
        self.assertTrue(self.current_event.fsm is fsm)

        fsm.bartobaz('positional', named_attribute='test')
        self.assertEqual(self.current_event.event, 'bartobaz')
        self.assertEqual(self.current_event.src, 'bar')
        self.assertEqual(self.current_event.dst, 'baz')
        self.assertEqual(self.current_event.named_attribute, 'test')
        self.assertEqual(self.current_event.args[0], 'positional')
        self.assertTrue(self.current_event.fsm is fsm)
Example #13
0
    def __init__(self, callbacks_dict=None, interactive_callbacks=None):
        """Interactive callbacks handle Plugin-Frontend interaction hooks."""
        self.interactive_callbacks = {}

        # Are we running on CLI or knitlib web?
        # If no callbacks are registered, we set a CLI set as default.
        if interactive_callbacks is None:
            self.register_interactive_callbacks({
                "blocking_user_action": BaseKnittingPlugin.__cli_blocking_action,
                "message": BaseKnittingPlugin.__cli_emit_message,
                "progress": BaseKnittingPlugin.__cli_log_progress
            })
        else:
            self.register_interactive_callbacks(interactive_callbacks)

        # Fysom allows to set hooks before changing states, we set them here.
        if callbacks_dict is None:
            callbacks_dict = {
                'onknit': self.onknit,
                'onconfigure': self.onconfigure,
                'onfinish': self.onfinish,
            }
        Fysom.__init__(self, {
            'initial': 'activated',
            'events': [  # TODO: add more states for handling error management.
                         {'name': 'configure', 'src': 'activated', 'dst': 'configured'},
                         {'name': 'configure', 'src': 'configured', 'dst': 'configured'},
                         {'name': 'configure', 'src': 'finished', 'dst': 'configured'},
                         {'name': 'configure', 'src': 'error', 'dst': 'configured'},
                         {'name': 'knit', 'src': 'configured', 'dst': 'knitting'},
                         {'name': 'finish', 'src': 'knitting', 'dst': 'finished'},
                         {'name': 'finish', 'src': 'finished', 'dst': 'finished'},
                         {'name': 'fail', 'src': 'knitting', 'dst': 'error'}],
            'callbacks': callbacks_dict
        })
 def __init__(self):
     self._states = []
     self._fsm = Fysom({
         'initial':
         'green',
         'events': [{
             'name': 'warn',
             'src': 'green',
             'dst': 'yellow'
         }, {
             'name': 'panic',
             'src': 'yellow',
             'dst': 'red'
         }, {
             'name': 'calm',
             'src': 'red',
             'dst': 'yellow'
         }, {
             'name': 'clear',
             'src': 'yellow',
             'dst': 'green'
         }],
         'callbacks': {
             'ongreen': self._on_green,
             'onyellow': self._on_yellow,
             'onred': self._on_red
         }
     })
Example #15
0
    def __init__(self, agent):
        package_version = 'unknown'
        try:
            package_version = pkg_resources.get_distribution('instana').version
        except pkg_resources.DistributionNotFound:
            pass

        logger.info("Stan is on the scene.  Starting Instana instrumentation version: %s", package_version)
        logger.debug("initializing fsm")

        self.agent = agent
        self.fsm = Fysom({
            "events": [
                ("lookup",   "*",            "found"),
                ("announce", "found",        "announced"),
                ("pending",  "announced",    "wait4init"),
                ("ready",    "wait4init",    "good2go")],
            "callbacks": {
                # Can add the following to debug
                # "onchangestate":  self.print_state_change,
                "onlookup":       self.lookup_agent_host,
                "onannounce":     self.announce_sensor,
                "onpending":      self.agent.start,
                "onready":        self.on_ready}})

        self.timer = t.Timer(5, self.fsm.lookup)
        self.timer.daemon = True
        self.timer.name = self.THREAD_NAME
        self.timer.start()
Example #16
0
    def __init__(self):
        self.electionTimerInterval=randint(6,10) #seconds timeout
        # self.electionTimerInterval=randint(2,5) #seconds timeout
        self.ns = NodeState()
        self.ownAddress = socket.gethostbyname(socket.gethostname())
        self.leaderId = None
        print(self.ownAddress)
        self.serverState = Fysom({'initial': 'follower',
                                  'events': [
                                      ('startElection', 'follower', 'candidate'),
                                      ('discoverLeader', 'candidate', 'follower'),
                                      ('newTerm', 'candidate', 'follower'),
                                      ('startElection', 'candidate', 'candidate'),
                                      ('receivedMajority', 'candidate', 'leader'),
                                      ('discoverServerWithHigherTerm',
                                       'leader', 'follower')
                                  ],
                                  'callbacks': {
                                      'onleader': self.become_leader,
                                      'onstartElection': self.become_candidate,
                                      'onleaveleader': self.stop_being_leader,
                                      'onfollower': self.become_follower
                                  }
                                  })
        self.nodeAddresses = []
        # need to make sure all nodes are started up before populating the node list
        while len(self.nodeAddresses) < self.nodesInCluster:
            self.update_node_list()
            time.sleep(1)
        print(self.nodeAddresses)

        self.otherNodeAddresses = [
            a for a in self.nodeAddresses if a != str(self.ownAddress)]
        print(self.otherNodeAddresses)
Example #17
0
    def __init__(self, fsm_table=setup_fsm.fsm_def.FSM_TABLE, options = None,
                 logger_name=sys.modules['__main__'].__name__,
                 logger_dir = '.'):
        """
        Initialise function of the generator FSM

        :param fsm_table: Table defining the FSM
        :param options  : A dictionary containing the necessary options
        :param : logger_name : the parent logger name
        :param fsm_table: Table defining the FSM
        """

        callbacks = {'onbeforeallocate': self.onbeforeallocate,
                     'onnot_ready': self.onnot_ready,
                     'onbeforeconfigure': self.onbeforeconfigure,
                     'onstand_by': self.onstand_by,
                     'onbeforestart_run': self.onbeforestart_run,
                     'onready': self.onready,
                     'onbeforestart_trigger': self.onbeforestart_trigger,
                     'onrunning': self.onrunning,
                     'onbeforestop_trigger': self.onbeforestop_trigger,
                     'onbeforestop_run': self.onbeforestop_run,
                     'onbeforereset': self.onbeforereset,
                     'onbeforedeallocate': self.onbeforedeallocate}


        Fysom.__init__(self, cfg = fsm_table, callbacks = callbacks)

        # Set up the logger
        self.logger = logging.getLogger(logger_name + '.camserver_fsm')
        self.logger.info('\t-|--|> Append the CameraServerFSM to the setup')
        self.options = options
        self.logger_dir = logger_dir
Example #18
0
 def __init__(self, location, size, disease):
     self.state = Fysom({
         'initial':
         'healthy',
         'events': [
             {
                 'name': 'get infected',
                 'src': 'healthy',
                 'dst': 'incubation'
             },
             {
                 'name': 'finish incubation',
                 'src': 'incubation',
                 'dst': 'contagious'
             },
             {
                 'name': 'die',
                 'src': 'contagious',
                 'dst': 'dead'
             },
             {
                 'name': 'recover',
                 'src': 'contagious',
                 'dst': 'immune'
             },
         ],
     })
     self.incubation_duration = disease['incubation duration']
     self.contagious_duration = disease['contagious duration']
     self.color = colors[self.state.current]
     self.next_trigger = None
     self.neighbors = []
     self.size = size
     self.x, self.y = location[0] * self.size, location[1] * self.size
Example #19
0
 def __init__(self, name, runner, references, config, **kwargs):
     """ Create a PrePostTask.
       @param str name: unique name of the task
       @param object runner: TaskRunner that manages this task
       @param dict references: contains references to all required modules
       @param dict config: configuration parameter dictionary
     """
     _default_callbacks = {'onprerun': self._pre, 'onpostrun': self._post}
     _stateList = {
         'initial': 'stopped',
         'events': [
             {'name': 'prerun', 'src': 'stopped', 'dst': 'paused'},
             {'name': 'postrun', 'src': 'paused', 'dst': 'stopped'}
         ],
         'callbacks': _default_callbacks
     }
     if 'PyQt5' in sys.modules:
         super().__init__(cfg=_stateList, **kwargs)
     else:
         QtCore.QObject.__init__(self)
         Fysom.__init__(self, _stateList)
     self.lock = Mutex()
     self.name = name
     self.runner = runner
     self.ref = references
     self.config = config
Example #20
0
    def setUp(self):
        self.fired_callbacks = []

        self.fsm = Fysom({
            'initial': 'sleeping',
            'events': [
                {'name': 'foo', 'src': 'sleeping', 'dst': 'fooed'},
                {'name': 'foo', 'src': 'fooed', 'dst': 'fooed'},
                {'name': 'bar', 'src': 'fooed', 'dst': 'bared'},
                {'name': 'bar', 'src': 'bared', 'dst': 'bared'},
                {'name': 'baz', 'src': 'bared', 'dst': 'bazed'},
                {'name': 'wait', 'src': 'sleeping', 'dst': 'waiting'}
            ],
            'callbacks': {
                'onfoo': self.on_foo,
                'onbar': self.on_bar,
                'onbaz': self.on_baz,
                'onbeforefoo': self.before_foo,
                'onbeforebar': self.before_bar,
                'onbeforewait': self.before_wait,
                'onenterfooed': self.on_enter_fooed,
                'onenterbared': self.on_enter_bared,
                'onreenterfooed': self.on_reenter_fooed,
                'onreenterbared': self.on_reenter_bared,
                'onleavesleeping': self.on_leave_sleeping,
                'onleavefooed': self.on_leave_fooed
            }
        })
Example #21
0
 def setUp(self):
     self.fsm = Fysom({
         'initial':
         'green',
         'events': [{
             'name': 'warn',
             'src': 'green',
             'dst': 'yellow'
         }, {
             'name': 'panic',
             'src': 'yellow',
             'dst': 'red'
         }, {
             'name': 'calm',
             'src': 'red',
             'dst': 'yellow'
         }, {
             'name': 'clear',
             'src': 'yellow',
             'dst': 'green'
         }, {
             'name': 'warm',
             'src': 'green',
             'dst': 'blue'
         }]
     })
Example #22
0
 def logon(self):
     self.psget = PasswordProtect(self.baseurl)
     self.logon_fsm = Fysom({
         'initial': {
             'state': 'start'
         },
         'events': [{
             'name': 'userid',
             'src': 'start',
             'dst': 'username_sent'
         }, {
             'name': 'password',
             'src': 'username_sent',
             'dst': 'password_sent'
         }, {
             'name': 'logon',
             'src': 'password_sent',
             'dst': 'logged_on'
         }],
         'final':
         'logged_on',
         'callbacks': {
             'onuserid': self.send_userid,
             'onpassword': self.send_password,
             'onlogon': self.send_logon
         }
     })
     self.logon_fsm.userid(html_id='userid')
     self.logon_fsm.password(html_id='password')
     self.logon_fsm.logon(html_id='logon')
Example #23
0
    def __init__(self, debuglevel=0, debugname='Halrcomp Subscribe'):
        self.debuglevel = debuglevel
        self.debugname = debugname
        self._error_string = ''
        self.on_error_string_changed = []
        # ZeroMQ
        context = zmq.Context()
        context.linger = 0
        self._context = context
        # pipe to signalize a shutdown
        self._shutdown = context.socket(zmq.PUSH)
        self._shutdown_uri = b'inproc://shutdown-%s' % str(uuid.uuid4()).encode()
        self._shutdown.bind(self._shutdown_uri)
        self._thread = None  # socket worker tread
        self._tx_lock = threading.Lock()  # lock for outgoing messages

        # Socket
        self.socket_uri = ''
        self._socket_topics = set()
        # more efficient to reuse protobuf messages
        self._socket_rx = Container()

        # Heartbeat
        self._heartbeat_lock = threading.Lock()
        self._heartbeat_interval = 2500
        self._heartbeat_timer = None
        self._heartbeat_active = False
        self._heartbeat_liveness = 0
        self._heartbeat_reset_liveness = 5

        # callbacks
        self.on_socket_message_received = []
        self.on_state_changed = []

        # fsm
        self._fsm = Fysom(
            {
                'initial': 'down',
                'events': [
                    {'name': 'start', 'src': 'down', 'dst': 'trying'},
                    {'name': 'full_update_received', 'src': 'trying', 'dst': 'up'},
                    {'name': 'stop', 'src': 'trying', 'dst': 'down'},
                    {'name': 'heartbeat_timeout', 'src': 'up', 'dst': 'trying'},
                    {'name': 'heartbeat_tick', 'src': 'up', 'dst': 'up'},
                    {'name': 'any_msg_received', 'src': 'up', 'dst': 'up'},
                    {'name': 'stop', 'src': 'up', 'dst': 'down'},
                ],
            }
        )

        self._fsm.ondown = self._on_fsm_down
        self._fsm.onafterstart = self._on_fsm_start
        self._fsm.ontrying = self._on_fsm_trying
        self._fsm.onafterfull_update_received = self._on_fsm_full_update_received
        self._fsm.onafterstop = self._on_fsm_stop
        self._fsm.onup = self._on_fsm_up
        self._fsm.onafterheartbeat_timeout = self._on_fsm_heartbeat_timeout
        self._fsm.onafterheartbeat_tick = self._on_fsm_heartbeat_tick
        self._fsm.onafterany_msg_received = self._on_fsm_any_msg_received
    def test_gc_should_not_break_callback(self):
        class MyTestObject(object):
            def __init__(self):
                self._states = []
                self._fsm = None

            def warn(self):
                self._fsm.warn()

            def panic(self):
                self._fsm.panic()

            def calm(self):
                self._fsm.calm()

            def clear(self):
                self._fsm.clear()

            def _on_green(self, *args, **kwargs):
                self._states.append('green')

            def _on_yellow(self, *args, **kwargs):
                self._states.append('yellow')

            def _on_red(self, *args, **kwargs):
                self._states.append('red')

        obj = MyTestObject()
        fsm = Fysom({
            'initial':
            'green',
            'events': [{
                'name': 'warn',
                'src': 'green',
                'dst': 'yellow'
            }, {
                'name': 'panic',
                'src': 'yellow',
                'dst': 'red'
            }, {
                'name': 'calm',
                'src': 'red',
                'dst': 'yellow'
            }, {
                'name': 'clear',
                'src': 'yellow',
                'dst': 'green'
            }],
            'callbacks': {
                'ongreen': obj._on_green,
                'onyellow': obj._on_yellow,
                'onred': obj._on_red
            }
        })
        obj._fsm = fsm
        obj.warn()
        obj.clear()
        del obj
        fsm.warn()
 def test_init_kwargs_only(self):
     fsm = Fysom(initial='green',
                 events=[('panic', 'green', 'red'),
                         ('calm', 'red', 'green')])
     self.assertEqual(fsm.current, "green")
     fsm.panic()
     self.assertEqual(fsm.current, "red")
     fsm.calm()
     self.assertEqual(fsm.current, "green")
Example #26
0
    def __init__(self, callbacks_dict):
        self.__NOT_IMPLEMENTED_ERROR = "Classes that inherit from KnittingPlugin should implment {0}"

        callbacks_dict = {
            'onknit': self.onknit,
            #'onknitting': self.onknitting,
            'onconfigure': self.onconfigure,
            'onfinish': self.onfinish,
        }
        Fysom.__init__(
            self,
            {
                'initial':
                'activated',
                'events': [
                    ## TODO: add more states for handling error management.
                    {
                        'name': 'configure',
                        'src': 'activated',
                        'dst': 'configured'
                    },
                    {
                        'name': 'configure',
                        'src': 'configured',
                        'dst': 'configured'
                    },
                    {
                        'name': 'configure',
                        'src': 'finished',
                        'dst': 'configured'
                    },
                    {
                        'name': 'configure',
                        'src': 'error',
                        'dst': 'configured'
                    },
                    {
                        'name': 'knit',
                        'src': 'configured',
                        'dst': 'knitting'
                    },
                    {
                        'name': 'finish',
                        'src': 'knitting',
                        'dst': 'finished'
                    },
                    {
                        'name': 'fail',
                        'src': 'knittng',
                        'dst': 'error'
                    }
                ],
                'callbacks':
                callbacks_dict
            })
 def test_never_finished_if_final_is_unspecified(self):
     fsm = Fysom({
         'initial':
         'green',
         'events': [{
             'name': 'warn',
             'src': 'green',
             'dst': 'yellow'
         }, {
             'name': 'panic',
             'src': 'yellow',
             'dst': 'red'
         }, {
             'name': 'calm',
             'src': 'red',
             'dst': 'yellow'
         }, {
             'name': 'clear',
             'src': 'yellow',
             'dst': 'green'
         }]
     })
     self.assertFalse(fsm.is_finished())
     fsm.warn()
     self.assertFalse(fsm.is_finished())
     fsm.panic()
     self.assertFalse(fsm.is_finished())
 def test_it_should_indicate_whether_fsm_in_finished_state(self):
     fsm = Fysom({
         'initial':
         'green',
         'final':
         'red',
         'events': [{
             'name': 'warn',
             'src': 'green',
             'dst': 'yellow'
         }, {
             'name': 'panic',
             'src': 'yellow',
             'dst': 'red'
         }, {
             'name': 'calm',
             'src': 'red',
             'dst': 'yellow'
         }, {
             'name': 'clear',
             'src': 'yellow',
             'dst': 'green'
         }]
     })
     self.assertFalse(fsm.is_finished())
     fsm.warn()
     self.assertFalse(fsm.is_finished())
     fsm.panic()
     self.assertTrue(fsm.is_finished())
Example #29
0
    def __init__(self, debuglevel=0, debugname='Log Base'):
        self.debuglevel = debuglevel
        self.debugname = debugname
        self._error_string = ''
        self.on_error_string_changed = []

        # Log
        self._log_channel = SimpleSubscribe(debuglevel=debuglevel)
        self._log_channel.debugname = '%s - %s' % (self.debugname, 'log')
        self._log_channel.on_state_changed.append(
            self._log_channel_state_changed)
        self._log_channel.on_socket_message_received.append(
            self._log_channel_message_received)
        # more efficient to reuse protobuf messages
        self._log_rx = Container()

        # callbacks
        self.on_log_message_received = []
        self.on_state_changed = []

        # fsm
        self._fsm = Fysom({
            'initial':
            'down',
            'events': [
                {
                    'name': 'connect',
                    'src': 'down',
                    'dst': 'trying'
                },
                {
                    'name': 'log_up',
                    'src': 'trying',
                    'dst': 'up'
                },
                {
                    'name': 'disconnect',
                    'src': 'trying',
                    'dst': 'down'
                },
                {
                    'name': 'disconnect',
                    'src': 'up',
                    'dst': 'down'
                },
            ],
        })

        self._fsm.ondown = self._on_fsm_down
        self._fsm.onafterconnect = self._on_fsm_connect
        self._fsm.ontrying = self._on_fsm_trying
        self._fsm.onafterlog_up = self._on_fsm_log_up
        self._fsm.onafterdisconnect = self._on_fsm_disconnect
        self._fsm.onup = self._on_fsm_up
        self._fsm.onleaveup = self._on_fsm_up_exit
Example #30
0
 def test_deferred_initial_state_should_be_none_then_state(self):
     fsm = Fysom({
         'initial': {'state': 'green', 'event': 'init', 'defer': True},
         'events': [
             {'name': 'panic', 'src': 'green', 'dst': 'red'},
             {'name': 'calm', 'src': 'red', 'dst': 'green'},
         ]
     })
     self.assertEqual(fsm.current, 'none')
     fsm.init()
     self.assertEqual(fsm.current, 'green')
 def test_kwargs_override_cfg(self):
     fsm = Fysom({
         'initial': 'green',
         'events': [
             {'name': 'panic', 'src': 'green', 'dst': 'red'},
             {'name': 'calm', 'src': 'red', 'dst': 'green'},
         ]},
         # override initial state and calm event
         initial='red', events=[('calm', 'red', 'black')])
     self.assertEqual(fsm.current, "red")
     fsm.calm()
     self.assertEqual(fsm.current, "black")
Example #32
0
class FysomAsynchronousStateTransitionTests(unittest.TestCase):
    def on_leave_foo(self, e):
        self.leave_foo_event = e
        return False

    def on_enter_bar(self, e):
        self.on_enter_bar_fired = True
        self.on_enter_bar_event = e

    def setUp(self):
        self.on_enter_bar_fired = False

        self.fsm = Fysom({
            'initial':
            'foo',
            'events': [
                {
                    'name': 'footobar',
                    'src': 'foo',
                    'dst': 'bar'
                },
                {
                    'name': 'bartobar',
                    'src': 'bar',
                    'dst': 'bar'
                },
            ],
            'callbacks': {
                'onleavefoo': self.on_leave_foo,
                'onenterbar': self.on_enter_bar,
            }
        })

    def test_fsm_should_be_put_on_hold_when_onleave_state_returns_false(self):
        self.fsm.footobar(id=123)
        self.assertEqual(self.fsm.current, 'foo')
        self.assertTrue(hasattr(self, 'leave_foo_event'),
                        'Callback onleavefoo did not fire.')
        self.assertTrue(self.leave_foo_event is not None)
        self.assertEqual(self.leave_foo_event.id, 123)
        self.fsm.transition()
        self.assertEqual(self.fsm.current, 'bar')

    def test_onenter_state_should_not_fire_when_fsm_is_put_on_hold(self):
        self.fsm.footobar(id=123)
        self.assertFalse(self.on_enter_bar_fired)
        self.fsm.transition()
        self.assertTrue(self.on_enter_bar_fired)

    def test_should_raise_exception_upon_further_transitions_when_fsm_is_on_hold(
            self):
        self.fsm.footobar(id=123)
        self.assertRaises(FysomError, self.fsm.bartobar)
Example #33
0
 def test_goto(self):
     fsm = Fysom({
         'initial': 'green',
         'events': [
             {'name': 'warn', 'src': 'green', 'dst': 'yellow'},
             {'name': 'panic', 'src': 'yellow', 'dst': 'red'},
             {'name': 'panic', 'src': 'green', 'dst': 'red'},
             {'name': 'calm', 'src': 'red', 'dst': 'yellow'},
             {'name': 'clear', 'src': 'yellow', 'dst': 'green'}
         ]
     })
     self.assertRaises(MultiplePossibilitesFound, fsm.next)
     self.assertEqual('red', fsm.goto('panic'))
Example #34
0
    def __init__(self, plugin_id, current_state):
        Fysom.__init__(self, {
            'initial': current_state,
            'events': events,
            'callbacks': {
                'oninstall': self.install,
                'oninitialize': self.initialize
            }
        })

        self.plugin_id = plugin_id
        self.current_state = current_state
        self.onchangestate = self._onchangestate
Example #35
0
File: fsm.py Project: mahak/fuelweb
    def __init__(self, plugin_id, current_state):
        Fysom.__init__(self, {
            'initial': current_state,
            'events': events,
            'callbacks': {
                'oninstall': self.install,
                'oninitialize': self.initialize
            }
        })

        self.plugin_id = plugin_id
        self.current_state = current_state
        self.onchangestate = self._onchangestate
Example #36
0
    def do_stem(self, word):
        fsm = Fysom(initial='start', events=self.events)

        i = len(word) - 1
        j = len(word)

        while (True):
            if i <= 0:
                break
            v = word[i:j]
            # print v
            res = fsm.can(v)
            if (res):
                if v == 'i' and fsm.can(word[i - 1:j]):
                    i = i - 1
                    continue
                fsm.trigger(v)
                if fsm.current == 'h':
                    if word[i - 1:i] == 'i':
                        i = i - 1  # skip i
                        if word[i - 1:i] == 'n':
                            # ning qushimchasi
                            fsm.current = 'start'
                            continue
                elif fsm.current == 'b':
                    fsm.current = 'start'
                j = i

            i = i - 1

        return word[:j]
Example #37
0
 def __init__(self, *args, **kwargs):
     logger.debug("PseudoDevice %s", kwargs)
     self.addr = kwargs.pop('addr', "0000")
     self.typemodule = kwargs.pop('typemodule', None)
     self.ser = kwargs.pop('ser', [])
     Fysom.__init__(
         self,
         {
             'initial':
             'idle',
             'events': [
                 {
                     'name': 'evt_askident',
                     'dst': 'ukn',
                     'src': [
                         'idle',
                     ]
                 },
                 {
                     'name': 'evt_giveident',
                     'dst': 'identified',
                     'src': [
                         'idle',
                         'ukn',
                     ]
                 },
                 {
                     'name': 'evt_newvalue',
                     'dst': 'newvalue',
                     'src': [
                         'identified',
                     ]
                 },
                 {
                     'name': 'evt_valueack',
                     'dst': 'identified',
                     'src': [
                         'newvalue',
                     ]
                 },
             ],
             "callbacks": {
                 #                        'onconnected':   self.connected_state,
                 'onidentified': self.identified_state,
                 'onnewvalue': self.newvalue_state,
                 #                        'onidle':        self.idle_state,
             }
         })
     logger.debug('Module of type %s at address %s detected',
                  self.typemodule, self.addr)
Example #38
0
    def do_stem(self, word):
        fsm = Fysom(initial='start', events=self.events)
        # FIXME: uncomment below and make sanitize functions support
        # both Python 2 and 3 versions
        # word = WordProcessor.sanitize(word)
        i = len(word) - 1
        j = len(word)

        while (True):
            if i <= 0:
                break
            v = word[i:j]
            # print v
            res = fsm.can(v)
            if (res):
                if v == 'i' and fsm.can(word[i - 1:j]):
                    i = i - 1
                    continue
                fsm.trigger(v)
                if fsm.current == 'h':
                    if word[i - 1:i] == 'i':
                        i = i - 1  # skip i
                        if word[i - 1:i] == 'n':
                            # ning qushimchasi
                            fsm.current = 'start'
                            continue
                elif fsm.current == 'b':
                    fsm.current = 'start'
                j = i

            i = i - 1

        return word[:j]
Example #39
0
    def __init__(self, name, runner, references, config, **kwargs):
        """ Create an Interruptable task.
          @param str name: unique task name
          @param object runner: reference to the TaskRunner managing this task
          @param dict references: a dictionary of all required modules
          @param dict config: configuration dictionary
        """
        default_callbacks = {
                'onrun': self._start,
                'onpause': self._pause,
                'onresume': self._resume,
                'onfinish': self._finish
                }
        _stateDict = {
            'initial': 'stopped',
            'events': [
                {'name': 'run',                 'src': 'stopped',   'dst': 'starting'},
                {'name': 'startingFinished',    'src': 'starting',  'dst': 'running'},
                {'name': 'pause',               'src': 'running',   'dst': 'pausing'},
                {'name': 'pausingFinished',     'src': 'pausing',   'dst': 'paused'},
                {'name': 'finish',              'src': 'running',   'dst': 'finishing'},
                {'name': 'finishingFinished',   'src': 'finishing', 'dst': 'stopped'},
                {'name': 'resume',              'src': 'paused',    'dst': 'resuming'},
                {'name': 'resumingFinished',    'src': 'resuming',  'dst': 'running'},
                {'name': 'abort',               'src': 'pausing',   'dst': 'stopped'},
                {'name': 'abort',               'src': 'starting',  'dst': 'stopped'},
                {'name': 'abort',               'src': 'resuming',  'dst': 'stopped'}
            ],
            'callbacks': default_callbacks
        }
        if 'PyQt5' in sys.modules:
            super().__init__(cfg=_stateDict, **kwargs)
        else:
            QtCore.QObject.__init__(self)
            Fysom.__init__(self, _stateDict)

        self.lock = Mutex()
        self.name = name
        self.interruptable = False
        self.success = False
        self.runner = runner
        self.ref = references
        self.config = config

        self.sigDoStart.connect(self._doStart, QtCore.Qt.QueuedConnection)
        self.sigDoPause.connect(self._doPause, QtCore.Qt.QueuedConnection)
        self.sigDoResume.connect(self._doResume, QtCore.Qt.QueuedConnection)
        self.sigDoFinish.connect(self._doFinish, QtCore.Qt.QueuedConnection)
        self.sigNextTaskStep.connect(self._doTaskStep, QtCore.Qt.QueuedConnection)
    def test_gc_should_not_break_callback(self):
        class MyTestObject(object):

            def __init__(self):
                self._states = []
                self._fsm = None

            def warn(self):
                self._fsm.warn()

            def panic(self):
                self._fsm.panic()

            def calm(self):
                self._fsm.calm()

            def clear(self):
                self._fsm.clear()

            def _on_green(self, *args, **kwargs):
                self._states.append('green')

            def _on_yellow(self, *args, **kwargs):
                self._states.append('yellow')

            def _on_red(self, *args, **kwargs):
                self._states.append('red')

        obj = MyTestObject()
        fsm = Fysom({
            'initial': 'green',
            'events': [
                {'name': 'warn', 'src': 'green', 'dst': 'yellow'},
                {'name': 'panic', 'src': 'yellow', 'dst': 'red'},
                {'name': 'calm', 'src': 'red', 'dst': 'yellow'},
                {'name': 'clear', 'src': 'yellow', 'dst': 'green'}
            ],
            'callbacks': {
                'ongreen':  obj._on_green,
                'onyellow': obj._on_yellow,
                'onred':    obj._on_red
            }
        })
        obj._fsm = fsm
        obj.warn()
        obj.clear()
        del obj
        fsm.warn()
Example #41
0
 def test_it_doesnt_break_with_unicode_literals(self):
     try:
         fsm = Fysom({
             'initial':
             'green',
             'final':
             'red',
             'events': [{
                 'name': 'warn',
                 'src': 'green',
                 'dst': 'yellow'
             }, {
                 'name': 'panic',
                 'src': 'yellow',
                 'dst': 'red'
             }, {
                 'name': 'calm',
                 'src': 'red',
                 'dst': 'yellow'
             }, {
                 'name': 'clear',
                 'src': 'yellow',
                 'dst': 'green'
             }]
         })
         self.assertTrue(True)
     except TypeError:
         self.assertTrue(False)
Example #42
0
    def setUp(self):
        self.fired_nocalled_to_called = []
        self.fired_called_to_called = []

        def record_event_nocalled_to_called(event):
            self.fired_nocalled_to_called.append(event.msg)
            return 42

        def record_event_called_to_called(event):
            self.fired_called_to_called.append(event.msg)
            return 42

        def record_event_before_notcalled_to_called(event):
            return True

        def record_event_before_called_to_called(event):
            return False

        self.fsm = Fysom({
            'initial': 'notcalled',
            'events': [
                {'name': 'multiple', 'src': 'notcalled', 'dst': 'called'},
                {'name': 'multiple', 'src': 'called', 'dst': 'called'},
            ],
            'callbacks': {
                'onbeforemultiple_notcalled_called': record_event_before_notcalled_to_called,
                'onaftermultiple_notcalled_called': record_event_nocalled_to_called,
                'onbeforemultiple_called_called': record_event_before_called_to_called,
                'onaftermultiple_called_called': record_event_called_to_called
            }
        })
Example #43
0
    def setUp(self):
        self.fired_callbacks = []

        self.fsm = Fysom({
            'initial': 'sleeping',
            'events': [
                {'name': 'foo', 'src': 'sleeping', 'dst': 'fooed'},
                {'name': 'foo', 'src': 'fooed', 'dst': 'fooed'},
                {'name': 'bar', 'src': 'fooed', 'dst': 'bared'},
                {'name': 'bar', 'src': 'bared', 'dst': 'bared'},
                {'name': 'baz', 'src': 'bared', 'dst': 'bazed'},
                {'name': 'wait', 'src': 'sleeping', 'dst': 'waiting'}
            ],
            'callbacks': {
                'onfoo': self.on_foo,
                'onbar': self.on_bar,
                'onbaz': self.on_baz,
                'onbeforefoo': self.before_foo,
                'onbeforebar': self.before_bar,
                'onbeforewait': self.before_wait,
                'onenterfooed': self.on_enter_fooed,
                'onenterbared': self.on_enter_bared,
                'onreenterfooed': self.on_reenter_fooed,
                'onreenterbared': self.on_reenter_bared,
                'onleavesleeping': self.on_leave_sleeping,
                'onleavefooed': self.on_leave_fooed
            }
        })
    def __init__(self,
                 left_button=None,
                 left_led=None,
                 right_button=None,
                 right_led=None,
                 track=None,
                 strawberry_factory=None,
                 chocolate_factory=None):

        self.buttons_locked = False
        self.micro_lock = threading.Lock()

        self.pending_cookies = Queue.Queue()

        self.left_button = left_button
        self.left_button.register(self.button_pressed)
        self.left_led = left_led
        self.left_led.off()

        self.right_button = right_button
        self.right_button.register(self.button_pressed)
        self.right_led = right_led
        self.right_led.off()

        self.track = track
        self.strawberry_factory = strawberry_factory
        self.chocolate_factory = chocolate_factory

        self.evolution = Evolution()

        self._fsm = Fysom(
            initial='waiting',
            events=[('reproduce', 'waiting', 'waiting')],
            callbacks=[('on_state_waiting', self._unlock),
                       ('onreproduce', self._reproduce)])
Example #45
0
 def __init__(self, cfg):
     from fysom import Fysom
     events = set([event['name'] for event in cfg['events']])
     cfg['callbacks'] = self.collect_event_listeners(
         events, cfg['callbacks'])
     self.fsm = Fysom(cfg)
     self.attach_proxy_methods(self.fsm, events)
    def __init__(self, debuglevel=0, debugname='Halrcomp Subscribe'):
        self.debuglevel = debuglevel
        self.debugname = debugname
        self._error_string = ''
        self.on_error_string_changed = []
        # ZeroMQ
        context = zmq.Context()
        context.linger = 0
        self._context = context
        # pipe to signalize a shutdown
        self._shutdown = context.socket(zmq.PUSH)
        self._shutdown_uri = b'inproc://shutdown-%s' % str(uuid.uuid4()).encode()
        self._shutdown.bind(self._shutdown_uri)
        self._thread = None  # socket worker tread
        self._tx_lock = threading.Lock()  # lock for outgoing messages

        # Socket
        self.socket_uri = ''
        self._socket_topics = set()
        # more efficient to reuse protobuf messages
        self._socket_rx = Container()

        # Heartbeat
        self._heartbeat_lock = threading.Lock()
        self._heartbeat_interval = 2500
        self._heartbeat_timer = None
        self._heartbeat_active = False
        self._heartbeat_liveness = 0
        self._heartbeat_reset_liveness = 5

        # callbacks
        self.on_socket_message_received = []
        self.on_state_changed = []

        # fsm
        self._fsm = Fysom(
            {
                'initial': 'down',
                'events': [
                    {'name': 'start', 'src': 'down', 'dst': 'trying'},
                    {'name': 'full_update_received', 'src': 'trying', 'dst': 'up'},
                    {'name': 'stop', 'src': 'trying', 'dst': 'down'},
                    {'name': 'heartbeat_timeout', 'src': 'up', 'dst': 'trying'},
                    {'name': 'heartbeat_tick', 'src': 'up', 'dst': 'up'},
                    {'name': 'any_msg_received', 'src': 'up', 'dst': 'up'},
                    {'name': 'stop', 'src': 'up', 'dst': 'down'},
                ],
            }
        )

        self._fsm.ondown = self._on_fsm_down
        self._fsm.onafterstart = self._on_fsm_start
        self._fsm.ontrying = self._on_fsm_trying
        self._fsm.onafterfull_update_received = self._on_fsm_full_update_received
        self._fsm.onafterstop = self._on_fsm_stop
        self._fsm.onup = self._on_fsm_up
        self._fsm.onafterheartbeat_timeout = self._on_fsm_heartbeat_timeout
        self._fsm.onafterheartbeat_tick = self._on_fsm_heartbeat_tick
        self._fsm.onafterany_msg_received = self._on_fsm_any_msg_received
Example #47
0
class FysomStateTests(unittest.TestCase):
    def setUp(self):
        self.fsm = Fysom({
            'initial': 'green',
            'events': [
                {'name': 'warn', 'src': 'green', 'dst': 'yellow'},
                {'name': 'panic', 'src': 'yellow', 'dst': 'red'},
                {'name': 'calm', 'src': 'red', 'dst': 'yellow'},
                {'name': 'clear', 'src': 'yellow', 'dst': 'green'}
            ]
        })

    def test_is_state_should_succeed_for_initial_state(self):
        self.assertTrue(self.fsm.isstate('green'))

    def test_identity_transition_should_not_be_allowed_by_default(self):
        self.assertFalse(self.fsm.can('clear'))
        self.assertTrue(self.fsm.cannot('clear'))

    def test_configured_transition_should_work(self):
        self.assertTrue(self.fsm.can('warn'))

    def test_transition_should_change_state(self):
        self.fsm.warn()
        self.assertTrue(self.fsm.isstate('yellow'))

    def test_should_raise_exception_when_state_transition_is_not_allowed(self):
        self.assertRaises(FysomError, self.fsm.panic)
        self.assertRaises(FysomError, self.fsm.calm)
        self.assertRaises(FysomError, self.fsm.clear)
Example #48
0
    def do_stem(self, word):
        fsm = Fysom(initial='start', events=self.events)
        # FIXME: uncomment below and make sanitize functions support
        # both Python 2 and 3 versions
        # word = WordProcessor.sanitize(word)
        i = len(word) - 1
        j = len(word)

        while(True):
            if i <= 0:
                break
            v = word[i:j]
            # print v
            res = fsm.can(v)
            if (res):
                if v == 'i' and fsm.can(word[i-1:j]):
                    i = i - 1
                    continue
                fsm.trigger(v)
                if fsm.current == 'h':
                    if word[i-1:i] == 'i':
                        i = i - 1  # skip i
                        if word[i-1:i] == 'n':
                            # ning qushimchasi
                            fsm.current = 'start'
                            continue
                elif fsm.current == 'b':
                    fsm.current = 'start'
                j = i

            i = i - 1

        return word[:j]
Example #49
0
    def test_no_possibility_for_goto(self):
        fsm = Fysom({
            'initial': 'green',
            'events': [
                {'name': 'warn', 'src': 'green', 'dst': 'yellow'},
                {'name': 'panic', 'src': 'yellow', 'dst': 'red'},
                {'name': 'panic', 'src': 'green', 'dst': 'red'},
                # when call panic from green, we go to red, from red we
                # should go to yellow, but it is commented and we should
                # have a exception
                # {'name': 'calm', 'src': 'red', 'dst': 'yellow'},
                {'name': 'clear', 'src': 'yellow', 'dst': 'green'}
            ]
        })

        self.assertRaises(MultiplePossibilitesFound, fsm.next)
        self.assertEqual('red', fsm.goto('panic'))
        self.assertRaises(NoPossibilityFound, fsm.goto, 'calm')
Example #50
0
 def __init__(self, display):
     self.display = display
     self.fsm = Fysom({ 'initial': 'start',
         'events': [
             {'name': 'up', 'src': 'credits', 'dst': 'start'},
             {'name': 'up', 'src': 'start', 'dst': 'credits'},
             {'name': 'down', 'src': 'start', 'dst': 'credits'},
             {'name': 'down', 'src': 'credits', 'dst': 'start'}] })
     self.player_controllers = [None, None]
Example #51
0
 def setUp(self):
     self.fsm = Fysom({
         'initial': 'green',
         'events': [
             {'name': 'warn', 'src': 'green', 'dst': 'yellow'},
             {'name': 'panic', 'src': 'yellow', 'dst': 'red'},
             {'name': 'calm', 'src': 'red', 'dst': 'yellow'},
             {'name': 'clear', 'src': 'yellow', 'dst': 'green'}
         ]
     })
 def test_tuples_as_trasition_spec(self):
     fsm = Fysom({
         'initial': 'green',
         'events': [  # freely mix dicts and tuples
             {'name': 'warn', 'src': 'green', 'dst': 'yellow'},
             ('panic', 'yellow', 'red'),
             ('calm', 'red', 'yellow'),
             {'name': 'clear', 'src': 'yellow', 'dst': 'green'}
         ]
     })
     fsm.warn()
     fsm.panic()
     self.assertEqual(fsm.current, 'red')
     fsm.calm()
     fsm.clear()
     self.assertEqual(fsm.current, 'green')
Example #53
0
class FysomStateTests(unittest.TestCase):
    def setUp(self):
        self.fsm = Fysom({
            'initial': 'green',
            'events': [
                {'name': 'warn', 'src': 'green', 'dst': 'yellow'},
                {'name': 'panic', 'src': 'yellow', 'dst': 'red'},
                {'name': 'calm', 'src': 'red', 'dst': 'yellow'},
                {'name': 'clear', 'src': 'yellow', 'dst': 'green'},
                {'name': 'warm', 'src': 'green', 'dst': 'blue'}
            ]
        })

    def test_is_state_should_succeed_for_initial_state(self):
        self.assertTrue(self.fsm.isstate('green'))

    def test_identity_transition_should_not_be_allowed_by_default(self):
        self.assertFalse(self.fsm.can('clear'))
        self.assertTrue(self.fsm.cannot('clear'))

    def test_configured_transition_should_work(self):
        self.assertTrue(self.fsm.can('warn'))

    def test_transition_should_change_state(self):
        self.fsm.warn()
        self.assertTrue(self.fsm.isstate('yellow'))

    def test_should_raise_exception_when_state_transition_is_not_allowed(self):
        self.assertRaises(FysomError, self.fsm.panic)
        self.assertRaises(FysomError, self.fsm.calm)
        self.assertRaises(FysomError, self.fsm.clear)

    def test_event_handler_has_name_and_docstring(self):
        self.assertEqual(self.fsm.warm.__name__, "warm", "Event handlers do not have appropriate name.")
        self.assertNotEqual(self.fsm.warm.__name__, None, "Docstring for event handler is None!")

    def test_trigger_should_trigger_the_event_handler(self):
        self.assertEqual(self.fsm.current, "green", "The initial state isn't the expected state.")
        self.fsm.trigger("warm")
        make_callable = lambda: self.fsm.trigger("unknowevent")
        self.assertRaises(FysomError, make_callable)
        self.assertEqual(self.fsm.current, "blue", "The initial state isn't the expected state.")
class FysomAsynchronousStateTransitionTests(unittest.TestCase):
    def on_leave_foo(self, e):
        self.leave_foo_event = e
        return False

    def on_enter_bar(self, e):
        self.on_enter_bar_fired = True
        self.on_enter_bar_event = e

    def setUp(self):
        self.on_enter_bar_fired = False

        self.fsm = Fysom({
            'initial': 'foo',
            'events': [
                {'name': 'footobar', 'src': 'foo', 'dst': 'bar'},
                {'name': 'bartobar', 'src': 'bar', 'dst': 'bar'},
            ],
            'callbacks': {
                'onleavefoo': self.on_leave_foo,
                'onenterbar': self.on_enter_bar,
            }
        })

    def test_fsm_should_be_put_on_hold_when_onleave_state_returns_false(self):
        self.fsm.footobar(id=123)
        self.assertEqual(self.fsm.current, 'foo')
        self.assertTrue(hasattr(self, 'leave_foo_event'), 'Callback onleavefoo did not fire.')
        self.assertTrue(self.leave_foo_event is not None)
        self.assertEqual(self.leave_foo_event.id, 123)
        self.fsm.transition()
        self.assertEqual(self.fsm.current, 'bar')

    def test_onenter_state_should_not_fire_when_fsm_is_put_on_hold(self):
        self.fsm.footobar(id=123)
        self.assertFalse(self.on_enter_bar_fired)
        self.fsm.transition()
        self.assertTrue(self.on_enter_bar_fired)

    def test_should_raise_exception_upon_further_transitions_when_fsm_is_on_hold(self):
        self.fsm.footobar(id=123)
        self.assertRaises(FysomError, self.fsm.bartobar)
Example #55
0
class Trail:
    IDLE = 'idle'
    REGISTERED = 'registered'
    HOLD = 'hold'
    ACTIVE = 'active'

    def __init__(self, path=None):
        self.path = path
        self.store = Store()
        self._fsm = Fysom(
                initial=Trail.IDLE,
                events=[
                    ('register', Trail.IDLE, Trail.REGISTERED),
                    ('prepare', Trail.REGISTERED, Trail.HOLD),
                    ('activate', Trail.HOLD, Trail.ACTIVE),
                    ('resolve', Trail.ACTIVE, Trail.IDLE),
                    ('resolve', Trail.HOLD, Trail.IDLE),
                    ('resolve', Trail.REGISTERED, Trail.IDLE)],
                callbacks=[
                    ('onbeforeregister', self._onbeforeregister),
                    ('onregistered', self._registered),
                    ('onidle', self._onidle)])

    @property
    def status(self):
        return self._fsm.current

    def onchangestate(self, on_change):
        self._fsm.onchangestate = on_change

    def register(self):
        self._fsm.register()

    def prepare(self):
        self._fsm.prepare()

    def activate(self):
        self._fsm.activate()

    def resolve(self):
        self._fsm.resolve()

    def _onbeforeregister(self, e):
        self.store.register(self.path)

    def _registered(self, e):
        self.prepare()

    def _onidle(self, e):
        if e.src is not "none":
            self.store.unregister(self.path)
Example #56
0
class FysomEventWithStateWithOnbeforeCallbackTests(unittest.TestCase):

    def setUp(self):
        self.fired_nocalled_to_called = []
        self.fired_called_to_called = []

        def record_event_nocalled_to_called(event):
            self.fired_nocalled_to_called.append(event.msg)
            return 42

        def record_event_called_to_called(event):
            self.fired_called_to_called.append(event.msg)
            return 42

        def record_event_before_notcalled_to_called(event):
            return True

        def record_event_before_called_to_called(event):
            return False

        self.fsm = Fysom({
            'initial': 'notcalled',
            'events': [
                {'name': 'multiple', 'src': 'notcalled', 'dst': 'called'},
                {'name': 'multiple', 'src': 'called', 'dst': 'called'},
            ],
            'callbacks': {
                'onbeforemultiple_notcalled_called': record_event_before_notcalled_to_called,
                'onaftermultiple_notcalled_called': record_event_nocalled_to_called,
                'onbeforemultiple_called_called': record_event_before_called_to_called,
                'onaftermultiple_called_called': record_event_called_to_called
            }
        })

    def test_onbefore_called_to_called_callbacks_raising_exceptions_should_not_be_eaten(self):
        self.fsm.multiple(msg="first")
        with self.assertRaises(Canceled):
            self.fsm.multiple(msg="second")

        self.assertEqual(self.fired_nocalled_to_called, ["first"])
        self.assertEqual(self.fired_called_to_called, [])
Example #57
0
 def __init__(self, display):
     self.display = display
     self.offset = 0
     self.fsm = Fysom({ 'initial': 'menu',
         'events': [
             {'name': 'start', 'src': 'menu', 'dst': 'game'},
             {'name': 'finish', 'src': 'game', 'dst': 'menu'},
             {'name': 'credits', 'src': 'menu', 'dst': 'credits'},
             {'name': 'menu', 'src': 'credits', 'dst': 'menu'} ] })
     self.fsm.onchangestate = Application.change_state
     self.commands = []
     self.active_state = Menu(self.display)
Example #58
0
 def __init__(self):
     self.switch = False
     self.sm = Fysom({
         'initial': 'Lights off',
         'events': [
             {'name': 'toggle', 'src': 'lights_off', 'dst': 'lights_on'},
             {'name': 'toggle', 'src': 'lights_on', 'dst': 'lights_off'}],
         'callbacks': {
             'on_Lights_on': self.lights_on,
             'on_Lights_off': self.lights_off,
         }
     })