blob: 8e21fe0f2e29f91f617b155fab68e77f77f8b36f [file] [log] [blame]
markdrdd1893d2018-02-05 17:13:47 -08001#!/usr/bin/env python3
markdra926f252017-04-06 16:14:04 -07002#
3# Copyright 2016 - The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17import copy
18import os
19import tempfile
20import shutil
21import unittest
22
markdrc870cb22017-05-31 11:36:17 -070023from acts.controllers.relay_lib import generic_relay_device
24from acts.controllers.relay_lib import relay
25from acts.controllers.relay_lib import relay_board
26from acts.controllers.relay_lib import relay_device
27from acts.controllers.relay_lib import relay_rig
28from acts.controllers.relay_lib import sain_smart_board
markdr071002b2017-04-21 17:40:52 -070029
30import acts.controllers.relay_lib.errors as errors
31import acts.controllers.relay_lib.fugu_remote as fugu_remote
markdra926f252017-04-06 16:14:04 -070032
markdrc870cb22017-05-31 11:36:17 -070033# Shorthand versions of the long class names.
34GenericRelayDevice = generic_relay_device.GenericRelayDevice
35Relay = relay.Relay
36RelayDict = relay.RelayDict
37RelayState = relay.RelayState
38SynchronizeRelays = relay.SynchronizeRelays
39RelayBoard = relay_board.RelayBoard
40RelayDevice = relay_device.RelayDevice
41RelayRig = relay_rig.RelayRig
42SainSmartBoard = sain_smart_board.SainSmartBoard
markdr1f703662017-09-05 18:01:41 -070043RelayDeviceConnectionError = errors.RelayDeviceConnectionError
markdrc870cb22017-05-31 11:36:17 -070044
markdra926f252017-04-06 16:14:04 -070045
46class MockBoard(RelayBoard):
47 def __init__(self, config):
48 self.relay_states = dict()
49 self.relay_previous_states = dict()
50 RelayBoard.__init__(self, config)
51
52 def get_relay_position_list(self):
53 return [0, 1]
54
55 def get_relay_status(self, relay_position):
56 if relay_position not in self.relay_states:
57 self.relay_states[relay_position] = RelayState.NO
58 self.relay_previous_states[relay_position] = RelayState.NO
59 return self.relay_states[relay_position]
60
61 def set(self, relay_position, state):
62 self.relay_previous_states[relay_position] = self.get_relay_status(
63 relay_position)
64 self.relay_states[relay_position] = state
65 return state
66
67
68class ActsRelayTest(unittest.TestCase):
69 def setUp(self):
70 Relay.transition_wait_time = 0
markdr071002b2017-04-21 17:40:52 -070071 Relay.button_press_time = 0
markdra926f252017-04-06 16:14:04 -070072 self.config = {
73 'name': 'MockBoard',
74 'relays': [{
75 'name': 'Relay',
76 'relay_pos': 0
77 }]
78 }
79 self.board = MockBoard(self.config)
80 self.relay = Relay(self.board, 'Relay')
81 self.board.set(self.relay.position, RelayState.NO)
82
markdr071002b2017-04-21 17:40:52 -070083 def tearDown(self):
84 Relay.transition_wait_time = .2
85 Relay.button_press_time = .25
86
markdra926f252017-04-06 16:14:04 -070087 def test_turn_on_from_off(self):
88 self.board.set(self.relay.position, RelayState.NO)
89 self.relay.set_nc()
90 self.assertEqual(
91 self.board.get_relay_status(self.relay.position), RelayState.NC)
92
93 def test_turn_on_from_on(self):
94 self.board.set(self.relay.position, RelayState.NC)
95 self.relay.set_nc()
96 self.assertEqual(
97 self.board.get_relay_status(self.relay.position), RelayState.NC)
98
99 def test_turn_off_from_on(self):
100 self.board.set(self.relay.position, RelayState.NC)
101 self.relay.set_no()
102 self.assertEqual(
103 self.board.get_relay_status(self.relay.position), RelayState.NO)
104
105 def test_turn_off_from_off(self):
106 self.board.set(self.relay.position, RelayState.NO)
107 self.relay.set_no()
108 self.assertEqual(
109 self.board.get_relay_status(self.relay.position), RelayState.NO)
110
111 def test_toggle_off_to_on(self):
112 self.board.set(self.relay.position, RelayState.NO)
113 self.relay.toggle()
114 self.assertEqual(
115 self.board.get_relay_status(self.relay.position), RelayState.NC)
116
117 def test_toggle_on_to_off(self):
118 self.board.set(self.relay.position, RelayState.NC)
119 self.relay.toggle()
120 self.assertEqual(
121 self.board.get_relay_status(self.relay.position), RelayState.NO)
122
123 def test_set_on(self):
124 self.board.set(self.relay.position, RelayState.NO)
125 self.relay.set(RelayState.NC)
126 self.assertEqual(
127 self.board.get_relay_status(self.relay.position), RelayState.NC)
128
129 def test_set_off(self):
130 self.board.set(self.relay.position, RelayState.NC)
131 self.relay.set(RelayState.NO)
132 self.assertEqual(
133 self.board.get_relay_status(self.relay.position), RelayState.NO)
134
135 def test_set_foo(self):
136 with self.assertRaises(ValueError):
137 self.relay.set('FOO')
138
139 def test_set_nc_for(self):
140 # Here we set twice so relay_previous_state will also be OFF
141 self.board.set(self.relay.position, RelayState.NO)
142 self.board.set(self.relay.position, RelayState.NO)
143
144 self.relay.set_nc_for(0)
145
146 self.assertEqual(
147 self.board.get_relay_status(self.relay.position), RelayState.NO)
148 self.assertEqual(self.board.relay_previous_states[self.relay.position],
149 RelayState.NC)
150
151 def test_set_no_for(self):
152 # Here we set twice so relay_previous_state will also be OFF
153 self.board.set(self.relay.position, RelayState.NC)
154 self.board.set(self.relay.position, RelayState.NC)
155
156 self.relay.set_no_for(0)
157
158 self.assertEqual(
159 self.board.get_relay_status(self.relay.position), RelayState.NC)
160 self.assertEqual(self.board.relay_previous_states[self.relay.position],
161 RelayState.NO)
162
163 def test_get_status_on(self):
164 self.board.set(self.relay.position, RelayState.NC)
165 self.assertEqual(self.relay.get_status(), RelayState.NC)
166
167 def test_get_status_off(self):
168 self.board.set(self.relay.position, RelayState.NO)
169 self.assertEqual(self.relay.get_status(), RelayState.NO)
170
171 def test_clean_up_default_on(self):
172 new_relay = Relay(self.board, 0)
markdrb79a34f2017-08-29 12:05:40 -0700173 new_relay._original_state = RelayState.NO
markdra926f252017-04-06 16:14:04 -0700174 self.board.set(new_relay.position, RelayState.NO)
175 new_relay.clean_up()
176
177 self.assertEqual(
178 self.board.get_relay_status(new_relay.position), RelayState.NO)
179
180 def test_clean_up_default_off(self):
181 new_relay = Relay(self.board, 0)
markdrb79a34f2017-08-29 12:05:40 -0700182 new_relay._original_state = RelayState.NO
markdra926f252017-04-06 16:14:04 -0700183 self.board.set(new_relay.position, RelayState.NC)
184 new_relay.clean_up()
185
186 self.assertEqual(
187 self.board.get_relay_status(new_relay.position), RelayState.NO)
188
markdrb79a34f2017-08-29 12:05:40 -0700189 def test_clean_up_original_state_none(self):
190 val = 'STAYS_THE_SAME'
191 new_relay = Relay(self.board, 0)
192 # _original_state is none by default
193 # The line below sets the dict to an impossible value.
194 self.board.set(new_relay.position, val)
195 new_relay.clean_up()
196 # If the impossible value is cleared, then the test should fail.
197 self.assertEqual(self.board.get_relay_status(new_relay.position), val)
198
markdra926f252017-04-06 16:14:04 -0700199
200class ActsSainSmartBoardTest(unittest.TestCase):
201 STATUS_MSG = ('<small><a href="{}"></a>'
202 '</small><a href="{}/{}TUX">{}TUX</a><p>')
203
204 RELAY_ON_PAGE_CONTENTS = 'relay_on page'
205 RELAY_OFF_PAGE_CONTENTS = 'relay_off page'
206
207 def setUp(self):
208 Relay.transition_wait_time = 0
markdr071002b2017-04-21 17:40:52 -0700209 Relay.button_press_time = 0
markdra926f252017-04-06 16:14:04 -0700210 self.test_dir = 'file://' + tempfile.mkdtemp() + '/'
211
212 # Creates the files used for testing
213 self._set_status_page('0000000000000000')
214 with open(self.test_dir[7:] + '00', 'w+') as file:
215 file.write(self.RELAY_OFF_PAGE_CONTENTS)
216 with open(self.test_dir[7:] + '01', 'w+') as file:
217 file.write(self.RELAY_ON_PAGE_CONTENTS)
218
219 self.config = ({
markdr3e5d31b2017-08-29 14:06:49 -0700220 'name': 'SSBoard',
221 'base_url': self.test_dir,
markdra926f252017-04-06 16:14:04 -0700222 'relays': [{
223 'name': '0',
224 'relay_pos': 0
225 }, {
226 'name': '1',
227 'relay_pos': 1
228 }, {
229 'name': '2',
230 'relay_pos': 7
231 }]
232 })
233 self.ss_board = SainSmartBoard(self.config)
234 self.r0 = Relay(self.ss_board, 0)
235 self.r1 = Relay(self.ss_board, 1)
236 self.r7 = Relay(self.ss_board, 7)
237
238 def tearDown(self):
239 shutil.rmtree(self.test_dir[7:])
markdr071002b2017-04-21 17:40:52 -0700240 Relay.transition_wait_time = .2
241 Relay.button_press_time = .25
markdra926f252017-04-06 16:14:04 -0700242
243 def test_get_url_code(self):
244 result = self.ss_board._get_relay_url_code(self.r0.position,
245 RelayState.NO)
246 self.assertEqual(result, '00')
247
248 result = self.ss_board._get_relay_url_code(self.r0.position,
249 RelayState.NC)
250 self.assertEqual(result, '01')
251
252 result = self.ss_board._get_relay_url_code(self.r7.position,
253 RelayState.NO)
254 self.assertEqual(result, '14')
255
256 result = self.ss_board._get_relay_url_code(self.r7.position,
257 RelayState.NC)
258 self.assertEqual(result, '15')
259
260 def test_load_page_status(self):
261 self._set_status_page('0000111100001111')
262 result = self.ss_board._load_page(SainSmartBoard.HIDDEN_STATUS_PAGE)
263 self.assertTrue(
264 result.endswith(
265 '0000111100001111TUX">0000111100001111TUX</a><p>'))
266
267 def test_load_page_relay(self):
268 result = self.ss_board._load_page('00')
269 self.assertEqual(result, self.RELAY_OFF_PAGE_CONTENTS)
270
271 result = self.ss_board._load_page('01')
272 self.assertEqual(result, self.RELAY_ON_PAGE_CONTENTS)
273
274 def test_load_page_no_connection(self):
275 with self.assertRaises(errors.RelayDeviceConnectionError):
276 self.ss_board._load_page('**')
277
278 def _set_status_page(self, status_16_chars):
279 with open(self.test_dir[7:] + '99', 'w+') as status_file:
280 status_file.write(
281 self.STATUS_MSG.format(self.test_dir[:-1], self.test_dir[:-1],
282 status_16_chars, status_16_chars))
283
284 def _test_sync_status_dict(self, status_16_chars):
285 self._set_status_page(status_16_chars)
286 expected_dict = dict()
287
288 for index, char in enumerate(status_16_chars):
289 expected_dict[
290 index] = RelayState.NC if char == '1' else RelayState.NO
291
292 self.ss_board._sync_status_dict()
293 self.assertDictEqual(expected_dict, self.ss_board.status_dict)
294
295 def test_sync_status_dict(self):
296 self._test_sync_status_dict('0000111100001111')
297 self._test_sync_status_dict('0000000000000000')
298 self._test_sync_status_dict('0101010101010101')
299 self._test_sync_status_dict('1010101010101010')
300 self._test_sync_status_dict('1111111111111111')
301
302 def test_get_relay_status_status_dict_none(self):
303 self._set_status_page('1111111111111111')
304 self.ss_board.status_dict = None
305 self.assertEqual(
306 self.ss_board.get_relay_status(self.r0.position), RelayState.NC)
307
308 def test_get_relay_status_status_dict_on(self):
309 self.r0.set(RelayState.NC)
310 self.assertEqual(
311 self.ss_board.get_relay_status(self.r0.position), RelayState.NC)
312
313 def test_get_relay_status_status_dict_off(self):
314 self.r0.set(RelayState.NO)
315 self.assertEqual(
316 self.ss_board.get_relay_status(self.r0.position), RelayState.NO)
317
318 def test_set_on(self):
319 os.utime(self.test_dir[7:] + '01', (0, 0))
320 self.ss_board.set(self.r0.position, RelayState.NC)
321 self.assertNotEqual(os.stat(self.test_dir[7:] + '01').st_atime, 0)
322
323 def test_set_off(self):
324 os.utime(self.test_dir[7:] + '00', (0, 0))
325 self.ss_board.set(self.r0.position, RelayState.NO)
326 self.assertNotEqual(os.stat(self.test_dir[7:] + '00').st_atime, 0)
327
markdr1f703662017-09-05 18:01:41 -0700328 def test_connection_error_no_tux(self):
329 default_status_msg = self.STATUS_MSG
330 self.STATUS_MSG = self.STATUS_MSG.replace('TUX', '')
331 try:
332 self._set_status_page('1111111111111111')
333 self.ss_board.get_relay_status(0)
334 except RelayDeviceConnectionError:
335 self.STATUS_MSG = default_status_msg
336 return
337
338 self.fail('Should have thrown an error without TUX appearing.')
339
markdra926f252017-04-06 16:14:04 -0700340
341class ActsRelayRigTest(unittest.TestCase):
342 def setUp(self):
343 Relay.transition_wait_time = 0
markdr071002b2017-04-21 17:40:52 -0700344 Relay.button_press_time = 0
markdra926f252017-04-06 16:14:04 -0700345 self.config = {
346 'boards': [{
347 'type': 'SainSmartBoard',
348 'name': 'ss_control',
349 'base_url': 'http://192.168.1.4/30000/'
350 }, {
351 'type': 'SainSmartBoard',
352 'name': 'ss_control_2',
353 'base_url': 'http://192.168.1.4/30000/'
354 }],
355 'devices': [{
markdr37b9f352017-04-28 10:23:13 -0700356 'type': 'GenericRelayDevice',
357 'name': 'device',
358 'relays': {
359 'Relay00': 'ss_control/0',
360 'Relay10': 'ss_control/1'
361 }
markdra926f252017-04-06 16:14:04 -0700362 }]
363 }
364
markdr071002b2017-04-21 17:40:52 -0700365 def tearDown(self):
366 Relay.transition_wait_time = .2
367 Relay.button_press_time = .25
368
markdra926f252017-04-06 16:14:04 -0700369 def test_init_relay_rig_missing_boards(self):
370 flawed_config = copy.deepcopy(self.config)
371 del flawed_config['boards']
372 with self.assertRaises(errors.RelayConfigError):
373 RelayRig(flawed_config)
374
375 def test_init_relay_rig_is_not_list(self):
376 flawed_config = copy.deepcopy(self.config)
377 flawed_config['boards'] = self.config['boards'][0]
378 with self.assertRaises(errors.RelayConfigError):
379 RelayRig(flawed_config)
380
381 def test_init_relay_rig_duplicate_board_names(self):
382 flawed_config = copy.deepcopy(self.config)
383 flawed_config['boards'][1]['name'] = (self.config['boards'][0]['name'])
384 with self.assertRaises(errors.RelayConfigError):
385 RelayRigMock(flawed_config)
386
387 def test_init_relay_rig_device_gets_relays(self):
388 modded_config = copy.deepcopy(self.config)
markdr37b9f352017-04-28 10:23:13 -0700389 del modded_config['devices'][0]['relays']['Relay00']
markdrc870cb22017-05-31 11:36:17 -0700390 rig = RelayRigMock(modded_config)
391 self.assertEqual(len(rig.relays), 4)
392 self.assertEqual(len(rig.devices['device'].relays), 1)
markdra926f252017-04-06 16:14:04 -0700393
markdrc870cb22017-05-31 11:36:17 -0700394 rig = RelayRigMock(self.config)
395 self.assertEqual(len(rig.devices['device'].relays), 2)
markdra926f252017-04-06 16:14:04 -0700396
397 def test_init_relay_rig_correct_device_type(self):
markdrc870cb22017-05-31 11:36:17 -0700398 rig = RelayRigMock(self.config)
399 self.assertEqual(len(rig.devices), 1)
400 self.assertIsInstance(rig.devices['device'], GenericRelayDevice)
markdra926f252017-04-06 16:14:04 -0700401
402 def test_init_relay_rig_missing_devices_creates_generic_device(self):
403 modded_config = copy.deepcopy(self.config)
404 del modded_config['devices']
markdrc870cb22017-05-31 11:36:17 -0700405 rig = RelayRigMock(modded_config)
406 self.assertEqual(len(rig.devices), 1)
407 self.assertIsInstance(rig.devices['device'], GenericRelayDevice)
408 self.assertDictEqual(rig.devices['device'].relays, rig.relays)
markdra926f252017-04-06 16:14:04 -0700409
410
411class RelayRigMock(RelayRig):
412 """A RelayRig that substitutes the MockBoard for any board."""
413
414 _board_constructors = {
415 'SainSmartBoard': lambda x: MockBoard(x),
markdr071002b2017-04-21 17:40:52 -0700416 'FuguMockBoard': lambda x: FuguMockBoard(x)
markdra926f252017-04-06 16:14:04 -0700417 }
418
419 def __init__(self, config=None):
420 if not config:
421 config = {
422 "boards": [{
423 'name': 'MockBoard',
424 'type': 'SainSmartBoard'
425 }]
426 }
427
428 RelayRig.__init__(self, config)
429
430
431class ActsGenericRelayDeviceTest(unittest.TestCase):
432 def setUp(self):
433 Relay.transition_wait_time = 0
markdr071002b2017-04-21 17:40:52 -0700434 Relay.button_press_time = 0
markdra926f252017-04-06 16:14:04 -0700435 self.board_config = {'name': 'MockBoard', 'type': 'SainSmartBoard'}
436
437 self.board = MockBoard(self.board_config)
438 self.r0 = self.board.relays[0]
439 self.r1 = self.board.relays[1]
440
441 self.device_config = {
markdr37b9f352017-04-28 10:23:13 -0700442 'name': 'MockDevice',
443 'relays': {
444 'r0': 'MockBoard/0',
445 'r1': 'MockBoard/1'
446 }
markdra926f252017-04-06 16:14:04 -0700447 }
448 config = {
449 'boards': [self.board_config],
450 'devices': [self.device_config]
451 }
452 self.rig = RelayRigMock(config)
453 self.rig.boards['MockBoard'] = self.board
454 self.rig.relays[self.r0.relay_id] = self.r0
455 self.rig.relays[self.r1.relay_id] = self.r1
456
markdr071002b2017-04-21 17:40:52 -0700457 def tearDown(self):
458 Relay.transition_wait_time = .2
459 Relay.button_press_time = .25
460
markdra926f252017-04-06 16:14:04 -0700461 def test_setup_single_relay(self):
462 self.r0.set(RelayState.NC)
463 self.r1.set(RelayState.NC)
464
465 modified_config = copy.deepcopy(self.device_config)
markdr37b9f352017-04-28 10:23:13 -0700466 del modified_config['relays']['r1']
markdra926f252017-04-06 16:14:04 -0700467
markdrc870cb22017-05-31 11:36:17 -0700468 grd = GenericRelayDevice(modified_config, self.rig)
469 grd.setup()
markdra926f252017-04-06 16:14:04 -0700470
471 self.assertEqual(self.r0.get_status(), RelayState.NO)
472 self.assertEqual(self.r1.get_status(), RelayState.NC)
473
474 def test_setup_multiple_relays(self):
475 self.board.set(self.r0.position, RelayState.NC)
476 self.board.set(self.r1.position, RelayState.NC)
477
markdrc870cb22017-05-31 11:36:17 -0700478 grd = GenericRelayDevice(self.device_config, self.rig)
479 grd.setup()
markdra926f252017-04-06 16:14:04 -0700480
481 self.assertEqual(self.r0.get_status(), RelayState.NO)
482 self.assertEqual(self.r1.get_status(), RelayState.NO)
483
484 def test_cleanup_single_relay(self):
485 self.test_setup_single_relay()
486
487 def test_cleanup_multiple_relays(self):
488 self.test_setup_multiple_relays()
489
markdr071002b2017-04-21 17:40:52 -0700490 def change_state(self, begin_state, call, end_state, previous_state=None):
491 self.board.set(self.r0.position, begin_state)
markdrc870cb22017-05-31 11:36:17 -0700492 grd = GenericRelayDevice(self.device_config, self.rig)
493 call(grd)
markdr071002b2017-04-21 17:40:52 -0700494 self.assertEqual(self.r0.get_status(), end_state)
495 if previous_state:
496 self.assertEqual(
497 self.board.relay_previous_states[self.r0.position],
498 previous_state)
499
500 def test_press_while_no(self):
501 self.change_state(RelayState.NO, lambda x: x.press('r0'),
502 RelayState.NO, RelayState.NC)
503
504 def test_press_while_nc(self):
505 self.change_state(RelayState.NC, lambda x: x.press('r0'),
506 RelayState.NO, RelayState.NC)
507
508 def test_hold_down_while_no(self):
509 self.change_state(RelayState.NO, lambda x: x.hold_down('r0'),
510 RelayState.NC)
511
512 def test_hold_down_while_nc(self):
513 self.change_state(RelayState.NC, lambda x: x.hold_down('r0'),
514 RelayState.NC)
515
516 def test_release_while_nc(self):
517 self.change_state(RelayState.NC, lambda x: x.release('r0'),
518 RelayState.NO)
519
markdra926f252017-04-06 16:14:04 -0700520
521class ActsRelayDeviceTest(unittest.TestCase):
522 def setUp(self):
523 Relay.transition_wait_time = 0
markdr071002b2017-04-21 17:40:52 -0700524 Relay.button_press_time = 0
markdra926f252017-04-06 16:14:04 -0700525
526 self.board_config = {
527 'name': 'MockBoard',
528 'relays': [{
529 'id': 0,
530 'relay_pos': 0
531 }, {
532 'id': 1,
533 'relay_pos': 1
534 }]
535 }
536
537 self.board = MockBoard(self.board_config)
538 self.r0 = Relay(self.board, 0)
539 self.r1 = Relay(self.board, 1)
540 self.board.set(self.r0.position, RelayState.NO)
541 self.board.set(self.r1.position, RelayState.NO)
542
543 self.rig = RelayRigMock()
544 self.rig.boards['MockBoard'] = self.board
545 self.rig.relays[self.r0.relay_id] = self.r0
546 self.rig.relays[self.r1.relay_id] = self.r1
547
548 self.device_config = {
markdr37b9f352017-04-28 10:23:13 -0700549 "type": "GenericRelayDevice",
550 "name": "device",
551 "relays": {
552 'r0': 'MockBoard/0',
553 'r1': 'MockBoard/1'
554 }
markdra926f252017-04-06 16:14:04 -0700555 }
556
markdr071002b2017-04-21 17:40:52 -0700557 def tearDown(self):
558 Relay.transition_wait_time = .2
559 Relay.button_press_time = .25
560
markdra926f252017-04-06 16:14:04 -0700561 def test_init_raise_on_name_missing(self):
562 flawed_config = copy.deepcopy(self.device_config)
563 del flawed_config['name']
564 with self.assertRaises(errors.RelayConfigError):
565 RelayDevice(flawed_config, self.rig)
566
567 def test_init_raise_on_name_wrong_type(self):
568 flawed_config = copy.deepcopy(self.device_config)
569 flawed_config['name'] = {}
570 with self.assertRaises(errors.RelayConfigError):
571 RelayDevice(flawed_config, self.rig)
572
573 def test_init_raise_on_relays_missing(self):
574 flawed_config = copy.deepcopy(self.device_config)
575 del flawed_config['relays']
576 with self.assertRaises(errors.RelayConfigError):
577 RelayDevice(flawed_config, self.rig)
578
579 def test_init_raise_on_relays_wrong_type(self):
580 flawed_config = copy.deepcopy(self.device_config)
581 flawed_config['relays'] = str
582 with self.assertRaises(errors.RelayConfigError):
583 RelayDevice(flawed_config, self.rig)
584
585 def test_init_raise_on_relays_is_empty(self):
586 flawed_config = copy.deepcopy(self.device_config)
587 flawed_config['relays'] = []
588 with self.assertRaises(errors.RelayConfigError):
589 RelayDevice(flawed_config, self.rig)
590
591 def test_init_raise_on_relays_are_dicts_without_names(self):
592 flawed_config = copy.deepcopy(self.device_config)
593 flawed_config['relays'] = [{'id': 0}, {'id': 1}]
594 with self.assertRaises(errors.RelayConfigError):
595 RelayDevice(flawed_config, self.rig)
596
597 def test_init_raise_on_relays_are_dicts_without_ids(self):
598 flawed_config = copy.deepcopy(self.device_config)
599 flawed_config['relays'] = [{'name': 'r0'}, {'name': 'r1'}]
600 with self.assertRaises(errors.RelayConfigError):
601 RelayDevice(flawed_config, self.rig)
602
603 def test_init_pass_relays_have_ids_and_names(self):
604 RelayDevice(self.device_config, self.rig)
605
606
607class TestRelayRigParser(unittest.TestCase):
608 def setUp(self):
609 Relay.transition_wait_time = 0
markdr071002b2017-04-21 17:40:52 -0700610 Relay.button_press_time = 0
markdra926f252017-04-06 16:14:04 -0700611 self.board_config = {
612 'name': 'MockBoard',
613 'relays': [{
614 'id': 'r0',
615 'relay_pos': 0
616 }, {
617 'id': 'r1',
618 'relay_pos': 1
619 }]
620 }
621 self.r0 = self.board_config['relays'][0]
622 self.r1 = self.board_config['relays'][1]
623 self.board = MockBoard(self.board_config)
624
markdr071002b2017-04-21 17:40:52 -0700625 def tearDown(self):
626 Relay.transition_wait_time = .2
627 Relay.button_press_time = .25
628
markdra926f252017-04-06 16:14:04 -0700629 def test_create_relay_board_raise_on_missing_type(self):
630 with self.assertRaises(errors.RelayConfigError):
631 RelayRigMock().create_relay_board(self.board_config)
632
633 def test_create_relay_board_valid_config(self):
634 config = copy.deepcopy(self.board_config)
635 config['type'] = 'SainSmartBoard'
markdra926f252017-04-06 16:14:04 -0700636 RelayRigMock().create_relay_board(config)
637
638 def test_create_relay_board_raise_on_type_not_found(self):
639 flawed_config = copy.deepcopy(self.board_config)
640 flawed_config['type'] = 'NonExistentBoard'
641 with self.assertRaises(errors.RelayConfigError):
642 RelayRigMock().create_relay_board(flawed_config)
643
644 def test_create_relay_device_create_generic_on_missing_type(self):
645 rig = RelayRigMock()
646 rig.relays['r0'] = self.r0
647 rig.relays['r1'] = self.r1
648 config = {
markdr37b9f352017-04-28 10:23:13 -0700649 'name': 'name',
650 'relays': {
651 'r0': 'MockBoard/0',
652 'r1': 'MockBoard/1'
653 }
markdra926f252017-04-06 16:14:04 -0700654 }
markdrc870cb22017-05-31 11:36:17 -0700655 device = rig.create_relay_device(config)
656 self.assertIsInstance(device, GenericRelayDevice)
markdra926f252017-04-06 16:14:04 -0700657
658 def test_create_relay_device_config_with_type(self):
659 rig = RelayRigMock()
660 rig.relays['r0'] = self.r0
661 rig.relays['r1'] = self.r1
662 config = {
markdr37b9f352017-04-28 10:23:13 -0700663 'type': 'GenericRelayDevice',
664 'name': '.',
665 'relays': {
666 'r0': 'MockBoard/0',
667 'r1': 'MockBoard/1'
668 }
markdra926f252017-04-06 16:14:04 -0700669 }
markdrc870cb22017-05-31 11:36:17 -0700670 device = rig.create_relay_device(config)
671 self.assertIsInstance(device, GenericRelayDevice)
markdra926f252017-04-06 16:14:04 -0700672
673 def test_create_relay_device_raise_on_type_not_found(self):
674 rig = RelayRigMock()
675 rig.relays['r0'] = self.r0
676 rig.relays['r1'] = self.r1
677 config = {
markdr3e5d31b2017-08-29 14:06:49 -0700678 'type': 'SomeInvalidType',
679 'name': '.',
markdra926f252017-04-06 16:14:04 -0700680 'relays': [{
681 'name': 'r0',
682 'pos': 'MockBoard/0'
683 }, {
684 'name': 'r1',
685 'pos': 'MockBoard/1'
686 }]
687 }
688 with self.assertRaises(errors.RelayConfigError):
689 rig.create_relay_device(config)
690
691
692class TestSynchronizeRelays(unittest.TestCase):
693 def test_synchronize_relays(self):
694 Relay.transition_wait_time = .1
695 with SynchronizeRelays():
696 self.assertEqual(Relay.transition_wait_time, 0)
697 self.assertEqual(Relay.transition_wait_time, .1)
698
699
markdr071002b2017-04-21 17:40:52 -0700700class FuguMockBoard(MockBoard):
701 def get_relay_position_list(self):
702 return range(4)
703
704
705class TestFuguRemote(unittest.TestCase):
706 def setUp(self):
707 Relay.transition_wait_time = 0
708 self.mock_rig = RelayRigMock({
709 "boards": [{
710 'name': 'MockBoard',
711 'type': 'FuguMockBoard'
712 }]
713 })
714 self.mock_board = self.mock_rig.boards['MockBoard']
715 self.fugu_config = {
markdreec70e12017-08-05 03:22:29 -0700716 'type': 'FuguRemote',
markdr8fcd9862017-05-01 12:17:48 -0700717 'name': 'UniqueDeviceName',
markdr955dae22017-05-09 15:43:21 -0700718 'mac_address': '00:00:00:00:00:00',
markdr8fcd9862017-05-01 12:17:48 -0700719 'relays': {
720 'Power': 'MockBoard/0',
721 fugu_remote.Buttons.BACK.value: 'MockBoard/1',
722 fugu_remote.Buttons.HOME.value: 'MockBoard/2',
723 fugu_remote.Buttons.PLAY_PAUSE.value: 'MockBoard/3'
724 }
markdr071002b2017-04-21 17:40:52 -0700725 }
726 Relay.button_press_time = 0
727
728 def tearDown(self):
729 Relay.button_press_time = .25
730 Relay.transition_wait_time = .2
731
732 def test_config_missing_button(self):
733 """FuguRemote __init__ should throw an error if a relay is missing."""
734 flawed_config = copy.deepcopy(self.fugu_config)
markdr8fcd9862017-05-01 12:17:48 -0700735 del flawed_config['relays']['Power']
736 del flawed_config['relays'][fugu_remote.Buttons.BACK.value]
markdr071002b2017-04-21 17:40:52 -0700737 with self.assertRaises(errors.RelayConfigError):
738 fugu_remote.FuguRemote(flawed_config, self.mock_rig)
739
markdr955dae22017-05-09 15:43:21 -0700740 def test_config_missing_mac_address(self):
741 """FuguRemote __init__ should throw an error without a mac address."""
742 flawed_config = copy.deepcopy(self.fugu_config)
743 del flawed_config['mac_address']
744 with self.assertRaises(errors.RelayConfigError):
745 fugu_remote.FuguRemote(flawed_config, self.mock_rig)
746
markdr071002b2017-04-21 17:40:52 -0700747 def test_config_no_issues(self):
748 """FuguRemote __init__ should not throw errors for a correct config."""
749 fugu_remote.FuguRemote(self.fugu_config, self.mock_rig)
750
751 def test_power_nc_after_setup(self):
752 """Power should be NORMALLY_CLOSED after calling setup if it exists."""
753 fugu = fugu_remote.FuguRemote(self.fugu_config, self.mock_rig)
754 fugu.setup()
755 self.assertEqual(self.mock_board.get_relay_status(0), RelayState.NC)
756 pass
757
758 def press_button_success(self, relay_position):
759 self.assertEqual(self.mock_board.relay_states[relay_position],
760 RelayState.NO)
761 self.assertEqual(self.mock_board.relay_previous_states[relay_position],
762 RelayState.NC)
763
764 def test_press_play_pause(self):
765 fugu = fugu_remote.FuguRemote(self.fugu_config, self.mock_rig)
766 fugu.press_play_pause()
767 self.press_button_success(3)
768
769 def test_press_back(self):
770 fugu = fugu_remote.FuguRemote(self.fugu_config, self.mock_rig)
771 fugu.press_back()
772 self.press_button_success(1)
773
774 def test_press_home(self):
775 fugu = fugu_remote.FuguRemote(self.fugu_config, self.mock_rig)
776 fugu.press_home()
777 self.press_button_success(2)
778
779 def test_enter_pairing_mode(self):
780 fugu = fugu_remote.FuguRemote(self.fugu_config, self.mock_rig)
781 fugu_remote.PAIRING_MODE_WAIT_TIME = 0
782 fugu.enter_pairing_mode()
783 self.press_button_success(2)
784 self.press_button_success(1)
785
786
markdr8fcd9862017-05-01 12:17:48 -0700787class TestRelayDict(unittest.TestCase):
788 def test_init(self):
789 mock_device = object()
790 blank_dict = dict()
791 relay_dict = RelayDict(mock_device, blank_dict)
792 self.assertEqual(relay_dict._store, blank_dict)
793 self.assertEqual(relay_dict.relay_device, mock_device)
794
795 def test_get_item_valid_key(self):
796 mock_device = object()
797 blank_dict = {'key': 'value'}
798 relay_dict = RelayDict(mock_device, blank_dict)
799 self.assertEqual(relay_dict['key'], 'value')
800
801 def test_get_item_invalid_key(self):
802 # Create an object with a single attribute 'name'
803 mock_device = type('', (object, ), {'name': 'name'})()
804 blank_dict = {'key': 'value'}
805 relay_dict = RelayDict(mock_device, blank_dict)
806 with self.assertRaises(errors.RelayConfigError):
807 value = relay_dict['not_key']
808
809 def test_iter(self):
810 mock_device = type('', (object, ), {'name': 'name'})()
811 data_dict = {'a': '1', 'b': '2', 'c': '3'}
812 relay_dict = RelayDict(mock_device, data_dict)
813
814 rd_set = set()
815 for key in relay_dict:
816 rd_set.add(key)
817 dd_set = set()
818 for key in data_dict:
819 dd_set.add(key)
820
821 self.assertSetEqual(rd_set, dd_set)
822
823
markdra926f252017-04-06 16:14:04 -0700824if __name__ == "__main__":
825 unittest.main()