BIND 10 master, updated. 6881cd3cc4fe062b1a067d0481c986eb6603a689 [master] Changelog for #2222
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Sep 25 10:49:46 UTC 2012
The branch, master has been updated
via 6881cd3cc4fe062b1a067d0481c986eb6603a689 (commit)
via 91311bdbfea95f65c5e8bd8294ba08fac12405f1 (commit)
via 0f3f6b1f3cdc54176c1abf4b22bbdfe4dbae0a5c (commit)
via 48df8a1486f00e27636febfa3487ddab9a051ca6 (commit)
via 668cdb357976bea8bc0b775459324b68dd2906b9 (commit)
via 179247735be1594337d07f0761b5fa8af2f44dc2 (commit)
via af6832161c3fc10de0239da3ddb47e7261413615 (commit)
via 704457924e2a892e012b7c750bfe08fe56da7128 (commit)
via 2fee008d989b5c60c13dbe86729e8a1ee8ac6456 (commit)
via 396bb7832e661dc597853e9f062e7094a209baf0 (commit)
via 9a655fdd02d00a22003c6f7c9902ef80072a2332 (commit)
via a258bfbbb515f7bd3d336d14e89f2dd58412e807 (commit)
via 8015bd0bde0d4adccf7f4fc66423156cc9504011 (commit)
via f92a3289255ec12a39e9d720398b72ee97197991 (commit)
via e294cb85d5bf15e7036a0b1c4ae659513be6a101 (commit)
via 4b3d83b7b5cf42576081426ab8aaeb7e545640a0 (commit)
via 8ab3a360bb68b257c5a9bd363ce28343e409684a (commit)
via 1c9fa8a0b9ea4d328bbb6325e94ce1af95d6e99d (commit)
from 21f612a9f5ec269d4ec4b1103b17857924cb2055 (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 6881cd3cc4fe062b1a067d0481c986eb6603a689
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Tue Sep 25 18:44:00 2012 +0900
[master] Changelog for #2222
commit 91311bdbfea95f65c5e8bd8294ba08fac12405f1
Merge: 21f612a 0f3f6b1
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Tue Sep 25 18:39:45 2012 +0900
[master] Merge branch 'trac2222'
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 6 +
src/bin/xfrout/b10-xfrout.xml | 26 ++-
src/bin/xfrout/tests/xfrout_test.py.in | 211 +++++++++++++-------
src/bin/xfrout/xfrout.py.in | 119 +++++++++--
src/bin/xfrout/xfrout.spec.pre.in | 16 ++
tests/lettuce/features/terrain/bind10_control.py | 25 ++-
.../lettuce/features/xfrin_notify_handling.feature | 56 +++---
7 files changed, 330 insertions(+), 129 deletions(-)
-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index 0cf23d4..e266ba9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+478. [func] naokikambe
+ New statistics items added into b10-xfrout: ixfr_running and
+ axfr_running. Their values can be obtained by invoking "Stats show
+ Xfrout" via bindctl while b10-xfrout is running.
+ (Trac #2222, git 91311bdbfea95f65c5e8bd8294ba08fac12405f1)
+
477. [bug] jelte
Fixed a problem with b10-msgq on OSX when using a custom Python
installation, that offers an unreliable select.poll() interface.
diff --git a/src/bin/xfrout/b10-xfrout.xml b/src/bin/xfrout/b10-xfrout.xml
index 4415cff..8b616d2 100644
--- a/src/bin/xfrout/b10-xfrout.xml
+++ b/src/bin/xfrout/b10-xfrout.xml
@@ -1,6 +1,6 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
- [<!ENTITY mdash "—">]>
+ [<!ENTITY mdash "—">]>
<!--
- Copyright (C) 2010-2012 Internet Systems Consortium, Inc. ("ISC")
-
@@ -166,15 +166,15 @@
<varlistentry>
<term>notifyoutv4</term>
<listitem><simpara>
- Number of IPv4 notifies per zone name sent out from Xfrout
- </simpara></listitem>
+ Number of IPv4 notifies per zone name sent out from Xfrout
+ </simpara></listitem>
</varlistentry>
<varlistentry>
<term>notifyoutv6</term>
<listitem><simpara>
- Number of IPv6 notifies per zone name sent out from Xfrout
- </simpara></listitem>
+ Number of IPv6 notifies per zone name sent out from Xfrout
+ </simpara></listitem>
</varlistentry>
<varlistentry>
@@ -187,7 +187,21 @@
<varlistentry>
<term>xfrreqdone</term>
<listitem><simpara>
- Number of requested zone transfers per zone name completed
+ Number of requested zone transfers per zone name completed
+ </simpara></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ixfr_running</term>
+ <listitem><simpara>
+ Number of IXFRs in progress
+ </simpara></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>axfr_running</term>
+ <listitem><simpara>
+ Number of AXFRs in progress
</simpara></listitem>
</varlistentry>
diff --git a/src/bin/xfrout/tests/xfrout_test.py.in b/src/bin/xfrout/tests/xfrout_test.py.in
index 9e07527..6e3f4a8 100644
--- a/src/bin/xfrout/tests/xfrout_test.py.in
+++ b/src/bin/xfrout/tests/xfrout_test.py.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2010 Internet Systems Consortium.
+# Copyright (C) 2010-2012 Internet Systems Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -270,6 +270,7 @@ class TestXfroutSessionBase(unittest.TestCase):
def setUp(self):
self.sock = MySocket(socket.AF_INET,socket.SOCK_STREAM)
+ self.setup_counters()
self.xfrsess = MyXfroutSession(self.sock, None, Dbserver(),
TSIGKeyRing(),
(socket.AF_INET, socket.SOCK_STREAM,
@@ -278,22 +279,54 @@ class TestXfroutSessionBase(unittest.TestCase):
isc.acl.dns.REQUEST_LOADER.load(
[{"action": "ACCEPT"}]),
{},
- counter_xfrrej=self._counter_xfrrej,
- counter_xfrreqdone=self._counter_xfrreqdone)
+ **self._counters)
self.set_request_type(RRType.AXFR()) # test AXFR by default
self.mdata = self.create_request_data()
self.soa_rrset = create_soa(SOA_CURRENT_VERSION)
# some test replaces a module-wide function. We should ensure the
# original is used elsewhere.
self.orig_get_rrset_len = xfrout.get_rrset_len
- self._zone_name_xfrrej = None
- self._zone_name_xfrreqdone = None
- def _counter_xfrrej(self, zone_name):
- self._zone_name_xfrrej = zone_name
+ def setup_counters(self):
+ self._statistics_data = {
+ 'zones' : {
+ TEST_ZONE_NAME_STR : {
+ 'xfrrej': 0,
+ 'xfrreqdone': 0
+ }
+ },
+ 'axfr_started': 0,
+ 'ixfr_started': 0,
+ 'axfr_ended': 0,
+ 'ixfr_ended': 0
+ }
+ def _counter_xfrrej(zone_name):
+ self._statistics_data['zones'][zone_name]['xfrrej'] += 1
+ def _counter_xfrreqdone(zone_name):
+ self._statistics_data['zones'][zone_name]['xfrreqdone'] += 1
+ def _inc_ixfr_running():
+ self._statistics_data['ixfr_started'] += 1
+ def _dec_ixfr_running():
+ self._statistics_data['ixfr_ended'] += 1
+ def _inc_axfr_running():
+ self._statistics_data['axfr_started'] += 1
+ def _dec_axfr_running():
+ self._statistics_data['axfr_ended'] += 1
+ self._counters = {
+ 'counter_xfrrej': _counter_xfrrej,
+ 'counter_xfrreqdone': _counter_xfrreqdone,
+ 'inc_ixfr_running': _inc_ixfr_running,
+ 'dec_ixfr_running': _dec_ixfr_running,
+ 'inc_axfr_running': _inc_axfr_running,
+ 'dec_axfr_running': _dec_axfr_running
+ }
- def _counter_xfrreqdone(self, zone_name):
- self._zone_name_xfrreqdone = zone_name
+ def get_counter(self, name):
+ if name.find('ixfr_') == 0 or name.find('axfr_') == 0:
+ return self._statistics_data[name]
+ else:
+ return \
+ self._statistics_data['zones'][TEST_ZONE_NAME_STR][name]
def tearDown(self):
xfrout.get_rrset_len = self.orig_get_rrset_len
@@ -386,6 +419,8 @@ class TestXfroutSession(TestXfroutSessionBase):
"action": "DROP"
}
]))
+ # check the 'xfrrej' counter initially
+ self.assertEqual(self.get_counter('xfrrej'), 0)
# Localhost (the default in this test) is accepted
rcode, msg = self.xfrsess._parse_query_message(self.mdata)
self.assertEqual(rcode.to_text(), "NOERROR")
@@ -399,6 +434,8 @@ class TestXfroutSession(TestXfroutSessionBase):
('192.0.2.2', 12345))
rcode, msg = self.xfrsess._parse_query_message(self.mdata)
self.assertEqual(rcode.to_text(), "REFUSED")
+ # check the 'xfrrej' counter after incrementing
+ self.assertEqual(self.get_counter('xfrrej'), 1)
# TSIG signed request
request_data = self.create_request_data(with_tsig=True)
@@ -427,6 +464,8 @@ class TestXfroutSession(TestXfroutSessionBase):
]))
[rcode, msg] = self.xfrsess._parse_query_message(request_data)
self.assertEqual(rcode.to_text(), "REFUSED")
+ # check the 'xfrrej' counter after incrementing
+ self.assertEqual(self.get_counter('xfrrej'), 2)
# ACL using TSIG: no TSIG; should be rejected
acl_setter(isc.acl.dns.REQUEST_LOADER.load([
@@ -434,6 +473,8 @@ class TestXfroutSession(TestXfroutSessionBase):
]))
[rcode, msg] = self.xfrsess._parse_query_message(self.mdata)
self.assertEqual(rcode.to_text(), "REFUSED")
+ # check the 'xfrrej' counter after incrementing
+ self.assertEqual(self.get_counter('xfrrej'), 3)
#
# ACL using IP + TSIG: both should match
@@ -453,34 +494,28 @@ class TestXfroutSession(TestXfroutSessionBase):
('192.0.2.2', 12345))
[rcode, msg] = self.xfrsess._parse_query_message(request_data)
self.assertEqual(rcode.to_text(), "REFUSED")
+ # check the 'xfrrej' counter after incrementing
+ self.assertEqual(self.get_counter('xfrrej'), 4)
# Address matches, but TSIG doesn't (not included)
self.xfrsess._remote = (socket.AF_INET, socket.SOCK_STREAM,
('192.0.2.1', 12345))
[rcode, msg] = self.xfrsess._parse_query_message(self.mdata)
self.assertEqual(rcode.to_text(), "REFUSED")
+ # check the 'xfrrej' counter after incrementing
+ self.assertEqual(self.get_counter('xfrrej'), 5)
# Neither address nor TSIG matches
self.xfrsess._remote = (socket.AF_INET, socket.SOCK_STREAM,
('192.0.2.2', 12345))
[rcode, msg] = self.xfrsess._parse_query_message(self.mdata)
self.assertEqual(rcode.to_text(), "REFUSED")
+ # check the 'xfrrej' counter after incrementing
+ self.assertEqual(self.get_counter('xfrrej'), 6)
def test_transfer_acl(self):
# ACL checks only with the default ACL
def acl_setter(acl):
self.xfrsess._acl = acl
- self.assertIsNone(self._zone_name_xfrrej)
- self.check_transfer_acl(acl_setter)
- self.assertEqual(self._zone_name_xfrrej, TEST_ZONE_NAME_STR)
-
- def test_transfer_acl_with_nonetype_xfrrej(self):
- # ACL checks only with the default ACL and NoneType xfrrej
- # counter
- def acl_setter(acl):
- self.xfrsess._acl = acl
- self.xfrsess._counter_xfrrej = None
- self.assertIsNone(self._zone_name_xfrrej)
self.check_transfer_acl(acl_setter)
- self.assertIsNone(self._zone_name_xfrrej)
def test_transfer_acl_with_notcallable_xfrrej(self):
# ACL checks only with the default ACL and not callable xfrrej
@@ -500,9 +535,7 @@ class TestXfroutSession(TestXfroutSessionBase):
self.xfrsess._zone_config[zone_key]['transfer_acl'] = acl
self.xfrsess._acl = isc.acl.dns.REQUEST_LOADER.load([
{"from": "127.0.0.1", "action": "DROP"}])
- self.assertIsNone(self._zone_name_xfrrej)
self.check_transfer_acl(acl_setter)
- self.assertEqual(self._zone_name_xfrrej, TEST_ZONE_NAME_STR)
def test_transfer_zoneacl_nomatch(self):
# similar to the previous one, but the per zone doesn't match the
@@ -514,9 +547,7 @@ class TestXfroutSession(TestXfroutSessionBase):
isc.acl.dns.REQUEST_LOADER.load([
{"from": "127.0.0.1", "action": "DROP"}])
self.xfrsess._acl = acl
- self.assertIsNone(self._zone_name_xfrrej)
self.check_transfer_acl(acl_setter)
- self.assertEqual(self._zone_name_xfrrej, TEST_ZONE_NAME_STR)
def test_get_transfer_acl(self):
# set the default ACL. If there's no specific zone ACL, this one
@@ -866,25 +897,11 @@ class TestXfroutSession(TestXfroutSessionBase):
def myreply(msg, sock):
self.sock.send(b"success")
- self.assertIsNone(self._zone_name_xfrreqdone)
+ self.assertEqual(self.get_counter('xfrreqdone'), 0)
self.xfrsess._reply_xfrout_query = myreply
self.xfrsess.dns_xfrout_start(self.sock, self.mdata)
self.assertEqual(self.sock.readsent(), b"success")
- self.assertEqual(self._zone_name_xfrreqdone, TEST_ZONE_NAME_STR)
-
- def test_dns_xfrout_start_with_nonetype_xfrreqdone(self):
- def noerror(msg, name, rrclass):
- return Rcode.NOERROR()
- self.xfrsess._xfrout_setup = noerror
-
- def myreply(msg, sock):
- self.sock.send(b"success")
-
- self.assertIsNone(self._zone_name_xfrreqdone)
- self.xfrsess._reply_xfrout_query = myreply
- self.xfrsess._counter_xfrreqdone = None
- self.xfrsess.dns_xfrout_start(self.sock, self.mdata)
- self.assertIsNone(self._zone_name_xfrreqdone)
+ self.assertGreater(self.get_counter('xfrreqdone'), 0)
def test_dns_xfrout_start_with_notcallable_xfrreqdone(self):
def noerror(msg, name, rrclass):
@@ -1154,10 +1171,20 @@ class TestXfroutSessionWithSQLite3(TestXfroutSessionBase):
self.assertTrue(rrsets_equal(expected_rr, actual_rr))
def test_axfr_normal_session(self):
+ self.assertEqual(self.get_counter('axfr_started'), 0)
+ self.assertEqual(self.get_counter('axfr_ended'), 0)
+ self.assertEqual(self.get_counter('ixfr_started'), 0)
+ self.assertEqual(self.get_counter('ixfr_ended'), 0)
XfroutSession._handle(self.xfrsess)
response = self.sock.read_msg(Message.PRESERVE_ORDER);
self.assertEqual(Rcode.NOERROR(), response.get_rcode())
self.check_axfr_stream(response)
+ self.assertEqual(self.xfrsess._request_type, RRType.AXFR())
+ self.assertNotEqual(self.xfrsess._request_type, RRType.IXFR())
+ self.assertEqual(self.get_counter('axfr_started'), 1)
+ self.assertEqual(self.get_counter('axfr_ended'), 1)
+ self.assertEqual(self.get_counter('ixfr_started'), 0)
+ self.assertEqual(self.get_counter('ixfr_ended'), 0)
def test_ixfr_to_axfr(self):
self.xfrsess._request_data = \
@@ -1176,6 +1203,10 @@ class TestXfroutSessionWithSQLite3(TestXfroutSessionBase):
# two beginning and trailing SOAs.
self.xfrsess._request_data = \
self.create_request_data(ixfr=IXFR_OK_VERSION)
+ self.assertEqual(self.get_counter('axfr_started'), 0)
+ self.assertEqual(self.get_counter('axfr_ended'), 0)
+ self.assertEqual(self.get_counter('ixfr_started'), 0)
+ self.assertEqual(self.get_counter('ixfr_ended'), 0)
XfroutSession._handle(self.xfrsess)
response = self.sock.read_msg(Message.PRESERVE_ORDER)
actual_records = response.get_section(Message.SECTION_ANSWER)
@@ -1191,6 +1222,12 @@ class TestXfroutSessionWithSQLite3(TestXfroutSessionBase):
self.assertEqual(len(expected_records), len(actual_records))
for (expected_rr, actual_rr) in zip(expected_records, actual_records):
self.assertTrue(rrsets_equal(expected_rr, actual_rr))
+ self.assertNotEqual(self.xfrsess._request_type, RRType.AXFR())
+ self.assertEqual(self.xfrsess._request_type, RRType.IXFR())
+ self.assertEqual(self.get_counter('axfr_started'), 0)
+ self.assertEqual(self.get_counter('axfr_ended'), 0)
+ self.assertEqual(self.get_counter('ixfr_started'), 1)
+ self.assertEqual(self.get_counter('ixfr_ended'), 1)
def ixfr_soa_only_common_checks(self, request_serial):
self.xfrsess._request_data = \
@@ -1578,9 +1615,9 @@ class MyXfroutServer(XfroutServer):
class TestXfroutCounter(unittest.TestCase):
def setUp(self):
- statistics_spec = \
- isc.config.module_spec_from_file(\
- xfrout.SPECFILE_LOCATION).get_statistics_spec()
+ self._module_spec = isc.config.module_spec_from_file(\
+ xfrout.SPECFILE_LOCATION)
+ statistics_spec = self._module_spec.get_statistics_spec()
self.xfrout_counter = XfroutCounter(statistics_spec)
self._counters = isc.config.spec_name_list(\
isc.config.find_spec_part(\
@@ -1591,22 +1628,23 @@ class TestXfroutCounter(unittest.TestCase):
self._cycle = 10000 # number of counting per thread
def test_get_default_statistics_data(self):
- self.assertEqual(self.xfrout_counter._get_default_statistics_data(),
- {XfroutCounter.perzone_prefix: {
- XfroutCounter.entire_server: \
- dict([(cnt, 0) for cnt in self._counters])
- }})
-
- def setup_incrementer(self, incrementer):
+ self.assertTrue(\
+ self._module_spec.validate_statistics(\
+ True,
+ self.xfrout_counter._get_default_statistics_data(),
+ )
+ )
+
+ def setup_incrementer(self, incrementer, *args):
self._started.wait()
- for i in range(self._cycle): incrementer(TEST_ZONE_NAME_STR)
+ for i in range(self._cycle): incrementer(*args)
- def start_incrementer(self, incrementer):
+ def start_incrementer(self, incrementer, *args):
threads = []
for i in range(self._number):
threads.append(threading.Thread(\
- target=self.setup_incrementer,\
- args=(incrementer,)\
+ target=self.setup_incrementer, \
+ args=(incrementer,) + args \
))
for th in threads: th.start()
self._started.set()
@@ -1618,24 +1656,61 @@ class TestXfroutCounter(unittest.TestCase):
'%s/%s/%s' % (XfroutCounter.perzone_prefix,\
zone_name, counter_name))
- def test_incrementers(self):
+ def test_incdecrementers(self):
+ # for per-zone counters
result = { XfroutCounter.entire_server: {},
TEST_ZONE_NAME_STR: {} }
for counter_name in self._counters:
- incrementer = getattr(self.xfrout_counter, 'inc_%s' % counter_name)
- self.start_incrementer(incrementer)
- self.assertEqual(self.get_count(\
- TEST_ZONE_NAME_STR, counter_name), \
- self._number * self._cycle)
- self.assertEqual(self.get_count(\
- XfroutCounter.entire_server, counter_name), \
- self._number * self._cycle)
- result[XfroutCounter.entire_server][counter_name] = \
- result[TEST_ZONE_NAME_STR][counter_name] = \
- self._number * self._cycle
+ cntrs_xfrss = \
+ self.xfrout_counter.get_counters_for_xfroutsession()
+ cntrs_notfy = \
+ self.xfrout_counter.get_counters_for_notifyout()
+ cnt_name = 'counter_%s' % counter_name
+ incrementer = None
+ if cnt_name in cntrs_xfrss:
+ incrementer = cntrs_xfrss[cnt_name]
+ else:
+ incrementer = cntrs_notfy[cnt_name]
+ self.start_incrementer(incrementer, TEST_ZONE_NAME_STR)
+ self.assertEqual(self.get_count(\
+ TEST_ZONE_NAME_STR, counter_name), \
+ self._number * self._cycle)
+ self.assertEqual(self.get_count(\
+ XfroutCounter.entire_server, counter_name), \
+ self._number * self._cycle)
+ result[XfroutCounter.entire_server][counter_name] = \
+ result[TEST_ZONE_NAME_STR][counter_name] = \
+ self._number * self._cycle
+ statistics_data = {XfroutCounter.perzone_prefix: result}
+
+ # for {a|i}xfrrunning counters
+ for counter_name in self.xfrout_counter._xfrrunning_names:
+ incrementer = \
+ dict(self.xfrout_counter.get_counters_for_xfroutsession(), \
+ **self.xfrout_counter.get_counters_for_notifyout())\
+ ['inc_%s' % counter_name]
+ self.start_incrementer(incrementer)
+ self.assertEqual(
+ self.xfrout_counter.get_statistics()[counter_name],
+ self._number * self._cycle
+ )
+ decrementer = \
+ dict(self.xfrout_counter.get_counters_for_xfroutsession(), \
+ **self.xfrout_counter.get_counters_for_notifyout())\
+ ['dec_%s' % counter_name]
+ self.start_incrementer(decrementer)
+ self.assertEqual(
+ self.xfrout_counter.get_statistics()[counter_name],
+ 0)
+ statistics_data[counter_name] = 0
self.assertEqual(
self.xfrout_counter.get_statistics(),
- {XfroutCounter.perzone_prefix: result})
+ statistics_data)
+ self.assertTrue(\
+ self._module_spec.validate_statistics(\
+ True, statistics_data
+ )
+ )
def test_add_perzone_counter(self):
for counter_name in self._counters:
diff --git a/src/bin/xfrout/xfrout.py.in b/src/bin/xfrout/xfrout.py.in
index d3141ad..835696e 100755
--- a/src/bin/xfrout/xfrout.py.in
+++ b/src/bin/xfrout/xfrout.py.in
@@ -1,6 +1,6 @@
#!@PYTHON@
-# Copyright (C) 2010 Internet Systems Consortium.
+# Copyright (C) 2010-2012 Internet Systems Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -154,7 +154,7 @@ def get_soa_serial(soa_rdata):
class XfroutSession():
def __init__(self, sock_fd, request_data, server, tsig_key_ring, remote,
default_acl, zone_config, client_class=DataSourceClient,
- counter_xfrrej=None, counter_xfrreqdone=None):
+ **counters):
self._sock_fd = sock_fd
self._request_data = request_data
self._server = server
@@ -169,10 +169,13 @@ class XfroutSession():
self.ClientClass = client_class # parameterize this for testing
self._soa = None # will be set in _xfrout_setup or in tests
self._jnl_reader = None # will be set to a reader for IXFR
- # Set counter handlers for counting Xfr requests. An argument
- # is required for zone name.
- self._counter_xfrrej = counter_xfrrej
- self._counter_xfrreqdone = counter_xfrreqdone
+ # Extract counter handler from the `counters` argument and add
+ # it to the class attribute of the name whose prefix is
+ # '_counter_' '_inc_' or '_dec_'
+ for (k, v) in counters.items():
+ if k.find('counter_') == 0 or k.find('inc_') == 0 \
+ or k.find('dec_') == 0:
+ setattr(self, "_%s" % k, v)
self._handle()
def create_tsig_ctx(self, tsig_record, tsig_key_ring):
@@ -275,9 +278,8 @@ class XfroutSession():
format_zone_str(zone_name, zone_class))
return None, None
elif acl_result == REJECT:
- if self._counter_xfrrej is not None:
- # count rejected Xfr request by each zone name
- self._counter_xfrrej(zone_name.to_text())
+ # count rejected Xfr request by each zone name
+ self._counter_xfrrej(zone_name.to_text())
logger.debug(DBG_XFROUT_TRACE, XFROUT_QUERY_REJECTED,
self._request_type, format_addrinfo(self._remote),
format_zone_str(zone_name, zone_class))
@@ -527,15 +529,25 @@ class XfroutSession():
return self._reply_query_with_error_rcode(msg, sock_fd, rcode_)
try:
+ # increment Xfr starts by RRType
+ if self._request_type == RRType.AXFR():
+ self._inc_axfr_running()
+ else:
+ self._inc_ixfr_running()
logger.info(XFROUT_XFR_TRANSFER_STARTED, self._request_typestr,
format_addrinfo(self._remote), zone_str)
self._reply_xfrout_query(msg, sock_fd)
except Exception as err:
logger.error(XFROUT_XFR_TRANSFER_ERROR, self._request_typestr,
format_addrinfo(self._remote), zone_str, err)
- if self._counter_xfrreqdone is not None:
- # count done Xfr requests by each zone name
- self._counter_xfrreqdone(zone_name.to_text())
+ finally:
+ # decrement Xfr starts by RRType
+ if self._request_type == RRType.AXFR():
+ self._dec_axfr_running()
+ else:
+ self._dec_ixfr_running()
+ # count done Xfr requests by each zone name
+ self._counter_xfrreqdone(zone_name.to_text())
logger.info(XFROUT_XFR_TRANSFER_DONE, self._request_typestr,
format_addrinfo(self._remote), zone_str)
@@ -948,6 +960,8 @@ class XfroutCounter:
zones/example.com./notifyoutv6
zones/example.com./xfrrej
zones/example.com./xfrreqdone
+ ixfr_running
+ axfr_running
"""
# '_SERVER_' is a special zone name representing an entire
# count. It doesn't mean a specific zone, but it means an
@@ -959,8 +973,15 @@ class XfroutCounter:
self._statistics_spec = statistics_spec
# holding statistics data for Xfrout module
self._statistics_data = {}
+ self._counters_for_xfroutsession = {}
+ self._counters_for_notifyout = {}
+ self._xfrrunning_names = [
+ n for n in isc.config.spec_name_list\
+ (self._statistics_spec) \
+ if n.find('xfr_running') == 1 ]
self._lock = threading.RLock()
self._create_perzone_incrementers()
+ self._create_xfrrunning_incdecrementers()
def get_statistics(self):
"""Calculates an entire server counts, and returns statistics
@@ -971,9 +992,9 @@ class XfroutCounter:
# If self._statistics_data contains nothing of zone name, it
# returns an empty dict.
if len(self._statistics_data) == 0: return {}
+ # for per-zone counter
zones = {}
- with self._lock:
- zones = self._statistics_data[self.perzone_prefix].copy()
+ zones = self._statistics_data[self.perzone_prefix]
# Start calculation for '_SERVER_' counts
attrs = self._get_default_statistics_data()[self.perzone_prefix][self.entire_server]
statistics_data = {self.perzone_prefix: {}}
@@ -991,7 +1012,12 @@ class XfroutCounter:
if sum_ > 0:
if self.entire_server not in statistics_data[self.perzone_prefix]:
statistics_data[self.perzone_prefix][self.entire_server] = {}
- statistics_data[self.perzone_prefix][self.entire_server].update({attr: sum_})
+ statistics_data[self.perzone_prefix][self.entire_server]\
+ .update({attr:sum_})
+ # for xfrrunning incrementer/decrementer
+ for name in self._xfrrunning_names:
+ if name in self._statistics_data:
+ statistics_data[name] = self._statistics_data[name]
return statistics_data
def _get_default_statistics_data(self):
@@ -1021,11 +1047,51 @@ class XfroutCounter:
with self._lock:
self._add_perzone_counter(zone_name)
self._statistics_data[self.perzone_prefix][zone_name][counter_name] += step
- setattr(self, 'inc_%s' % item, __perzone_incrementer)
-
+ if 'notifyout' in item:
+ self._counters_for_notifyout['counter_%s' % item] \
+ = __perzone_incrementer
+ else:
+ self._counters_for_xfroutsession['counter_%s' % item] \
+ = __perzone_incrementer
+
+ def _create_xfrrunning_incdecrementers(self):
+ """Creates increment/decrement method of (a|i)xfr_running
+ based on the spec file. Incrementer can be accessed by name
+ "inc_${item_name}". Decrementer can be accessed by name
+ "dec_${item_name}". Both of them are passed to the
+ XfroutSession as counter handlers."""
+ # can be accessed by the name 'inc_xxx' or 'dec_xxx'
+ for item in self._xfrrunning_names:
+ def __xfrrunning_incrementer(counter_name=item, step=1):
+ """A incrementer for axfr or ixfr running. Locks the thread
+ because it is considered to be invoked by a multi-threading
+ caller."""
+ with self._lock:
+ self._add_xfrrunning_counter(counter_name)
+ self._statistics_data[counter_name] += step
+ def __xfrrunning_decrementer(counter_name=item, step=-1):
+ """A decrementer for axfr or ixfr running. Locks the thread
+ because it is considered to be invoked by a multi-threading
+ caller."""
+ with self._lock:
+ self._statistics_data[counter_name] += step
+ self._counters_for_xfroutsession['inc_%s' % item] \
+ = __xfrrunning_incrementer
+ self._counters_for_xfroutsession['dec_%s' % item] \
+ = __xfrrunning_decrementer
+
+ def get_counters_for_xfroutsession(self):
+ """Returns counters, incrementers, and decrementers to be
+ passed to XfroutSession/UnixSockServer class."""
+ return self._counters_for_xfroutsession
+
+ def get_counters_for_notifyout(self):
+ """Returns counters handlers to be passed to NotifyOut
+ class."""
+ return self._counters_for_notifyout
def _add_perzone_counter(self, zone):
- """Adds named_set-type counter for each zone name"""
+ """Adds a named_set-type counter for each zone name."""
try:
self._statistics_data[self.perzone_prefix][zone]
except KeyError:
@@ -1041,6 +1107,17 @@ class XfroutCounter:
(self.perzone_prefix, zone, id_),
spec['item_default'])
+ def _add_xfrrunning_counter(self, counter_name):
+ """Adds a counter for counting (a|i)xfr_running"""
+ try:
+ self._statistics_data[counter_name]
+ except KeyError:
+ # examines the names of xfer running
+ for n in self._xfrrunning_names:
+ spec = isc.config.find_spec_part(self._statistics_spec, n)
+ isc.cc.data.set(self._statistics_data, n, \
+ spec['item_default'])
+
class XfroutServer:
def __init__(self):
self._unix_socket_server = None
@@ -1064,8 +1141,7 @@ class XfroutServer:
self._shutdown_event,
self._config_data,
self._cc,
- counter_xfrrej=self._counter.inc_xfrrej,
- counter_xfrreqdone=self._counter.inc_xfrreqdone
+ **self._counter.get_counters_for_xfroutsession()
)
listener = threading.Thread(target=self._unix_socket_server.serve_forever)
listener.start()
@@ -1074,8 +1150,7 @@ class XfroutServer:
datasrc = self._unix_socket_server.get_db_file()
self._notifier = notify_out.NotifyOut(
datasrc,
- counter_notifyoutv4=self._counter.inc_notifyoutv4,
- counter_notifyoutv6=self._counter.inc_notifyoutv6
+ **self._counter.get_counters_for_notifyout()
)
if 'also_notify' in self._config_data:
for slave in self._config_data['also_notify']:
diff --git a/src/bin/xfrout/xfrout.spec.pre.in b/src/bin/xfrout/xfrout.spec.pre.in
index c59dee8..1d24be2 100644
--- a/src/bin/xfrout/xfrout.spec.pre.in
+++ b/src/bin/xfrout/xfrout.spec.pre.in
@@ -172,6 +172,22 @@
}
]
}
+ },
+ {
+ "item_name": "ixfr_running",
+ "item_type": "integer",
+ "item_optional": false,
+ "item_default": 0,
+ "item_title": "IXFR running",
+ "item_description": "Number of IXFRs in progress"
+ },
+ {
+ "item_name": "axfr_running",
+ "item_type": "integer",
+ "item_optional": false,
+ "item_default": 0,
+ "item_title": "AXFR running",
+ "item_description": "Number of AXFRs in progress"
}
]
}
diff --git a/tests/lettuce/features/terrain/bind10_control.py b/tests/lettuce/features/terrain/bind10_control.py
index b1c8ace..142a78e 100644
--- a/tests/lettuce/features/terrain/bind10_control.py
+++ b/tests/lettuce/features/terrain/bind10_control.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2011 Internet Systems Consortium.
+# Copyright (C) 2011-2012 Internet Systems Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -391,19 +391,21 @@ def find_value(dictionary, key):
for v in dictionary.values():
return find_value(v, key)
- at step('The counter (\S+)(?: for the zone (\S+))? should be' + \
- '(?:( greater than| less than))? (\d+)')
-def check_statistics(step, counter, zone, gtlt, number):
+ at step('the statistics counter (\S+)(?: for the zone (\S+))? should be' + \
+ '(?:( greater than| less than| between))? (\-?\d+)(?: and (\-?\d+))?')
+def check_statistics(step, counter, zone, gtltbt, number, upper):
"""
check the output of bindctl for statistics of specified counter
and zone.
Parameters:
counter ('counter <counter>'): The counter name of statistics.
zone ('zone <zone>', optional): The zone name.
- gtlt (' greater than'|' less than', optional): greater than
- <number> or less than <number>.
+ gtltbt (' greater than'|' less than'|' between', optional): greater than
+ <number> or less than <number> or between <number> and <upper>.
number ('<number>): The expect counter number. <number> is assumed
to be an unsigned integer.
+ upper ('<upper>, optional): The expect upper counter number when
+ using 'between'.
"""
output = parse_bindctl_output_as_data_structure()
found = None
@@ -416,10 +418,15 @@ def check_statistics(step, counter, zone, gtlt, number):
assert found is not None, \
'Not found statistics counter %s%s' % (counter, zone_str)
msg = "Got %s, expected%s %s as counter %s%s" % \
- (found, gtlt, number, counter, zone_str)
- if gtlt and 'greater' in gtlt:
+ (found, gtltbt, number, counter, zone_str)
+ if gtltbt and 'between' in gtltbt and upper:
+ msg = "Got %s, expected%s %s and %s as counter %s%s" % \
+ (found, gtltbt, number, upper, counter, zone_str)
+ assert int(number) <= int(found) \
+ and int(found) <= int(upper), msg
+ elif gtltbt and 'greater' in gtltbt:
assert int(found) > int(number), msg
- elif gtlt and 'less' in gtlt:
+ elif gtltbt and 'less' in gtltbt:
assert int(found) < int(number), msg
else:
assert int(found) == int(number), msg
diff --git a/tests/lettuce/features/xfrin_notify_handling.feature b/tests/lettuce/features/xfrin_notify_handling.feature
index 5f28cdf..80a8873 100644
--- a/tests/lettuce/features/xfrin_notify_handling.feature
+++ b/tests/lettuce/features/xfrin_notify_handling.feature
@@ -27,10 +27,18 @@ Feature: Xfrin incoming notify handling
When I query statistics zones of bind10 module Xfrout with cmdctl port 47804
last bindctl output should not contain "error"
last bindctl output should not contain "example.org."
- The counter notifyoutv4 for the zone _SERVER_ should be 0
- The counter notifyoutv6 for the zone _SERVER_ should be 0
- The counter xfrrej for the zone _SERVER_ should be 0
- The counter xfrreqdone for the zone _SERVER_ should be 0
+ Then the statistics counter notifyoutv4 for the zone _SERVER_ should be 0
+ Then the statistics counter notifyoutv6 for the zone _SERVER_ should be 0
+ Then the statistics counter xfrrej for the zone _SERVER_ should be 0
+ Then the statistics counter xfrreqdone for the zone _SERVER_ should be 0
+
+ When I query statistics ixfr_running of bind10 module Xfrout with cmdctl port 47804
+ Then the statistics counter ixfr_running should be 0
+ Then the statistics counter ixfr_running should be 0
+
+ When I query statistics axfr_running of bind10 module Xfrout with cmdctl port 47804
+ Then the statistics counter axfr_running should be 0
+ Then the statistics counter axfr_running should be 0
When I send bind10 with cmdctl port 47804 the command Xfrout notify example.org IN
Then wait for new master stderr message XFROUT_NOTIFY_COMMAND
@@ -56,14 +64,14 @@ Feature: Xfrin incoming notify handling
When I query statistics zones of bind10 module Xfrout with cmdctl port 47804
last bindctl output should not contain "error"
- The counter notifyoutv4 for the zone _SERVER_ should be 0
- The counter notifyoutv4 for the zone example.org. should be 0
- The counter notifyoutv6 for the zone _SERVER_ should be 5
- The counter notifyoutv6 for the zone example.org. should be 5
- The counter xfrrej for the zone _SERVER_ should be 0
- The counter xfrrej for the zone example.org. should be 0
- The counter xfrreqdone for the zone _SERVER_ should be 1
- The counter xfrreqdone for the zone example.org. should be 1
+ Then the statistics counter notifyoutv4 for the zone _SERVER_ should be 0
+ Then the statistics counter notifyoutv4 for the zone example.org. should be 0
+ Then the statistics counter notifyoutv6 for the zone _SERVER_ should be 5
+ Then the statistics counter notifyoutv6 for the zone example.org. should be 5
+ Then the statistics counter xfrrej for the zone _SERVER_ should be 0
+ Then the statistics counter xfrrej for the zone example.org. should be 0
+ Then the statistics counter xfrreqdone for the zone _SERVER_ should be 1
+ Then the statistics counter xfrreqdone for the zone example.org. should be 1
#
# Test for Xfr request rejected
@@ -94,10 +102,10 @@ Feature: Xfrin incoming notify handling
When I query statistics zones of bind10 module Xfrout with cmdctl port 47804
last bindctl output should not contain "error"
last bindctl output should not contain "example.org."
- The counter notifyoutv4 for the zone _SERVER_ should be 0
- The counter notifyoutv6 for the zone _SERVER_ should be 0
- The counter xfrrej for the zone _SERVER_ should be 0
- The counter xfrreqdone for the zone _SERVER_ should be 0
+ Then the statistics counter notifyoutv4 for the zone _SERVER_ should be 0
+ Then the statistics counter notifyoutv6 for the zone _SERVER_ should be 0
+ Then the statistics counter xfrrej for the zone _SERVER_ should be 0
+ Then the statistics counter xfrreqdone for the zone _SERVER_ should be 0
#
# set transfer_acl rejection
@@ -134,13 +142,13 @@ Feature: Xfrin incoming notify handling
When I query statistics zones of bind10 module Xfrout with cmdctl port 47804
last bindctl output should not contain "error"
- The counter notifyoutv4 for the zone _SERVER_ should be 0
- The counter notifyoutv4 for the zone example.org. should be 0
- The counter notifyoutv6 for the zone _SERVER_ should be 5
- The counter notifyoutv6 for the zone example.org. should be 5
+ Then the statistics counter notifyoutv4 for the zone _SERVER_ should be 0
+ Then the statistics counter notifyoutv4 for the zone example.org. should be 0
+ Then the statistics counter notifyoutv6 for the zone _SERVER_ should be 5
+ Then the statistics counter notifyoutv6 for the zone example.org. should be 5
# The counts of rejection would be between 1 and 2. They are not
# fixed. It would depend on timing or the platform.
- The counter xfrrej for the zone _SERVER_ should be greater than 0
- The counter xfrrej for the zone example.org. should be greater than 0
- The counter xfrreqdone for the zone _SERVER_ should be 0
- The counter xfrreqdone for the zone example.org. should be 0
+ Then the statistics counter xfrrej for the zone _SERVER_ should be greater than 0
+ Then the statistics counter xfrrej for the zone example.org. should be greater than 0
+ Then the statistics counter xfrreqdone for the zone _SERVER_ should be 0
+ Then the statistics counter xfrreqdone for the zone example.org. should be 0
More information about the bind10-changes
mailing list