import ipaddress import socket import textwrap import urllib import pytest import dynv6_update_zone def test_host_addresses(monkeypatch): ipv6 = "2001:db8::" def _getaddrinfo(*args, **kwargs): return [ (socket.AF_INET6, socket.SOCK_STREAM, 0, "", (ipv6, 0, 0, 0)), (socket.AF_INET, socket.SOCK_STREAM, 6, "", ("192.0.2.1", 0)), ] monkeypatch.setattr("socket.getaddrinfo", _getaddrinfo) assert dynv6_update_zone.host_addresses("a.b.c") == {ipaddress.IPv6Address(ipv6)} def test_host_addresses_error(monkeypatch): exc = Exception("uh oh!") def _getaddrinfo(*args, **kwargs): raise exc monkeypatch.setattr("socket.getaddrinfo", _getaddrinfo) with pytest.raises(dynv6_update_zone.HostnameResolutionError) as exc_info: dynv6_update_zone.host_addresses("a.b.c") assert exc_info.value.__cause__ is exc def test_local_addresses(monkeypatch): def _check_output(*args, **kwargs): return textwrap.dedent( """ 2: wlp0s20f3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 inet6 2001:db8::1/64 scope global temporary dynamic valid_lft 86149sec preferred_lft 82736sec inet6 2001:db8::2/64 scope global dynamic mngtmpaddr noprefixroute valid_lft 86149sec preferred_lft 86149sec """ ).encode() monkeypatch.setattr("subprocess.check_output", _check_output) assert dynv6_update_zone.local_addresses(network="2001:db8::/64") == { ipaddress.IPv6Address("2001:db8::1"), ipaddress.IPv6Address("2001:db8::2"), } def test_local_addresses_error(monkeypatch): exc = Exception("uh oh!") def _check_output(*args, **kwargs): raise exc monkeypatch.setattr("subprocess.check_output", _check_output) with pytest.raises(dynv6_update_zone.AddressRetrievalError) as exc_info: dynv6_update_zone.local_addresses(network="2001:db8::/64") assert exc_info.value.__cause__ is exc def test_unordered_list(): assert ( dynv6_update_zone.unordered_list(["a", "b", "c"], prefix="* ") == "* a\n* b\n* c" ) def test_update_gaierror(monkeypatch, caplog): monkeypatch.setenv("token", "abc123") err = -2 msg = "Name or service not known" def _urlopen(*args, **kwargs): raise urllib.error.URLError(socket.gaierror(err, msg)) monkeypatch.setattr("urllib.request.urlopen", _urlopen) with pytest.raises(dynv6_update_zone.ZoneUpdateError): dynv6_update_zone.update_zone("a.b.c") [record] = caplog.records assert record.levelname == "ERROR" assert record.msg == f"{dynv6_update_zone.UPDATE_URL.netloc}: [Errno {err}] {msg}" def test_update_502(monkeypatch, caplog): monkeypatch.setenv("token", "abc123") monkeypatch.setattr( "dynv6_update_zone.UPDATE_URL", urllib.parse.urlsplit("https://httpbin.org/status/502"), ) with pytest.raises(dynv6_update_zone.ZoneUpdateError): dynv6_update_zone.update_zone("a.b.c") [record] = caplog.records assert record.levelname == "ERROR" assert ( record.msg == f"{dynv6_update_zone.UPDATE_URL.netloc}: HTTP Error 502: BAD GATEWAY" )