kellyjonbrazil / jc

CLI tool and python library that converts the output of popular command-line tools, file-types, and common strings to JSON, YAML, or Dictionaries. This allows piping of output to tools like jq and simplifying automation scripts.
MIT License
7.9k stars 210 forks source link

Python 3.12 test regression: `tests.test_ip_address.MyTests.test_ip_address_ipv6_6to4` #572

Open mgorny opened 5 months ago

mgorny commented 5 months ago

When running the test suite under Python 3.12.4, the following test fails:

$ python3.12 -m unittest tests/test_ip_address.py 
.....F......
======================================================================
FAIL: test_ip_address_ipv6_6to4 (tests.test_ip_address.MyTests.test_ip_address_ipv6_6to4)
Test ipv6 6to4 address string
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/jc/tests/test_ip_address.py", line 103, in test_ip_address_ipv6_6to4
    self.assertEqual(jc.parsers.ip_address.parse(data, quiet=True), expected)
AssertionError: {'ver[768 chars]te': True, 'is_global': False, 'is_link_local'[1797 chars]10'}} != {'ver[768 chars]te': False, 'is_global': True, 'is_link_local'[1797 chars]10'}}
  {'bin': {'broadcast': '00100000000000101100000000000000000000100000010011111111111111111111111111111111111111111111111111111111111111111111111111111111',
           'first_host': '00100000000000101100000000000000000000100000010000000000000000000000000000000000000000000000000000000000000000000000000000000001',
           'hostmask': '00000000000000000000000000000000000000000000000011111111111111111111111111111111111111111111111111111111111111111111111111111111',
           'ip': '00100000000000101100000000000000000000100000010000000000000000000000000000000000000000000000000000000000000000000000000000000000',
           'last_host': '00100000000000101100000000000000000000100000010011111111111111111111111111111111111111111111111111111111111111111111111111111110',
           'netmask': '11111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000',
           'network': '00100000000000101100000000000000000000100000010000000000000000000000000000000000000000000000000000000000000000000000000000000000'},
   'broadcast': '2002:c000:204:ffff:ffff:ffff:ffff:ffff',
   'cidr_netmask': 48,
   'dns_ptr': '0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.4.0.2.0.0.0.0.c.2.0.0.2.ip6.arpa',
   'first_host': '2002:c000:204::1',
   'hex': {'broadcast': '20:02:c0:00:02:04:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff',
           'first_host': '20:02:c0:00:02:04:00:00:00:00:00:00:00:00:00:01',
           'hostmask': '00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff',
           'ip': '20:02:c0:00:02:04:00:00:00:00:00:00:00:00:00:00',
           'last_host': '20:02:c0:00:02:04:ff:ff:ff:ff:ff:ff:ff:ff:ff:fe',
           'netmask': 'ff:ff:ff:ff:ff:ff:00:00:00:00:00:00:00:00:00:00',
           'network': '20:02:c0:00:02:04:00:00:00:00:00:00:00:00:00:00'},
   'hostmask': '::ffff:ffff:ffff:ffff:ffff',
   'hosts': 1208925819614629174706174,
   'int': {'broadcast': 42549574682103293357641048077199474687,
           'first_host': 42549574682102084431821433448024768513,
           'ip': 42549574682102084431821433448024768512,
           'last_host': 42549574682103293357641048077199474686,
           'network': 42549574682102084431821433448024768512},
   'ip': '2002:c000:204::',
   'ip_compressed': '2002:c000:204::',
   'ip_exploded': '2002:c000:0204:0000:0000:0000:0000:0000',
   'ip_split': ['2002', 'c000', '0204', '0000', '0000', '0000', '0000', '0000'],
   'ipv4_mapped': None,
-  'is_global': False,
?               ^^^^

+  'is_global': True,
?               ^^^

   'is_link_local': False,
   'is_loopback': False,
   'is_multicast': False,
-  'is_private': True,
?                ^^^

+  'is_private': False,
?                ^^^^

   'is_reserved': False,
   'is_unspecified': False,
   'last_host': '2002:c000:204:ffff:ffff:ffff:ffff:fffe',
   'max_prefix_length': 128,
   'netmask': 'ffff:ffff:ffff::',
   'network': '2002:c000:204::',
   'scope_id': None,
   'six_to_four': '192.0.2.4',
   'teredo_client': None,
   'teredo_server': None,
   'version': 6}

----------------------------------------------------------------------
Ran 12 tests in 0.009s

FAILED (failures=1)

It seems to pass with 3.11 and older.

Note I had to add maxDiff = None to get a diff there.

kellyjonbrazil commented 5 months ago

Hi, thanks for reporting this!

I'm seeing tests passing for Python 3.12 in Github Actions.

Maybe it's a difference in underlying hardware?

mgorny commented 5 months ago

I've been able to reproduce it both in Gentoo packaging process that uses an isolated network namespace with just the loopback interface, and on my regular system.

The ifconfig from the test setup is:

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536                                                                                           
        inet 127.0.0.1  netmask 255.0.0.0               
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        inet6 fd::1  prefixlen 8  scopeid 0x0<global>                                                                                  
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)                                                                                                  
        RX errors 0  dropped 0  overruns 0  frame 0                
        TX packets 0  bytes 0 (0.0 B)        
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0       
mgorny commented 5 months ago

I've got another data point: the test passes with Python 3.12.3 but fails with 3.12.4. FWICS GitHub Actions are stuck on .3 for some reason.

The log for 3.12.4 says:

Fixed is_global and is_private behavior in IPv4Address, IPv6Address, IPv4Network and IPv6Network.

https://docs.python.org/3.12/whatsnew/3.12.html#ipaddress

kellyjonbrazil commented 5 months ago

Thanks! I'll have to figure out how to update the tests for this.

mgorny commented 5 months ago

This seems to be cause by python/cpython@f86b17ac511e68192ba71f27e752321a3252cee3, particularly:

+        # IANA says N/A, let's consider it not globally reachable to be safe
+        IPv6Network('2002::/16'),

Perhaps the simplest solution would be to avoid this particular range, since it's "undefined" by IANA.

kellyjonbrazil commented 5 months ago

Good call! Thanks for the research.

kellyjonbrazil commented 5 months ago

Hmmm... after looking at this I'm not sure if I can use another range because this test is specifically testing 6to4 addressing which is in this network space. I may just need to do a python version check and allow either value depending on the version.

mgorny commented 5 months ago

Ah, right then. According to the documentation, the results changed in 3.12.4 and 3.13.0, so I guess you can just check for >= (3, 12, 4).

sudipm-mukherjee commented 5 months ago

@kellyjonbrazil I am also seeing this test failure in Debian.

mgorny commented 5 months ago

I'm going to try making a pull request.

kellyjonbrazil commented 5 months ago

Thanks for the PR - I'll get that in the next release.