1# Copyright (C) 2015 Red Hat, Inc.
2# Author: Petr Spacek <pspacek@redhat.com>
3#
4# Permission to use, copy, modify, and distribute this software and its
5# documentation for any purpose with or without fee is hereby granted,
6# provided that the above copyright notice and this permission notice
7# appear in all copies.
8#
9# THE SOFTWARE IS PROVIDED 'AS IS' AND RED HAT DISCLAIMS ALL WARRANTIES
10# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
12# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
15# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
17import unittest
18from io import BytesIO
19
20import dns.rrset
21import dns.rdtypes.ANY.EUI48
22import dns.rdtypes.ANY.EUI64
23import dns.exception
24
25
26class RdtypeAnyEUI48TestCase(unittest.TestCase):
27    def testInstOk(self):
28        '''Valid binary input.'''
29        eui = b'\x01\x23\x45\x67\x89\xab'
30        inst = dns.rdtypes.ANY.EUI48.EUI48(dns.rdataclass.IN,
31                                           dns.rdatatype.EUI48,
32                                           eui)
33        self.assertEqual(inst.eui, eui)
34
35    def testInstLength(self):
36        '''Incorrect input length.'''
37        eui = b'\x01\x23\x45\x67\x89\xab\xcd'
38        with self.assertRaises(dns.exception.FormError):
39            dns.rdtypes.ANY.EUI48.EUI48(dns.rdataclass.IN,
40                                        dns.rdatatype.EUI48,
41                                        eui)
42
43    def testFromTextOk(self):
44        '''Valid text input.'''
45        r1 = dns.rrset.from_text('foo', 300, 'IN', 'EUI48',
46                                 '01-23-45-67-89-ab')
47        eui = b'\x01\x23\x45\x67\x89\xab'
48        self.assertEqual(r1[0].eui, eui)
49
50    def testFromTextLength(self):
51        '''Invalid input length.'''
52        with self.assertRaises(dns.exception.SyntaxError):
53            dns.rrset.from_text('foo', 300, 'IN', 'EUI48',
54                                '00-01-23-45-67-89-ab')
55
56    def testFromTextDelim(self):
57        '''Invalid delimiter.'''
58        with self.assertRaises(dns.exception.SyntaxError):
59            dns.rrset.from_text('foo', 300, 'IN', 'EUI48', '01_23-45-67-89-ab')
60
61    def testFromTextExtraDash(self):
62        '''Extra dash instead of hex digit.'''
63        with self.assertRaises(dns.exception.SyntaxError):
64            dns.rrset.from_text('foo', 300, 'IN', 'EUI48', '0--23-45-67-89-ab')
65
66    def testFromTextMultipleTokens(self):
67        '''Invalid input divided to multiple tokens.'''
68        with self.assertRaises(dns.exception.SyntaxError):
69            dns.rrset.from_text('foo', 300, 'IN', 'EUI48', '01 23-45-67-89-ab')
70
71    def testFromTextInvalidHex(self):
72        '''Invalid hexadecimal input.'''
73        with self.assertRaises(dns.exception.SyntaxError):
74            dns.rrset.from_text('foo', 300, 'IN', 'EUI48', 'g0-23-45-67-89-ab')
75
76    def testToTextOk(self):
77        '''Valid text output.'''
78        eui = b'\x01\x23\x45\x67\x89\xab'
79        exp_text = '01-23-45-67-89-ab'
80        inst = dns.rdtypes.ANY.EUI48.EUI48(dns.rdataclass.IN,
81                                           dns.rdatatype.EUI48,
82                                           eui)
83        text = inst.to_text()
84        self.assertEqual(exp_text, text)
85
86    def testToWire(self):
87        '''Valid wire format.'''
88        eui = b'\x01\x23\x45\x67\x89\xab'
89        inst = dns.rdtypes.ANY.EUI48.EUI48(dns.rdataclass.IN,
90                                           dns.rdatatype.EUI48,
91                                           eui)
92        buff = BytesIO()
93        inst.to_wire(buff)
94        self.assertEqual(buff.getvalue(), eui)
95
96    def testFromWireOk(self):
97        '''Valid wire format.'''
98        eui = b'\x01\x23\x45\x67\x89\xab'
99        pad_len = 100
100        wire = dns.wiredata.WireData(b'x' * pad_len + eui + b'y' * pad_len * 2)
101        inst = dns.rdtypes.ANY.EUI48.EUI48.from_wire(dns.rdataclass.IN,
102                                                     dns.rdatatype.EUI48,
103                                                     wire,
104                                                     pad_len,
105                                                     len(eui))
106        self.assertEqual(inst.eui, eui)
107
108    def testFromWireLength(self):
109        '''Valid wire format.'''
110        eui = b'\x01\x23\x45\x67\x89'
111        pad_len = 100
112        wire = dns.wiredata.WireData(b'x' * pad_len + eui + b'y' * pad_len * 2)
113        with self.assertRaises(dns.exception.FormError):
114            dns.rdtypes.ANY.EUI48.EUI48.from_wire(dns.rdataclass.IN,
115                                                  dns.rdatatype.EUI48,
116                                                  wire,
117                                                  pad_len,
118                                                  len(eui))
119
120
121class RdtypeAnyEUI64TestCase(unittest.TestCase):
122    def testInstOk(self):
123        '''Valid binary input.'''
124        eui = b'\x01\x23\x45\x67\x89\xab\xcd\xef'
125        inst = dns.rdtypes.ANY.EUI64.EUI64(dns.rdataclass.IN,
126                                           dns.rdatatype.EUI64,
127                                           eui)
128        self.assertEqual(inst.eui, eui)
129
130    def testInstLength(self):
131        '''Incorrect input length.'''
132        eui = b'\x01\x23\x45\x67\x89\xab'
133        with self.assertRaises(dns.exception.FormError):
134            dns.rdtypes.ANY.EUI64.EUI64(dns.rdataclass.IN,
135                                        dns.rdatatype.EUI64,
136                                        eui)
137
138    def testFromTextOk(self):
139        '''Valid text input.'''
140        r1 = dns.rrset.from_text('foo', 300, 'IN', 'EUI64',
141                                 '01-23-45-67-89-ab-cd-ef')
142        eui = b'\x01\x23\x45\x67\x89\xab\xcd\xef'
143        self.assertEqual(r1[0].eui, eui)
144
145    def testFromTextLength(self):
146        '''Invalid input length.'''
147        with self.assertRaises(dns.exception.SyntaxError):
148            dns.rrset.from_text('foo', 300, 'IN', 'EUI64',
149                                '01-23-45-67-89-ab')
150
151    def testFromTextDelim(self):
152        '''Invalid delimiter.'''
153        with self.assertRaises(dns.exception.SyntaxError):
154            dns.rrset.from_text('foo', 300, 'IN', 'EUI64',
155                                '01_23-45-67-89-ab-cd-ef')
156
157    def testFromTextExtraDash(self):
158        '''Extra dash instead of hex digit.'''
159        with self.assertRaises(dns.exception.SyntaxError):
160            dns.rrset.from_text('foo', 300, 'IN', 'EUI64',
161                                '0--23-45-67-89-ab-cd-ef')
162
163    def testFromTextMultipleTokens(self):
164        '''Invalid input divided to multiple tokens.'''
165        with self.assertRaises(dns.exception.SyntaxError):
166            dns.rrset.from_text('foo', 300, 'IN', 'EUI64',
167                                '01 23-45-67-89-ab-cd-ef')
168
169    def testFromTextInvalidHex(self):
170        '''Invalid hexadecimal input.'''
171        with self.assertRaises(dns.exception.SyntaxError):
172            dns.rrset.from_text('foo', 300, 'IN', 'EUI64',
173                                'g0-23-45-67-89-ab-cd-ef')
174
175    def testToTextOk(self):
176        '''Valid text output.'''
177        eui = b'\x01\x23\x45\x67\x89\xab\xcd\xef'
178        exp_text = '01-23-45-67-89-ab-cd-ef'
179        inst = dns.rdtypes.ANY.EUI64.EUI64(dns.rdataclass.IN,
180                                           dns.rdatatype.EUI64,
181                                           eui)
182        text = inst.to_text()
183        self.assertEqual(exp_text, text)
184
185    def testToWire(self):
186        '''Valid wire format.'''
187        eui = b'\x01\x23\x45\x67\x89\xab\xcd\xef'
188        inst = dns.rdtypes.ANY.EUI64.EUI64(dns.rdataclass.IN,
189                                           dns.rdatatype.EUI64,
190                                           eui)
191        buff = BytesIO()
192        inst.to_wire(buff)
193        self.assertEqual(buff.getvalue(), eui)
194
195    def testFromWireOk(self):
196        '''Valid wire format.'''
197        eui = b'\x01\x23\x45\x67\x89\xab\xcd\xef'
198        pad_len = 100
199        wire = dns.wiredata.WireData(b'x' * pad_len + eui + b'y' * pad_len * 2)
200        inst = dns.rdtypes.ANY.EUI64.EUI64.from_wire(dns.rdataclass.IN,
201                                                     dns.rdatatype.EUI64,
202                                                     wire,
203                                                     pad_len,
204                                                     len(eui))
205        self.assertEqual(inst.eui, eui)
206
207    def testFromWireLength(self):
208        '''Valid wire format.'''
209        eui = b'\x01\x23\x45\x67\x89'
210        pad_len = 100
211        wire = dns.wiredata.WireData(b'x' * pad_len + eui + b'y' * pad_len * 2)
212        with self.assertRaises(dns.exception.FormError):
213            dns.rdtypes.ANY.EUI64.EUI64.from_wire(dns.rdataclass.IN,
214                                                  dns.rdatatype.EUI64,
215                                                  wire,
216                                                  pad_len,
217                                                  len(eui))
218
219
220if __name__ == '__main__':
221    unittest.main()
222