"""
Test the ClientDataOption implementation
"""
import unittest
from ipaddress import IPv6Address, IPv6Network
from dhcpkit.ipv6.duids import EnterpriseDUID
from dhcpkit.ipv6.extensions.leasequery import CLTTimeOption, ClientDataOption, LQRelayDataOption
from dhcpkit.ipv6.extensions.prefix_delegation import IAPrefixOption
from dhcpkit.ipv6.messages import RelayForwardMessage
from dhcpkit.ipv6.options import ClientIdOption, IAAddressOption, InterfaceIdOption, UnknownOption
from dhcpkit.tests.ipv6.options import test_option
[docs]class ClientDataOptionTestCase(test_option.OptionTestCase):
[docs] def setUp(self):
self.option_bytes = bytes.fromhex(
'002d' # Option type 45: OPTION_CLIENT_DATA
'0099' # Option length: 153
'0001' # Option type 1: OPTION_CLIENT_ID
'0015' # Option length: 21
'0002' # DUID type: DUID_EN
'00009d10' # Enterprise ID: 40208
'303132333435363738396162636465' # Identifier: '0123456789abcde'
'0005' # Option type: OPTION_IAADDR
'0018' # Option length: 24
'20010db800000000000000000000cafe' # IPv6 address: 2001:db8::cafe
'00000708' # Preferred lifetime: 1800
'00000e10' # Valid lifetime: 3600
'001a' # Option type: OPTION_IAPREFIX
'0019' # Option length: 25
'00000708' # Preferred lifetime: 1800
'00000e10' # Valid lifetime: 3600
'30' # Prefix length: 48
'20010db8000100000000000000000000'
'002e' # Option type: OPTION_CLT_TIME
'0004' # Option length: 4
'00000384' # Client-Last-Transaction time: 900
'002f' # Option type: OPTION_LQ_RELAY_DATA
'003b' # Option length: 59
'20010db8000000000000000000000002' # Peer address: 2001:db8::2
'0c' # Message type: MSG_RELAY_FORW
'00' # Hop count: 0
'20010db8000000000000000000000002' # Link address: 2001:db8::2
'fe800000000000000000000000000022' # Peer address: fe80::22
'0012' # Option type: OPTION_INTERFACE_ID
'0005' # Option length: 5
'4661322f33' # Interface ID: 'Fa2/3'
)
self.option_object = ClientDataOption(options=[
ClientIdOption(EnterpriseDUID(40208, b'0123456789abcde')),
IAAddressOption(address=IPv6Address('2001:db8::cafe'), preferred_lifetime=1800, valid_lifetime=3600),
IAPrefixOption(prefix=IPv6Network('2001:db8:1::/48'), preferred_lifetime=1800, valid_lifetime=3600),
CLTTimeOption(clt_time=900),
LQRelayDataOption(peer_address=IPv6Address('2001:db8::2'), relay_message=RelayForwardMessage(
hop_count=0,
link_address=IPv6Address('2001:db8::2'),
peer_address=IPv6Address('fe80::22'),
options=[
InterfaceIdOption(interface_id=b'Fa2/3'),
]
))
])
self.parse_option()
[docs] def test_parse_wrong_type(self):
with self.assertRaisesRegex(ValueError, 'does not contain ClientDataOption data'):
option = ClientDataOption()
option.load_from(b'00020010ff12000000000000000000000000abcd')
[docs] def test_bad_option_length(self):
with self.assertRaisesRegex(ValueError, 'length does not match'):
ClientDataOption.parse(bytes.fromhex(
'002d' # Option type 45: OPTION_CLIENT_DATA
'0018' # Option length: 24 (should be 25)
'0001' # Option type 1: OPTION_CLIENT_ID
'0015' # Option length: 21
'0002' # DUID type: DUID_EN
'00009d10' # Enterprise ID: 40208
'303132333435363738396162636465' # Identifier: '0123456789abcde'
))
with self.assertRaisesRegex(ValueError, 'longer than the available buffer'):
ClientDataOption.parse(bytes.fromhex(
'002d' # Option type 45: OPTION_CLIENT_DATA
'001a' # Option length: 26 (should be 25)
'0001' # Option type 1: OPTION_CLIENT_ID
'0015' # Option length: 21
'0002' # DUID type: DUID_EN
'00009d10' # Enterprise ID: 40208
'303132333435363738396162636465' # Identifier: '0123456789abcde'
))
[docs] def test_get_options_of_type(self):
# Our test-cases have one ClientIdOption
found_options = self.option.get_options_of_type(ClientIdOption)
self.assertEqual(len(found_options), 1)
self.assertIsInstance(found_options[0], ClientIdOption)
# But our test-cases don't have an UnknownOption in them
found_options = self.option.get_options_of_type(UnknownOption)
self.assertEqual(len(found_options), 0)
[docs] def test_get_option_of_type(self):
# Our test-cases have one OptionRequestOption
found_option = self.option.get_option_of_type(ClientIdOption)
self.assertIsInstance(found_option, ClientIdOption)
# But our test-cases don't have an UnknownOption in them
found_option = self.option.get_option_of_type(UnknownOption)
self.assertIsNone(found_option)
if __name__ == '__main__': # pragma: no cover
unittest.main()