1 # test.connections - tests for connection manager
3 # Part of WiFi Radar: A utility for managing WiFi profiles on GNU/Linux.
5 # Copyright (C) 2014 Sean Robinson <seankrobinson@gmail.com>
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; version 2 of the License.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License in LICENSE.GPL for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 from signal
import SIGTERM
23 from subprocess
import CalledProcessError
28 import wifiradar
.connections
29 from wifiradar
.config
import ConfigManager
30 from wifiradar
.misc
import DeviceError
33 class TestConnectionManager(unittest
.TestCase
):
35 self
.conn_manager
= wifiradar
.connections
.ConnectionManager(mock
.Mock())
36 self
.mock_config
= mock
.Mock()
37 self
.conn_manager
.config
= self
.mock_config
39 def test_set_config(self
):
40 """ Test set_config method. """
41 self
.assertRaises(TypeError, self
.conn_manager
.set_config
, None)
42 self
.assertEqual(None, self
.conn_manager
.set_config(ConfigManager({})))
44 @mock.patch('wifiradar.misc.shellcmd')
45 def test__run_script(self
, mock_shellcmd
):
46 """ Test _run_script method. """
47 script_name
= 'con_script'
50 essid
= 'WinterPalace'
51 bssid
= '01:02:03:04:05:06'
53 'con_script': 'mysterious_bash_command',
59 self
.conn_manager
.get_current_ip
= mock
.Mock(return_value
=ip
)
60 self
.conn_manager
.get_current_essid
= mock
.Mock(return_value
=essid
)
61 self
.conn_manager
.get_current_bssid
= mock
.Mock(return_value
=bssid
)
63 self
.assertEqual(None,
64 self
.conn_manager
._run
_script
(script_name
, profile
, device
))
68 "WIFIRADAR_ESSID": essid
,
69 "WIFIRADAR_BSSID": bssid
,
70 "WIFIRADAR_PROFILE": '{}:{}'.format(essid
, bssid
),
71 "WIFIRADAR_ENCMODE": 'none',
72 "WIFIRADAR_SECMODE": '',
73 "WIFIRADAR_IF": device
}
74 mock_shellcmd
.assert_called_with(['mysterious_bash_command'],
77 @mock.patch('wifiradar.misc.shellcmd')
78 def test__prepare_nic(self
, mock_shellcmd
):
79 """ Test _prepare_nic method. """
80 self
.mock_config
.get_opt
.return_value
= 'mock_iwconfig'
81 self
.mock_config
.get_opt_as_bool
.return_value
= True
82 essid
= 'WinterPalace'
83 bssid
= '01:02:03:04:05:06'
91 self
.assertEqual(None,
92 self
.conn_manager
._prepare
_nic
(profile
, device
))
93 mock_shellcmd
.assert_called_with(['mock_iwconfig', device
,
94 'essid', "'{}'".format(essid
), 'key', 'off',
95 'mode', 'managed', 'channel', 11, 'ap', bssid
, 'commit'])
98 self
.mock_config
.get_opt
.return_value
= 'mock_iwconfig'
99 self
.mock_config
.get_opt_as_bool
.return_value
= True
100 mock_shellcmd
.side_effect
= CalledProcessError(250, 'mock_iwconfig')
101 self
.assertRaises(DeviceError
,
102 self
.conn_manager
._prepare
_nic
, profile
, device
)
104 @mock.patch('__builtin__.open', )
105 @mock.patch('os.kill')
106 @mock.patch('os.access')
107 @mock.patch('wifiradar.misc.shellcmd')
108 def test__stop_dhcp(self
, mock_shellcmd
, mock_access
, mock_kill
, mock_open
):
109 """ Test _stop_dhcp method. """
112 kill_args_list
= ['-k', '-d']
113 self
.mock_config
.get_opt
.side_effect
= ['mock_pidfile', kill_args
,
115 mock_access
.return_value
= True
118 self
.assertEqual(None, self
.conn_manager
._stop
_dhcp
(device
))
119 call_list
= [dhcp_cmd
]
120 call_list
.extend(kill_args_list
)
121 call_list
.append(device
)
122 mock_shellcmd
.assert_called_with(call_list
)
124 self
.mock_config
.get_opt
.side_effect
= ['mock_pidfile', '',
125 dhcp_cmd
, '', 'mock_pidfile']
127 mock_open
.return_value
.readline
.return_value
= PID
128 self
.assertEqual(None, self
.conn_manager
._stop
_dhcp
(device
))
129 mock_kill
.assert_called_with(PID
, SIGTERM
)
131 @mock.patch('wifiradar.connections.Popen')
132 def test_if_change(self
, mock_popen
):
133 """ Test if_change method. """
134 self
.mock_config
.get_opt
.return_value
= 'mock_ifconfig'
135 self
.mock_config
.get_network_device
.return_value
= 'wlan0'
137 # Test normal operation.
138 self
.assertEqual(None, self
.conn_manager
.if_change('up'))
139 self
.assertEqual(None, self
.conn_manager
.if_change('down'))
140 self
.assertEqual(None, self
.conn_manager
.if_change('UP'))
141 self
.assertEqual(None, self
.conn_manager
.if_change('DOWN'))
143 # Test unknown state.
144 self
.assertRaises(ValueError, self
.conn_manager
.if_change
, 'sideways')
146 # Test failed state change with found ifconfig.
147 mock_popen_instance
= mock
.MagicMock()
148 mock_popen_instance
.stdout
.__iter
__.return_value
= [
149 'wlan0: ERROR while getting interface flags: No such device']
150 mock_popen
.return_value
= mock_popen_instance
151 self
.assertRaises(DeviceError
, self
.conn_manager
.if_change
, 'up')
154 mock_popen
.side_effect
= OSError(2, 'No such file or directory')
155 self
.assertRaises(OSError, self
.conn_manager
.if_change
, 'up')
157 @mock.patch('wifiradar.connections.Popen')
158 def test_get_current_ip(self
, mock_popen
):
159 """ Test get_current_ip method. """
160 self
.mock_config
.get_opt
.return_value
= 'mock_ifconfig'
161 self
.mock_config
.get_network_device
.return_value
= 'wlan0'
163 # Test connected and with an IP address.
164 mock_popen_instance
= mock
.Mock()
165 mock_popen_instance
.stdout
.read
.return_value
= \
166 'wlan0: flags=4098<BROADCAST,MULTICAST> mtu 1500\n' + \
167 'inet addr:192.168.1.1 netmask 255.255.255.0 broadcast 192.168.1.255\n' + \
168 'ether 00:00:00:00:00:00 txqueuelen 1000 (Ethernet)\n' + \
169 'RX packets 246 bytes 259631 (253.5 KiB)\n' + \
170 'RX errors 0 dropped 1 overruns 0 frame 0\n' + \
171 'TX packets 123 bytes 140216 (136.9 KiB)\n' + \
172 'TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0\n'
173 mock_popen
.return_value
= mock_popen_instance
174 self
.assertEqual('192.168.1.1', self
.conn_manager
.get_current_ip())
176 # Test not connected and without an IP address.
177 mock_popen_instance
.stdout
.read
.return_value
= \
178 'wlan0: flags=4098<BROADCAST,MULTICAST> mtu 1500\n' + \
179 'ether 00:00:00:00:00:00 txqueuelen 1000 (Ethernet)\n' + \
180 'RX packets 246 bytes 259631 (253.5 KiB)\n' + \
181 'RX errors 0 dropped 1 overruns 0 frame 0\n' + \
182 'TX packets 123 bytes 140216 (136.9 KiB)\n' + \
183 'TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0\n'
184 mock_popen
.return_value
= mock_popen_instance
185 self
.assertEqual(None, self
.conn_manager
.get_current_ip())
187 @mock.patch('wifiradar.connections.Popen')
188 def test_get_current_essid(self
, mock_popen
):
189 """ Test get_current_essid method. """
190 self
.mock_config
.get_opt
.return_value
= 'mock_iwconfig'
191 self
.mock_config
.get_network_device
.return_value
= 'wlan0'
193 # Test associated interface.
194 mock_popen_instance
= mock
.Mock()
195 mock_popen_instance
.stdout
.read
.return_value
= \
196 'wlan0 IEEE 802.11abgn ESSID:"WinterPalace"\n' + \
197 ' Mode:Managed Frequency:5.26 GHz Access Point: 00:00:00:00:00:00\n' + \
198 ' Tx-Power=15 dBm\n' + \
199 ' Retry long limit:7 RTS thr:off Fragment thr:off\n' + \
200 ' Power Management:off\n'
201 mock_popen
.return_value
= mock_popen_instance
202 self
.assertEqual('WinterPalace', self
.conn_manager
.get_current_essid())
204 # Test not associated interface.
205 mock_popen_instance
= mock
.Mock()
206 mock_popen_instance
.stdout
.read
.return_value
= \
207 'wlan0 IEEE 802.11abgn ESSID:off/any\n' + \
208 ' Mode:Managed Frequency:5.26 GHz Access Point: Not-Associated\n' + \
209 ' Tx-Power=15 dBm\n' + \
210 ' Retry long limit:7 RTS thr:off Fragment thr:off\n' + \
211 ' Power Management:off\n'
212 mock_popen
.return_value
= mock_popen_instance
213 self
.assertEqual(None, self
.conn_manager
.get_current_essid())
215 @mock.patch('wifiradar.connections.Popen')
216 def test_get_current_bssid(self
, mock_popen
):
217 """ Test get_current_bssid method. """
218 self
.mock_config
.get_opt
.return_value
= 'mock_iwconfig'
219 self
.mock_config
.get_network_device
.return_value
= 'wlan0'
221 # Test associated interface.
222 mock_popen_instance
= mock
.Mock()
223 mock_popen_instance
.stdout
.read
.return_value
= \
224 'wlan0 IEEE 802.11abgn ESSID:"WinterPalace"\n' + \
225 ' Mode:Managed Frequency:5.26 GHz Access Point: 00:00:00:00:00:00\n' + \
226 ' Tx-Power=15 dBm\n' + \
227 ' Retry long limit:7 RTS thr:off Fragment thr:off\n' + \
228 ' Power Management:off\n'
230 mock_popen
.return_value
= mock_popen_instance
231 self
.assertEqual('00:00:00:00:00:00', self
.conn_manager
.get_current_bssid())
233 # Test not associated interface.
234 mock_popen_instance
= mock
.Mock()
235 mock_popen_instance
.stdout
.read
.return_value
= \
236 'wlan0 IEEE 802.11abgn ESSID:off/any\n' + \
237 ' Mode:Managed Frequency:5.26 GHz Access Point: Not-Associated\n' + \
238 ' Tx-Power=15 dBm\n' + \
239 ' Retry long limit:7 RTS thr:off Fragment thr:off\n' + \
240 ' Power Management:off\n'
241 mock_popen
.return_value
= mock_popen_instance
242 self
.assertEqual(None, self
.conn_manager
.get_current_bssid())