1# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import state_machine
6
7import logging
8import mox
9import unittest
10
11import at_transceiver
12import global_state
13import modem_configuration
14import task_loop
15import wardmodem_exceptions as wme
16
17class StateMachineBadTestCase(unittest.TestCase):
18    """
19    Test that an abstract machine can not be instantiated.
20
21    """
22
23    def test_failed_instantiation(self):
24        """
25        Only subclasses of StateMachine that implement the get_well_known_name
26        can be instantiated. Test that a direct instantiation of StateMachine
27        fails.
28
29        """
30        self._mox = mox.Mox()
31        self._transceiver = self._mox.CreateMock(at_transceiver.ATTransceiver)
32        self._state = self._mox.CreateMock(global_state.GlobalState)
33        self._task_loop = self._mox.CreateMock(task_loop.TaskLoop)
34        self._modem_conf = self._mox.CreateMock(
35                modem_configuration.ModemConfiguration)
36
37        self.assertRaises(wme.WardModemSetupException,
38                          state_machine.StateMachine, self._state,
39                          self._transceiver, self._modem_conf)
40
41class StateMachineTestCase(unittest.TestCase):
42    """
43    Test fixture for StateMachine class.
44
45    """
46
47    class TestStateMachine(state_machine.StateMachine):
48        #pylint: disable=C0111
49        """
50        A simple test machine that can be instantiated.
51        """
52
53        def get_well_known_name(self):
54            return 'TestStateMachine'
55
56
57    def setUp(self):
58        self._mox = mox.Mox()
59        self._transceiver = self._mox.CreateMock(at_transceiver.ATTransceiver)
60        self._state = self._mox.CreateMock(global_state.GlobalState)
61        self._task_loop = self._mox.CreateMock(task_loop.TaskLoop)
62        self._modem_conf = self._mox.CreateMock(
63                modem_configuration.ModemConfiguration)
64
65        self._state_machine = StateMachineTestCase.TestStateMachine(
66                self._state, self._transceiver, self._modem_conf)
67        # Replace some internal objects with mocks.
68        self._state_machine._task_loop = self._task_loop
69
70    def _add_response_functions(self):
71        self._state_machine._add_response_function('wm_response_1')
72        self._state_machine._add_response_function('wm_response_2')
73        self._state_machine._add_response_function('wm_response_3')
74
75
76    def test_add_response_function(self):
77        """
78        Tests that only valid response functions can be added.
79
80        """
81        self.assertRaises(
82                wme.WardModemSetupException,
83                self._state_machine._add_response_function,
84                'no spaces')
85        self.assertRaises(
86                wme.WardModemSetupException,
87                self._state_machine._add_response_function,
88                'MUST_BE_LOWER_CASE')
89        self.assertRaises(
90                wme.WardModemSetupException,
91                self._state_machine._add_response_function,
92                'must_begin_with_wm_response_')
93
94        self._state_machine._add_response_function('wm_response_something')
95
96
97    def test_dispatch_functions(self):
98        """
99        Basic test for the _respond, _update_state and _update_state_and_respond
100        dispatch functions.
101
102        """
103        self._add_response_functions()
104        response_delay_ms  = 30
105        response = self._state_machine.wm_response_1
106        response_arg1 = 1
107        response_arg2 = 'blah'
108        state_update = {'comp1': 'VAL1', 'comp2': 'VAL2'}
109        state_update_delay_ms = 20
110
111        self._task_loop.post_task_after_delay(
112                self._transceiver.process_wardmodem_response, response_delay_ms,
113                response, response_arg1, response_arg2)
114        self._task_loop.post_task_after_delay(
115                self._state_machine._update_state_callback,
116                state_update_delay_ms, state_update, mox.IgnoreArg())
117
118        self._mox.ReplayAll()
119        self._state_machine._respond(response, response_delay_ms, response_arg1,
120                                     response_arg2)
121        self._state_machine._update_state(state_update, state_update_delay_ms)
122        self._mox.VerifyAll()
123
124
125if __name__ == '__main__':
126    logging.basicConfig(level=logging.DEBUG)
127    unittest.main()
128