def test_tx_id_exhaustion(pubmock): pubmock.reset_mock() attrs = {"addr": "0011223344556677"} mgr = XBeeEventManager(registry) pollermock = mgr.poller pollermock.poll.return_value = [(mgr.socket.fileno.return_value, selectmock.POLLOUT)] # Get the listener from subscribe's last call listener = get_listener(pubmock) assert listener is not None # Create command object el = Element("send_serial", attrib=attrs) el.text = "1234" rsp = Mock() for _ in xrange(255): listener(element=el, response=rsp) eq_(rsp.put.call_count, 1) rsp.put.assert_called_once_with(ResponsePending) rsp.reset_mock() # tx_callbacks should contain entries for range [1,255] inclusive # Push it over the limit listener(element=el, response=rsp) eq_(rsp.put.call_count, 1) r = rsp.put.call_args[0][0] assert_command_error(r, "Too many outstanding transmits")
def test_empty_poll_result(pubmock): pubmock.reset_mock() mgr = DDOEventManager() # Make manager's poller.poll return an empty list mgr.poller.poll.return_value = [] # Get the listener from subscribe's last call listener = get_dout_listener(pubmock) assert listener is not None attrs = {'addr': '123456', 'index': '1'} el = Element("set_digital_output", attrib=attrs) el.text = "low" response = Mock() listener(element=el, response=response) eq_(response.put.call_count, 1) # Extract the listener's response r = response.put.call_args[0][0] assert_command_error(r, errors['txfailed'], "No poll events returned") # Check that we never reached the socket.sendto call assert not sockmock.return_value.sendto.called
def test_socket_unavailable_on_poll(pubmock): pubmock.reset_mock() mgr = DDOEventManager() # Make manager's poller.poll return a non-empty list which does not include # the manager socket's fileno mgr.poller.poll.return_value = [(-1, selectmock.POLLOUT)] # Get the listener from subscribe's last call listener = get_dout_listener(pubmock) assert listener is not None attrs = {'addr': '123456', 'index': '1'} el = Element("set_digital_output", attrib=attrs) el.text = "low" response = Mock() listener(element=el, response=response) eq_(response.put.call_count, 1) # Extract the listener's response r = response.put.call_args[0][0] errmsg = "Socket not available for write" assert_command_error(r, errors['txfailed'], errmsg) # Check that we never reached the socket.sendto call assert not sockmock.return_value.sendto.called
def test_tx_id_exhaustion(pubmock): pubmock.reset_mock() mgr = DDOEventManager() # Fill manager's status callbacks # (Get the manager's TxStatusCallbacks object and fill it manually. This is # easier than, say, calling the pubsub listener for set_digital_output 255 # times) callbacks = mgr.tx_callbacks cb = lambda *a: None for _ in xrange(255): callbacks.add_callback(cb) # Now, get the pubsub listener, send a set_digital_output command, check # the return value. listener = get_dout_listener(pubmock) # Command object attrs = {'addr': '123456', 'name': "DIO4"} el = Element("set_digital_output", attrib=attrs) el.text = "high" rsp_mock = Mock(name="response queue mock") listener(element=el, response=rsp_mock) assert rsp_mock.put.call_count == 1 response = rsp_mock.put.call_args[0][0] assert_command_error(response, "Too many outstanding transmits")
def test_with_raised_error(pubmock): DDOEventManager() # Get the listener from subscribe's last call listener = get_dout_listener(pubmock) assert listener is not None el = Element("set_digital_output") el.set("addr", "0011223344556677") el.set("index", "5") el.text = "on" old_se = sockmock.return_value.sendto.side_effect sockmock.return_value.sendto.side_effect = Exception("-- exc --") response = Mock() listener(element=el, response=response) assert response.put.call_count == 1 assert sockmock.return_value.sendto.called # Extract the listener's response r = response.put.call_args[0][0] print tostring(r) assert_command_error(r, errors['txfailed'], sockmock.return_value.sendto.side_effect.message) # Reset the side effect sockmock.return_value.sendto.side_effect = old_se
def test_no_response(): with captured_callback() as cb, captured_queue(): # UUT keeps the reference alive for CB handling # pylint: disable=unused-variable uut = RCICommandProcessor() rtn = cb("<test/>") root = ET.fromstring(rtn) assert_that(root.tag, equal_to("responses")) assert_that(root.get("command"), equal_to("test")) assert_that(len(root), equal_to(1)) # Single response assert_command_error(root[0], "Command not handled")
def do_status_error(pubmock, addr, name, status, message, hint=None): pubmock.reset_mock() mgr = DDOEventManager() # Get the listener from subscribe's last call listener = get_dout_listener(pubmock) assert listener is not None attrs = {'addr': addr, 'name': name} el = Element("set_digital_output", attrib=attrs) el.text = "low" response = Mock() listener(element=el, response=response) eq_(response.put.call_count, 1) assert mgr.socket.sendto.called # Extract the transaction ID sent_addr = mgr.socket.sendto.call_args[0][1] tx_id = sent_addr[-1] assert response.put.call_args[0][0] is ResponsePending response.reset_mock() # Normalize the input address, because recvfrom() return values have the # normalized addresses. recv_addr = normalize_ieee_address(addr) mgr.socket.recvfrom.return_value = ("", (recv_addr, name, 0, tx_id, status)) # Trigger a read on the socket mgr.handle_read() eq_(response.put.call_count, 1) r = response.put.call_args[0][0] assert isinstance(r, DeferredResponse) print r.response assert_command_error(r.response, message, hint)
def do_error_starts_with(pubmock, message, attrs={}, text="", hint=None): pubmock.reset_mock() DDOEventManager() # Get the listener from subscribe's last call listener = get_dout_listener(pubmock) assert listener is not None el = Element("set_digital_output", attrib=attrs) el.text = text response = Mock() listener(element=el, response=response) eq_(response.put.call_count, 1) # Extract the listener's response r = response.put.call_args[0][0] assert_command_error(r, message, hint) # Check that we never reached the socket.sendto call assert not sockmock.return_value.sendto.called
def test_socket_error(pubmock): pubmock.reset_mock() mgr = DDOEventManager() # Make the socket appear to be ready for writing mgr.poller.poll.return_value = [(mgr.socket.fileno(), selectmock.POLLOUT)] # Get the listener from subscribe's last call listener = get_dout_listener(pubmock) assert listener is not None attrs = {'addr': '123456', 'index': '1'} el = Element("set_digital_output", attrib=attrs) el.text = "low" # Set socket.error as a side effect old_se = mgr.socket.sendto.side_effect mgr.socket.sendto.side_effect = socket.error(70, "") response = Mock() listener(element=el, response=response) eq_(response.put.call_count, 1) # Extract the listener's response r = response.put.call_args[0][0] # Check that the error message is the return value of os.strerror on the # error's errno import os errmsg = os.strerror(70) assert_command_error(r, errors['txfailed'], errmsg) # Reset the socket sendto side effect mgr.socket.sendto.side_effect = old_se
def do_send_serial_error(pubmock, attrs, data, error_prefix, error_hint=None, tx_status_err=0, send_exc=None, fileno_val=0): pubmock.reset_mock() mgr = XBeeEventManager(registry) pollermock = mgr.poller if fileno_val: fno_return = fileno_val else: fno_return = mgr.socket.fileno.return_value pollermock.poll.return_value = [(fno_return, selectmock.POLLOUT)] # Get the listener from subscribe's last call listener = get_listener(pubmock) assert listener is not None # Create command object el = Element("send_serial", attrib=attrs) el.text = data if send_exc: mgr.socket.sendto.side_effect = send_exc rsp = Mock() listener(element=el, response=rsp) if send_exc: mgr.socket.sendto.side_effect = None if not tx_status_err: assert_that(rsp.put.call_count, equal_to(1)) r = rsp.put.call_args[0][0] rsp.put.assert_called_once_with(match_equality(instance_of(Element))) # Only call, only arg is hopeful error element el = rsp.put.call_args[0][0] assert_command_error(el, error_prefix, error_hint) return #### Deal only with tx_status errors beyond here # Grab the transmit identifier so we can comlete it # First call, second argument, sixth member of address tuple tx_id = mgr.socket.sendto.call_args[0][1][5] rsp.put.assert_called_once_with(ResponsePending) rsp.reset_mock() # Trigger completion with transmit status mgr.socket.recvfrom.return_value = ( # TX Status response, frame info, dst, and other # indicators all success '\x8b\x00\x00\x00\x00' + chr(tx_status_err) + '\x00', ('[00:00:00:00:00:00:00:00]!', 0x0, 0xc105, 0x8b, 0x0, tx_id)) print mgr.socket.recvfrom.return_value # Tell dispatcher portion that it has data mgr.handle_read() rsp.put.assert_called_once_with( match_equality(instance_of(DeferredResponse))) # First call, only arg dr = rsp.put.call_args[0][0] el = dr.response assert_command_error(el, error_prefix, error_hint)