BIND 10 master, updated. d6d7f7d201eb0dcfbcfda4e8589b556b596e826b [master] Add lettuce test for mixed-case query

BIND 10 source code commits bind10-changes at lists.isc.org
Mon Nov 11 04:46:47 UTC 2013


The branch, master has been updated
       via  d6d7f7d201eb0dcfbcfda4e8589b556b596e826b (commit)
       via  4655c110afa0ec6f5669bf53245bffe6b30ece4b (commit)
       via  46b7d9d9e329ea3ed9a338924e0cec4e3c83ee04 (commit)
       via  5b63f9693efd47c600139b8522c37ea2f01666a0 (commit)
       via  499e6f2e3f5bd141459ba46f90359d9dbc72c125 (commit)
       via  dc10e21d3ace93577e654885981ace4cae92ee09 (commit)
       via  90b12d797d33c23ec96cc877ecf4c84a42f6214a (commit)
       via  f7a34944f319ebffaced2e1ea8a7dd1c420a4c99 (commit)
       via  d9ee65e374924d0f1cde75f4aa9c242218d1ad85 (commit)
      from  e4475a2cd90aa4247482b1a4b96ec3dac21b802b (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit d6d7f7d201eb0dcfbcfda4e8589b556b596e826b
Author: Mukund Sivaraman <muks at isc.org>
Date:   Thu Nov 7 18:22:42 2013 +0530

    [master] Add lettuce test for mixed-case query

commit 4655c110afa0ec6f5669bf53245bffe6b30ece4b
Merge: e4475a2 46b7d9d
Author: Mukund Sivaraman <muks at isc.org>
Date:   Thu Nov 7 11:54:29 2013 +0530

    Merge branch 'trac2300'
    
    Conflicts:
    	src/bin/xfrin/b10-xfrin.xml
    	src/bin/xfrin/xfrin.spec
    	tests/lettuce/features/xfrin_notify_handling.feature

-----------------------------------------------------------------------

Summary of changes:
 src/bin/xfrin/b10-xfrin.xml                        |   82 ++++++++
 src/bin/xfrin/tests/xfrin_test.py                  |  121 ++++++++++-
 src/bin/xfrin/xfrin.py.in                          |   77 ++++++-
 src/bin/xfrin/xfrin.spec                           |  221 ++++++++++++++++++++
 tests/lettuce/features/example.feature             |   30 +++
 tests/lettuce/features/terrain/querying.py         |   13 +-
 .../lettuce/features/xfrin_notify_handling.feature |   59 ++++++
 7 files changed, 594 insertions(+), 9 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/bin/xfrin/b10-xfrin.xml b/src/bin/xfrin/b10-xfrin.xml
index ceae54c..0b58f9a 100644
--- a/src/bin/xfrin/b10-xfrin.xml
+++ b/src/bin/xfrin/b10-xfrin.xml
@@ -358,6 +358,88 @@ operation
         </simpara></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term>socket</term>
+        <listitem><simpara>
+          A directory name of socket statistics
+          </simpara>
+          <variablelist>
+
+            <varlistentry>
+              <term><replaceable>ipversion</replaceable></term>
+              <listitem><simpara>
+                A directory name of an IP version as ipv4 or ipv6
+                </simpara>
+                <variablelist>
+
+                  <varlistentry>
+                    <term>tcp</term>
+                    <listitem><simpara>
+                      A directory name of TCP statistics
+                      </simpara>
+                      <variablelist>
+
+                        <varlistentry>
+                          <term>open</term>
+                          <listitem><simpara>
+                           IPv4 or IPv6 TCP sockets opened successfully
+                          </simpara></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                          <term>openfail</term>
+                          <listitem><simpara>
+                           IPv4 or IPv6 TCP sockets open failures
+                          </simpara></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                          <term>close</term>
+                          <listitem><simpara>
+                           IPv4 or IPv6 TCP sockets closed
+                          </simpara></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                          <term>connfail</term>
+                          <listitem><simpara>
+                           IPv4 or IPv6 TCP sockets connection failures
+                          </simpara></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                          <term>conn</term>
+                          <listitem><simpara>
+                           IPv4 or IPv6 TCP connections established successfully
+                          </simpara></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                          <term>senderr</term>
+                          <listitem><simpara>
+                           IPv4 or IPv6 TCP sockets send errors
+                          </simpara></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                          <term>recverr</term>
+                          <listitem><simpara>
+                           IPv4 or IPv6 TCP sockets receive errors
+                          </simpara></listitem>
+                        </varlistentry>
+
+                      </variablelist>
+                    </listitem>
+                  </varlistentry><!-- end of tcp -->
+
+                </variablelist>
+              </listitem>
+            </varlistentry><!-- end of ipv4 | ipv6 -->
+
+          </variablelist>
+        </listitem>
+      </varlistentry><!-- end of socket -->
+
     </variablelist>
 
     <para>
diff --git a/src/bin/xfrin/tests/xfrin_test.py b/src/bin/xfrin/tests/xfrin_test.py
index 9df2bde..4158638 100644
--- a/src/bin/xfrin/tests/xfrin_test.py
+++ b/src/bin/xfrin/tests/xfrin_test.py
@@ -1105,12 +1105,10 @@ class TestAXFR(TestXfrinConnection):
         for (info, ver) in addrs:
             c = MockXfrinConnection({}, TEST_ZONE_NAME, RRClass.CH, None,
                                     threading.Event(), info)
-            c.init_socket()
             if ver is not None:
                 self.assertEqual(ver, c._get_ipver_str())
             else:
                 self.assertRaises(ValueError, c._get_ipver_str)
-            c.close()
 
     def test_soacheck(self):
         # we need to defer the creation until we know the QID, which is
@@ -3497,6 +3495,125 @@ class TestXfrinTransferStats(unittest.TestCase):
         zbps = self.stats.get_bytes_per_second()
         self.assertEqual(0, zbps)
 
+class TestXfrinConnectionSocketCounter(unittest.TestCase):
+
+    @property
+    def _master_addrinfo(self):
+        return TEST_MASTER_IPV4_ADDRINFO
+    @property
+    def _ipver(self):
+        return 'ipv4'
+
+    def setUp(self):
+        self.conn = XfrinConnection(
+            None, TEST_ZONE_NAME, None, MockDataSourceClient(), None,
+            self._master_addrinfo, None,
+            xfrin.Counters(xfrin.SPECFILE_LOCATION))
+        self.expception = socket.error
+
+    def raise_expception(self, *args):
+        raise self.expception
+
+    def test_open(self):
+        self.assertRaises(isc.cc.data.DataNotFoundError,
+                          self.conn._counters.get,
+                          'socket', self._ipver, 'tcp', 'open')
+        self.conn.create_socket(self._master_addrinfo[0],
+                                self._master_addrinfo[1])
+        self.assertEqual(1, self.conn._counters.get(
+                'socket', self._ipver, 'tcp', 'open'))
+
+    def test_openfail(self):
+        self.assertRaises(isc.cc.data.DataNotFoundError,
+                          self.conn._counters.get,
+                          'socket', self._ipver, 'tcp', 'openfail')
+        orig_create_socket = xfrin.asyncore.dispatcher.create_socket
+        xfrin.asyncore.dispatcher.create_socket = self.raise_expception
+        try:
+            self.assertRaises(self.expception, self.conn.create_socket,
+                              self._master_addrinfo[0],
+                              self._master_addrinfo[1])
+            self.assertEqual(1, self.conn._counters.get(
+                    'socket', self._ipver, 'tcp', 'openfail'))
+        finally:
+            xfrin.asyncore.dispatcher.create_socket = orig_create_socket
+
+    def test_close(self):
+        self.assertRaises(isc.cc.data.DataNotFoundError,
+                          self.conn._counters.get,
+                          'socket', self._ipver, 'tcp', 'close')
+        orig_socket_close = xfrin.asyncore.dispatcher.close
+        xfrin.asyncore.dispatcher.close = lambda x: None
+        try:
+            self.conn.close()
+            self.assertEqual(1, self.conn._counters.get(
+                    'socket', self._ipver, 'tcp', 'close'))
+        finally:
+            xfrin.asyncore.dispatcher.close = orig_socket_close
+
+    def test_conn(self):
+        self.assertRaises(isc.cc.data.DataNotFoundError,
+                          self.conn._counters.get,
+                          'socket', self._ipver, 'tcp', 'conn')
+        orig_socket_connect = xfrin.asyncore.dispatcher.connect
+        xfrin.asyncore.dispatcher.connect = lambda *a: None
+        try:
+            self.conn.connect(self._master_addrinfo[2])
+            self.assertEqual(1, self.conn._counters.get(
+                    'socket', self._ipver, 'tcp', 'conn'))
+        finally:
+            xfrin.asyncore.dispatcher.connect = orig_socket_connect
+
+    def test_connfail(self):
+        self.assertRaises(isc.cc.data.DataNotFoundError,
+                          self.conn._counters.get,
+                          'socket', self._ipver, 'tcp', 'connfail')
+        orig_socket_connect = xfrin.asyncore.dispatcher.connect
+        xfrin.asyncore.dispatcher.connect = self.raise_expception
+        try:
+            self.assertRaises(self.expception, self.conn.connect,
+                              self._master_addrinfo[2])
+            self.assertFalse(self.conn.connect_to_master())
+            self.assertEqual(2, self.conn._counters.get(
+                    'socket', self._ipver, 'tcp', 'connfail'))
+        finally:
+            xfrin.asyncore.dispatcher.connect = orig_socket_connect
+
+    def test_senderr(self):
+        self.assertRaises(isc.cc.data.DataNotFoundError,
+                          self.conn._counters.get,
+                          'socket', self._ipver, 'tcp', 'senderr')
+        orig_socket_send = xfrin.asyncore.dispatcher.send
+        xfrin.asyncore.dispatcher.send = self.raise_expception
+        try:
+            self.assertRaises(self.expception, self.conn.send, None)
+            self.assertEqual(1, self.conn._counters.get(
+                    'socket', self._ipver, 'tcp', 'senderr'))
+        finally:
+            xfrin.asyncore.dispatcher.send = orig_socket_send
+
+    def test_recverr(self):
+        self.assertRaises(isc.cc.data.DataNotFoundError,
+                          self.conn._counters.get,
+                          'socket', self._ipver, 'tcp', 'recverr')
+        orig_socket_recv = xfrin.asyncore.dispatcher.recv
+        xfrin.asyncore.dispatcher.recv = self.raise_expception
+        try:
+            self.assertRaises(self.expception, self.conn.recv, None)
+            self.assertEqual(1, self.conn._counters.get(
+                    'socket', self._ipver, 'tcp', 'recverr'))
+        finally:
+            xfrin.asyncore.dispatcher.recv = orig_socket_recv
+
+class TestXfrinConnectionSocketCounterV6(TestXfrinConnectionSocketCounter):
+
+    @property
+    def _master_addrinfo(self):
+        return TEST_MASTER_IPV6_ADDRINFO
+    @property
+    def _ipver(self):
+        return 'ipv6'
+
 if __name__== "__main__":
     try:
         isc.log.resetUnitTestRootLogger()
diff --git a/src/bin/xfrin/xfrin.py.in b/src/bin/xfrin/xfrin.py.in
index 79093b2..a894d55 100755
--- a/src/bin/xfrin/xfrin.py.in
+++ b/src/bin/xfrin/xfrin.py.in
@@ -611,6 +611,11 @@ class XfrinConnection(asyncore.dispatcher):
         self._shutdown_event = shutdown_event
         self._master_addrinfo = master_addrinfo
         self._tsig_key = tsig_key
+        # self.tsig_key_name is used for outputting an error massage in
+        # connect_to_master().
+        self.tsig_key_name = None
+        if tsig_key:
+            self.tsig_key_name = self._tsig_key.get_key_name()
         self._tsig_ctx = None
         # tsig_ctx_creator is introduced to allow tests to use a mock class for
         # easier tests (in normal case we always use the default)
@@ -621,6 +626,74 @@ class XfrinConnection(asyncore.dispatcher):
         self._transfer_stats = XfrinTransferStats()
         self._counters = counters
 
+    def create_socket(self, family, type):
+        """create_socket() overridden from the super class for
+        statistics counter open and openfail"""
+        try:
+            ret = super().create_socket(family, type)
+            # count open
+            self._counters.inc('socket',
+                               'ip' + self._get_ipver_str(),
+                               'tcp', 'open')
+            return ret
+        except:
+            # count openfail
+            self._counters.inc('socket',
+                               'ip' + self._get_ipver_str(),
+                               'tcp', 'openfail')
+            raise
+
+    def close(self):
+        """close() overridden from the super class for
+        statistics counter close"""
+        ret = super().close()
+        # count close
+        self._counters.inc('socket',
+                           'ip' + self._get_ipver_str(),
+                           'tcp', 'close')
+        return ret
+
+    def connect(self, address):
+        """connect() overridden from the super class for
+        statistics counter conn and connfail"""
+        try:
+            ret = super().connect(address)
+            # count conn
+            self._counters.inc('socket',
+                               'ip' + self._get_ipver_str(),
+                               'tcp', 'conn')
+            return ret
+        except:
+            # count connfail
+            self._counters.inc('socket',
+                               'ip' + self._get_ipver_str(),
+                               'tcp', 'connfail')
+            raise
+
+    def send(self, data):
+        """send() overridden from the super class for
+        statistics counter senderr"""
+        try:
+            return super().send(data)
+        except:
+            # count senderr
+            self._counters.inc('socket',
+                               'ip' + self._get_ipver_str(),
+                               'tcp', 'senderr')
+            raise
+
+    def recv(self, buffer_size):
+        """recv() overridden from the super class for
+        statistics counter senderr"""
+        try:
+            return super().recv(buffer_size)
+        except:
+            # count recverr
+            self._counters.inc('socket',
+                               'ip' + self._get_ipver_str(),
+                               'tcp', 'recverr')
+            raise
+
     def init_socket(self):
         '''Initialize the underlyig socket.
 
@@ -861,9 +934,9 @@ class XfrinConnection(asyncore.dispatcher):
         It raises a ValueError exception on other address families.
 
         """
-        if self.socket.family == socket.AF_INET:
+        if self._master_addrinfo[0] == socket.AF_INET:
             return 'v4'
-        elif self.socket.family == socket.AF_INET6:
+        elif self._master_addrinfo[0] == socket.AF_INET6:
             return 'v6'
         raise ValueError("Invalid address family. "
                          "This is supported only for IP sockets")
diff --git a/src/bin/xfrin/xfrin.spec b/src/bin/xfrin/xfrin.spec
index 826fde4..a662f75 100644
--- a/src/bin/xfrin/xfrin.spec
+++ b/src/bin/xfrin/xfrin.spec
@@ -274,6 +274,227 @@
         "item_default": 0,
         "item_title": "SOA queries",
         "item_description": "Number of SOA queries in progress"
+      },
+      {
+        "item_name": "socket",
+        "item_type": "map",
+        "item_optional": false,
+        "item_default": {
+          "ipv4": {
+            "tcp": {
+              "open": 0,
+              "openfail": 0,
+              "close": 0,
+              "connfail": 0,
+              "conn": 0,
+              "senderr": 0,
+              "recverr": 0
+            }
+          },
+          "ipv6": {
+            "tcp": {
+              "open": 0,
+              "openfail": 0,
+              "close": 0,
+              "connfail": 0,
+              "conn": 0,
+              "senderr": 0,
+              "recverr": 0
+            }
+          }
+        },
+        "item_title": "Socket",
+        "item_description": "A directory name of socket statistics",
+        "map_item_spec": [
+          {
+            "item_name": "ipv4",
+            "item_type": "map",
+            "item_optional": false,
+            "item_default": {
+              "tcp": {
+                "open": 0,
+                "openfail": 0,
+                "close": 0,
+                "connfail": 0,
+                "conn": 0,
+                "senderr": 0,
+                "recverr": 0
+              }
+            },
+            "item_title": "IPv4",
+            "item_description": "A directory name of IPv4",
+            "map_item_spec": [
+              {
+                "item_name": "tcp",
+                "item_type": "map",
+                "item_optional": false,
+                "item_default": {
+                  "open": 0,
+                  "openfail": 0,
+                  "close": 0,
+                  "connfail": 0,
+                  "conn": 0,
+                  "senderr": 0,
+                  "recverr": 0
+                },
+                "item_title": "TCP",
+                "item_description": "A directory name of TCP statistics",
+                "map_item_spec": [
+                  {
+                    "item_name": "open",
+                    "item_type": "integer",
+                    "item_optional": false,
+                    "item_default": 0,
+                    "item_title": "Open",
+                    "item_description": "IPv4 TCP sockets opened successfully"
+                  },
+                  {
+                    "item_name": "openfail",
+                    "item_type": "integer",
+                    "item_optional": false,
+                    "item_default": 0,
+                    "item_title": "Open failures",
+                    "item_description": "IPv4 TCP sockets open failures"
+                  },
+                  {
+                    "item_name": "close",
+                    "item_type": "integer",
+                    "item_optional": false,
+                    "item_default": 0,
+                    "item_title": "Close",
+                    "item_description": "IPv4 TCP sockets closed"
+                  },
+                  {
+                    "item_name": "connfail",
+                    "item_type": "integer",
+                    "item_optional": false,
+                    "item_default": 0,
+                    "item_title": "Connect failures",
+                    "item_description": "IPv4 TCP sockets connection failures"
+                  },
+                  {
+                    "item_name": "conn",
+                    "item_type": "integer",
+                    "item_optional": false,
+                    "item_default": 0,
+                    "item_title": "Connect",
+                    "item_description": "IPv4 TCP connections established successfully"
+                  },
+                  {
+                    "item_name": "senderr",
+                    "item_type": "integer",
+                    "item_optional": false,
+                    "item_default": 0,
+                    "item_title": "Send errors",
+                    "item_description": "IPv4 TCP sockets send errors"
+                  },
+                  {
+                    "item_name": "recverr",
+                    "item_type": "integer",
+                    "item_optional": false,
+                    "item_default": 0,
+                    "item_title": "Receive errors",
+                    "item_description": "IPv4 TCP sockets receive errors"
+                  }
+                ]
+              }
+            ]
+          },
+          {
+            "item_name": "ipv6",
+            "item_type": "map",
+            "item_optional": false,
+            "item_default": {
+              "tcp": {
+                "open": 0,
+                "openfail": 0,
+                "close": 0,
+                "connfail": 0,
+                "conn": 0,
+                "senderr": 0,
+                "recverr": 0
+              }
+            },
+            "item_title": "IPv6",
+            "item_description": "A directory name of IPv6",
+            "map_item_spec": [
+              {
+                "item_name": "tcp",
+                "item_type": "map",
+                "item_optional": false,
+                "item_default": {
+                  "open": 0,
+                  "openfail": 0,
+                  "close": 0,
+                  "connfail": 0,
+                  "conn": 0,
+                  "senderr": 0,
+                  "recverr": 0
+                },
+                "item_title": "TCP",
+                "item_description": "A directory name of TCP statistics",
+                "map_item_spec": [
+                  {
+                    "item_name": "open",
+                    "item_type": "integer",
+                    "item_optional": false,
+                    "item_default": 0,
+                    "item_title": "Open",
+                    "item_description": "IPv6 TCP sockets opened successfully"
+                  },
+                  {
+                    "item_name": "openfail",
+                    "item_type": "integer",
+                    "item_optional": false,
+                    "item_default": 0,
+                    "item_title": "Open failures",
+                    "item_description": "IPv6 TCP sockets open failures"
+                  },
+                  {
+                    "item_name": "close",
+                    "item_type": "integer",
+                    "item_optional": false,
+                    "item_default": 0,
+                    "item_title": "Close",
+                    "item_description": "IPv6 TCP sockets closed"
+                  },
+                  {
+                    "item_name": "connfail",
+                    "item_type": "integer",
+                    "item_optional": false,
+                    "item_default": 0,
+                    "item_title": "Connect failures",
+                    "item_description": "IPv6 TCP sockets connection failures"
+                  },
+                  {
+                    "item_name": "conn",
+                    "item_type": "integer",
+                    "item_optional": false,
+                    "item_default": 0,
+                    "item_title": "Connect",
+                    "item_description": "IPv6 TCP connections established successfully"
+                  },
+                  {
+                    "item_name": "senderr",
+                    "item_type": "integer",
+                    "item_optional": false,
+                    "item_default": 0,
+                    "item_title": "Send errors",
+                    "item_description": "IPv6 TCP sockets send errors"
+                  },
+                  {
+                    "item_name": "recverr",
+                    "item_type": "integer",
+                    "item_optional": false,
+                    "item_default": 0,
+                    "item_title": "Receive errors",
+                    "item_description": "IPv6 TCP sockets receive errors"
+                  }
+                ]
+              }
+            ]
+          }
+        ]
       }
     ]
   }
diff --git a/tests/lettuce/features/example.feature b/tests/lettuce/features/example.feature
index ee84b46..48cef20 100644
--- a/tests/lettuce/features/example.feature
+++ b/tests/lettuce/features/example.feature
@@ -132,6 +132,36 @@ Feature: Example feature
         A query for www.example.org to 127.0.0.1:47806 should have rcode NOERROR
         A query for www.example.org type A class IN to 127.0.0.1:47806 should have rcode NOERROR
 
+    Scenario: example.org mixed-case query
+        # This scenario performs a mixed-case query and checks that the
+        # response has the name copied from the question exactly
+        # (without any change in case). For why this is necessary, see
+        # section 5.2 of:
+        # http://tools.ietf.org/html/draft-vixie-dnsext-dns0x20-00
+
+        Given I have bind10 running with configuration example.org.config
+        And wait for bind10 stderr message BIND10_STARTED_CC
+        And wait for bind10 stderr message CMDCTL_STARTED
+        And wait for bind10 stderr message AUTH_SERVER_STARTED
+
+        bind10 module Auth should be running
+        And bind10 module Resolver should not be running
+        And bind10 module Xfrout should not be running
+        And bind10 module Zonemgr should not be running
+        And bind10 module Xfrin should not be running
+        And bind10 module Stats should not be running
+        And bind10 module StatsHttpd should not be running
+
+        A query for wWw.eXaMpLe.Org should have rcode NOERROR
+        The last query response should have qdcount 1
+        The last query response should have ancount 1
+        The last query response should have nscount 3
+        The last query response should have adcount 0
+        The question section of the last query response should exactly be
+        """
+        ;wWw.eXaMpLe.Org. IN A
+        """
+
     Scenario: changing database
         # This scenario contains a lot of 'wait for' steps
         # If those are not present, the asynchronous nature of the application
diff --git a/tests/lettuce/features/terrain/querying.py b/tests/lettuce/features/terrain/querying.py
index ec75490..d585e5e 100644
--- a/tests/lettuce/features/terrain/querying.py
+++ b/tests/lettuce/features/terrain/querying.py
@@ -110,6 +110,8 @@ class QueryResult(object):
             self.line_handler = self.parse_answer
         elif line == ";; OPT PSEUDOSECTION:\n":
             self.line_handler = self.parse_opt
+        elif line == ";; QUESTION SECTION:\n":
+            self.line_handler = self.parse_question
         elif line == ";; AUTHORITY SECTION:\n":
             self.line_handler = self.parse_authority
         elif line == ";; ADDITIONAL SECTION:\n":
@@ -290,8 +292,8 @@ def check_last_query(step, item, value):
     assert str(value) == str(lq_val),\
            "Got: " + str(lq_val) + ", expected: " + str(value)
 
- at step('([a-zA-Z]+) section of the last query response should be')
-def check_last_query_section(step, section):
+ at step('([a-zA-Z]+) section of the last query response should (exactly )?be')
+def check_last_query_section(step, section, exact):
     """
     Check the entire contents of the given section of the response of the last
     query.
@@ -330,9 +332,10 @@ def check_last_query_section(step, section):
     # replace whitespace of any length by one space
     response_string = re.sub("[ \t]+", " ", response_string)
     expect = re.sub("[ \t]+", " ", step.multiline)
-    # lowercase them
-    response_string = response_string.lower()
-    expect = expect.lower()
+    # lowercase them unless we need to do an exact match
+    if exact is None:
+        response_string = response_string.lower()
+        expect = expect.lower()
     # sort them
     response_string_parts = response_string.split("\n")
     response_string_parts.sort()
diff --git a/tests/lettuce/features/xfrin_notify_handling.feature b/tests/lettuce/features/xfrin_notify_handling.feature
index 4822552..2f43dfd 100644
--- a/tests/lettuce/features/xfrin_notify_handling.feature
+++ b/tests/lettuce/features/xfrin_notify_handling.feature
@@ -118,6 +118,10 @@ Feature: Xfrin incoming notify handling
       | zones.IN.example.org..last_axfr_duration |            |       0.0 |
       | soa_in_progress                          |          0 |           |
       | axfr_running                             |          0 |           |
+      | socket.ipv6.tcp.open                     |            |         1 |
+      | socket.ipv6.tcp.close                    |            |         1 |
+      | socket.ipv6.tcp.conn                     |            |         1 |
+      | socket.ipv6.tcp.connfail                 |          0 |           |
 
     #
     # Test for handling incoming notify only in IPv4
@@ -226,6 +230,10 @@ Feature: Xfrin incoming notify handling
       | zones.IN.example.org..last_axfr_duration |            |       0.0 |
       | soa_in_progress                          |          0 |           |
       | axfr_running                             |          0 |           |
+      | socket.ipv4.tcp.open                     |            |         1 |
+      | socket.ipv4.tcp.close                    |            |         1 |
+      | socket.ipv4.tcp.conn                     |            |         1 |
+      | socket.ipv4.tcp.connfail                 |          0 |           |
 
     #
     # Test for Xfr request rejected
@@ -338,6 +346,10 @@ Feature: Xfrin incoming notify handling
       | zones.IN.example.org..xfrfail   |            |         1 |
       | soa_in_progress                 |            |         0 |
       | axfr_running                    |            |         0 |
+      | socket.ipv6.tcp.open            |            |         1 |
+      | socket.ipv6.tcp.close           |            |         1 |
+      | socket.ipv6.tcp.conn            |            |         1 |
+      | socket.ipv6.tcp.connfail        |          0 |           |
 
     #
     # Test for Xfr request rejected in IPv4
@@ -450,6 +462,10 @@ Feature: Xfrin incoming notify handling
       | zones.IN.example.org..xfrfail   |            |         1 |
       | soa_in_progress                 |            |         0 |
       | axfr_running                    |            |         0 |
+      | socket.ipv4.tcp.open            |            |         1 |
+      | socket.ipv4.tcp.close           |            |         1 |
+      | socket.ipv4.tcp.conn            |            |         1 |
+      | socket.ipv4.tcp.connfail        |          0 |           |
 
     #
     # Test for unreachable slave
@@ -613,3 +629,46 @@ Feature: Xfrin incoming notify handling
     Then wait for master stderr message NOTIFY_OUT_TIMEOUT not NOTIFY_OUT_REPLY_RECEIVED
 
     A query for www.example.org to [::1]:47806 should have rcode NXDOMAIN
+
+    #
+    # Test for unreachable master
+    #
+    Scenario: Handle incoming notify (unreachable master)
+
+    And I have bind10 running with configuration xfrin/retransfer_slave_notify.conf
+    And wait for bind10 stderr message BIND10_STARTED_CC
+    And wait for bind10 stderr message CMDCTL_STARTED
+    And wait for bind10 stderr message AUTH_SERVER_STARTED
+    And wait for bind10 stderr message XFRIN_STARTED
+    And wait for bind10 stderr message ZONEMGR_STARTED
+
+    A query for www.example.org to [::1]:47806 should have rcode NXDOMAIN
+
+    #
+    # Test1 for Xfrin statistics
+    #
+    check initial statistics not containing example.org for Xfrin
+
+    #
+    # execute reftransfer for Xfrin
+    #
+    When I send bind10 the command Xfrin retransfer example.org IN
+    Then wait for new bind10 stderr message XFRIN_CONNECT_MASTER
+    Then wait for new bind10 stderr message ZONEMGR_RECEIVE_XFRIN_FAILED
+
+    #
+    # Test2 for Xfrin statistics
+    #
+    # check initial statistics
+    #
+
+    # wait until the last stats requesting is finished
+    wait for new bind10 stderr message STATS_SEND_STATISTICS_REQUEST
+    wait for new bind10 stderr message XFRIN_RECEIVED_COMMAND
+
+    When I query statistics socket of bind10 module Xfrin with cmdctl
+    The statistics counters are 0 in category .Xfrin.socket.ipv6.tcp except for the following items
+      | item_name | min_value |
+      | open      |         1 |
+      | close     |         1 |
+      | connfail  |         1 |



More information about the bind10-changes mailing list