backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / tests / unit / packet / test_lldp.py
1 # Copyright (C) 2013 Nippon Telegraph and Telephone Corporation.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 # implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 # vim: tabstop=4 shiftwidth=4 softtabstop=4
17
18 import unittest
19 import logging
20 import six
21 import struct
22 import inspect
23 from nose.tools import ok_, eq_, nottest
24
25 from ryu.ofproto import ether
26 from ryu.lib.packet import packet
27 from ryu.lib.packet import ethernet
28 from ryu.lib.packet import lldp
29 from ryu.lib import addrconv
30
31 LOG = logging.getLogger(__name__)
32
33
34 class TestLLDPMandatoryTLV(unittest.TestCase):
35     def setUp(self):
36         # sample data is based on:
37         # http://wiki.wireshark.org/LinkLayerDiscoveryProtocol
38         #
39         # mandatory TLV only
40         self.data = b'\x01\x80\xc2\x00\x00\x0e\x00\x04' \
41                     + b'\x96\x1f\xa7\x26\x88\xcc\x02\x07' \
42                     + b'\x04\x00\x04\x96\x1f\xa7\x26\x04' \
43                     + b'\x04\x05\x31\x2f\x33\x06\x02\x00' \
44                     + b'\x78\x00\x00'
45
46     def tearDown(self):
47         pass
48
49     def test_get_tlv_type(self):
50         buf = b'\x02\x07\x04\x00\x04\x96\x1f\xa7\x26'
51         eq_(lldp.LLDPBasicTLV.get_type(buf), lldp.LLDP_TLV_CHASSIS_ID)
52
53     def test_parse_without_ethernet(self):
54         buf = self.data[ethernet.ethernet._MIN_LEN:]
55         (lldp_pkt, cls, rest_buf) = lldp.lldp.parser(buf)
56         eq_(len(rest_buf), 0)
57
58         tlvs = lldp_pkt.tlvs
59         eq_(tlvs[0].tlv_type, lldp.LLDP_TLV_CHASSIS_ID)
60         eq_(tlvs[0].len, 7)
61         eq_(tlvs[0].subtype, lldp.ChassisID.SUB_MAC_ADDRESS)
62         eq_(tlvs[0].chassis_id, b'\x00\x04\x96\x1f\xa7\x26')
63         eq_(tlvs[1].tlv_type, lldp.LLDP_TLV_PORT_ID)
64         eq_(tlvs[1].len, 4)
65         eq_(tlvs[1].subtype, lldp.PortID.SUB_INTERFACE_NAME)
66         eq_(tlvs[1].port_id, b'1/3')
67         eq_(tlvs[2].tlv_type, lldp.LLDP_TLV_TTL)
68         eq_(tlvs[2].len, 2)
69         eq_(tlvs[2].ttl, 120)
70         eq_(tlvs[3].tlv_type, lldp.LLDP_TLV_END)
71
72     def test_parse(self):
73         buf = self.data
74         pkt = packet.Packet(buf)
75         i = iter(pkt)
76
77         eq_(type(next(i)), ethernet.ethernet)
78         eq_(type(next(i)), lldp.lldp)
79
80     def test_tlv(self):
81         tlv = lldp.ChassisID(subtype=lldp.ChassisID.SUB_MAC_ADDRESS,
82                              chassis_id=b'\x00\x04\x96\x1f\xa7\x26')
83         eq_(tlv.tlv_type, lldp.LLDP_TLV_CHASSIS_ID)
84         eq_(tlv.len, 7)
85         (typelen, ) = struct.unpack('!H', b'\x02\x07')
86         eq_(tlv.typelen, typelen)
87
88     def test_serialize_without_ethernet(self):
89         tlv_chassis_id = lldp.ChassisID(subtype=lldp.ChassisID.SUB_MAC_ADDRESS,
90                                         chassis_id=b'\x00\x04\x96\x1f\xa7\x26')
91         tlv_port_id = lldp.PortID(subtype=lldp.PortID.SUB_INTERFACE_NAME,
92                                   port_id=b'1/3')
93         tlv_ttl = lldp.TTL(ttl=120)
94         tlv_end = lldp.End()
95         tlvs = (tlv_chassis_id, tlv_port_id, tlv_ttl, tlv_end)
96         lldp_pkt = lldp.lldp(tlvs)
97
98         eq_(lldp_pkt.serialize(None, None),
99             self.data[ethernet.ethernet._MIN_LEN:])
100
101     def test_serialize(self):
102         pkt = packet.Packet()
103
104         dst = lldp.LLDP_MAC_NEAREST_BRIDGE
105         src = '00:04:96:1f:a7:26'
106         ethertype = ether.ETH_TYPE_LLDP
107         eth_pkt = ethernet.ethernet(dst, src, ethertype)
108         pkt.add_protocol(eth_pkt)
109
110         tlv_chassis_id = lldp.ChassisID(subtype=lldp.ChassisID.SUB_MAC_ADDRESS,
111                                         chassis_id=addrconv.mac.
112                                         text_to_bin(src))
113         tlv_port_id = lldp.PortID(subtype=lldp.PortID.SUB_INTERFACE_NAME,
114                                   port_id=b'1/3')
115         tlv_ttl = lldp.TTL(ttl=120)
116         tlv_end = lldp.End()
117         tlvs = (tlv_chassis_id, tlv_port_id, tlv_ttl, tlv_end)
118         lldp_pkt = lldp.lldp(tlvs)
119         pkt.add_protocol(lldp_pkt)
120
121         eq_(len(pkt.protocols), 2)
122
123         pkt.serialize()
124
125         # Note: If ethernet frame is less than 60 bytes length,
126         # ethernet.ethernet() appends padding to the payload.
127         # So, we splits the serialized data to compare.
128         data_len = len(self.data)
129         pkt_data_lldp = pkt.data[:data_len]
130         pkt_data_pad = pkt.data[data_len:]
131         eq_(b'\x00' * (60 - data_len), pkt_data_pad)
132
133         eq_(self.data, pkt_data_lldp)
134
135     def test_to_string(self):
136         chassis_id = lldp.ChassisID(subtype=lldp.ChassisID.SUB_MAC_ADDRESS,
137                                     chassis_id=b'\x00\x04\x96\x1f\xa7\x26')
138         port_id = lldp.PortID(subtype=lldp.PortID.SUB_INTERFACE_NAME,
139                               port_id=b'1/3')
140         ttl = lldp.TTL(ttl=120)
141         end = lldp.End()
142         tlvs = (chassis_id, port_id, ttl, end)
143         lldp_pkt = lldp.lldp(tlvs)
144
145         chassis_id_values = {'subtype': lldp.ChassisID.SUB_MAC_ADDRESS,
146                              'chassis_id': b'\x00\x04\x96\x1f\xa7\x26',
147                              'len': chassis_id.len,
148                              'typelen': chassis_id.typelen}
149         _ch_id_str = ','.join(['%s=%s' % (k, repr(chassis_id_values[k]))
150                                for k, v in inspect.getmembers(chassis_id)
151                                if k in chassis_id_values])
152         tlv_chassis_id_str = '%s(%s)' % (lldp.ChassisID.__name__, _ch_id_str)
153
154         port_id_values = {'subtype': port_id.subtype,
155                           'port_id': port_id.port_id,
156                           'len': port_id.len,
157                           'typelen': port_id.typelen}
158         _port_id_str = ','.join(['%s=%s' % (k, repr(port_id_values[k]))
159                                  for k, v in inspect.getmembers(port_id)
160                                  if k in port_id_values])
161         tlv_port_id_str = '%s(%s)' % (lldp.PortID.__name__, _port_id_str)
162
163         ttl_values = {'ttl': ttl.ttl,
164                       'len': ttl.len,
165                       'typelen': ttl.typelen}
166         _ttl_str = ','.join(['%s=%s' % (k, repr(ttl_values[k]))
167                              for k, v in inspect.getmembers(ttl)
168                              if k in ttl_values])
169         tlv_ttl_str = '%s(%s)' % (lldp.TTL.__name__, _ttl_str)
170
171         end_values = {'len': end.len,
172                       'typelen': end.typelen}
173         _end_str = ','.join(['%s=%s' % (k, repr(end_values[k]))
174                              for k, v in inspect.getmembers(end)
175                              if k in end_values])
176         tlv_end_str = '%s(%s)' % (lldp.End.__name__, _end_str)
177
178         _tlvs_str = '(%s, %s, %s, %s)'
179         tlvs_str = _tlvs_str % (tlv_chassis_id_str,
180                                 tlv_port_id_str,
181                                 tlv_ttl_str,
182                                 tlv_end_str)
183
184         _lldp_str = '%s(tlvs=%s)'
185         lldp_str = _lldp_str % (lldp.lldp.__name__,
186                                 tlvs_str)
187
188         eq_(str(lldp_pkt), lldp_str)
189         eq_(repr(lldp_pkt), lldp_str)
190
191     def test_json(self):
192         chassis_id = lldp.ChassisID(subtype=lldp.ChassisID.SUB_MAC_ADDRESS,
193                                     chassis_id=b'\x00\x04\x96\x1f\xa7\x26')
194         port_id = lldp.PortID(subtype=lldp.PortID.SUB_INTERFACE_NAME,
195                               port_id=b'1/3')
196         ttl = lldp.TTL(ttl=120)
197         end = lldp.End()
198         tlvs = (chassis_id, port_id, ttl, end)
199         lldp1 = lldp.lldp(tlvs)
200         jsondict = lldp1.to_jsondict()
201         lldp2 = lldp.lldp.from_jsondict(jsondict['lldp'])
202         eq_(str(lldp1), str(lldp2))
203
204
205 class TestLLDPOptionalTLV(unittest.TestCase):
206     def setUp(self):
207         # sample data is based on:
208         # http://wiki.wireshark.org/LinkLayerDiscoveryProtocol
209         #
210         # include optional TLV
211         self.data = b'\x01\x80\xc2\x00\x00\x0e\x00\x01' \
212                     + b'\x30\xf9\xad\xa0\x88\xcc\x02\x07' \
213                     + b'\x04\x00\x01\x30\xf9\xad\xa0\x04' \
214                     + b'\x04\x05\x31\x2f\x31\x06\x02\x00' \
215                     + b'\x78\x08\x17\x53\x75\x6d\x6d\x69' \
216                     + b'\x74\x33\x30\x30\x2d\x34\x38\x2d' \
217                     + b'\x50\x6f\x72\x74\x20\x31\x30\x30' \
218                     + b'\x31\x00\x0a\x0d\x53\x75\x6d\x6d' \
219                     + b'\x69\x74\x33\x30\x30\x2d\x34\x38' \
220                     + b'\x00\x0c\x4c\x53\x75\x6d\x6d\x69' \
221                     + b'\x74\x33\x30\x30\x2d\x34\x38\x20' \
222                     + b'\x2d\x20\x56\x65\x72\x73\x69\x6f' \
223                     + b'\x6e\x20\x37\x2e\x34\x65\x2e\x31' \
224                     + b'\x20\x28\x42\x75\x69\x6c\x64\x20' \
225                     + b'\x35\x29\x20\x62\x79\x20\x52\x65' \
226                     + b'\x6c\x65\x61\x73\x65\x5f\x4d\x61' \
227                     + b'\x73\x74\x65\x72\x20\x30\x35\x2f' \
228                     + b'\x32\x37\x2f\x30\x35\x20\x30\x34' \
229                     + b'\x3a\x35\x33\x3a\x31\x31\x00\x0e' \
230                     + b'\x04\x00\x14\x00\x14\x10\x0e\x07' \
231                     + b'\x06\x00\x01\x30\xf9\xad\xa0\x02' \
232                     + b'\x00\x00\x03\xe9\x00\xfe\x07\x00' \
233                     + b'\x12\x0f\x02\x07\x01\x00\xfe\x09' \
234                     + b'\x00\x12\x0f\x01\x03\x6c\x00\x00' \
235                     + b'\x10\xfe\x09\x00\x12\x0f\x03\x01' \
236                     + b'\x00\x00\x00\x00\xfe\x06\x00\x12' \
237                     + b'\x0f\x04\x05\xf2\xfe\x06\x00\x80' \
238                     + b'\xc2\x01\x01\xe8\xfe\x07\x00\x80' \
239                     + b'\xc2\x02\x01\x00\x00\xfe\x17\x00' \
240                     + b'\x80\xc2\x03\x01\xe8\x10\x76\x32' \
241                     + b'\x2d\x30\x34\x38\x38\x2d\x30\x33' \
242                     + b'\x2d\x30\x35\x30\x35\x00\xfe\x05' \
243                     + b'\x00\x80\xc2\x04\x00\x00\x00'
244
245     def tearDown(self):
246         pass
247
248     def test_parse(self):
249         buf = self.data
250         pkt = packet.Packet(buf)
251         i = iter(pkt)
252
253         eq_(type(next(i)), ethernet.ethernet)
254         lldp_pkt = next(i)
255         eq_(type(lldp_pkt), lldp.lldp)
256
257         tlvs = lldp_pkt.tlvs
258
259         # Port Description
260         eq_(tlvs[3].tlv_type, lldp.LLDP_TLV_PORT_DESCRIPTION)
261         eq_(tlvs[3].port_description, b'Summit300-48-Port 1001\x00')
262
263         # System Name
264         eq_(tlvs[4].tlv_type, lldp.LLDP_TLV_SYSTEM_NAME)
265         eq_(tlvs[4].system_name, b'Summit300-48\x00')
266
267         # System Description
268
269         eq_(tlvs[5].tlv_type, lldp.LLDP_TLV_SYSTEM_DESCRIPTION)
270         eq_(tlvs[5].system_description,
271             b'Summit300-48 - Version 7.4e.1 (Build 5) '
272             + b'by Release_Master 05/27/05 04:53:11\x00')
273
274         # SystemCapabilities
275         eq_(tlvs[6].tlv_type, lldp.LLDP_TLV_SYSTEM_CAPABILITIES)
276         eq_(tlvs[6].system_cap & lldp.SystemCapabilities.CAP_MAC_BRIDGE,
277             lldp.SystemCapabilities.CAP_MAC_BRIDGE)
278         eq_(tlvs[6].enabled_cap & lldp.SystemCapabilities.CAP_MAC_BRIDGE,
279             lldp.SystemCapabilities.CAP_MAC_BRIDGE)
280         eq_(tlvs[6].system_cap & lldp.SystemCapabilities.CAP_TELEPHONE, 0)
281         eq_(tlvs[6].enabled_cap & lldp.SystemCapabilities.CAP_TELEPHONE, 0)
282
283         # Management Address
284         eq_(tlvs[7].tlv_type, lldp.LLDP_TLV_MANAGEMENT_ADDRESS)
285         eq_(tlvs[7].addr_len, 7)
286         eq_(tlvs[7].addr, b'\x00\x01\x30\xf9\xad\xa0')
287         eq_(tlvs[7].intf_num, 1001)
288
289         # Organizationally Specific
290         eq_(tlvs[8].tlv_type, lldp.LLDP_TLV_ORGANIZATIONALLY_SPECIFIC)
291         eq_(tlvs[8].oui, b'\x00\x12\x0f')  # IEEE 802.3
292         eq_(tlvs[8].subtype, 0x02)  # Power Via MDI
293
294         # End
295         eq_(tlvs[16].tlv_type, lldp.LLDP_TLV_END)
296
297     def test_parse_corrupted(self):
298         buf = self.data
299         pkt = packet.Packet(buf[:128])
300
301     def test_serialize(self):
302         pkt = packet.Packet()
303
304         dst = lldp.LLDP_MAC_NEAREST_BRIDGE
305         src = '00:01:30:f9:ad:a0'
306         ethertype = ether.ETH_TYPE_LLDP
307         eth_pkt = ethernet.ethernet(dst, src, ethertype)
308         pkt.add_protocol(eth_pkt)
309
310         tlv_chassis_id = lldp.ChassisID(subtype=lldp.ChassisID.SUB_MAC_ADDRESS,
311                                         chassis_id=addrconv.mac.
312                                         text_to_bin(src))
313         tlv_port_id = lldp.PortID(subtype=lldp.PortID.SUB_INTERFACE_NAME,
314                                   port_id=b'1/1')
315         tlv_ttl = lldp.TTL(ttl=120)
316         tlv_port_description = lldp.PortDescription(
317             port_description=b'Summit300-48-Port 1001\x00')
318         tlv_system_name = lldp.SystemName(system_name=b'Summit300-48\x00')
319         tlv_system_description = lldp.SystemDescription(
320             system_description=b'Summit300-48 - Version 7.4e.1 (Build 5) '
321                                + b'by Release_Master 05/27/05 04:53:11\x00')
322         tlv_system_capabilities = lldp.SystemCapabilities(
323             system_cap=0x14,
324             enabled_cap=0x14)
325         tlv_management_address = lldp.ManagementAddress(
326             addr_subtype=0x06, addr=b'\x00\x01\x30\xf9\xad\xa0',
327             intf_subtype=0x02, intf_num=1001,
328             oid=b'')
329         tlv_organizationally_specific = lldp.OrganizationallySpecific(
330             oui=b'\x00\x12\x0f', subtype=0x02, info=b'\x07\x01\x00')
331         tlv_end = lldp.End()
332         tlvs = (tlv_chassis_id, tlv_port_id, tlv_ttl, tlv_port_description,
333                 tlv_system_name, tlv_system_description,
334                 tlv_system_capabilities, tlv_management_address,
335                 tlv_organizationally_specific, tlv_end)
336         lldp_pkt = lldp.lldp(tlvs)
337         pkt.add_protocol(lldp_pkt)
338
339         eq_(len(pkt.protocols), 2)
340
341         pkt.serialize()
342
343         # self.data has many organizationally specific TLVs
344         data = six.binary_type(pkt.data[:-2])
345         eq_(data, self.data[:len(data)])
346
347     def test_to_string(self):
348         chassis_id = lldp.ChassisID(subtype=lldp.ChassisID.SUB_MAC_ADDRESS,
349                                     chassis_id=b'\x00\x01\x30\xf9\xad\xa0')
350         port_id = lldp.PortID(subtype=lldp.PortID.SUB_INTERFACE_NAME,
351                               port_id=b'1/1')
352         ttl = lldp.TTL(ttl=120)
353         port_desc = lldp.PortDescription(
354             port_description=b'Summit300-48-Port 1001\x00')
355         sys_name = lldp.SystemName(system_name=b'Summit300-48\x00')
356         sys_desc = lldp.SystemDescription(
357             system_description=b'Summit300-48 - Version 7.4e.1 (Build 5) '
358                                + b'by Release_Master 05/27/05 04:53:11\x00')
359         sys_cap = lldp.SystemCapabilities(
360             system_cap=0x14,
361             enabled_cap=0x14)
362         man_addr = lldp.ManagementAddress(
363             addr_subtype=0x06, addr=b'\x00\x01\x30\xf9\xad\xa0',
364             intf_subtype=0x02, intf_num=1001,
365             oid='')
366         org_spec = lldp.OrganizationallySpecific(
367             oui=b'\x00\x12\x0f', subtype=0x02, info=b'\x07\x01\x00')
368         end = lldp.End()
369         tlvs = (chassis_id, port_id, ttl, port_desc, sys_name,
370                 sys_desc, sys_cap, man_addr, org_spec, end)
371         lldp_pkt = lldp.lldp(tlvs)
372
373         # ChassisID string
374         chassis_id_values = {'subtype': lldp.ChassisID.SUB_MAC_ADDRESS,
375                              'chassis_id': b'\x00\x01\x30\xf9\xad\xa0',
376                              'len': chassis_id.len,
377                              'typelen': chassis_id.typelen}
378         _ch_id_str = ','.join(['%s=%s' % (k, repr(chassis_id_values[k]))
379                                for k, v in inspect.getmembers(chassis_id)
380                                if k in chassis_id_values])
381         tlv_chassis_id_str = '%s(%s)' % (lldp.ChassisID.__name__, _ch_id_str)
382
383         # PortID string
384         port_id_values = {'subtype': port_id.subtype,
385                           'port_id': port_id.port_id,
386                           'len': port_id.len,
387                           'typelen': port_id.typelen}
388         _port_id_str = ','.join(['%s=%s' % (k, repr(port_id_values[k]))
389                                  for k, v in inspect.getmembers(port_id)
390                                  if k in port_id_values])
391         tlv_port_id_str = '%s(%s)' % (lldp.PortID.__name__, _port_id_str)
392
393         # TTL string
394         ttl_values = {'ttl': ttl.ttl,
395                       'len': ttl.len,
396                       'typelen': ttl.typelen}
397         _ttl_str = ','.join(['%s=%s' % (k, repr(ttl_values[k]))
398                              for k, v in inspect.getmembers(ttl)
399                              if k in ttl_values])
400         tlv_ttl_str = '%s(%s)' % (lldp.TTL.__name__, _ttl_str)
401
402         # PortDescription string
403         port_desc_values = {'tlv_info': port_desc.tlv_info,
404                             'len': port_desc.len,
405                             'typelen': port_desc.typelen}
406         _port_desc_str = ','.join(['%s=%s' % (k, repr(port_desc_values[k]))
407                                    for k, v in inspect.getmembers(port_desc)
408                                    if k in port_desc_values])
409         tlv_port_desc_str = '%s(%s)' % (lldp.PortDescription.__name__,
410                                         _port_desc_str)
411
412         # SystemName string
413         sys_name_values = {'tlv_info': sys_name.tlv_info,
414                            'len': sys_name.len,
415                            'typelen': sys_name.typelen}
416         _system_name_str = ','.join(['%s=%s' % (k, repr(sys_name_values[k]))
417                                      for k, v in inspect.getmembers(sys_name)
418                                      if k in sys_name_values])
419         tlv_system_name_str = '%s(%s)' % (lldp.SystemName.__name__,
420                                           _system_name_str)
421
422         # SystemDescription string
423         sys_desc_values = {'tlv_info': sys_desc.tlv_info,
424                            'len': sys_desc.len,
425                            'typelen': sys_desc.typelen}
426         _sys_desc_str = ','.join(['%s=%s' % (k, repr(sys_desc_values[k]))
427                                   for k, v in inspect.getmembers(sys_desc)
428                                   if k in sys_desc_values])
429         tlv_sys_desc_str = '%s(%s)' % (lldp.SystemDescription.__name__,
430                                        _sys_desc_str)
431
432         # SystemCapabilities string
433         sys_cap_values = {'system_cap': 0x14,
434                           'enabled_cap': 0x14,
435                           'len': sys_cap.len,
436                           'typelen': sys_cap.typelen}
437         _sys_cap_str = ','.join(['%s=%s' % (k, repr(sys_cap_values[k]))
438                                  for k, v in inspect.getmembers(sys_cap)
439                                  if k in sys_cap_values])
440         tlv_sys_cap_str = '%s(%s)' % (lldp.SystemCapabilities.__name__,
441                                       _sys_cap_str)
442
443         # ManagementAddress string
444         man_addr_values = {'addr_subtype': 0x06,
445                            'addr': b'\x00\x01\x30\xf9\xad\xa0',
446                            'addr_len': man_addr.addr_len,
447                            'intf_subtype': 0x02,
448                            'intf_num': 1001,
449                            'oid': '',
450                            'oid_len': man_addr.oid_len,
451                            'len': man_addr.len,
452                            'typelen': man_addr.typelen}
453         _man_addr_str = ','.join(['%s=%s' % (k, repr(man_addr_values[k]))
454                                   for k, v in inspect.getmembers(man_addr)
455                                   if k in man_addr_values])
456         tlv_man_addr_str = '%s(%s)' % (lldp.ManagementAddress.__name__,
457                                        _man_addr_str)
458
459         # OrganizationallySpecific string
460         org_spec_values = {'oui': b'\x00\x12\x0f',
461                            'subtype': 0x02,
462                            'info': b'\x07\x01\x00',
463                            'len': org_spec.len,
464                            'typelen': org_spec.typelen}
465         _org_spec_str = ','.join(['%s=%s' % (k, repr(org_spec_values[k]))
466                                   for k, v in inspect.getmembers(org_spec)
467                                   if k in org_spec_values])
468         tlv_org_spec_str = '%s(%s)' % (lldp.OrganizationallySpecific.__name__,
469                                        _org_spec_str)
470
471         # End string
472         end_values = {'len': end.len,
473                       'typelen': end.typelen}
474         _end_str = ','.join(['%s=%s' % (k, repr(end_values[k]))
475                              for k, v in inspect.getmembers(end)
476                              if k in end_values])
477         tlv_end_str = '%s(%s)' % (lldp.End.__name__, _end_str)
478
479         # tlvs string
480         _tlvs_str = '(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)'
481         tlvs_str = _tlvs_str % (tlv_chassis_id_str,
482                                 tlv_port_id_str,
483                                 tlv_ttl_str,
484                                 tlv_port_desc_str,
485                                 tlv_system_name_str,
486                                 tlv_sys_desc_str,
487                                 tlv_sys_cap_str,
488                                 tlv_man_addr_str,
489                                 tlv_org_spec_str,
490                                 tlv_end_str)
491
492         # lldp string
493         _lldp_str = '%s(tlvs=%s)'
494         lldp_str = _lldp_str % (lldp.lldp.__name__,
495                                 tlvs_str)
496
497         eq_(str(lldp_pkt), lldp_str)
498         eq_(repr(lldp_pkt), lldp_str)
499
500     def test_json(self):
501         chassis_id = lldp.ChassisID(subtype=lldp.ChassisID.SUB_MAC_ADDRESS,
502                                     chassis_id=b'\x00\x01\x30\xf9\xad\xa0')
503         port_id = lldp.PortID(subtype=lldp.PortID.SUB_INTERFACE_NAME,
504                               port_id=b'1/1')
505         ttl = lldp.TTL(ttl=120)
506         port_desc = lldp.PortDescription(
507             port_description=b'Summit300-48-Port 1001\x00')
508         sys_name = lldp.SystemName(system_name=b'Summit300-48\x00')
509         sys_desc = lldp.SystemDescription(
510             system_description=b'Summit300-48 - Version 7.4e.1 (Build 5) '
511                                + b'by Release_Master 05/27/05 04:53:11\x00')
512         sys_cap = lldp.SystemCapabilities(
513             system_cap=0x14,
514             enabled_cap=0x14)
515         man_addr = lldp.ManagementAddress(
516             addr_subtype=0x06, addr=b'\x00\x01\x30\xf9\xad\xa0',
517             intf_subtype=0x02, intf_num=1001,
518             oid='')
519         org_spec = lldp.OrganizationallySpecific(
520             oui=b'\x00\x12\x0f', subtype=0x02, info=b'\x07\x01\x00')
521         end = lldp.End()
522         tlvs = (chassis_id, port_id, ttl, port_desc, sys_name,
523                 sys_desc, sys_cap, man_addr, org_spec, end)
524         lldp1 = lldp.lldp(tlvs)
525         jsondict = lldp1.to_jsondict()
526         lldp2 = lldp.lldp.from_jsondict(jsondict['lldp'])
527         eq_(str(lldp1), str(lldp2))