diff --git a/tests-extra/tests/security/protos/test.py b/tests-extra/tests/security/protos/test.py
index a6f9c9bfc54e168f30734f90088778abd8144081..17aa37e0566029b097cd303f7d8f53b2928e11f4 100644
--- a/tests-extra/tests/security/protos/test.py
+++ b/tests-extra/tests/security/protos/test.py
@@ -4,6 +4,7 @@
 
 import shutil
 from subprocess import check_call
+from dnstest.utils import *
 from dnstest.test import Test
 from dnstest.params import get_binary
 
@@ -13,9 +14,9 @@ protos_java_bin = get_binary("PROTOS_JAVA_BIN", "java")
 protos_query_bin = get_binary("PROTOS_QUERY_BIN", protos_bin[0])
 protos_zonetransfer_bin = get_binary("PROTOS_ZONETRANSFER_BIN", protos_bin[1])
 if not protos_java_bin:
-    raise Exception("Java not found, skipping test.")
+    raise Skip("Java not found")
 if not protos_query_bin:
-    raise Exception("'%s' PROTOS binary not found" % protos_bin[0])
+    raise Skip("'%s' PROTOS binary not found" % protos_bin[0])
 
 t = Test(ip=4, tsig=False) # PROTOS works on IPv4, no TSIG
 master = t.server("dummy")
diff --git a/tests-extra/tools/dnstest/keys.py b/tests-extra/tools/dnstest/keys.py
index 3a7f6fb5b8cb1da2f2a33fbf1fc064df68f11ce6..532129fcfe79e18d23231205602bda65c96673d3 100644
--- a/tests-extra/tools/dnstest/keys.py
+++ b/tests-extra/tools/dnstest/keys.py
@@ -24,32 +24,40 @@ class Tsig(object):
     vocabulary = string.ascii_uppercase + string.ascii_lowercase + \
                  string.digits
 
-    def __init__(self, alg=None):
-        nlabels = random.randint(1, 10)
+    def __init__(self, name=None, alg=None, key=None):
+        if not name:
+            nlabels = random.randint(1, 10)
 
-        self.name = ""
-        for i in range(nlabels):
-            label_len = random.randint(1, 63)
+            self.name = ""
+            for i in range(nlabels):
+                label_len = random.randint(1, 63)
 
-            # Check for maximal dname length (255 B = max fqdn in wire).
-            # 255 = 1 leading byte + 253 + 1 trailing byte.
-            if len(self.name) + 1 + label_len > 253:
-                break
+                # Check for maximal dname length (255 B = max fqdn in wire).
+                # 255 = 1 leading byte + 253 + 1 trailing byte.
+                if len(self.name) + 1 + label_len > 253:
+                    break
 
-            # Add label separator.
-            if i > 0:
-                self.name += "."
+                # Add label separator.
+                if i > 0:
+                    self.name += "."
 
-            self.name += "".join(random.choice(Tsig.vocabulary)
-                         for x in range(label_len))
-
-        if alg and alg not in Tsig.algs:
-            raise Exception("Unsupported TSIG algorithm %s" % alg)
+                self.name += "".join(random.choice(Tsig.vocabulary)
+                             for x in range(label_len))
+        else:
+            self.name = str(name)
 
-        self.alg = alg if alg else random.choice(list(Tsig.algs.keys()))
+        if not alg:
+            self.alg = random.choice(list(Tsig.algs.keys()))
+        else:
+            if alg not in Tsig.algs:
+                raise Exception("Unsupported TSIG algorithm %s" % alg)
+            self.alg = alg
 
-        self.key = base64.b64encode(os.urandom(Tsig.algs[self.alg])). \
-                   decode('ascii')
+        if not key:
+            self.key = base64.b64encode(os.urandom(Tsig.algs[self.alg])). \
+                       decode('ascii')
+        else:
+            self.key = str(key)
 
         # TSIG preparation for pythondns utils.
         if self.alg == "hmac-md5":
diff --git a/tests-extra/tools/dnstest/server.py b/tests-extra/tools/dnstest/server.py
index 5ed0f7cdfccc4aa044f942716f9637f75f62d0b5..99ead41169b00facb8db9e2b0a10e3f97222a208 100644
--- a/tests-extra/tools/dnstest/server.py
+++ b/tests-extra/tools/dnstest/server.py
@@ -133,6 +133,7 @@ class Server(object):
         self.ctlkey = None
         self.ctlkeyfile = None
         self.tsig = None
+        self.tsig_test = None
 
         self.zones = dict()
 
@@ -316,7 +317,7 @@ class Server(object):
     def dig(self, rname, rtype, rclass="IN", udp=None, serial=None,
             timeout=None, tries=3, flags="", bufsize=None,
             nsid=False, dnssec=False, log_no_sep=False):
-        key_params = self.tsig.key_params if self.tsig else dict()
+        key_params = self.tsig_test.key_params if self.tsig_test else dict()
 
         # Convert one item zone list to zone name.
         if isinstance(rname, list):
@@ -416,7 +417,8 @@ class Server(object):
         check_log("DIG %s %s %s @%s -p %i %s" %
                   (rname, rtype_str, rclass, self.addr, self.port, dig_flags))
         if key_params:
-            detail_log("%s:%s:%s" % (self.tsig.alg, self.tsig.name, self.tsig.key))
+            detail_log("%s:%s:%s" %
+                (self.tsig_test.alg, self.tsig_test.name, self.tsig_test.key))
 
         for t in range(tries):
             try:
@@ -521,7 +523,7 @@ class Server(object):
                 raise Exception("One zone required.")
             zone = zone[0]
 
-        key_params = self.tsig.key_params if self.tsig else dict()
+        key_params = self.tsig_test.key_params if self.tsig_test else dict()
 
         return dnstest.update.Update(self, dns.update.Update(zone.name,
                                                              **key_params))
@@ -638,6 +640,12 @@ class Bind(Server):
             s.item("algorithm", t.alg)
             s.item_str("secret", t.key)
             s.end()
+            t = self.tsig_test
+            s.begin("key", t.name)
+            s.item("# Test key")
+            s.item("algorithm", t.alg)
+            s.item_str("secret", t.key)
+            s.end()
 
             keys = set() # Duplicy check.
             for zone in sorted(self.zones):
@@ -681,33 +689,30 @@ class Bind(Server):
                 if z.ixfr and not z.ddns:
                     s.item("ixfr-from-differences", "yes")
 
-            # Init update list with the default local server.
-            slaves_upd = ""
-            if self.tsig:
-                slaves_upd += "key %s; " % self.tsig.name
-            else:
-                slaves_upd += "%s; " % self.addr
-
             if z.slaves:
                 slaves = ""
                 for slave in z.slaves:
                     if self.tsig:
                         slaves += "%s port %i key %s; " \
                                   % (slave.addr, slave.port, self.tsig.name)
-                        slaves_upd += "key %s; " % slave.tsig.name
                     else:
                         slaves += "%s port %i; " % (slave.addr, slave.port)
-                        slaves_upd += "%s; " % slave.addr
                 s.item("also-notify", "{ %s}" % slaves)
 
             if z.ddns:
+                if self.tsig:
+                    upd = "key %s; " % self.tsig_test.name
+                else:
+                    upd = "%s; " % self.addr
+
                 if z.master:
-                    s.item("allow-update-forwarding", "{ %s}" % slaves_upd)
+                    s.item("allow-update-forwarding", "{ %s}" % upd)
                 else:
-                    s.item("allow-update", "{ %s}" % slaves_upd)
+                    s.item("allow-update", "{ %s}" % upd)
 
             if self.tsig:
-                s.item("allow-transfer", "{ key %s; }" % self.tsig.name)
+                s.item("allow-transfer", "{ key %s; key %s; }" %
+                       (self.tsig.name, self.tsig_test.name))
             else:
                 s.item("allow-transfer", "{ %s; }" % self.addr)
             s.end()
@@ -777,6 +782,8 @@ class Knot(Server):
             s.begin("keys")
             t = self.tsig
             s.item_str("\"%s\" %s" % (t.name, t.alg), t.key)
+            t = self.tsig_test
+            s.item_str("\"%s\" %s" % (t.name, t.alg), t.key)
 
             keys = set() # Duplicy check.
             for zone in sorted(self.zones):
@@ -798,6 +805,11 @@ class Knot(Server):
         if self.tsig:
             s.item_str("key", self.tsig.name)
         s.end()
+        s.begin("test")
+        s.item("address", self.addr)
+        if self.tsig_test:
+            s.item_str("key", self.tsig_test.name)
+        s.end()
 
         servers = set() # Duplicity check.
         for zone in sorted(self.zones):
@@ -848,11 +860,10 @@ class Knot(Server):
                     slaves += slave.name
                 s.item("notify-out", slaves)
 
-            s.item("xfr-out", "local")
+            s.item("xfr-out", "local, test")
 
             if z.ddns:
-                all_slaves = "local" if not slaves else slaves + ", local"
-                s.item("update-in", all_slaves)
+                s.item("update-in", "test")
 
             if z.ixfr and not z.master:
                 s.item("ixfr-from-differences", "on")
diff --git a/tests-extra/tools/dnstest/test.py b/tests-extra/tools/dnstest/test.py
index ef079d9bd41456848633b15b0f332f48812672cc..0bec76f60b846f3589759b86ae494aa8924e8b02 100644
--- a/tests-extra/tools/dnstest/test.py
+++ b/tests-extra/tools/dnstest/test.py
@@ -38,7 +38,14 @@ class Test(object):
         if self.ip not in [4, 6]:
             raise Exception("Invalid IP version")
 
-        self.tsig = bool(tsig) if tsig != None else random.choice([True, False])
+        self.tsig = None
+        if tsig != None:
+            if type(tsig) is dnstest.keys.Tsig:
+                self.tsig = tsig
+            elif tsig:
+                self.tsig = dnstest.keys.Tsig()
+        elif random.choice([True, False]):
+            self.tsig = dnstest.keys.Tsig()
 
         self.servers = set()
 
@@ -109,6 +116,7 @@ class Test(object):
         srv.ip = self.ip
         srv.addr = Test.LOCAL_ADDR[self.ip]
         srv.tsig = dnstest.keys.Tsig() if self.tsig else None
+        srv.tsig_test = self.tsig
 
         srv.name = "%s%s" % (server, srv.count)
         srv.dir = self.out_dir + "/" + srv.name