]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add XFR max-transfer-time-out and max-tranfer-idle-out system tests
authorOndřej Surý <ondrej@isc.org>
Tue, 8 Feb 2022 20:32:10 +0000 (21:32 +0100)
committerOndřej Surý <ondrej@isc.org>
Thu, 17 Feb 2022 21:59:24 +0000 (22:59 +0100)
Extend the timeouts system test to ensure that the maximum outgoing
transfer time (max-transfer-time-out) and maximum outgoing transfer idle
time (max-transfer-idle-out) works as expected.  This is done by
lowering the limits to 5/1 minutes and testing that the connection has
been dropped while sleeping between the individual XFR messages.

(cherry picked from commit 8fed1b64618a1625dd1efc2d7cd8983284b1f4a5)

bin/tests/system/timeouts/conftest.py
bin/tests/system/timeouts/ns1/named.conf.in
bin/tests/system/timeouts/tests-tcp.py

index 0ce749b3fda87eb4734de6e8304cd216806a3d05..d92d87f72c1d2e59fdbf759ced2b3b9c6de70eaf 100644 (file)
@@ -20,6 +20,9 @@ def pytest_configure(config):
     config.addinivalue_line(
         "markers", "dnspython2: mark tests that need dnspython >= 2.0.0"
     )
+    config.addinivalue_line(
+        "markers", "long: mark tests that take a long time to run"
+    )
 
 
 def pytest_collection_modifyitems(config, items):
@@ -46,6 +49,13 @@ def pytest_collection_modifyitems(config, items):
             if "dnspython2" in item.keywords:
                 item.add_marker(skip_dnspython2)
 
+    skip_long_tests = pytest.mark.skip(
+        reason="need CI_ENABLE_ALL_TESTS environment variable")
+    if not os.environ.get("CI_ENABLE_ALL_TESTS"):
+        for item in items:
+            if "long" in item.keywords:
+                item.add_marker(skip_long_tests)
+
 
 @pytest.fixture
 def port(request):
index c9a7a6b42e2a600ffd0e6b0a12e1700c9f20c89e..4b422e22b288a930757148e21f09e3930e6a5fc4 100644 (file)
@@ -30,6 +30,8 @@ options {
        tcp-initial-timeout 20;
        tcp-idle-timeout 50;
        tcp-keepalive-timeout 70;
+       max-transfer-time-out 5; /* minutes */
+       max-transfer-idle-out 1; /* minutes */
 };
 
 zone "." {
index e1f19608c8a59357fbcb9bc227fcb4ce17a83029..a1c94839ea55c5409941d1e57ecf49a4dbb4286f 100644 (file)
@@ -220,3 +220,76 @@ def test_send_timeout(port):
                 (response, rtime) = dns.query.receive_tcp(sock, timeout())
             except ConnectionError as e:
                 raise EOFError from e
+
+
+@pytest.mark.dnspython
+@pytest.mark.dnspython2
+@pytest.mark.long
+def test_max_transfer_idle_out(port):
+    import dns.query
+    import dns.rdataclass
+    import dns.rdatatype
+
+    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
+        sock.connect(("10.53.0.1", port))
+
+        name = dns.name.from_text("example.")
+        msg = create_msg("example.", "AXFR")
+        (sbytes, stime) = dns.query.send_tcp(sock, msg, timeout())
+
+        # Receive the initial DNS message with SOA
+        (response, rtime) = dns.query.receive_tcp(sock, timeout(),
+                                                  one_rr_per_rrset=True)
+        soa = response.get_rrset(dns.message.ANSWER, name,
+                                 dns.rdataclass.IN, dns.rdatatype.SOA)
+        assert soa is not None
+
+        time.sleep(61)  # max-transfer-idle-out is 1 minute
+
+        with pytest.raises(ConnectionResetError):
+            # Process queued TCP messages
+            while True:
+                (response, rtime) = \
+                    dns.query.receive_tcp(sock, timeout(),
+                                          one_rr_per_rrset=True)
+                soa = response.get_rrset(dns.message.ANSWER, name,
+                                         dns.rdataclass.IN, dns.rdatatype.SOA)
+                if soa is not None:
+                    break
+            assert soa is None
+
+
+@pytest.mark.dnspython
+@pytest.mark.dnspython2
+@pytest.mark.long
+def test_max_transfer_time_out(port):
+    import dns.query
+    import dns.rdataclass
+    import dns.rdatatype
+
+    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
+        sock.connect(("10.53.0.1", port))
+
+        name = dns.name.from_text("example.")
+        msg = create_msg("example.", "AXFR")
+        (sbytes, stime) = dns.query.send_tcp(sock, msg, timeout())
+
+        # Receive the initial DNS message with SOA
+        (response, rtime) = dns.query.receive_tcp(sock, timeout(),
+                                                  one_rr_per_rrset=True)
+        soa = response.get_rrset(dns.message.ANSWER, name,
+                                 dns.rdataclass.IN, dns.rdatatype.SOA)
+        assert soa is not None
+
+        # The loop should timeout at the 5 minutes (max-transfer-time-out)
+        with pytest.raises(EOFError):
+            while True:
+                time.sleep(1)
+                (response, rtime) = \
+                    dns.query.receive_tcp(sock, timeout(),
+                                          one_rr_per_rrset=True)
+                soa = response.get_rrset(dns.message.ANSWER, name,
+                                         dns.rdataclass.IN, dns.rdatatype.SOA)
+                if soa is not None:
+                    break
+        assert soa is None