File: test_ipv6_strategy.py

package info (click to toggle)
python-netaddr 1.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 9,912 kB
  • sloc: xml: 8,264; python: 6,697; makefile: 198; sh: 5
file content (172 lines) | stat: -rw-r--r-- 5,730 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
import platform

import pytest

from netaddr import AddrFormatError
from netaddr.strategy import ipv6
from netaddr.tests import IS_MUSL


def test_strategy_ipv6():
    b = '0000000000000000:0000000000000000:0000000000000000:0000000000000000:0000000000000000:0000000000000000:1111111111111111:1111111111111110'
    i = 4294967294
    t = (0, 0, 0, 0, 0, 0, 0xFFFF, 0xFFFE)
    s = '::255.255.255.254'
    p = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xfe'

    assert ipv6.bits_to_int(b) == i
    assert ipv6.int_to_bits(i) == b

    # musl renders IPv4-compatible IPv6 addresses like any other IPv6 address.
    assert ipv6.int_to_str(i) == s if not IS_MUSL else '::ffff:fffe'
    assert ipv6.str_to_int(s) == i

    assert ipv6.int_to_words(i) == t
    assert ipv6.words_to_int(t) == i
    assert ipv6.words_to_int(list(t)) == i

    assert ipv6.int_to_packed(i) == p
    assert ipv6.packed_to_int(p) == 4294967294


@pytest.mark.parametrize(
    'str_value',
    (
        '2001:0db8:0000:0000:0000:0000:1428:57ab',
        '2001:0db8:0000:0000:0000::1428:57ab',
        '2001:0db8:0:0:0:0:1428:57ab',
        '2001:0db8:0:0::1428:57ab',
        '2001:0db8::1428:57ab',
        '2001:0DB8:0000:0000:0000:0000:1428:57AB',
        '2001:DB8::1428:57AB',
    ),
)
def test_strategy_ipv6_equivalent_variants(str_value):
    assert ipv6.str_to_int(str_value) == 42540766411282592856903984951992014763


@pytest.mark.parametrize(
    'str_value',
    (
        #   Long forms.
        'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210',
        '1080:0:0:0:8:800:200C:417A',  #   a unicast address
        'FF01:0:0:0:0:0:0:43',  #   a multicast address
        '0:0:0:0:0:0:0:1',  #   the loopback address
        '0:0:0:0:0:0:0:0',  #   the unspecified addresses
        #   Short forms.
        '1080::8:800:200C:417A',  #   a unicast address
        'FF01::43',  #   a multicast address
        '::1',  #   the loopback address
        '::',  #   the unspecified addresses
        #   IPv4 compatible forms.
        '::192.0.2.1',
        '::ffff:192.0.2.1',
        '0:0:0:0:0:0:192.0.2.1',
        '0:0:0:0:0:FFFF:192.0.2.1',
        '0:0:0:0:0:0:13.1.68.3',
        '0:0:0:0:0:FFFF:129.144.52.38',
        '::13.1.68.3',
        '::FFFF:129.144.52.38',
        #   Other tests.
        '1::',
        '::ffff',
        'ffff::',
        'ffff::ffff',
        '0:1:2:3:4:5:6:7',
        '8:9:a:b:c:d:e:f',
        '0:0:0:0:0:0:0:0',
        'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
    ),
)
def test_strategy_ipv6_valid_str(str_value):
    assert ipv6.valid_str(str_value)


@pytest.mark.parametrize(
    'str_value',
    (
        '',
        'g:h:i:j:k:l:m:n',  # bad chars.
        '0:0:0:0:0:0:0:0:0',  # too long,
    ),
)
def test_strategy_ipv6_is_not_valid_str(str_value):
    assert not ipv6.valid_str(str_value)


@pytest.mark.parametrize(
    'str_value',
    (
        [],
        (),
        {},
        True,
        False,
        192,
    ),
)
def test_valid_str_unexpected_types(str_value):
    with pytest.raises(TypeError):
        ipv6.valid_str(str_value)


@pytest.mark.parametrize(
    ('long_form', 'short_form'),
    (
        ('FEDC:BA98:7654:3210:FEDC:BA98:7654:3210', 'fedc:ba98:7654:3210:fedc:ba98:7654:3210'),
        ('1080:0:0:0:8:800:200C:417A', '1080::8:800:200c:417a'),  # unicast address
        ('FF01:0:0:0:0:0:0:43', 'ff01::43'),  # multicast address
        ('0:0:0:0:0:0:0:1', '::1'),  # loopback address
        ('0:0:0:0:0:0:0:0', '::'),  # unspecified addresses
    ),
)
def test_strategy_ipv6_string_compaction(long_form, short_form):
    int_val = ipv6.str_to_int(long_form)
    calc_short_form = ipv6.int_to_str(int_val)
    assert calc_short_form == short_form


def test_strategy_ipv6_mapped_and_compatible_ipv4_string_formatting():
    # musl renders IPv4-compatible IPv6 addresses like any other IPv6 address.
    assert ipv6.int_to_str(0xFFFFFF) == '::0.255.255.255' if not IS_MUSL else '::ff:ffff'
    assert ipv6.int_to_str(0xFFFFFFFF) == '::255.255.255.255' if not IS_MUSL else '::ffff:ffff'

    assert ipv6.int_to_str(0x1FFFFFFFF) == '::1:ffff:ffff'
    assert ipv6.int_to_str(0xFFFFFFFFFFFF) == '::ffff:255.255.255.255'
    assert ipv6.int_to_str(0xFFFEFFFFFFFF) == '::fffe:ffff:ffff'
    assert ipv6.int_to_str(0xFFFFFFFFFFFF) == '::ffff:255.255.255.255'
    assert ipv6.int_to_str(0xFFFFFFFFFFF1) == '::ffff:255.255.255.241'
    assert ipv6.int_to_str(0xFFFFFFFFFFFE) == '::ffff:255.255.255.254'
    assert ipv6.int_to_str(0xFFFFFFFFFF00) == '::ffff:255.255.255.0'
    assert ipv6.int_to_str(0xFFFFFFFF0000) == '::ffff:255.255.0.0'
    assert ipv6.int_to_str(0xFFFFFF000000) == '::ffff:255.0.0.0'
    assert ipv6.int_to_str(0xFFFF000000) == '::ff:ff00:0'
    assert ipv6.int_to_str(0x1FFFF00000000) == '::1:ffff:0:0'
    # So this is strange. Even though on Windows we get decimal notation in a lot of the addresses above,
    # in case of 0.0.0.0 we get hex instead. Worth investigating, putting
    # the conditional assert here for now to make this visible.
    if platform.system() == 'Windows':
        assert ipv6.int_to_str(0xFFFF00000000) == '::ffff:0:0'
    else:
        assert ipv6.int_to_str(0xFFFF00000000) == '::ffff:0.0.0.0'


def test_strategy_ipv6_str_to_int_behaviour_legacy_mode():
    assert ipv6.str_to_int('::127') == 295

    with pytest.raises(AddrFormatError):
        ipv6.str_to_int('::0x7f')

    assert ipv6.str_to_int('::0177') == 375

    with pytest.raises(AddrFormatError):
        ipv6.str_to_int('::127.1')

    with pytest.raises(AddrFormatError):
        ipv6.str_to_int('::0x7f.1')

    with pytest.raises(AddrFormatError):
        ipv6.str_to_int('::0177.1')

    assert ipv6.str_to_int('::127.0.0.1') == 2130706433