tplinkrouterc6u 5.12.3__py3-none-any.whl → 5.13.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- test/test_client_c6u.py +53 -20
- test/test_client_c6u_v1_11.py +95 -0
- test/test_client_ex.py +80 -0
- test/test_client_r.py +633 -0
- test/test_client_xdr.py +5 -0
- tplinkrouterc6u/__init__.py +2 -1
- tplinkrouterc6u/client/c6u.py +99 -1
- tplinkrouterc6u/client/ex.py +10 -12
- tplinkrouterc6u/client/mr.py +1 -1
- tplinkrouterc6u/client/r.py +198 -0
- tplinkrouterc6u/client/xdr.py +10 -1
- tplinkrouterc6u/provider.py +4 -1
- {tplinkrouterc6u-5.12.3.dist-info → tplinkrouterc6u-5.13.0.dist-info}/METADATA +12 -2
- {tplinkrouterc6u-5.12.3.dist-info → tplinkrouterc6u-5.13.0.dist-info}/RECORD +17 -14
- {tplinkrouterc6u-5.12.3.dist-info → tplinkrouterc6u-5.13.0.dist-info}/WHEEL +0 -0
- {tplinkrouterc6u-5.12.3.dist-info → tplinkrouterc6u-5.13.0.dist-info}/licenses/LICENSE +0 -0
- {tplinkrouterc6u-5.12.3.dist-info → tplinkrouterc6u-5.13.0.dist-info}/top_level.txt +0 -0
test/test_client_c6u.py
CHANGED
|
@@ -14,6 +14,12 @@ from tplinkrouterc6u import (
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class TestTPLinkClient(TestCase):
|
|
17
|
+
router_class = TplinkRouter
|
|
18
|
+
game_accelerator_path = 'admin/smart_network?form=game_accelerator'
|
|
19
|
+
openvpn_config_path = 'admin/openvpn?form=config'
|
|
20
|
+
pptpd_config_path = 'admin/pptpd?form=config'
|
|
21
|
+
vpn_uses_data_param = True
|
|
22
|
+
|
|
17
23
|
def test_get_status(self) -> None:
|
|
18
24
|
response_status = '''
|
|
19
25
|
{
|
|
@@ -211,7 +217,9 @@ class TestTPLinkClient(TestCase):
|
|
|
211
217
|
}
|
|
212
218
|
'''
|
|
213
219
|
|
|
214
|
-
|
|
220
|
+
router_class = self.router_class
|
|
221
|
+
|
|
222
|
+
class TPLinkRouterTest(router_class):
|
|
215
223
|
def request(self, path: str, data: str,
|
|
216
224
|
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
217
225
|
if path == 'admin/status?form=all&operation=read':
|
|
@@ -339,7 +347,9 @@ class TestTPLinkClient(TestCase):
|
|
|
339
347
|
}
|
|
340
348
|
'''
|
|
341
349
|
|
|
342
|
-
|
|
350
|
+
router_class = self.router_class
|
|
351
|
+
|
|
352
|
+
class TPLinkRouterTest(router_class):
|
|
343
353
|
def request(self, path: str, data: str,
|
|
344
354
|
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
345
355
|
if path == 'admin/status?form=all&operation=read':
|
|
@@ -484,12 +494,15 @@ class TestTPLinkClient(TestCase):
|
|
|
484
494
|
}
|
|
485
495
|
'''
|
|
486
496
|
|
|
487
|
-
|
|
497
|
+
router_class = self.router_class
|
|
498
|
+
game_accelerator_path = self.game_accelerator_path
|
|
499
|
+
|
|
500
|
+
class TPLinkRouterTest(router_class):
|
|
488
501
|
def request(self, path: str, data: str,
|
|
489
502
|
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
490
503
|
if path == 'admin/status?form=all&operation=read':
|
|
491
504
|
return loads(response_status)['data']
|
|
492
|
-
elif path ==
|
|
505
|
+
elif path == game_accelerator_path:
|
|
493
506
|
return loads(response_game_accelerator)['data']
|
|
494
507
|
elif path == 'admin/wireless?form=statistics':
|
|
495
508
|
return loads(response_stats)['data']
|
|
@@ -508,7 +521,7 @@ class TestTPLinkClient(TestCase):
|
|
|
508
521
|
self.assertEqual(status.wired_total, 2)
|
|
509
522
|
self.assertEqual(status.wifi_clients_total, 2)
|
|
510
523
|
self.assertEqual(status.guest_clients_total, 0)
|
|
511
|
-
self.assertEqual(status.clients_total,
|
|
524
|
+
self.assertEqual(status.clients_total, 7)
|
|
512
525
|
self.assertEqual(status.iot_clients_total, 3)
|
|
513
526
|
self.assertEqual(status.guest_2g_enable, True)
|
|
514
527
|
self.assertEqual(status.guest_5g_enable, None)
|
|
@@ -618,7 +631,9 @@ class TestTPLinkClient(TestCase):
|
|
|
618
631
|
}
|
|
619
632
|
'''
|
|
620
633
|
|
|
621
|
-
|
|
634
|
+
router_class = self.router_class
|
|
635
|
+
|
|
636
|
+
class TPLinkRouterTest(router_class):
|
|
622
637
|
def request(self, path: str, data: str,
|
|
623
638
|
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
624
639
|
if path == 'admin/status?form=all&operation=read':
|
|
@@ -661,8 +676,9 @@ class TestTPLinkClient(TestCase):
|
|
|
661
676
|
def test_set_wifi(self) -> None:
|
|
662
677
|
check_url = ''
|
|
663
678
|
check_data = ''
|
|
679
|
+
router_class = self.router_class
|
|
664
680
|
|
|
665
|
-
class TPLinkRouterTest(
|
|
681
|
+
class TPLinkRouterTest(router_class):
|
|
666
682
|
def request(self, path: str, data: str,
|
|
667
683
|
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
668
684
|
nonlocal check_url, check_data
|
|
@@ -705,8 +721,9 @@ class TestTPLinkClient(TestCase):
|
|
|
705
721
|
|
|
706
722
|
def test_get_ipv4_status_empty(self) -> None:
|
|
707
723
|
response_network = '{"result": {}, "error_code": 0}'
|
|
724
|
+
router_class = self.router_class
|
|
708
725
|
|
|
709
|
-
class TPLinkRouterTest(
|
|
726
|
+
class TPLinkRouterTest(router_class):
|
|
710
727
|
def request(self, path: str, data: str,
|
|
711
728
|
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
712
729
|
if path == 'admin/network?form=status_ipv4&operation=read':
|
|
@@ -750,8 +767,9 @@ class TestTPLinkClient(TestCase):
|
|
|
750
767
|
"operator": "load"
|
|
751
768
|
}
|
|
752
769
|
'''
|
|
770
|
+
router_class = self.router_class
|
|
753
771
|
|
|
754
|
-
class TPLinkRouterTest(
|
|
772
|
+
class TPLinkRouterTest(router_class):
|
|
755
773
|
def request(self, path: str, data: str,
|
|
756
774
|
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
757
775
|
if path == 'admin/status?form=all&operation=read':
|
|
@@ -800,8 +818,9 @@ class TestTPLinkClient(TestCase):
|
|
|
800
818
|
}
|
|
801
819
|
}
|
|
802
820
|
'''
|
|
821
|
+
router_class = self.router_class
|
|
803
822
|
|
|
804
|
-
class TPLinkRouterTest(
|
|
823
|
+
class TPLinkRouterTest(router_class):
|
|
805
824
|
def request(self, path: str, data: str,
|
|
806
825
|
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
807
826
|
if path == 'admin/status?form=all&operation=read':
|
|
@@ -871,7 +890,12 @@ class TestTPLinkClient(TestCase):
|
|
|
871
890
|
"extra": "7450", "vpntype": "pptp", "key": "7450"}
|
|
872
891
|
]"""
|
|
873
892
|
|
|
874
|
-
|
|
893
|
+
router_class = self.router_class
|
|
894
|
+
openvpn_config_path = self.openvpn_config_path
|
|
895
|
+
pptpd_config_path = self.pptpd_config_path
|
|
896
|
+
vpn_uses_data_param = self.vpn_uses_data_param
|
|
897
|
+
|
|
898
|
+
class TPLinkRouterTest(router_class):
|
|
875
899
|
def request(
|
|
876
900
|
self,
|
|
877
901
|
path: str,
|
|
@@ -879,14 +903,20 @@ class TestTPLinkClient(TestCase):
|
|
|
879
903
|
ignore_response: bool = False,
|
|
880
904
|
ignore_errors: bool = False,
|
|
881
905
|
) -> dict | None:
|
|
882
|
-
if path ==
|
|
906
|
+
if path == openvpn_config_path:
|
|
883
907
|
return loads(response_openvpn_read)
|
|
884
|
-
if path ==
|
|
908
|
+
if path == pptpd_config_path:
|
|
885
909
|
return loads(response_pptp_read)
|
|
886
|
-
if
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
910
|
+
if vpn_uses_data_param:
|
|
911
|
+
if path == "admin/vpnconn?form=config" and data == "operation=list&vpntype=openvpn":
|
|
912
|
+
return loads(respone_vpnconn_openvpn)
|
|
913
|
+
if path == "admin/vpnconn?form=config" and data == "operation=list&vpntype=pptp":
|
|
914
|
+
return loads(respone_vpnconn_pptpvpn)
|
|
915
|
+
else:
|
|
916
|
+
if path == "admin/vpnconn?form=config&operation=list&vpntype=openvpn":
|
|
917
|
+
return loads(respone_vpnconn_openvpn)
|
|
918
|
+
if path == "admin/vpnconn?form=config&operation=list&vpntype=pptp":
|
|
919
|
+
return loads(respone_vpnconn_pptpvpn)
|
|
890
920
|
raise ClientException()
|
|
891
921
|
|
|
892
922
|
client = TPLinkRouterTest("", "")
|
|
@@ -910,7 +940,10 @@ class TestTPLinkClient(TestCase):
|
|
|
910
940
|
}
|
|
911
941
|
"""
|
|
912
942
|
|
|
913
|
-
|
|
943
|
+
router_class = self.router_class
|
|
944
|
+
openvpn_config_path = self.openvpn_config_path
|
|
945
|
+
|
|
946
|
+
class TPLinkRouterTest(router_class):
|
|
914
947
|
def request(
|
|
915
948
|
self,
|
|
916
949
|
path: str,
|
|
@@ -918,7 +951,7 @@ class TestTPLinkClient(TestCase):
|
|
|
918
951
|
ignore_response: bool = False,
|
|
919
952
|
ignore_errors: bool = False,
|
|
920
953
|
) -> dict | None:
|
|
921
|
-
if path ==
|
|
954
|
+
if path == openvpn_config_path and data == "operation=read":
|
|
922
955
|
return loads(response_openvpn_read)
|
|
923
956
|
self.captured_path = path
|
|
924
957
|
self.captured_data = data
|
|
@@ -930,7 +963,7 @@ class TestTPLinkClient(TestCase):
|
|
|
930
963
|
"operation=write&enabled=on"
|
|
931
964
|
"&proto=udp&access=home&cert_exist=True&mask=255.255.255.0&port=1194&serverip=10.8.0.0"
|
|
932
965
|
)
|
|
933
|
-
self.assertEqual(client.captured_path,
|
|
966
|
+
self.assertEqual(client.captured_path, self.openvpn_config_path)
|
|
934
967
|
self.assertEqual(client.captured_data, expected_data)
|
|
935
968
|
|
|
936
969
|
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
from unittest import main
|
|
2
|
+
from unittest.mock import patch, Mock
|
|
3
|
+
from test_client_c6u import TestTPLinkClient
|
|
4
|
+
from tplinkrouterc6u import TplinkRouterV1_11, ClientException
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TestTPLinkClientV1_11(TestTPLinkClient):
|
|
8
|
+
"""Inherits all tests from TestTPLinkClient, using TplinkRouterV1_11."""
|
|
9
|
+
|
|
10
|
+
router_class = TplinkRouterV1_11
|
|
11
|
+
game_accelerator_path = 'admin/smart_network?form=game_accelerator&operation=loadDevice'
|
|
12
|
+
openvpn_config_path = 'admin/openvpn?form=config&operation=read'
|
|
13
|
+
pptpd_config_path = 'admin/pptpd?form=config&operation=read'
|
|
14
|
+
vpn_uses_data_param = False
|
|
15
|
+
|
|
16
|
+
# V1_11-specific tests only
|
|
17
|
+
|
|
18
|
+
def test_supports_password_too_long(self) -> None:
|
|
19
|
+
long_password = 'a' * 126
|
|
20
|
+
client = TplinkRouterV1_11('http://192.168.0.1', long_password)
|
|
21
|
+
self.assertFalse(client.supports())
|
|
22
|
+
|
|
23
|
+
@patch('tplinkrouterc6u.client.c6u.EncryptionWrapper.rsa_encrypt')
|
|
24
|
+
@patch('tplinkrouterc6u.client.c6u.post')
|
|
25
|
+
def test_authorize_success(self, mock_post: Mock, mock_rsa: Mock) -> None:
|
|
26
|
+
mock_rsa.return_value = 'encrypted_password_hex'
|
|
27
|
+
|
|
28
|
+
keys_response = Mock()
|
|
29
|
+
keys_response.json.return_value = {
|
|
30
|
+
'success': True,
|
|
31
|
+
'data': {
|
|
32
|
+
'password': ['mock_nn_value', '010001']
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
login_response = Mock()
|
|
37
|
+
login_response.json.return_value = {
|
|
38
|
+
'success': True,
|
|
39
|
+
'data': {
|
|
40
|
+
'stok': 'test_stok_12345'
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
login_response.headers = {'set-cookie': 'sysauth=test_sysauth_cookie; path=/'}
|
|
44
|
+
|
|
45
|
+
mock_post.side_effect = [keys_response, login_response]
|
|
46
|
+
|
|
47
|
+
client = TplinkRouterV1_11('http://192.168.0.1', 'testpassword')
|
|
48
|
+
client.authorize()
|
|
49
|
+
|
|
50
|
+
self.assertTrue(client._logged)
|
|
51
|
+
self.assertEqual(client._stok, 'test_stok_12345')
|
|
52
|
+
self.assertEqual(client._sysauth, 'test_sysauth_cookie')
|
|
53
|
+
self.assertEqual(mock_post.call_count, 2)
|
|
54
|
+
|
|
55
|
+
first_call = mock_post.call_args_list[0]
|
|
56
|
+
self.assertIn('login?form=keys', first_call[0][0])
|
|
57
|
+
|
|
58
|
+
second_call = mock_post.call_args_list[1]
|
|
59
|
+
self.assertIn('login?form=login', second_call[0][0])
|
|
60
|
+
login_data = second_call[1]['data']
|
|
61
|
+
self.assertTrue(login_data.startswith('operation=login&password='))
|
|
62
|
+
|
|
63
|
+
@patch('tplinkrouterc6u.client.c6u.EncryptionWrapper.rsa_encrypt')
|
|
64
|
+
@patch('tplinkrouterc6u.client.c6u.post')
|
|
65
|
+
def test_authorize_failure(self, mock_post: Mock, mock_rsa: Mock) -> None:
|
|
66
|
+
mock_rsa.return_value = 'encrypted_password_hex'
|
|
67
|
+
|
|
68
|
+
keys_response = Mock()
|
|
69
|
+
keys_response.json.return_value = {
|
|
70
|
+
'success': True,
|
|
71
|
+
'data': {
|
|
72
|
+
'password': ['mock_nn_value', '010001']
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
login_response = Mock()
|
|
77
|
+
login_response.json.return_value = {
|
|
78
|
+
'success': False,
|
|
79
|
+
'data': {'errorcode': 'invalid password'}
|
|
80
|
+
}
|
|
81
|
+
login_response.headers = {}
|
|
82
|
+
|
|
83
|
+
mock_post.side_effect = [keys_response, login_response]
|
|
84
|
+
|
|
85
|
+
client = TplinkRouterV1_11('http://192.168.0.1', 'wrongpassword')
|
|
86
|
+
|
|
87
|
+
with self.assertRaises(ClientException) as context:
|
|
88
|
+
client.authorize()
|
|
89
|
+
|
|
90
|
+
self.assertIn('Login failed', str(context.exception))
|
|
91
|
+
self.assertFalse(client._logged)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
if __name__ == '__main__':
|
|
95
|
+
main()
|
test/test_client_ex.py
CHANGED
|
@@ -204,6 +204,86 @@ class TestTPLinkEXClient(TestCase):
|
|
|
204
204
|
self.assertEqual(status.devices[1].packets_sent, None) # TODO
|
|
205
205
|
self.assertEqual(status.devices[1].packets_received, None) # TODO
|
|
206
206
|
|
|
207
|
+
def test_get_status_NE200(self) -> None:
|
|
208
|
+
DEV2_ADT_LAN = ('{"data":[{"MACAddress":"a0:28:84:de:dd:5c","IPAddress":"192.168.4.1","stack":"1,0,0,0,0,0"}],'
|
|
209
|
+
'"operation":"gl","oid":"DEV2_ADT_LAN","success":true}')
|
|
210
|
+
DEV2_ADT_WAN = ('{"data":[{"enable":"1","MACAddr":"","connIPv4Address":"","connIPv4Gateway":""'
|
|
211
|
+
',"stack":"1,0,0,0,0,0"}],"operation":"gl","oid":"DEV2_ADT_WAN","success":true}')
|
|
212
|
+
DEV2_ADT_WIFI_COMMON = ('{"data":[],"operation":"gl",'
|
|
213
|
+
'"oid":"DEV2_ADT_WIFI_COMMON","success":true}')
|
|
214
|
+
DEV2_HOST_ENTRY = ('{"data":[{"active":"1","X_TP_LanConnType":"1","physAddress":"66-E2-02-BD-B5-1B",'
|
|
215
|
+
'"IPAddress":"192.168.30.10","hostName":"host1","stack":"1,0,0,0,0,0"},'
|
|
216
|
+
'{"active":"1","X_TP_LanConnType":"1","physAddress":"F4-A3-86-2D-41-B5",'
|
|
217
|
+
'"IPAddress":"192.168.30.11","hostName":"host2","stack":"2,0,0,0,0,0"}],"operation":"gl",'
|
|
218
|
+
'"oid":"DEV2_HOST_ENTRY","success":true}')
|
|
219
|
+
DEV2_MEM_STATUS = ('{"data":{"total":"192780","free":"78400","stack":"0,0,0,0,0,0"},"operation":"go",'
|
|
220
|
+
'"oid":"DEV2_MEM_STATUS","success":true}')
|
|
221
|
+
DEV2_PROC_STATUS = ('{"data":{"CPUUsage":"69","stack":"0,0,0,0,0,0"},"operation":"go",'
|
|
222
|
+
'"oid":"DEV2_PROC_STATUS","success":true}')
|
|
223
|
+
|
|
224
|
+
class TPLinkEXClientTest(TPLinkEXClient):
|
|
225
|
+
self._token = True
|
|
226
|
+
|
|
227
|
+
def _request(self, url, method='POST', data_str=None, encrypt=False):
|
|
228
|
+
if 'DEV2_ADT_LAN' in data_str:
|
|
229
|
+
return 200, DEV2_ADT_LAN
|
|
230
|
+
elif 'DEV2_ADT_WAN' in data_str:
|
|
231
|
+
return 200, DEV2_ADT_WAN
|
|
232
|
+
elif 'DEV2_ADT_WIFI_COMMON' in data_str:
|
|
233
|
+
return 200, DEV2_ADT_WIFI_COMMON
|
|
234
|
+
elif 'DEV2_HOST_ENTRY' in data_str:
|
|
235
|
+
return 200, DEV2_HOST_ENTRY
|
|
236
|
+
elif 'DEV2_MEM_STATUS' in data_str:
|
|
237
|
+
return 200, DEV2_MEM_STATUS
|
|
238
|
+
elif 'DEV2_PROC_STATUS' in data_str:
|
|
239
|
+
return 200, DEV2_PROC_STATUS
|
|
240
|
+
raise ClientException()
|
|
241
|
+
|
|
242
|
+
client = TPLinkEXClientTest('', '')
|
|
243
|
+
status = client.get_status()
|
|
244
|
+
|
|
245
|
+
self.assertIsInstance(status, Status)
|
|
246
|
+
self.assertEqual(status.wan_macaddr, None)
|
|
247
|
+
self.assertEqual(status.lan_macaddr, 'A0-28-84-DE-DD-5C')
|
|
248
|
+
self.assertIsInstance(status.lan_macaddress, EUI48)
|
|
249
|
+
self.assertEqual(status.wan_ipv4_addr, None)
|
|
250
|
+
self.assertEqual(status.lan_ipv4_addr, '192.168.4.1')
|
|
251
|
+
self.assertEqual(status.wan_ipv4_gateway, None)
|
|
252
|
+
self.assertEqual(status.wired_total, 0)
|
|
253
|
+
self.assertEqual(status.wifi_clients_total, 2)
|
|
254
|
+
self.assertEqual(status.guest_clients_total, 0)
|
|
255
|
+
self.assertEqual(status.clients_total, 2)
|
|
256
|
+
self.assertEqual(status.guest_2g_enable, None)
|
|
257
|
+
self.assertEqual(status.guest_5g_enable, None)
|
|
258
|
+
self.assertEqual(status.iot_2g_enable, None)
|
|
259
|
+
self.assertEqual(status.iot_5g_enable, None)
|
|
260
|
+
self.assertEqual(status.wifi_2g_enable, None)
|
|
261
|
+
self.assertEqual(status.wifi_5g_enable, None)
|
|
262
|
+
self.assertEqual(status.wan_ipv4_uptime, None)
|
|
263
|
+
self.assertGreaterEqual(status.mem_usage, 0)
|
|
264
|
+
self.assertLessEqual(status.mem_usage, 1)
|
|
265
|
+
self.assertGreaterEqual(status.cpu_usage, 0)
|
|
266
|
+
self.assertLessEqual(status.cpu_usage, 1)
|
|
267
|
+
self.assertEqual(len(status.devices), 2)
|
|
268
|
+
self.assertIsInstance(status.devices[0], Device)
|
|
269
|
+
self.assertEqual(status.devices[0].type, Connection.HOST_2G)
|
|
270
|
+
self.assertEqual(status.devices[0].macaddr, '66-E2-02-BD-B5-1B')
|
|
271
|
+
self.assertIsInstance(status.devices[0].macaddress, EUI48)
|
|
272
|
+
self.assertEqual(status.devices[0].ipaddr, '192.168.30.10')
|
|
273
|
+
self.assertIsInstance(status.devices[0].ipaddress, IPv4Address)
|
|
274
|
+
self.assertEqual(status.devices[0].hostname, 'host1')
|
|
275
|
+
self.assertEqual(status.devices[0].packets_sent, None)
|
|
276
|
+
self.assertEqual(status.devices[0].packets_received, None)
|
|
277
|
+
self.assertIsInstance(status.devices[1], Device)
|
|
278
|
+
self.assertEqual(status.devices[1].type, Connection.HOST_2G)
|
|
279
|
+
self.assertEqual(status.devices[1].macaddr, 'F4-A3-86-2D-41-B5')
|
|
280
|
+
self.assertIsInstance(status.devices[1].macaddress, EUI48)
|
|
281
|
+
self.assertEqual(status.devices[1].ipaddr, '192.168.30.11')
|
|
282
|
+
self.assertIsInstance(status.devices[1].ipaddress, IPv4Address)
|
|
283
|
+
self.assertEqual(status.devices[1].hostname, 'host2')
|
|
284
|
+
self.assertEqual(status.devices[1].packets_sent, None) # TODO
|
|
285
|
+
self.assertEqual(status.devices[1].packets_received, None) # TODO
|
|
286
|
+
|
|
207
287
|
def test_get_ipv4_reservations(self) -> None:
|
|
208
288
|
|
|
209
289
|
response = ('{"data":[{"enable":"1","chaddr":"bf:75:44:4c:dc:9e","yiaddr":"192.168.8.21",'
|