farc icon indicating copy to clipboard operation
farc copied to clipboard

Allow to run several unit test cases independently

Open maxpeng opened this issue 4 years ago • 1 comments

When I perform unit testing for the state machines using farc, I want to independently run several test cases. That is, I want to have a new loop created for each test. Currently, once we import the farc package, a default event loop, which is a class variable, is created for the Framework class.

class Framework(object):
    """Framework is a composite class that holds:
    - the asyncio event loop
    - the registry of AHSMs
    - the set of TimeEvents
    - the handle to the next TimeEvent
    - the table subscriptions to events
    """

    _event_loop = asyncio.get_event_loop()

I propose to add a class method to allow us to specify the used event loop and reset the Framework.

For example:

class Framework(object):
    """Framework is a composite class that holds:
    - the asyncio event loop
    - the registry of AHSMs
    - the set of TimeEvents
    - the handle to the next TimeEvent
    - the table subscriptions to events
    """

    #_event_loop = asyncio.get_event_loop()
    _event_loop = None
    
    ...

    @classmethod
    def init(cls, loop):
        cls._event_loop = loop
        cls._priority_dict.clear()
        # May need to reset other class variables too.

        # Bind a useful set of POSIX signals to the handler
        # (ignore a NotImplementedError on Windows)
        try:
            cls._event_loop.add_signal_handler(signal.SIGINT, lambda: Framework.stop())
            cls._event_loop.add_signal_handler(signal.SIGTERM, lambda: Framework.stop())
            cls._event_loop.add_signal_handler(29, Framework.print_info)
        except NotImplementedError:
            pass

maxpeng avatar Dec 11 '20 03:12 maxpeng

First concern is about these lines

    #_event_loop = asyncio.get_event_loop()
    _event_loop = None

this would force all existing users to change their code to use the new init() method. I believe the list of users is very small, but I would prefer not to force a method like this. I would leave out this code change and then only the people using init() will have the _event_loop that was instantiated by default be replaced by the one given in init().

Second concern is about people passing in outside event loops. farc assumes that the asyncio event loop is used. I don't know what would happen if other types of event loops were used.

If you have an example of your suggestion, I would appreciate seeing how it works. As in, you could create a fork of farc, make your suggested code modifications and also provide a generic example in the examples/ folder and submit a pull request.

dwhall avatar Dec 12 '20 23:12 dwhall