File: test_state.py

package info (click to toggle)
asterisk-testsuite 0.0.0%2Bsvn.5781-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd, stretch
  • size: 18,632 kB
  • sloc: xml: 33,912; python: 32,904; ansic: 1,599; sh: 395; makefile: 170; sql: 17
file content (174 lines) | stat: -rw-r--r-- 5,250 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#!/usr/bin/env python
"""Module that manipulates test state as a state machine

Note that this module has been superceded by the pluggable
test configuration framework and the apptest module.

Copyright (C) 2011, Digium, Inc.
Matt Jordan <mjordan@digium.com>

This program is free software, distributed under the terms of
the GNU General Public License Version 2.
"""

import logging

LOGGER = logging.getLogger(__name__)

def print_test_event(event):
    """Log a test event

    Keyword Arguments:
    event    The TestEvent
    """
    LOGGER.debug("Test Event received:")
    for key, value in event.items():
        LOGGER.debug("\t" + key + "\t=\t" + value)


class TestStateController(object):
    """The controller for the TestEvent state machine"""

    def __init__(self, test_case, ami_receiver):
        """Constructor

        Keyword Arguments:
        test_case       The TestCase derived class that owns this controller
        ami_receiver    The AMI instance that will send the controller TestEvent
                        notifications
        """
        self._test_case = test_case
        self._current_state = None
        self._assert_handler = None

        # Register for TestEvent updates
        ami_receiver.registerEvent('TestEvent', self.handle_test_event)

    def handle_test_event(self, ami, event):
        """Handler for a TestEvent

        Keyword Arguments:
        ami     The AMI instance that sent us the TestEvent
        event   The TestEvent
        """
        print_test_event(event)

        if event['type'] == 'StateChange':
            if (self._current_state != None):
                self._current_state.handle_state_change(ami, event)
            else:
                LOGGER.error("No initial state set before TestEvent received")
                self._current_state = FailureTestState(self)
        elif event['type'] == 'Assert':
            if (self._assert_handler != None):
                self._assert_handler(ami, event)
            else:
                LOGGER.warn("ASSERT received but no handler defined; " \
                            "test will now fail")
                self.fail_test()

    def change_state(self, test_state):
        """Change the current state machine state to a new state

        Keyword Arguments:
        test_state   The TestState to change to
        """
        self._current_state = test_state

    def fail_test(self):
        """
        Fail and stop the test
        """
        LOGGER.info("Setting test state to Fail")
        self._test_case.passed = False

        LOGGER.info("Stopping reactor")
        self._test_case.stop_reactor()

    def add_assert_handler(self, assert_handler_func):
        """Add an assert handler for Assert TestEvent types

        Keyword Arguments:
        assert_handler_func   The handler function that takes in an AMI instance
                              and an event instance and receives the Asserts

        Note that without a handler function, receiving any assert will
        automatically fail a test
        """
        self._assert_handler = assert_handler_func


class TestState(object):
    """Base class for the TestEvent state machine objects"""

    def __init__(self, controller):
        """Constructor

        Keyword Arguments:
        controller  The TestStateController instance
        """
        self.controller = controller

        if (self.controller == None):
            LOGGER.error("Controller is none")
            raise RuntimeError('Controller is none')

    def handle_state_change(self, ami, event):
        """Handle a state change.

        Called whenever a state change is received by the TestStateController.
        Concrete implementations should override this method and use it to
        change the state of the test by calling the change_state method

        Keyword Arguments:
        ami     The instance of AMI that sent us the TestEvent
        event   The TestEvent object
        """
        pass

    def change_state(self, new_state):
        """Inform the TestStateController that the test state needs to change

        Keyword Arguments:
        new_state    The new TestState to change to
        """
        self.controller.change_state(new_state)

class FailureTestState(TestState):
    """A generic failure state.

    Once transitioned to, the test will automatically fail.  No further
    state changes will be processed.
    """

    def __init__(self, controller):
        """Constructor

        Keyword Arguments:
        controller  The TestStateController instance
        """
        super(FailureTestState, self).__init__(controller)
        controller.fail_test()

    def handle_state_change(self, ami, event):
        """Handle a state change.

        This class ignores all subsequent state changes.

        Keyword Arguments:
        ami     The instance of AMI that sent us the TestEvent
        event   The TestEvent object
        """
        pass

    def change_state(self, new_state):
        """Inform the TestStateController that the test state needs to change

        This class ignores all changes of state.

        Keyword Arguments:
        new_state    The new TestState to change to
        """
        return