mirror of
https://gitlab.nic.cz/knot/knot-dns.git
synced 2026-02-03 18:49:28 -05:00
178 lines
5.5 KiB
Python
178 lines
5.5 KiB
Python
#!/usr/bin/env python3
|
|
|
|
'''Test concurrent access to control socket.'''
|
|
|
|
from dnstest.utils import *
|
|
from dnstest.test import Test
|
|
import random
|
|
import threading
|
|
import time
|
|
|
|
zone_backup_running = dict()
|
|
|
|
def check_shutdown(server):
|
|
if not server.log_search("shutting down"):
|
|
set_err("server %s not shut down" % server.name)
|
|
|
|
def random_sleep():
|
|
time.sleep(random.choice([0, 0, 0, 0, 0, 0.1, 0.2, 1, 2, 3 ]))
|
|
|
|
def random_ctl(server, zone_name):
|
|
cmd = random.choice(["status", "reload", "stats", "zone-check", "zone-status", "zone-reload",
|
|
"zone-refresh", "zone-retransfer", "zone-notify", "zone-flush",
|
|
"zone-sign", "zone-keys-load", "zone-ksk-submitted", "zone-freeze",
|
|
"zone-thaw", "zone-xfr-freeze", "zone-xfr-thaw", "zone-read", "zone-get",
|
|
"zone-stats", "conf-init", "conf-list", "conf-read", "conf-diff",
|
|
"conf-get"])
|
|
if cmd[0:5] == "zone-" and random.choice([False, True, True]):
|
|
cmd += " " + zone_name
|
|
if random.choice([False, True]):
|
|
cmd = "-b " + cmd
|
|
try:
|
|
server.ctl(cmd, availability=False)
|
|
except:
|
|
pass
|
|
|
|
def random_ctls(server, zone_name):
|
|
for i in range(random.choice([1, 1, 2, 3])):
|
|
random_ctl(server, zone_name)
|
|
random_sleep()
|
|
|
|
def ctl_txn_generic(server, txn_start, txn_modify, txn_commit, txn_abort, abort_failed_start):
|
|
txnsock = server.ctl_sock_rnd()
|
|
try:
|
|
server.ctl("zone-status", availability=False, custom_parm=txnsock)
|
|
except:
|
|
pass
|
|
try:
|
|
server.ctl(txn_start, availability=False, custom_parm=txnsock)
|
|
except:
|
|
try:
|
|
if abort_failed_start:
|
|
server.ctl(txn_abort, availability=False, custom_parm=txnsock)
|
|
except:
|
|
pass
|
|
return
|
|
random_sleep()
|
|
try:
|
|
server.ctl(txn_modify, availability=False, custom_parm=txnsock)
|
|
random_sleep()
|
|
server.ctl(txn_commit, availability=False, custom_parm=txnsock)
|
|
except:
|
|
attempts = 9
|
|
while attempts > 0:
|
|
time.sleep(2)
|
|
attempts -= 1
|
|
try:
|
|
server.ctl(txn_abort, availability=False, custom_parm=txnsock)
|
|
attempts = 0
|
|
except:
|
|
pass
|
|
|
|
def bck_purge_rest(server, zone_name):
|
|
global zone_backup_running
|
|
if random.choice([False, True]) and not True in zone_backup_running.values():
|
|
zone_name = " "
|
|
if zone_name in zone_backup_running and zone_backup_running[zone_name]:
|
|
return
|
|
if " " in zone_backup_running and zone_backup_running[" "]:
|
|
return
|
|
zone_backup_running[zone_name] = True
|
|
|
|
bckdir = "%s/backup" % server.dir
|
|
bckdir += str(int(time.time()))
|
|
bckdir = " +backupdir " + bckdir
|
|
cmd_bck = "-t 14 -b zone-backup " + zone_name + bckdir
|
|
cmd_pur = "-b -f zone-purge " + ("--" if zone_name == " " else zone_name)
|
|
cmd_res = "-b zone-restore " + zone_name + bckdir
|
|
ctl_txn_generic(server, cmd_bck, cmd_pur, cmd_res, cmd_res, False)
|
|
try:
|
|
server.ctl("zone-refresh " + zone_name, availability=False)
|
|
except:
|
|
pass
|
|
try:
|
|
server.ctl("zone-reload " + zone_name, availability=False)
|
|
except:
|
|
pass
|
|
for i in range(10):
|
|
try:
|
|
resp = server.dig(zone_name, "SOA")
|
|
if resp.count("SOA") > 0:
|
|
break
|
|
except:
|
|
pass
|
|
time.sleep(1)
|
|
zone_backup_running[zone_name] = False
|
|
|
|
def ctl_update(server, zone_name):
|
|
ctl_txn_generic(server, "-b zone-begin " + zone_name,
|
|
"zone-set " + zone_name + " abc 3600 A 1.2.3." + str(random.randint(1, 254)),
|
|
"zone-commit " + zone_name, "zone-abort " + zone_name, True)
|
|
|
|
def conf_update(server, zone_name):
|
|
ctl_txn_generic(server, "conf-begin",
|
|
"conf-set zone[" + zone_name + "].zonemd-generate " + random.choice(["none", "zonemd-sha384", "zonemd-sha512", "remove"]),
|
|
"conf-commit", "conf-abort", True)
|
|
|
|
def random_thing(server, zone_name):
|
|
scn = random.choice([random_ctls, random_ctls, random_ctls, random_ctls, bck_purge_rest, ctl_update, conf_update])
|
|
scn(server, zone_name)
|
|
|
|
def run_thr(fun, server, zone_name):
|
|
threading.Thread(target=fun, args=[server, zone_name]).start()
|
|
|
|
t = Test()
|
|
|
|
master = t.server("knot")
|
|
slave = t.server("knot")
|
|
zones = t.zone_rnd(2, dnssec=False, records=40)
|
|
t.link(zones, master, slave)
|
|
|
|
for z in zones:
|
|
master.dnssec(z).enable = True
|
|
master.dnssec(z).nsec3 = True
|
|
|
|
for s in [ master, slave ]:
|
|
s.bg_workers = 3
|
|
s.udp_workers = 1
|
|
s.tcp_workers = 1
|
|
|
|
t.start()
|
|
slave.zones_wait(zones)
|
|
|
|
for i in range(60):
|
|
s = random.choice([master, slave])
|
|
z = random.choice(zones)
|
|
run_thr(random_thing, s, z.name)
|
|
random_sleep()
|
|
|
|
for s in [ master, slave ]:
|
|
for z in zones:
|
|
try:
|
|
s.ctl("zone-xfr-thaw " + z.name, availability=False)
|
|
s.ctl("zone-thaw " + z.name, availability=False)
|
|
s.ctl("zone-notify " + z.name, availability=False)
|
|
except:
|
|
pass
|
|
|
|
for s in [ master, slave ]:
|
|
try:
|
|
s.ctl("conf-abort", availability=False)
|
|
except:
|
|
pass
|
|
for z in zones:
|
|
try:
|
|
s.ctl("zone-abort " + z.name, availability=False)
|
|
except:
|
|
pass
|
|
|
|
|
|
t.sleep(10)
|
|
master.zones_wait(zones) # check that server is still operable
|
|
slave.zones_wait(zones) # check that server is still operable
|
|
|
|
t.end()
|
|
|
|
time.sleep(4)
|
|
for s in [ master, slave ]:
|
|
check_shutdown(s)
|