|
| 1 | +# SPDX-FileCopyrightText: 2022 Martin Stephens |
| 2 | +# |
| 3 | +# SPDX-License-Identifier: MIT |
| 4 | +"""Tests to confirm that there are no changes in behaviour to public methods and functions.""" |
| 5 | + |
| 6 | +# pylint: disable=no-self-use, redefined-outer-name, protected-access, invalid-name, too-many-arguments |
| 7 | +import pytest |
| 8 | + |
| 9 | +from micropython import const |
| 10 | +import adafruit_wiznet5k.adafruit_wiznet5k_dhcp as wiz_dhcp |
| 11 | + |
| 12 | +# |
| 13 | +DEFAULT_DEBUG_ON = True |
| 14 | + |
| 15 | + |
| 16 | +@pytest.fixture |
| 17 | +def wiznet(mocker): |
| 18 | + return mocker.patch("adafruit_wiznet5k.adafruit_wiznet5k.WIZNET5K", autospec=True) |
| 19 | + |
| 20 | + |
| 21 | +@pytest.fixture |
| 22 | +def wrench(mocker): |
| 23 | + return mocker.patch( |
| 24 | + "adafruit_wiznet5k.adafruit_wiznet5k_dhcp.socket", autospec=True |
| 25 | + ) |
| 26 | + |
| 27 | + |
| 28 | +class TestDHCPInit: |
| 29 | + def test_constants(self): |
| 30 | + # DHCP State Machine |
| 31 | + assert wiz_dhcp.STATE_DHCP_START == const(0x00) |
| 32 | + assert wiz_dhcp.STATE_DHCP_DISCOVER == const(0x01) |
| 33 | + assert wiz_dhcp.STATE_DHCP_REQUEST == const(0x02) |
| 34 | + assert wiz_dhcp.STATE_DHCP_LEASED == const(0x03) |
| 35 | + assert wiz_dhcp.STATE_DHCP_REREQUEST == const(0x04) |
| 36 | + assert wiz_dhcp.STATE_DHCP_RELEASE == const(0x05) |
| 37 | + assert wiz_dhcp.STATE_DHCP_WAIT == const(0x06) |
| 38 | + assert wiz_dhcp.STATE_DHCP_DISCONN == const(0x07) |
| 39 | + |
| 40 | + # DHCP wait time between attempts |
| 41 | + assert wiz_dhcp.DHCP_WAIT_TIME == const(60) |
| 42 | + |
| 43 | + # DHCP Message Types |
| 44 | + assert wiz_dhcp.DHCP_DISCOVER == const(1) |
| 45 | + assert wiz_dhcp.DHCP_OFFER == const(2) |
| 46 | + assert wiz_dhcp.DHCP_REQUEST == const(3) |
| 47 | + assert wiz_dhcp.DHCP_DECLINE == const(4) |
| 48 | + assert wiz_dhcp.DHCP_ACK == const(5) |
| 49 | + assert wiz_dhcp.DHCP_NAK == const(6) |
| 50 | + assert wiz_dhcp.DHCP_RELEASE == const(7) |
| 51 | + assert wiz_dhcp.DHCP_INFORM == const(8) |
| 52 | + |
| 53 | + # DHCP Message OP Codes |
| 54 | + assert wiz_dhcp.DHCP_BOOT_REQUEST == const(0x01) |
| 55 | + assert wiz_dhcp.DHCP_BOOT_REPLY == const(0x02) |
| 56 | + |
| 57 | + assert wiz_dhcp.DHCP_HTYPE10MB == const(0x01) |
| 58 | + assert wiz_dhcp.DHCP_HTYPE100MB == const(0x02) |
| 59 | + |
| 60 | + assert wiz_dhcp.DHCP_HLENETHERNET == const(0x06) |
| 61 | + assert wiz_dhcp.DHCP_HOPS == const(0x00) |
| 62 | + |
| 63 | + assert wiz_dhcp.MAGIC_COOKIE == const(0x63825363) |
| 64 | + assert wiz_dhcp.MAX_DHCP_OPT == const(0x10) |
| 65 | + |
| 66 | + # Default DHCP Server port |
| 67 | + assert wiz_dhcp.DHCP_SERVER_PORT == const(67) |
| 68 | + # DHCP Lease Time, in seconds |
| 69 | + assert wiz_dhcp.DEFAULT_LEASE_TIME == const(900) |
| 70 | + assert wiz_dhcp.BROADCAST_SERVER_ADDR == (255, 255, 255, 255) |
| 71 | + |
| 72 | + # DHCP Response Options |
| 73 | + assert wiz_dhcp.MSG_TYPE == 53 |
| 74 | + assert wiz_dhcp.SUBNET_MASK == 1 |
| 75 | + assert wiz_dhcp.ROUTERS_ON_SUBNET == 3 |
| 76 | + assert wiz_dhcp.DNS_SERVERS == 6 |
| 77 | + assert wiz_dhcp.DHCP_SERVER_ID == 54 |
| 78 | + assert wiz_dhcp.T1_VAL == 58 |
| 79 | + assert wiz_dhcp.T2_VAL == 59 |
| 80 | + assert wiz_dhcp.LEASE_TIME == 51 |
| 81 | + assert wiz_dhcp.OPT_END == 255 |
| 82 | + |
| 83 | + # Packet buffer |
| 84 | + assert wiz_dhcp._BUFF == bytearray(318) |
| 85 | + |
| 86 | + @pytest.mark.parametrize( |
| 87 | + "mac_address", |
| 88 | + ( |
| 89 | + [1, 2, 3, 4, 5, 6], |
| 90 | + (7, 8, 9, 10, 11, 12), |
| 91 | + bytes([1, 2, 4, 6, 7, 8]), |
| 92 | + ), |
| 93 | + ) |
| 94 | + def test_dhcp_setup_default(self, mocker, wiznet, wrench, mac_address): |
| 95 | + # Test with mac address as tuple, list and bytes with default values. |
| 96 | + mock_randint = mocker.patch( |
| 97 | + "adafruit_wiznet5k.adafruit_wiznet5k_dhcp.randint", autospec=True |
| 98 | + ) |
| 99 | + mock_randint.return_value = 0x1234567 |
| 100 | + dhcp_client = wiz_dhcp.DHCP(wiznet, mac_address) |
| 101 | + assert dhcp_client._eth == wiznet |
| 102 | + assert dhcp_client._response_timeout == 30.0 |
| 103 | + assert dhcp_client._debug is False |
| 104 | + assert dhcp_client._mac_address == mac_address |
| 105 | + wrench.set_interface.assert_called_once_with(wiznet) |
| 106 | + assert dhcp_client._sock is None |
| 107 | + assert dhcp_client._dhcp_state == wiz_dhcp.STATE_DHCP_START |
| 108 | + assert dhcp_client._initial_xid == 0 |
| 109 | + mock_randint.assert_called_once() |
| 110 | + assert dhcp_client._transaction_id == 0x1234567 |
| 111 | + assert dhcp_client._start_time == 0 |
| 112 | + assert dhcp_client.dhcp_server_ip == wiz_dhcp.BROADCAST_SERVER_ADDR |
| 113 | + assert dhcp_client.local_ip == 0 |
| 114 | + assert dhcp_client.gateway_ip == 0 |
| 115 | + assert dhcp_client.subnet_mask == 0 |
| 116 | + assert dhcp_client.dns_server_ip == 0 |
| 117 | + assert dhcp_client._lease_time == 0 |
| 118 | + assert dhcp_client._last_lease_time == 0 |
| 119 | + assert dhcp_client._renew_in_sec == 0 |
| 120 | + assert dhcp_client._rebind_in_sec == 0 |
| 121 | + assert dhcp_client._t1 == 0 |
| 122 | + assert dhcp_client._t2 == 0 |
| 123 | + mac_string = "".join("{:02X}".format(o) for o in mac_address) |
| 124 | + assert dhcp_client._hostname == bytes( |
| 125 | + "WIZnet{}".split(".", maxsplit=1)[0].format(mac_string)[:42], "utf-8" |
| 126 | + ) |
| 127 | + |
| 128 | + def test_dhcp_setup_other_args(self, wiznet): |
| 129 | + mac_address = (7, 8, 9, 10, 11, 12) |
| 130 | + dhcp_client = wiz_dhcp.DHCP( |
| 131 | + wiznet, mac_address, hostname="fred.com", response_timeout=25.0, debug=True |
| 132 | + ) |
| 133 | + |
| 134 | + assert dhcp_client._response_timeout == 25.0 |
| 135 | + assert dhcp_client._debug is True |
| 136 | + mac_string = "".join("{:02X}".format(o) for o in mac_address) |
| 137 | + assert dhcp_client._hostname == bytes( |
| 138 | + "fred.com".split(".", maxsplit=1)[0].format(mac_string)[:42], "utf-8" |
| 139 | + ) |
| 140 | + |
| 141 | + |
| 142 | +class TestSendDHCPMessage: |
| 143 | + DHCP_SEND_01 = bytearray( |
| 144 | + b"\x01\x01\x06\x00\xff\xff\xffo\x00\x17\x80\x00\x00\x00\x00\x00" |
| 145 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x05\x06\x07" |
| 146 | + b"\x08\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 147 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 148 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 149 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 150 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 151 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 152 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 153 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 154 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 155 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 156 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 157 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 158 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00c\x82Sc5\x01\x01=" |
| 159 | + b"\x07\x01\x04\x05\x06\x07\x08\t\x0c\x12WIZnet040506070809" |
| 160 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x007\x06\x01\x03" |
| 161 | + b"\x06\x0f:;\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 162 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 163 | + ) |
| 164 | + |
| 165 | + DHCP_SEND_02 = bytearray( |
| 166 | + b"\x01\x01\x06\x00\xff\xff\xffo\x00#\x80\x00\x00\x00\x00\x00" |
| 167 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18#.9DO\x00\x00" |
| 168 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 169 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 170 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 171 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 172 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 173 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 174 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 175 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 176 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 177 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 178 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 179 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 180 | + b"\x00\x00\x00\x00\x00\x00\x00\x00c\x82Sc5\x01\x02=\x07\x01\x18#.9DO" |
| 181 | + b"\x0c\x04bert\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x007\x06" |
| 182 | + b"\x01\x03\x06\x0f:;\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 183 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 184 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 185 | + ) |
| 186 | + |
| 187 | + DHCP_SEND_03 = bytearray( |
| 188 | + b"\x01\x01\x06\x00\xff\xff\xffo\x00#\x80\x00\n\n\n+\x00\x00\x00\x00" |
| 189 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\xffa$e*c\x00\x00\x00\x00\x00\x00" |
| 190 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 191 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 192 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 193 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 194 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 195 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 196 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 197 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 198 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 199 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 200 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 201 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 202 | + b"\x00\x00\x00\x00c\x82Sc5\x01\x02=\x07\x01\xffa$e*c\x0c\x05cl" |
| 203 | + b"ash\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x007" |
| 204 | + b"\x06\x01\x03\x06\x0f:;\xff\x00\x00\x00\x00\x00\x00\x00\x00" |
| 205 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 206 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 207 | + ) |
| 208 | + |
| 209 | + def test_send_with_defaults(self, wiznet, wrench): |
| 210 | + assert len(wiz_dhcp._BUFF) == 318 |
| 211 | + dhcp_client = wiz_dhcp.DHCP(wiznet, (4, 5, 6, 7, 8, 9)) |
| 212 | + dhcp_client._sock = wrench.socket(type=wrench.SOCK_DGRAM) |
| 213 | + dhcp_client._transaction_id = 0x6FFFFFFF |
| 214 | + dhcp_client.send_dhcp_message(1, 23.4) |
| 215 | + dhcp_client._sock.send.assert_called_once_with(self.DHCP_SEND_01) |
| 216 | + assert len(wiz_dhcp._BUFF) == 318 |
| 217 | + |
| 218 | + @pytest.mark.parametrize( |
| 219 | + "mac_address, hostname, state, time_elapsed, renew, local_ip, server_ip, result", |
| 220 | + ( |
| 221 | + ( |
| 222 | + (4, 5, 6, 7, 8, 9), |
| 223 | + None, |
| 224 | + wiz_dhcp.STATE_DHCP_DISCOVER, |
| 225 | + 23.4, |
| 226 | + False, |
| 227 | + 0, |
| 228 | + 0, |
| 229 | + DHCP_SEND_01, |
| 230 | + ), |
| 231 | + ( |
| 232 | + (24, 35, 46, 57, 68, 79), |
| 233 | + "bert.co.uk", |
| 234 | + wiz_dhcp.STATE_DHCP_REQUEST, |
| 235 | + 35.5, |
| 236 | + False, |
| 237 | + (192, 168, 3, 4), |
| 238 | + (222, 123, 23, 10), |
| 239 | + DHCP_SEND_02, |
| 240 | + ), |
| 241 | + ( |
| 242 | + (255, 97, 36, 101, 42, 99), |
| 243 | + "clash.net", |
| 244 | + wiz_dhcp.STATE_DHCP_REQUEST, |
| 245 | + 35.5, |
| 246 | + True, |
| 247 | + (10, 10, 10, 43), |
| 248 | + (145, 66, 45, 22), |
| 249 | + DHCP_SEND_03, |
| 250 | + ), |
| 251 | + ), |
| 252 | + ) |
| 253 | + def test_send_dhcp_message( |
| 254 | + self, |
| 255 | + wiznet, |
| 256 | + wrench, |
| 257 | + mac_address, |
| 258 | + hostname, |
| 259 | + state, |
| 260 | + time_elapsed, |
| 261 | + renew, |
| 262 | + local_ip, |
| 263 | + server_ip, |
| 264 | + result, |
| 265 | + ): |
| 266 | + dhcp_client = wiz_dhcp.DHCP(wiznet, mac_address, hostname=hostname) |
| 267 | + # Mock out socket to check what is sent |
| 268 | + dhcp_client._sock = wrench.socket(type=wrench.SOCK_DGRAM) |
| 269 | + # Set client attributes for test |
| 270 | + dhcp_client.local_ip = local_ip |
| 271 | + dhcp_client.dhcp_server_ip = server_ip |
| 272 | + dhcp_client._transaction_id = 0x6FFFFFFF |
| 273 | + # Test |
| 274 | + dhcp_client.send_dhcp_message(state, time_elapsed, renew=renew) |
| 275 | + dhcp_client._sock.send.assert_called_once_with(result) |
| 276 | + assert len(wiz_dhcp._BUFF) == 318 |
0 commit comments