2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-09-04 07:55:18 +00:00

Merge branch 'trac2300'

Conflicts:
	src/bin/xfrin/b10-xfrin.xml
	src/bin/xfrin/xfrin.spec
	tests/lettuce/features/xfrin_notify_handling.feature
This commit is contained in:
Mukund Sivaraman
2013-11-07 11:54:29 +05:30
5 changed files with 556 additions and 4 deletions

View File

@@ -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>

View File

@@ -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()

View File

@@ -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")

View File

@@ -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"
}
]
}
]
}
]
}
]
}

View File

@@ -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 |