From 6e64015068b00669624a05cd60e92d36482e5fec Mon Sep 17 00:00:00 2001
From: Daniel Salzman <daniel.salzman@nic.cz>
Date: Tue, 18 Mar 2014 15:07:04 +0100
Subject: [PATCH] tests-extra: add AXFR comparation with slave Bind in dnssec
 tests

---
 tests-extra/tests/dnssec/none_to_nsec/test.py | 10 ++++---
 .../tests/dnssec/none_to_nsec3/test.py        | 10 ++++---
 .../tests/dnssec/nsec3_to_nsec/test.py        | 15 +++++++----
 .../tests/dnssec/nsec3_to_nsec_ddns/test.py   | 15 +++++++----
 .../tests/dnssec/nsec_to_nsec3/test.py        | 15 +++++++----
 .../tests/dnssec/nsec_to_nsec3_ddns/test.py   | 15 +++++++----
 tests-extra/tools/dnstest/zonefile.py         | 27 +++++++++++++++++++
 tests-extra/tools/zone_generate.py            |  2 +-
 8 files changed, 82 insertions(+), 27 deletions(-)

diff --git a/tests-extra/tests/dnssec/none_to_nsec/test.py b/tests-extra/tests/dnssec/none_to_nsec/test.py
index 28e42254cd..97ea74b5bd 100644
--- a/tests-extra/tests/dnssec/none_to_nsec/test.py
+++ b/tests-extra/tests/dnssec/none_to_nsec/test.py
@@ -8,13 +8,16 @@ from dnstest.test import Test
 t = Test()
 
 master = t.server("knot")
+slave = t.server("bind")
 zone = t.zone_rnd(1, dnssec=False)
-t.link(zone, master)
+t.link(zone, master, slave)
 
 t.start()
 
 # Wait for listening server with unsigned zone.
 old_serial = master.zone_wait(zone)
+slave.zone_wait(zone)
+t.xfr_diff(master, slave, zone)
 
 # Check NSEC absence.
 master.check_nsec(zone, nonsec=True)
@@ -31,8 +34,9 @@ master.gen_confile()
 master.start()
 
 # Wait for changed zone and flush.
-new_serial = master.zone_wait(zone, serial=old_serial)
-t.sleep(1)
+new_serial = master.zone_wait(zone, old_serial)
+slave.zone_wait(zone, old_serial)
+t.xfr_diff(master, slave, zone)
 master.flush()
 t.sleep(1)
 
diff --git a/tests-extra/tests/dnssec/none_to_nsec3/test.py b/tests-extra/tests/dnssec/none_to_nsec3/test.py
index ef14647e76..9cb95e290d 100644
--- a/tests-extra/tests/dnssec/none_to_nsec3/test.py
+++ b/tests-extra/tests/dnssec/none_to_nsec3/test.py
@@ -8,13 +8,16 @@ from dnstest.test import Test
 t = Test()
 
 master = t.server("knot")
+slave = t.server("bind")
 zone = t.zone_rnd(1, dnssec=False)
-t.link(zone, master)
+t.link(zone, master, slave)
 
 t.start()
 
 # Wait for listening server with unsigned zone.
 old_serial = master.zone_wait(zone)
+slave.zone_wait(zone)
+t.xfr_diff(master, slave, zone)
 
 # Check NSEC absence.
 master.check_nsec(zone, nonsec=True)
@@ -32,8 +35,9 @@ master.gen_confile()
 master.start()
 
 # Wait for changed zone and flush.
-new_serial = master.zone_wait(zone, serial=old_serial)
-t.sleep(1)
+new_serial = master.zone_wait(zone, old_serial)
+slave.zone_wait(zone, old_serial)
+t.xfr_diff(master, slave, zone)
 master.flush()
 t.sleep(1)
 
diff --git a/tests-extra/tests/dnssec/nsec3_to_nsec/test.py b/tests-extra/tests/dnssec/nsec3_to_nsec/test.py
index 7a58c6d311..9249d0c805 100644
--- a/tests-extra/tests/dnssec/nsec3_to_nsec/test.py
+++ b/tests-extra/tests/dnssec/nsec3_to_nsec/test.py
@@ -8,13 +8,16 @@ from dnstest.test import Test
 t = Test()
 
 master = t.server("knot")
+slave = t.server("bind")
 zone = t.zone_rnd(1, dnssec=False)
-t.link(zone, master)
+t.link(zone, master, slave)
 
 t.start()
 
 # Wait for listening server with unsigned zone.
 old_serial = master.zone_wait(zone)
+slave.zone_wait(zone)
+t.xfr_diff(master, slave, zone)
 
 # Check NSEC absence.
 master.check_nsec(zone, nonsec=True)
@@ -32,8 +35,9 @@ master.gen_confile()
 master.start()
 
 # Wait for changed zone and flush.
-new_serial = master.zone_wait(zone, serial=old_serial)
-t.sleep(1)
+new_serial = master.zone_wait(zone, old_serial)
+slave.zone_wait(zone, old_serial)
+t.xfr_diff(master, slave, zone)
 master.flush()
 t.sleep(1)
 
@@ -62,8 +66,9 @@ master.gen_confile()
 master.start()
 
 # Wait for changed zone and flush.
-master.zone_wait(zone, serial=new_serial)
-t.sleep(1)
+master.zone_wait(zone, new_serial)
+slave.zone_wait(zone, new_serial)
+t.xfr_diff(master, slave, zone)
 master.flush()
 t.sleep(1)
 
diff --git a/tests-extra/tests/dnssec/nsec3_to_nsec_ddns/test.py b/tests-extra/tests/dnssec/nsec3_to_nsec_ddns/test.py
index 8419de68ae..e4fefac537 100644
--- a/tests-extra/tests/dnssec/nsec3_to_nsec_ddns/test.py
+++ b/tests-extra/tests/dnssec/nsec3_to_nsec_ddns/test.py
@@ -8,13 +8,16 @@ from dnstest.test import Test
 t = Test()
 
 master = t.server("knot")
+slave = t.server("bind")
 zone = t.zone_rnd(1, dnssec=False)
-t.link(zone, master, ddns=True)
+t.link(zone, master, slave, ddns=True)
 
 t.start()
 
 # Wait for listening server with unsigned zone.
 old_serial = master.zone_wait(zone)
+slave.zone_wait(zone)
+t.xfr_diff(master, slave, zone)
 
 # Check NSEC absence.
 master.check_nsec(zone, nonsec=True)
@@ -32,8 +35,9 @@ master.gen_confile()
 master.start()
 
 # Wait for changed zone and flush.
-new_serial = master.zone_wait(zone, serial=old_serial)
-t.sleep(1)
+new_serial = master.zone_wait(zone, old_serial)
+slave.zone_wait(zone, old_serial)
+t.xfr_diff(master, slave, zone)
 master.flush()
 t.sleep(1)
 
@@ -61,8 +65,9 @@ update.delete(zone[0].name, "NSEC3PARAM")
 update.send("NOERROR")
 
 # Wait for changed zone and flush.
-master.zone_wait(zone, serial=new_serial)
-t.sleep(1)
+master.zone_wait(zone, new_serial)
+slave.zone_wait(zone, new_serial)
+t.xfr_diff(master, slave, zone)
 master.flush()
 t.sleep(1)
 
diff --git a/tests-extra/tests/dnssec/nsec_to_nsec3/test.py b/tests-extra/tests/dnssec/nsec_to_nsec3/test.py
index 8515631f71..bf4a1d0d2f 100644
--- a/tests-extra/tests/dnssec/nsec_to_nsec3/test.py
+++ b/tests-extra/tests/dnssec/nsec_to_nsec3/test.py
@@ -8,13 +8,16 @@ from dnstest.test import Test
 t = Test()
 
 master = t.server("knot")
+slave = t.server("bind")
 zone = t.zone_rnd(1, dnssec=False)
-t.link(zone, master)
+t.link(zone, master, slave)
 
 t.start()
 
 # Wait for listening server with unsigned zone.
 old_serial = master.zone_wait(zone)
+slave.zone_wait(zone)
+t.xfr_diff(master, slave, zone)
 
 # Check NSEC absence.
 master.check_nsec(zone, nonsec=True)
@@ -31,8 +34,9 @@ master.gen_confile()
 master.start()
 
 # Wait for changed zone and flush.
-new_serial = master.zone_wait(zone, serial=old_serial)
-t.sleep(1)
+new_serial = master.zone_wait(zone, old_serial)
+slave.zone_wait(zone, old_serial)
+t.xfr_diff(master, slave, zone)
 master.flush()
 t.sleep(1)
 
@@ -61,8 +65,9 @@ master.gen_confile()
 master.start()
 
 # Wait for changed zone and flush.
-master.zone_wait(zone, serial=new_serial)
-t.sleep(1)
+master.zone_wait(zone, new_serial)
+slave.zone_wait(zone, new_serial)
+t.xfr_diff(master, slave, zone)
 master.flush()
 t.sleep(1)
 
diff --git a/tests-extra/tests/dnssec/nsec_to_nsec3_ddns/test.py b/tests-extra/tests/dnssec/nsec_to_nsec3_ddns/test.py
index e040a867fd..26035defd7 100644
--- a/tests-extra/tests/dnssec/nsec_to_nsec3_ddns/test.py
+++ b/tests-extra/tests/dnssec/nsec_to_nsec3_ddns/test.py
@@ -8,13 +8,16 @@ from dnstest.test import Test
 t = Test()
 
 master = t.server("knot")
+slave = t.server("bind")
 zone = t.zone_rnd(1, dnssec=False)
-t.link(zone, master, ddns=True)
+t.link(zone, master, slave, ddns=True)
 
 t.start()
 
 # Wait for listening server with unsigned zone.
 old_serial = master.zone_wait(zone)
+slave.zone_wait(zone)
+t.xfr_diff(master, slave, zone)
 
 # Check NSEC absence.
 master.check_nsec(zone, nonsec=True)
@@ -31,8 +34,9 @@ master.gen_confile()
 master.start()
 
 # Wait for changed zone and flush.
-new_serial = master.zone_wait(zone, serial=old_serial)
-t.sleep(1)
+new_serial = master.zone_wait(zone, old_serial)
+slave.zone_wait(zone, old_serial)
+t.xfr_diff(master, slave, zone)
 master.flush()
 t.sleep(1)
 
@@ -60,8 +64,9 @@ update.add(zone[0].name, 0, "NSEC3PARAM", "1 0 2 fedcba")
 update.send("NOERROR")
 
 # Wait for changed zone and flush.
-master.zone_wait(zone, serial=new_serial)
-t.sleep(1)
+master.zone_wait(zone, new_serial)
+slave.zone_wait(zone, new_serial)
+t.xfr_diff(master, slave, zone)
 master.flush()
 t.sleep(1)
 
diff --git a/tests-extra/tools/dnstest/zonefile.py b/tests-extra/tools/dnstest/zonefile.py
index 54ae7b9341..967d76d6ca 100644
--- a/tests-extra/tools/dnstest/zonefile.py
+++ b/tests-extra/tools/dnstest/zonefile.py
@@ -129,6 +129,8 @@ class ZoneFile(object):
         with open(self.path, "a") as file:
             file.write("@ 0 NSEC3PARAM 1 0 %i %s" % (iters, salt))
 
+        self.update_serial()
+
     def disable_nsec3(self):
         '''Remove NSEC3PARAM record if any.'''
 
@@ -142,6 +144,8 @@ class ZoneFile(object):
 
         os.remove(old_name)
 
+        self.update_serial()
+
     def backup(self):
         '''Make a backup copy of the actual zone file.'''
 
@@ -150,3 +154,26 @@ class ZoneFile(object):
             self.backup_num += 1
         except:
             raise Exception("Can't make a copy of zone file %s" % self.path)
+
+    def update_serial(self, new_serial=None):
+        '''Change SOA serial.'''
+
+        serial = None
+        first = False
+
+        old_name = self.path + ".old"
+        os.rename(self.path, old_name)
+
+        with open(old_name) as old_file, open(self.path, 'w') as new_file:
+            for line in old_file:
+                if "SOA" in line and not first:
+                    items = line.split()
+                    serial = int(items[-5])
+                    items[-5] = str(serial + 1) if not new_serial else str(new_serial)
+                    new_file.write(str.join(" ", items))
+                    new_file.write("\n")
+                    first = True
+                else:
+                    new_file.write(line)
+
+        os.remove(old_name)
diff --git a/tests-extra/tools/zone_generate.py b/tests-extra/tools/zone_generate.py
index 99ac738380..0f6fd08eab 100755
--- a/tests-extra/tools/zone_generate.py
+++ b/tests-extra/tools/zone_generate.py
@@ -369,7 +369,7 @@ def gen_soa(origin, serial, auth = None):
     soa =  ''
     soa += '$TTL %d\n' % TTL
     s = '@ IN SOA %s %s' % (g_fqdn('ns'), g_fqdn('username'))
-    s += '( %s %d %d %s %s )\n' % (serial, refresh, refresh * 3, '4w', '1h' )
+    s += ' %s %d %d %s %s\n' % (serial, refresh, refresh * 3, '4w', '1h' )
     if auth != None:
         if auth != '.':
             auth += '.'
-- 
GitLab