1
0
Fork 0
bind9/bin/tests/system/addzone/tests_rndc_deadlock.py
Daniel Baumann f66ff7eae6
Adding upstream version 1:9.20.9.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-21 13:32:37 +02:00

90 lines
2.6 KiB
Python
Executable file

# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
import concurrent.futures
import time
import pytest
import isctest
pytestmark = pytest.mark.extra_artifacts(
[
"ns*/*.nzf*",
"ns*/*.nzd*",
"ns1/redirect.db",
"ns2/new-zones",
"ns2/redirect.db",
"ns3/redirect.db",
]
)
def rndc_loop(test_state, domain, ns3):
"""
Run "rndc addzone", "rndc modzone", and "rndc delzone" in a tight loop
until the test is considered finished, ignoring errors
"""
rndc_commands = [
["addzone", domain, '{ type primary; file "example.db"; };'],
[
"modzone",
domain,
'{ type primary; file "example.db"; allow-transfer { any; }; };',
],
["delzone", domain],
]
while not test_state["finished"]:
for command in rndc_commands:
ns3.rndc(" ".join(command), ignore_errors=True, log=False)
def check_if_server_is_responsive(ns3):
"""
Check if server status can be successfully retrieved using "rndc status"
"""
try:
ns3.rndc("status", log=False)
return True
except isctest.rndc.RNDCException:
return False
def test_rndc_deadlock(servers):
"""
Test whether running "rndc addzone", "rndc modzone", and "rndc delzone"
commands concurrently does not trigger a deadlock
"""
test_state = {"finished": False}
ns3 = servers["ns3"]
# Create 4 worker threads running "rndc" commands in a loop.
with concurrent.futures.ThreadPoolExecutor() as executor:
for i in range(1, 5):
domain = "example%d" % i
executor.submit(rndc_loop, test_state, domain, ns3)
# Run "rndc status" 10 times, with 1-second pauses between attempts.
# Each "rndc status" invocation has a timeout of 10 seconds. If any of
# them fails, the loop will be interrupted.
server_is_responsive = True
attempts = 10
while server_is_responsive and attempts > 0:
server_is_responsive = check_if_server_is_responsive(ns3)
attempts -= 1
time.sleep(1)
# Signal worker threads that the test is finished.
test_state["finished"] = True
# Check whether all "rndc status" commands succeeded.
assert server_is_responsive