BIND 10 trac2225_xfrout, updated. 01c389aec693882f1b8233500cba1f7f65517fd0 [2225_xfrout] remove assignment of an unused variable
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Dec 7 02:32:59 UTC 2012
The branch, trac2225_xfrout has been updated
discards d48e433c30b683d066d5947a34364be8eaafeb6b (commit)
discards edcc41946b244c7a47d7e70a32ccb2759ecec424 (commit)
discards d8603fcdf49691085632d29cef57895574cb0b93 (commit)
discards df8e406aa20bdf7d3f551714a1f0da9e7836a1c3 (commit)
discards 70be41b79a198562f435cd485bf3a5cc007bf0b9 (commit)
discards fc1ba72dbb3edffa256bfd9771f37c49185f52e6 (commit)
discards a59c55245028a6a8a13fc49820069a705b16ec1e (commit)
discards f4e0507966f2b1933ac5b888e0b793de1fc181a5 (commit)
discards 9fb2682c74213c35617060482b55698580a264e6 (commit)
discards 77108be34ea6fc07f6e90715684efdb7ada7894c (commit)
discards fac2e182c9a7262510992b8e1d98df30e82f0b05 (commit)
discards 30ed3aa224c6162137ab70baae80e3fef92d2f56 (commit)
discards 6bddfe75fae2009704436eee7b70f41ddfcb874c (commit)
discards cc8825b4bae289bea7ec2f40147971483f0146c4 (commit)
via 01c389aec693882f1b8233500cba1f7f65517fd0 (commit)
via c3df8d055117b28da4fabc20e15a14d4def90c00 (commit)
via 46478bcb06ce13b7e2c1b342e6b7e63764c1e225 (commit)
via 89f99b959381e5d976199785cd4432b7aa82757d (commit)
via da239e501ca0db170007d4d3462a96da2ccc3a99 (commit)
via f27d218ea32e57bc08c4b1db77e0a7a05862345c (commit)
via f516250903358f645c37f6ab0d313e3571c52d66 (commit)
via c087ea5ba98e927b5c523a0b02f4b3858c602e8d (commit)
via 64416e1d8bdd8cdf9c0535098b78eb96ce03fe26 (commit)
via df8958f661691900968a43d344e0bd548703b9d5 (commit)
via 5360d3c534c58a31223cba2a69265f93976f59c0 (commit)
via 143b9517ac82f0682cc6b39a58bdd292e0c2ce8e (commit)
via a3b6ba5f5ad3c2455635a8aff1ba475e3ce56337 (commit)
via d929e11039128ce6f1e5b4798de81d3c967996d1 (commit)
via 7c19613f47670a123ba3bb08b0f64b47086cec84 (commit)
via 0eba3b5dfc1d263ad55e90a07c6b12c94fc09155 (commit)
via c1473d95e39b86ebfa57eb47f7da8e96ebe55203 (commit)
via 37391946e9c47b849e5f6e38345aa8298c963f87 (commit)
via b25e2ffb1e511dacc6703935e819ed3ae922e293 (commit)
via 77171e9cda20fab175b23359c7412c9df26d5107 (commit)
via 6535b61e9ddc6325ccd7bbfd56e1c094a0f54335 (commit)
via 216f61003202faf7381a627a1138d891a6d1e28a (commit)
via cc098e6d33b092c46194dcb40179d5688655964f (commit)
via 09c9166b4a26afa42b6b51070d4a05b2fea6e87e (commit)
via 0c8094b0e3e9ecae8fe44cb889b959ed467bac8b (commit)
via cf41749b421bd09330ca5cbec3e3e9a3cdae06d7 (commit)
via 02e63b13f8e523d913de3a516c442677dc15e4c6 (commit)
via 1e45b7161d9405b25072a4b6e979a18fa26981ce (commit)
via e78b80b2a929ab815dee2d4ff6c7e29315a5f2f7 (commit)
via 966b5ee5cf9512da8f4a4ea31f7f67ca3836df26 (commit)
via b95523d5350585a707693d680152903ede08bb0a (commit)
via 58771328093e3bb51463437cae9555da0ed945cc (commit)
via 17e0f403185b1e0136cf1059856c1f30a5bdfdec (commit)
via 1150b0ef4bae79e2ffe254dddd5863690a71d60f (commit)
via 65a2fbba5becb20d276aeb90e5d13d02190828c7 (commit)
via 32bb433cb895fd5013c050612abfe62fb09a689c (commit)
via 525dc51879ae8164ed085f5f6c48f8566853b230 (commit)
via 9a08bfa4933a435a4911cef029e63f57deed0dc3 (commit)
via e1aca7e9404c4064f0125b7596d67cbd8af932e5 (commit)
via f5dc6575c10281b39320167809689df16ae913cf (commit)
via 46dba3a3c60b81e609ee7ac2acc9641a8b62c9f3 (commit)
via 96ee507bbc179b6e3732114dfad67e6c5168c538 (commit)
via 3836cadb5368169a86a27e8af12374c8b715f5a5 (commit)
via 02e9061387eff505391762b5568c2e9700b021e5 (commit)
via b53ecd7c2508d159e92bf890f9d3b2e3747d053b (commit)
via a1fcd146a64717e59311eaeae9b97fb66857e636 (commit)
via 0e4b3df29c59a4b4cf4c75f37fd3c3180332e7fb (commit)
via 13c2eb59454d17b9d00c3cc7205ba19e8b69ec8f (commit)
via 8e0ebda2f002e9ef7530ac16ab7947104767d20d (commit)
This update added new revisions after undoing existing revisions. That is
to say, the old revision is not a strict subset of the new revision. This
situation occurs when you --force push a change and generate a repository
containing something like this:
* -- * -- B -- O -- O -- O (d48e433c30b683d066d5947a34364be8eaafeb6b)
\
N -- N -- N (01c389aec693882f1b8233500cba1f7f65517fd0)
When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.
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 01c389aec693882f1b8233500cba1f7f65517fd0
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Thu Dec 6 15:00:13 2012 +0900
[2225_xfrout] remove assignment of an unused variable
commit c3df8d055117b28da4fabc20e15a14d4def90c00
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Thu Dec 6 14:57:58 2012 +0900
[2225_xfrout] update creating the counter object and invoking the getter method according to the new interface
commit 46478bcb06ce13b7e2c1b342e6b7e63764c1e225
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Thu Dec 6 14:46:28 2012 +0900
[2225_xfrout] update creating the counter object and invoking the incrementer method according to the new interface
commit 89f99b959381e5d976199785cd4432b7aa82757d
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Thu Dec 6 14:42:50 2012 +0900
[2225_xfrout] remove obsolete creation of a counter object
commit da239e501ca0db170007d4d3462a96da2ccc3a99
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Thu Dec 6 14:40:52 2012 +0900
[2225_xfrout] fix the wrong counter numbers
It is realized that the removed dummy counter class didn't increase
the counters properly.
commit f27d218ea32e57bc08c4b1db77e0a7a05862345c
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Thu Dec 6 14:39:51 2012 +0900
[2225_xfrout] update the counter object and its getter method according to the new interface
It raises DataNotFoundError instead of zero-count on the new interface when the
getter method is invoked if its counter hasn't been incremented yet
commit f516250903358f645c37f6ab0d313e3571c52d66
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Thu Dec 6 14:35:31 2012 +0900
[2225_xfrout] update the counter object and its getter method since the interface of the counter class was changed
commit c087ea5ba98e927b5c523a0b02f4b3858c602e8d
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Thu Dec 6 14:13:04 2012 +0900
[2225_xfrout] remove an unnecessary dummy counter class
commit 64416e1d8bdd8cdf9c0535098b78eb96ce03fe26
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Thu Dec 6 14:11:22 2012 +0900
[2225_xfrout] remove an unnecessary keyword argument
commit df8958f661691900968a43d344e0bd548703b9d5
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Thu Dec 6 14:10:28 2012 +0900
[2225_xfrout] update the counter object according since the interface of the counter class is changed
commit 5360d3c534c58a31223cba2a69265f93976f59c0
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Mon Nov 26 16:15:03 2012 +0900
[2225_xfrout] changed the test condition for "socket/unixdomain/open" counter of Xfrout
because its counter would probably return 0 or 1 depending on timing
commit 143b9517ac82f0682cc6b39a58bdd292e0c2ce8e
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Mon Nov 26 15:58:09 2012 +0900
[2225_xfrout] rename module name(counter) to class name(Counter)
commit a3b6ba5f5ad3c2455635a8aff1ba475e3ce56337
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Wed Sep 12 16:29:21 2012 +0900
[2252] added checking DataNotFoundError is raised
If un-incremented counter is referred, DataNotFoundError exception
must be raised.
commit d929e11039128ce6f1e5b4798de81d3c967996d1
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Sep 28 14:19:52 2012 +0900
[2225] added a new scenario which a slave isn't started
commit 7c19613f47670a123ba3bb08b0f64b47086cec84
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Sep 28 13:17:00 2012 +0900
[2225] added same tests as the above tests
commit 0eba3b5dfc1d263ad55e90a07c6b12c94fc09155
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Sep 28 11:13:49 2012 +0900
[2225] removed duplicate tests
commit c1473d95e39b86ebfa57eb47f7da8e96ebe55203
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Mon Sep 3 18:58:47 2012 +0900
[2225] corrected the wrong place to count receive errors of a unix socket
moved the counter from handle_request() to _select_loop() and revised the
related unit test
commit 37391946e9c47b849e5f6e38345aa8298c963f87
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Aug 31 14:48:52 2012 +0900
[2225] added descriptions about unixsocket counters into the manpage
commit b25e2ffb1e511dacc6703935e819ed3ae922e293
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Aug 31 12:16:17 2012 +0900
[2225] added checks for statistics unixsocket counters
commit 77171e9cda20fab175b23359c7412c9df26d5107
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Aug 31 14:31:31 2012 +0900
[2225] changed according the changes of the counter class
- implemented a dummy counter class inside of the notifyout test and made it
use it.
commit 6535b61e9ddc6325ccd7bbfd56e1c094a0f54335
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Aug 31 12:13:10 2012 +0900
[2225] changed the format of the debug when revised getstats command
- output content of answer to the stats module with the debug message
commit 216f61003202faf7381a627a1138d891a6d1e28a
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Mon Nov 19 14:31:36 2012 +0900
[2225] removed obsoleted classes from xfrout.py and xfrout_test.py
XfroutCounter class and TestXfroutCounter are removed
commit cc098e6d33b092c46194dcb40179d5688655964f
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Thu Nov 22 18:56:28 2012 +0900
[2252] fixed the spec file path of Xfrin for unittesting
SPECFILE_LOCATION was located under the B10_FROM_SOURCE tree
commit 09c9166b4a26afa42b6b51070d4a05b2fea6e87e
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Mon Nov 19 14:31:31 2012 +0900
[2225] add unixdomain socket as statistics spec
-----------------------------------------------------------------------
Summary of changes:
src/bin/xfrout/tests/xfrout_test.py.in | 97 ++++--
src/bin/xfrout/xfrout.py.in | 38 ++-
src/lib/python/isc/notify/notify_out.py | 9 +-
src/lib/python/isc/notify/tests/notify_out_test.py | 63 ++--
src/lib/python/isc/statistics/counter.py | 350 +++++++-------------
.../python/isc/statistics/tests/counter_test.py | 297 +++++++----------
6 files changed, 364 insertions(+), 490 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/bin/xfrout/tests/xfrout_test.py.in b/src/bin/xfrout/tests/xfrout_test.py.in
index e18ee44..53a80f9 100644
--- a/src/bin/xfrout/tests/xfrout_test.py.in
+++ b/src/bin/xfrout/tests/xfrout_test.py.in
@@ -291,7 +291,7 @@ class TestXfroutSessionBase(unittest.TestCase):
# the XfroutSession object. We check the condition here.
self.assertEqual(0, self.xfrsess._server.transfer_counter)
# clear statistics counters
- Counter.clear_counters()
+ self.xfrsess._counter.clear_counters()
class TestXfroutSession(TestXfroutSessionBase):
def test_quota_error(self):
@@ -380,7 +380,8 @@ class TestXfroutSession(TestXfroutSessionBase):
]))
# check the 'xfrrej' counter initially
self.assertRaises(isc.cc.data.DataNotFoundError,
- Counter.get_xfrrej, TEST_ZONE_NAME_STR)
+ self.xfrsess._counter.get, 'zones',
+ TEST_ZONE_NAME_STR, 'xfrrej')
# Localhost (the default in this test) is accepted
rcode, msg = self.xfrsess._parse_query_message(self.mdata)
self.assertEqual(rcode.to_text(), "NOERROR")
@@ -395,7 +396,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(Counter.get_xfrrej(TEST_ZONE_NAME_STR), 1)
+ self.assertEqual(self.xfrsess._counter.get(
+ 'zones', TEST_ZONE_NAME_STR, 'xfrrej'), 1)
# TSIG signed request
request_data = self.create_request_data(with_tsig=True)
@@ -425,7 +427,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(Counter.get_xfrrej(TEST_ZONE_NAME_STR), 2)
+ self.assertEqual(self.xfrsess._counter.get(
+ 'zones', TEST_ZONE_NAME_STR, 'xfrrej'), 2)
# ACL using TSIG: no TSIG; should be rejected
acl_setter(isc.acl.dns.REQUEST_LOADER.load([
@@ -434,7 +437,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(Counter.get_xfrrej(TEST_ZONE_NAME_STR), 3)
+ self.assertEqual(self.xfrsess._counter.get(
+ 'zones', TEST_ZONE_NAME_STR, 'xfrrej'), 3)
#
# ACL using IP + TSIG: both should match
@@ -455,21 +459,24 @@ 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(Counter.get_xfrrej(TEST_ZONE_NAME_STR), 4)
+ self.assertEqual(self.xfrsess._counter.get(
+ 'zones', TEST_ZONE_NAME_STR, '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(Counter.get_xfrrej(TEST_ZONE_NAME_STR), 5)
+ self.assertEqual(self.xfrsess._counter.get(
+ 'zones', TEST_ZONE_NAME_STR, '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(Counter.get_xfrrej(TEST_ZONE_NAME_STR), 6)
+ self.assertEqual(self.xfrsess._counter.get(
+ 'zones', TEST_ZONE_NAME_STR, 'xfrrej'), 6)
def test_transfer_acl(self):
# ACL checks only with the default ACL
@@ -853,9 +860,11 @@ class TestXfroutSession(TestXfroutSessionBase):
self.xfrsess._reply_xfrout_query = myreply
self.assertRaises(isc.cc.data.DataNotFoundError,
- Counter.get_unixsocket_senderr)
+ self.xfrsess._counter.get,
+ 'socket', 'unixdomain', 'senderr')
self.xfrsess.dns_xfrout_start(self.sock, self.mdata)
- self.assertEqual(Counter.get_unixsocket_senderr(), 1)
+ self.assertEqual(self.xfrsess._counter.get(
+ 'socket', 'unixdomain', 'senderr'), 1)
def test_dns_xfrout_start_noerror(self):
def noerror(msg, name, rrclass):
@@ -866,12 +875,13 @@ class TestXfroutSession(TestXfroutSessionBase):
self.sock.send(b"success")
self.assertRaises(isc.cc.data.DataNotFoundError,
- Counter.get_xfrreqdone, TEST_ZONE_NAME_STR)
+ self.xfrsess._counter.get,
+ 'zones', TEST_ZONE_NAME_STR, 'xfrreqdone')
self.xfrsess._reply_xfrout_query = myreply
self.xfrsess.dns_xfrout_start(self.sock, self.mdata)
self.assertEqual(self.sock.readsent(), b"success")
- self.assertGreater(\
- Counter.get_xfrreqdone(TEST_ZONE_NAME_STR), 0)
+ self.assertGreater(self.xfrsess._counter.get(
+ 'zones', TEST_ZONE_NAME_STR, 'xfrreqdone'), 0)
def test_reply_xfrout_query_axfr(self):
self.xfrsess._soa = self.soa_rrset
@@ -1128,7 +1138,7 @@ class TestXfroutSessionWithSQLite3(TestXfroutSessionBase):
def test_axfr_normal_session(self):
self.assertRaises(isc.cc.data.DataNotFoundError,
- Counter.get_axfr_running)
+ self.xfrsess._counter.get, 'axfr_running')
XfroutSession._handle(self.xfrsess)
response = self.sock.read_msg(Message.PRESERVE_ORDER);
self.assertEqual(Rcode.NOERROR(), response.get_rcode())
@@ -1136,8 +1146,8 @@ class TestXfroutSessionWithSQLite3(TestXfroutSessionBase):
self.assertEqual(self.xfrsess._request_type, RRType.AXFR())
self.assertNotEqual(self.xfrsess._request_type, RRType.IXFR())
self.assertRaises(isc.cc.data.DataNotFoundError,
- Counter.get_ixfr_running)
- self.assertEqual(Counter.get_axfr_running(), 0)
+ self.xfrsess._counter.get, 'ixfr_running')
+ self.assertEqual(self.xfrsess._counter.get('axfr_running'), 0)
def test_ixfr_to_axfr(self):
self.xfrsess._request_data = \
@@ -1157,9 +1167,9 @@ class TestXfroutSessionWithSQLite3(TestXfroutSessionBase):
self.xfrsess._request_data = \
self.create_request_data(ixfr=IXFR_OK_VERSION)
self.assertRaises(isc.cc.data.DataNotFoundError,
- Counter.get_axfr_running)
+ self.xfrsess._counter.get, 'axfr_running')
self.assertRaises(isc.cc.data.DataNotFoundError,
- Counter.get_ixfr_running)
+ self.xfrsess._counter.get, 'ixfr_running')
XfroutSession._handle(self.xfrsess)
response = self.sock.read_msg(Message.PRESERVE_ORDER)
actual_records = response.get_section(Message.SECTION_ANSWER)
@@ -1178,8 +1188,8 @@ class TestXfroutSessionWithSQLite3(TestXfroutSessionBase):
self.assertNotEqual(self.xfrsess._request_type, RRType.AXFR())
self.assertEqual(self.xfrsess._request_type, RRType.IXFR())
self.assertRaises(isc.cc.data.DataNotFoundError,
- Counter.get_axfr_running)
- self.assertEqual(Counter.get_ixfr_running(), 0)
+ self.xfrsess._counter.get, 'axfr_running')
+ self.assertEqual(self.xfrsess._counter.get('ixfr_running'), 0)
def ixfr_soa_only_common_checks(self, request_serial):
self.xfrsess._request_data = \
@@ -1207,7 +1217,7 @@ class MyUnixSockServer(UnixSockServer):
self._common_init()
self._cc = MyCCSession()
self.update_config_data(self._cc.get_full_config())
- self._counters = {}
+ self._counter = xfrout.Counter(xfrout.SPECFILE_LOCATION)
class TestUnixSockServer(unittest.TestCase):
def setUp(self):
@@ -1568,45 +1578,57 @@ class TestUnixSockServerForCounter(unittest.TestCase):
super,
self.orig_process_request,
self.orig_select )
- Counter.clear_counters()
+ self.unix._counter.clear_counters()
def test_open(self):
# open
- self.assertEqual(Counter.get_unixsocket_open(), 1)
+ self.assertEqual(
+ self.unix._counter.get('socket', 'unixdomain', 'open'), 1)
self.assertRaises(isc.cc.data.DataNotFoundError,
- Counter.get_unixsocket_openfail)
+ self.unix._counter.get,
+ 'socket', 'unixdomain', 'openfail')
xfrout.ThreadingUnixStreamServer = DummySocketserverException
self.unix = UnixSockServer(None, None, None, None, None)
- self.assertEqual(Counter.get_unixsocket_open(), 1)
- self.assertEqual(Counter.get_unixsocket_openfail(), 1)
+ self.assertEqual(
+ self.unix._counter.get('socket', 'unixdomain', 'open'), 1)
+ self.assertEqual(
+ self.unix._counter.get('socket', 'unixdomain', 'openfail'), 1)
def test_close(self):
# close
self.assertRaises(isc.cc.data.DataNotFoundError,
- Counter.get_unixsocket_close)
+ self.unix._counter.get,
+ 'socket','unixdomain', 'close')
self.unix.shutdown()
- self.assertEqual(Counter.get_unixsocket_close(), 1)
+ self.assertEqual(
+ self.unix._counter.get('socket', 'unixdomain', 'close'), 1)
def test_bindfail(self):
# bindfail
self.assertRaises(isc.cc.data.DataNotFoundError,
- Counter.get_unixsocket_bindfail)
+ self.unix._counter.get,
+ 'socket', 'unixdomain', 'bindfail')
self.assertRaises(Exception, self.unix.server_bind)
- self.assertEqual(Counter.get_unixsocket_bindfail(), 1)
+ self.assertEqual(
+ self.unix._counter.get('socket', 'unixdomain', 'bindfail'), 1)
def test_accept(self):
# accept
self.assertRaises(isc.cc.data.DataNotFoundError,
- Counter.get_unixsocket_accept)
+ self.unix._counter.get,
+ 'socket', 'unixdomain', 'accept')
self.unix.get_request()
- self.assertEqual(Counter.get_unixsocket_accept(), 1)
+ self.assertEqual(
+ self.unix._counter.get('socket', 'unixdomain', 'accept'), 1)
# acceptfail
self.assertRaises(isc.cc.data.DataNotFoundError,
- Counter.get_unixsocket_acceptfail)
+ self.unix._counter.get,
+ 'socket', 'unixdomain', 'acceptfail')
xfrout.super = lambda : DummyClassException()
self.unix = UnixSockServer(None, None, None, None, None)
self.assertRaises(Exception, self.unix.get_request)
- self.assertEqual(Counter.get_unixsocket_acceptfail(), 1)
+ self.assertEqual(
+ self.unix._counter.get('socket', 'unixdomain', 'acceptfail'), 1)
def test_senderr(self):
# do inside of above TestXfroutSession
@@ -1615,12 +1637,14 @@ class TestUnixSockServerForCounter(unittest.TestCase):
def test_recverr(self):
# recverr
self.assertRaises(isc.cc.data.DataNotFoundError,
- Counter.get_unixsocket_recverr)
+ self.unix._counter.get,
+ 'socket', 'unixdomain', 'recverr')
def raise_socketerror(x,y):
raise socket.error
self.unix.process_request = raise_socketerror
self.unix._select_loop(None)
- self.assertEqual(Counter.get_unixsocket_recverr(), 1)
+ self.assertEqual(self.unix._counter.get(
+ 'socket', 'unixdomain', 'recverr'), 1)
class TestInitialization(unittest.TestCase):
def setEnv(self, name, value):
@@ -1670,6 +1694,7 @@ class MyXfroutServer(XfroutServer):
self._wait_for_threads = lambda : None
self._cc.get_module_spec = lambda:\
isc.config.module_spec_from_file(xfrout.SPECFILE_LOCATION)
+ self._counter = xfrout.Counter(xfrout.SPECFILE_LOCATION)
class TestXfroutServer(unittest.TestCase):
def setUp(self):
diff --git a/src/bin/xfrout/xfrout.py.in b/src/bin/xfrout/xfrout.py.in
index 7932cc1..8d51438 100755
--- a/src/bin/xfrout/xfrout.py.in
+++ b/src/bin/xfrout/xfrout.py.in
@@ -109,9 +109,6 @@ VERBOSE_MODE = False
XFROUT_DNS_HEADER_SIZE = 12 # protocol constant
XFROUT_MAX_MESSAGE_SIZE = 65535 # ditto
-# setup statistics counter
-Counter.init(SPECFILE_LOCATION)
-
# borrowed from xfrin.py @ #1298. We should eventually unify it.
def format_zone_str(zone_name, zone_class):
"""Helper function to format a zone name and class as a string of
@@ -172,6 +169,9 @@ 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
+ # Creation of self.counter should be done before of
+ # invoking self._handle()
+ self._counter = Counter(SPECFILE_LOCATION)
self._handle()
def create_tsig_ctx(self, tsig_record, tsig_key_ring):
@@ -275,7 +275,7 @@ class XfroutSession():
return None, None
elif acl_result == REJECT:
# count rejected Xfr request by each zone name
- Counter.inc_xfrrej(zone_name.to_text())
+ self._counter.inc('zones', zone_name.to_text(), 'xfrrej')
logger.debug(DBG_XFROUT_TRACE, XFROUT_QUERY_REJECTED,
self._request_type, format_addrinfo(self._remote),
format_zone_str(zone_name, zone_class))
@@ -527,25 +527,25 @@ class XfroutSession():
try:
# increment Xfr starts by RRType
if self._request_type == RRType.AXFR():
- Counter.inc_axfr_running()
+ self._counter.inc('axfr_running')
else:
- Counter.inc_ixfr_running()
+ self._counter.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:
# count unixsockets send errors
- Counter.inc_unixsocket_senderr()
+ self._counter.inc('socket', 'unixdomain', 'senderr')
logger.error(XFROUT_XFR_TRANSFER_ERROR, self._request_typestr,
format_addrinfo(self._remote), zone_str, err)
finally:
# decrement Xfr starts by RRType
if self._request_type == RRType.AXFR():
- Counter.dec_axfr_running()
+ self._counter.dec('axfr_running')
else:
- Counter.dec_ixfr_running()
+ self._counter.dec('ixfr_running')
# count done Xfr requests by each zone name
- Counter.inc_xfrreqdone(zone_name.to_text())
+ self._counter.inc('zones', zone_name.to_text(), 'xfrreqdone')
logger.info(XFROUT_XFR_TRANSFER_DONE, self._request_typestr,
format_addrinfo(self._remote), zone_str)
@@ -659,13 +659,14 @@ class UnixSockServer(socketserver_mixin.NoPollMixIn,
self._remove_unused_sock_file(sock_file)
self._sock_file = sock_file
socketserver_mixin.NoPollMixIn.__init__(self)
+ self._counter = Counter(SPECFILE_LOCATION)
try:
ThreadingUnixStreamServer.__init__(self, sock_file, \
handle_class)
except:
- Counter.inc_unixsocket_openfail()
+ self._counter.inc('socket', 'unixdomain', 'openfail')
else:
- Counter.inc_unixsocket_open()
+ self._counter.inc('socket', 'unixdomain', 'open')
self._shutdown_event = shutdown_event
self._write_sock, self._read_sock = socket.socketpair()
self._common_init()
@@ -682,7 +683,7 @@ class UnixSockServer(socketserver_mixin.NoPollMixIn,
return super().server_bind()
except:
# count bind failed unixsockets
- Counter.inc_unixsocket_bindfail()
+ self._counter.inc('socket', 'unixdomain', 'bindfail')
raise
def get_request(self):
@@ -694,11 +695,11 @@ class UnixSockServer(socketserver_mixin.NoPollMixIn,
# ThreadingUnixStreamServer
ret = super().get_request()
# count successfully accepted unixsockets
- Counter.inc_unixsocket_accept()
+ self._counter.inc('socket', 'unixdomain', 'accept')
return ret
except:
# count failed accepted unixsockets
- Counter.inc_unixsocket_acceptfail()
+ self._counter.inc('socket', 'unixdomain', 'acceptfail')
raise
def _common_init(self):
@@ -768,7 +769,7 @@ class UnixSockServer(socketserver_mixin.NoPollMixIn,
break
except Exception as pre:
# count unixsockets receive errors
- Counter.inc_unixsocket_recverr()
+ self._counter.inc('socket', 'unixdomain', 'recverr')
logger.error(XFROUT_PROCESS_REQUEST_ERROR, pre)
break
@@ -895,7 +896,7 @@ class UnixSockServer(socketserver_mixin.NoPollMixIn,
super().shutdown() # call the shutdown() of class socketserver_mixin.NoPollMixIn
try:
# count closed unixsockets
- Counter.inc_unixsocket_close()
+ self._counter.inc('socket', 'unixdomain', 'close')
os.unlink(self._sock_file)
except Exception as e:
logger.error(XFROUT_REMOVE_UNIX_SOCKET_FILE_ERROR, self._sock_file, str(e))
@@ -998,6 +999,7 @@ class XfroutServer:
isc.server_common.tsig_keyring.init_keyring(self._cc)
self._start_xfr_query_listener()
self._start_notifier()
+ self._counter = Counter(SPECFILE_LOCATION)
def _start_xfr_query_listener(self):
'''Start a new thread to accept xfr query. '''
@@ -1093,7 +1095,7 @@ class XfroutServer:
# The log level is here set to debug in order to avoid
# that a log becomes too verbose. Because the b10-stats
# daemon is periodically asking to the b10-xfrout daemon.
- answer = create_answer(0, Counter.dump_statistics())
+ answer = create_answer(0, self._counter.dump_statistics())
logger.debug(DBG_XFROUT_TRACE, \
XFROUT_RECEIVED_GETSTATS_COMMAND, \
str(answer))
diff --git a/src/lib/python/isc/notify/notify_out.py b/src/lib/python/isc/notify/notify_out.py
index 8ff62f6..64f9186 100644
--- a/src/lib/python/isc/notify/notify_out.py
+++ b/src/lib/python/isc/notify/notify_out.py
@@ -128,7 +128,7 @@ class NotifyOut:
notify message to its slaves). notify service can be started by
calling dispatcher(), and it can be stopped by calling shutdown()
in another thread. '''
- def __init__(self, datasrc_file, counter_handler=None, verbose=True):
+ def __init__(self, datasrc_file, verbose=True):
self._notify_infos = {} # key is (zone_name, zone_class)
self._waiting_zones = []
self._notifying_zones = []
@@ -143,6 +143,7 @@ class NotifyOut:
# Use nonblock event to eliminate busy loop
# If there are no notifying zones, clear the event bit and wait.
self._nonblock_event = threading.Event()
+ self._counter = Counter()
def _init_notify_out(self, datasrc_file):
'''Get all the zones name and its notify target's address.
@@ -481,9 +482,11 @@ class NotifyOut:
sock.sendto(render.get_data(), 0, addrinfo)
# count notifying by IPv4 or IPv6 for statistics
if zone_notify_info.get_socket().family == socket.AF_INET:
- Counter.inc_notifyoutv4(zone_notify_info.zone_name)
+ self._counter.inc('zones', zone_notify_info.zone_name,
+ 'notifyoutv4')
elif zone_notify_info.get_socket().family == socket.AF_INET6:
- Counter.inc_notifyoutv6(zone_notify_info.zone_name)
+ self._counter.inc('zones', zone_notify_info.zone_name,
+ 'notifyoutv6')
logger.info(NOTIFY_OUT_SENDING_NOTIFY, addrinfo[0],
addrinfo[1])
except (socket.error, addr.InvalidAddress) as err:
diff --git a/src/lib/python/isc/notify/tests/notify_out_test.py b/src/lib/python/isc/notify/tests/notify_out_test.py
index 2ee6d17..149096c 100644
--- a/src/lib/python/isc/notify/tests/notify_out_test.py
+++ b/src/lib/python/isc/notify/tests/notify_out_test.py
@@ -92,23 +92,6 @@ class TestZoneNotifyInfo(unittest.TestCase):
temp_info.prepare_notify_out()
self.assertIsNone(temp_info.get_current_notify_target())
-class DummyNotifyOutCounter:
- _notifiesv4 = []
- _notifiesv6 = []
- def inc_notifyoutv4(self, arg):
- self._notifiesv4.append(arg)
- def inc_notifyoutv6(self, arg):
- self._notifiesv6.append(arg)
- def get_notifyoutv4(self, arg):
- return self._notifiesv4.count(arg)
- def get_notifyoutv6(self, arg):
- return self._notifiesv6.count(arg)
- def clear_counters(self):
- self._notifiesv4 = []
- self._notifiesv6 = []
-
-notify_out.Counter = DummyNotifyOutCounter()
-Counter = notify_out.Counter
class TestNotifyOut(unittest.TestCase):
def setUp(self):
@@ -129,7 +112,7 @@ class TestNotifyOut(unittest.TestCase):
com_ch_info.notify_slaves.append(('1.1.1.1', 5353))
def tearDown(self):
- Counter.clear_counters()
+ self._notify._counter.clear_counters()
def test_send_notify(self):
notify_out._MAX_NOTIFY_NUM = 2
@@ -283,35 +266,51 @@ class TestNotifyOut(unittest.TestCase):
def test_send_notify_message_udp_ipv4(self):
example_com_info = self._notify._notify_infos[('example.net.', 'IN')]
- self.assertEqual(Counter.get_notifyoutv4('example.net.'), 0)
- self.assertEqual(Counter.get_notifyoutv6('example.net.'), 0)
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self._notify._counter.get,
+ 'zones', 'example.net.', 'notifyoutv4')
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self._notify._counter.get,
+ 'zones', 'example.net.', 'notifyoutv6')
example_com_info.prepare_notify_out()
ret = self._notify._send_notify_message_udp(example_com_info,
('192.0.2.1', 53))
self.assertTrue(ret)
self.assertEqual(socket.AF_INET, example_com_info.sock_family)
- self.assertGreater(Counter.get_notifyoutv4('example.net.'), 0)
- self.assertEqual(Counter.get_notifyoutv6('example.net.'), 0)
+ self.assertEqual(self._notify._counter.get(
+ 'zones', 'example.net.', 'notifyoutv4'), 1)
+ self.assertEqual(self._notify._counter.get(
+ 'zones', 'example.net.', 'notifyoutv6'), 0)
def test_send_notify_message_udp_ipv6(self):
example_com_info = self._notify._notify_infos[('example.net.', 'IN')]
- self.assertEqual(Counter.get_notifyoutv4('example.net.'), 0)
- self.assertEqual(Counter.get_notifyoutv6('example.net.'), 0)
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self._notify._counter.get,
+ 'zones', 'example.net.', 'notifyoutv4')
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self._notify._counter.get,
+ 'zones', 'example.net.', 'notifyoutv6')
ret = self._notify._send_notify_message_udp(example_com_info,
('2001:db8::53', 53))
self.assertTrue(ret)
self.assertEqual(socket.AF_INET6, example_com_info.sock_family)
- self.assertEqual(Counter.get_notifyoutv4('example.net.'), 0)
- self.assertGreater(Counter.get_notifyoutv6('example.net.'), 0)
+ self.assertEqual(self._notify._counter.get(
+ 'zones', 'example.net.', 'notifyoutv4'), 0)
+ self.assertEqual(self._notify._counter.get(
+ 'zones', 'example.net.', 'notifyoutv6'), 1)
def test_send_notify_message_with_bogus_address(self):
example_com_info = self._notify._notify_infos[('example.net.', 'IN')]
- self.assertEqual(Counter.get_notifyoutv4('example.net.'), 0)
- self.assertEqual(Counter.get_notifyoutv6('example.net.'), 0)
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self._notify._counter.get,
+ 'zones', 'example.net.', 'notifyoutv4')
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self._notify._counter.get,
+ 'zones', 'example.net.', 'notifyoutv6')
# As long as the underlying data source validates RDATA this shouldn't
# happen, but right now it's not actually the case. Even if the
@@ -321,8 +320,12 @@ class TestNotifyOut(unittest.TestCase):
('invalid', 53))
self.assertFalse(ret)
- self.assertEqual(Counter.get_notifyoutv4('example.net.'), 0)
- self.assertEqual(Counter.get_notifyoutv6('example.net.'), 0)
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self._notify._counter.get,
+ 'zones', 'example.net.', 'notifyoutv4')
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self._notify._counter.get,
+ 'zones', 'example.net.', 'notifyoutv4')
def test_zone_notify_handler(self):
old_send_msg = self._notify._send_notify_message_udp
diff --git a/src/lib/python/isc/statistics/counter.py b/src/lib/python/isc/statistics/counter.py
index 22b8e4c..5946790 100644
--- a/src/lib/python/isc/statistics/counter.py
+++ b/src/lib/python/isc/statistics/counter.py
@@ -21,42 +21,40 @@ invoked in each module like b10-xfrin or b10-xfrout after importing
this module.
from isc.statistics import Counter
- Counter.init(SPECFILE_LOCATION)
+ self.counter = Counter(/path/to/foo.spec)
-The first argument of Counter.init() is required, which is the
+The first argument of Counter() can be specified, which is the
location of the specification file like src/bin/xfrout/xfrout.spec. If
this initial preparation is done, statistics counters can be accessed
from each module. For example, in case that the item `xfrreqdone` is
-defined in statistics_spec in xfrout.spec, the following methods can
-be dynamically created: Counter.inc_xfrreqdone(),
-Counter.get_xfrreqdone(). Since these methods requires the string of
-the zone name in the first argument, in the b10-xfrout,
+defined in statistics_spec in xfrout.spec, the following methods is
+callable. Since these methods requires the string of the zone name in
+the first argument, in the b10-xfrout,
- Counter.inc_xfrreqdone(zone_name)
+ self.counter.inc('zones', zone_name, 'xfrreqdone')
-then the xfrreqdone counter corresponding to zone_name was
+then the counter for xfrreqdone corresponding to zone_name was
incremented. For getting the current number of this counter, we can do
this,
- number = Counter.get_xfrreqdone(zone_name)
+ number = self.counter.get('zones', zone_name, 'xfrreqdone')
then the current number was obtained and set in the above variable
`number`. Such a getter method would be mainly used for unittesting.
-In other example, regarding the item `axfr_running`,
-the decrementer method is also created:
-Counter.dec_axfr_running(). This method is used for decrementing the
+In other example, regarding the item `axfr_running`, the decrementer
+method is also callable. This method is used for decrementing the
counter number. Regarding the item `axfr_running`, an argument like
zone name is not required.
- Counter.dec_axfr_running()
+ self.counter.dec('axfr_running')
-These accessors are effective in other module. For example, in case
+These methods are effective in other module. For example, in case
that this module `counter.py` is once imported in such a main module
as b10-xfrout, Regarding the item `notifyoutv4`, the incrementer
-inc_notifyoutv4() can be invoked via other module like notify_out.py,
+as the following can be invoked via other module like notify_out.py,
which is firstly imported in the main module.
- Counter.inc_notifyoutv4(zone_name)
+ self.counter.inc('zones', zone_name, 'notifyoutv4')
In this example this is for incrementing the counter of the item
notifyoutv4. Thus, such statement can be also written in the other
@@ -64,11 +62,8 @@ library like isc.notify.notify_out. If this module `counter.py` isn't
imported in the main module but imported in such a library module as
isc.notify.notify_out, in this example, empty methods would be
invoked, which is directly defined in `counter.py`.
-
-Other accessors can be also defined in such individual class in
-future. For adding or modifying such accessor, we need to implement in
-`counter.py`.
"""
+
import threading
import isc.config
from datetime import datetime
@@ -139,37 +134,55 @@ def _stop_timer(start_time, element, spec, identifier):
delta.microseconds * 1E-6, 6)
_set_counter(element, spec, identifier, sec)
-class Counter():
- """A counter class"""
- # container of a counter object
- _COUNTER = None
-
- @classmethod
- def init(cls, spec_file_name):
- """A creator method for a counter class. It creates a counter
- object by the module name of the given spec file. An argument is a
- specification file name."""
- if isinstance(cls._COUNTER, _Counter):
- # already loaded
- return cls._COUNTER
- # create an instance once
- cls._COUNTER = _Counter(spec_file_name)
- # set methods in Counter
- for (k, v) in cls._COUNTER._to_global.items():
- setattr(Counter, k, v)
- return cls._COUNTER
-
- # These method are dummies for isc.notify.notify_out.
- @staticmethod
- def inc_notifyoutv4(arg):
- """An empty method to be disclosed"""
- pass
- @staticmethod
- def inc_notifyoutv6(arg):
- """An empty method to be disclosed"""
- pass
+class _Statistics():
+ """Statistics data set"""
+ # default statistics data
+ _data = {}
+ # default statistics spec used in case of the specfile omitted in
+ # Counter()
+ _spec = [
+ {
+ "item_name": "zones",
+ "item_type": "named_set",
+ "item_optional": False,
+ "item_default": {
+ "_SERVER_" : {
+ "notifyoutv4" : 0,
+ "notifyoutv6" : 0
+ }
+ },
+ "item_title": "Zone names",
+ "item_description": "Zone names",
+ "named_set_item_spec": {
+ "item_name": "zonename",
+ "item_type": "map",
+ "item_optional": False,
+ "item_default": {},
+ "item_title": "Zone name",
+ "item_description": "Zone name",
+ "map_item_spec": [
+ {
+ "item_name": "notifyoutv4",
+ "item_type": "integer",
+ "item_optional": False,
+ "item_default": 0,
+ "item_title": "IPv4 notifies",
+ "item_description": "Number of IPv4 notifies per zone name sent out"
+ },
+ {
+ "item_name": "notifyoutv6",
+ "item_type": "integer",
+ "item_optional": False,
+ "item_default": 0,
+ "item_title": "IPv6 notifies",
+ "item_description": "Number of IPv6 notifies per zone name sent out"
+ }
+ ]
+ }
+ }
+ ]
-class _Counter():
+class Counter():
"""A module for holding all statistics counters of modules. The
counter numbers can be accessed by the accesseers defined
according to a spec file. In this class, the structure of per-zone
@@ -221,63 +234,30 @@ class _Counter():
_entire_server = '_SERVER_'
# zone names are contained under this dirname in the spec file.
_perzone_prefix = 'zones'
+ # default statistics data set
+ _statistics = _Statistics()
- def __init__(self, spec_file_name):
- # for exporting to the global scope
- self._to_global = {}
- self._statistics_spec = {}
- self._statistics_data = {}
+ def __init__(self, spec_file_name=None):
self._zones_item_list = []
- self._xfrrunning_names = []
- self._unixsocket_names = []
self._start_time = {}
self._disabled = False
self._rlock = threading.RLock()
- self._module_spec = \
- isc.config.module_spec_from_file(spec_file_name)
- self._statistics_spec = \
- self._module_spec.get_statistics_spec()
- self._parse_stats_spec()
- self._create_perzone_functors()
- self._create_perzone_timer_functors()
- self._create_xfrrunning_functors()
- self._create_unixsocket_functors()
- self._create_ipsocket_functors()
- self._to_global['clear_counters'] = self.clear_counters
- self._to_global['disable'] = self.disable
- self._to_global['enable'] = self.enable
- self._to_global['dump_statistics'] = self.dump_statistics
-
- def _parse_stats_spec(self):
- """Gets each list of names on statistics spec"""
+ if not spec_file_name: return
+ # change the default statistics spec
+ self._statistics._spec = \
+ isc.config.module_spec_from_file(spec_file_name).\
+ get_statistics_spec()
if self._perzone_prefix in \
- isc.config.spec_name_list(self._statistics_spec):
+ isc.config.spec_name_list(self._statistics._spec):
self._zones_item_list = isc.config.spec_name_list(
isc.config.find_spec_part(
- self._statistics_spec, self._perzone_prefix)\
+ self._statistics._spec, self._perzone_prefix)\
['named_set_item_spec']['map_item_spec'])
- self._xfrrunning_names = [
- n for n in isc.config.spec_name_list\
- (self._statistics_spec) \
- if n.find('xfr_running') == 1 \
- or n.find('xfr_deferred') == 1 \
- or n.find('soa_in_progress') == 0 ]
- self._unixsocket_names = [ \
- n.split('/')[-1] for n in \
- isc.config.spec_name_list(
- self._statistics_spec, "", True) \
- if n.find('socket/unixdomain/') == 0 ]
- self._ipsocket_names = [ \
- (n.split('/')[-3], n.split('/')[-1]) for n in \
- isc.config.spec_name_list(
- self._statistics_spec, "", True) \
- if n.find('socket/ipv4/tcp/') == 0 \
- or n.find('socket/ipv6/tcp/') == 0 ]
def clear_counters(self):
"""clears all statistics data"""
with self._rlock:
- self._statistics_data = {}
+ self._statistics._data = {}
def disable(self):
"""disables incrementing/decrementing counters"""
@@ -287,122 +267,74 @@ class _Counter():
"""enables incrementing/decrementing counters"""
self._disabled = False
- def _incrementer(self, identifier, step=1):
- """A per-zone incrementer for counter_name. Locks the
- thread because it is considered to be invoked by a
- multi-threading caller."""
+ def inc(self, *args):
+ """A incrementer for per-zone counter. Locks the thread
+ because it is considered to be invoked by a multi-threading
+ caller. isc.cc.data.DataNotFoundError is raised when
+ incrementing the counter of the item undefined in the spec
+ file."""
+ identifier = '/'.join(args)
+ step = 1
if self._disabled: return
with self._rlock:
- _inc_counter(self._statistics_data,
- self._statistics_spec,
+ _inc_counter(self._statistics._data,
+ self._statistics._spec,
identifier, step)
- def _decrementer(self, identifier, step=-1):
- """A decrementer for axfr or ixfr running. Locks the
- thread because it is considered to be invoked by a
- multi-threading caller."""
- self._incrementer(identifier, step)
+ def dec(self, *args):
+ """A decrementer for axfr or ixfr running. Locks the thread
+ because it is considered to be invoked by a multi-threading
+ caller. isc.cc.data.DataNotFoundError is raised when
+ decrementing the counter of the item undefined in the spec
+ file."""
+ identifier = '/'.join(args)
+ step = -1
+ if self._disabled: return
+ with self._rlock:
+ _inc_counter(self._statistics._data,
+ self._statistics._spec,
+ identifier, step)
- def _getter(self, identifier):
- """A getter method for perzone counters"""
- return _get_counter(self._statistics_data, identifier)
+ def get(self, *args):
+ """A getter method for counters. It returns the current number
+ of the specified counter. isc.cc.data.DataNotFoundError is
+ raised when the counter doesn't have a number yet."""
+ identifier = '/'.join(args)
+ return _get_counter(self._statistics._data, identifier)
- def _starttimer(self, identifier):
+ def start(self, *args):
"""Sets the value returned from _start_timer() as a value of
the identifier in the self._start_time which is dict-type"""
+ identifier = '/'.join(args)
isc.cc.data.set(self._start_time, identifier, _start_timer())
- def _stoptimer(self, identifier):
+ def stop(self, *args):
"""Sets duration time between corresponding time in
self._start_time and current time into the value of the
identifier. It deletes corresponding time in self._start_time
- after setting is successfully done. If DataNotFoundError is
- raised while invoking _stop_timer(), it stops setting and
- ignores the exception."""
+ after setting is successfully done. In case of stopping the
+ timer which has never been started, it raises and does
+ nothing. But in case of stopping the time which isn't defined
+ in the spec file, it raises DataNotFoundError"""
+ identifier = '/'.join(args)
try:
+ start_time = isc.cc.data.find(self._start_time,
+ identifier)
+ except isc.cc.data.DataNotFoundError:
+ # do not set the end time if the timer isn't started
+ pass
+ else:
+ # set the end time
_stop_timer(
- isc.cc.data.find(self._start_time, identifier),
- self._statistics_data,
- self._statistics_spec,
+ start_time,
+ self._statistics._data,
+ self._statistics._spec,
identifier)
+ # delete the started timer
del isc.cc.data.find(
self._start_time,
'/'.join(identifier.split('/')[0:-1]))\
[identifier.split('/')[-1]]
- except isc.cc.data.DataNotFoundError:
- # do not set end time if it's not started
- pass
-
- def _create_perzone_functors(self):
- """Creates increment method of each per-zone counter based on
- the spec file. Incrementer can be accessed by name
- "inc_${item_name}".Incrementers are passed to the
- XfrinConnection class as counter handlers."""
- for item in self._zones_item_list:
- if item.find('time_to_') == 0: continue
- def __incrementer(zone_name, counter_name=item, step=1):
- """A per-zone incrementer for counter_name."""
- self._incrementer(
- '%s/%s/%s' % \
- (self._perzone_prefix, zone_name, counter_name),
- step)
- def __getter(zone_name, counter_name=item):
- """A getter method for perzone counters"""
- return self._getter(
- '%s/%s/%s' % \
- (self._perzone_prefix, zone_name, counter_name))
- self._to_global['inc_%s' % item] = __incrementer
- self._to_global['get_%s' % item] = __getter
-
- def _create_perzone_timer_functors(self):
- """Creates timer method of each per-zone counter based on the
- spec file. Starter of the timer can be accessed by the name
- "start_${item_name}". Stopper of the timer can be accessed by
- the name "stop_${item_name}". These starter and stopper are
- passed to the XfrinConnection class as timer handlers."""
- for item in self._zones_item_list:
- if item.find('time_to_') == -1: continue
- def __getter(zone_name, counter_name=item):
- """A getter method for perzone timer. A zone name in
- string is required in argument."""
- return self._getter(
- '%s/%s/%s' % \
- (self._perzone_prefix, zone_name, counter_name))
- def __starttimer(zone_name, counter_name=item):
- """A starter method for perzone timer. A zone name in
- string is required in argument."""
- self._starttimer(
- '%s/%s/%s' % \
- (self._perzone_prefix, zone_name, counter_name))
- def __stoptimer(zone_name, counter_name=item):
- """A stopper method for perzone timer. A zone name in
- string is required in argument."""
- self._stoptimer(
- '%s/%s/%s' % \
- (self._perzone_prefix, zone_name, counter_name))
- self._to_global['start_%s' % item] = __starttimer
- self._to_global['stop_%s' % item] = __stoptimer
- self._to_global['get_%s' % item] = __getter
-
- def _create_xfrrunning_functors(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."""
- for item in self._xfrrunning_names:
- def __incrementer(counter_name=item, step=1):
- """A incrementer for axfr or ixfr running."""
- self._incrementer(counter_name, step)
- def __decrementer(counter_name=item, step=-1):
- """A decrementer for axfr or ixfr running."""
- self._decrementer(counter_name, step)
- def __getter(counter_name=item):
- """A getter method for xfr_running counters"""
- return self._getter(counter_name)
- self._to_global['inc_%s' % item] = __incrementer
- self._to_global['dec_%s' % item] = __decrementer
- self._to_global['get_%s' % item] = __getter
def dump_statistics(self):
"""Calculates an entire server counts, and returns statistics
@@ -410,14 +342,14 @@ class _Counter():
counter. If there is no counts, then it returns an empty
dictionary."""
# entire copy
- statistics_data = self._statistics_data.copy()
+ statistics_data = self._statistics._data.copy()
# If self.statistics_data contains nothing of zone name, it
# returns an empty dict.
if self._perzone_prefix not in statistics_data:
return statistics_data
zones = statistics_data[self._perzone_prefix]
# Start calculation for '_SERVER_' counts
- zones_spec = isc.config.find_spec_part(self._statistics_spec,
+ zones_spec = isc.config.find_spec_part(self._statistics._spec,
self._perzone_prefix)
zones_attrs = zones_spec['item_default'][self._entire_server]
zones_data = {}
@@ -436,37 +368,3 @@ class _Counter():
**zones_data)
return statistics_data
- def _create_unixsocket_functors(self):
- """Creates increment method of unixsocket socket. Incrementer
- can be accessed by name "inc_unixsocket_${item_name}"."""
- for item in self._unixsocket_names:
- def __incrementer(counter_name=item, step=1):
- """A incrementer for unix socket counter"""
- self._incrementer(
- 'socket/unixdomain/%s' % counter_name,
- step)
- def __getter(counter_name=item):
- """A getter method for unix socket counter"""
- return self._getter(
- 'socket/unixdomain/%s' % counter_name)
- self._to_global['inc_unixsocket_%s' % item] = __incrementer
- self._to_global['get_unixsocket_%s' % item] = __getter
-
- def _create_ipsocket_functors(self):
- """Creates increment method of ip socket. Incrementer can be
- accessed by name "inc_ipv4socket_${item_name}" for ipv4 or
- "inc_ipv6socket_${item_name}" for ipv6."""
- for item in self._ipsocket_names:
- # item should be tuple-type
- def __incrementer(counter_name=item, step=1):
- """A incrementer for ip socket counter"""
- self._incrementer(
- 'socket/%s/tcp/%s' % counter_name,
- step)
- def __getter(counter_name=item):
- """A getter method for ip socket counter"""
- return self._getter(
- 'socket/%s/tcp/%s' % counter_name)
- self._to_global['inc_%ssocket_%s' % item] = __incrementer
- self._to_global['get_%ssocket_%s' % item] = __getter
-
diff --git a/src/lib/python/isc/statistics/tests/counter_test.py b/src/lib/python/isc/statistics/tests/counter_test.py
index 55e59e8..090188a 100644
--- a/src/lib/python/isc/statistics/tests/counter_test.py
+++ b/src/lib/python/isc/statistics/tests/counter_test.py
@@ -33,15 +33,15 @@ def setup_functor(event, cycle, functor, *args):
event.wait()
for i in range(cycle): functor(*args)
-def start_functor(number, cycle, functor, *args):
+def start_functor(concurrency, number, functor, *args):
"""Creates the threads of the number and makes them start. Sets
the event and waits until these threads are finished."""
threads = []
event = threading.Event()
- for i in range(number):
+ for i in range(concurrency):
threads.append(threading.Thread(\
target=setup_functor, \
- args=(event, cycle, functor,) + args))
+ args=(event, number, functor,) + args))
for th in threads: th.start()
event.set()
for th in threads: th.join()
@@ -50,16 +50,19 @@ class TestBasicMethods(unittest.TestCase):
TEST_SPECFILE_LOCATION = TESTDATA_SRCDIR + os.sep + 'test_spec1.spec'
def setUp(self):
- self.counter = counter.Counter.init(self.TEST_SPECFILE_LOCATION)
+ self.counter = counter.Counter(self.TEST_SPECFILE_LOCATION)
def tearDown(self):
self.counter.clear_counters()
def test_clear_counters(self):
- self.counter._statistics_data = {'counter': 1}
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self.counter.get, 'counter')
+ self.counter.inc('counter')
+ self.assertEqual(self.counter.get('counter'), 1)
self.counter.clear_counters()
- self.assertEqual(self.counter._statistics_data,
- {})
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self.counter.get, 'counter')
def test_enablediable(self):
self.assertFalse(self.counter._disabled)
@@ -120,116 +123,36 @@ class TestBasicMethods(unittest.TestCase):
def test_rasing_incrementers(self):
""" use Thread"""
- number = 3 # number of the threads
- cycle = 10000 # number of counting per thread
- statistics_data = {}
+ concurrency = 3 # number of the threads
+ number = 10000 # number of counting per thread
counter_name = "counter"
timer_name = "seconds"
- statistics_spec = \
- isc.config.module_spec_from_file(self.TEST_SPECFILE_LOCATION)\
- .get_statistics_spec()
- self.counter._statistics_data = statistics_data
- self.counter._statistics_spec = statistics_spec
start_time = counter._start_timer()
- start_functor(number, cycle, self.counter._incrementer,
+ start_functor(concurrency, number, self.counter.inc,
counter_name)
counter._stop_timer(start_time,
- statistics_data,
- statistics_spec,
+ self.counter._statistics._data,
+ self.counter._statistics._spec,
timer_name)
self.assertEqual(
- counter._get_counter(statistics_data,
+ counter._get_counter(self.counter._statistics._data,
counter_name),
- number * cycle)
+ concurrency * number)
self.assertGreater(
- counter._get_counter(statistics_data,
+ counter._get_counter(self.counter._statistics._data,
timer_name), 0)
class BaseTestCounter():
- @classmethod
- def setUpClass(cls):
- imp.reload(counter)
+
def setUp(self):
- self._module_spec = isc.config.module_spec_from_file(
- self.TEST_SPECFILE_LOCATION)
- self.counter = counter.Counter.init(self.TEST_SPECFILE_LOCATION)
self._statistics_data = {}
+ self.counter = counter.Counter(self.TEST_SPECFILE_LOCATION)
self._entire_server = self.counter._entire_server
self._perzone_prefix = self.counter._perzone_prefix
- self._xfrrunning_names = self.counter._xfrrunning_names
- self._unixsocket_names = self.counter._unixsocket_names
- self._ipsocket_names = self.counter._ipsocket_names
- self._zones_item_list = self.counter._zones_item_list
- self._started = threading.Event()
def tearDown(self):
self.counter.clear_counters()
- def test_perzone_counters(self):
- # for per-zone counters
- for counter_name in self._zones_item_list:
- if counter_name.find('time_to_') == 0:
- isc.cc.data.set(\
- self._statistics_data,
- '%s/%s/%s' % (self._perzone_prefix,
- TEST_ZONE_NAME_STR,
- counter_name), 0.0)
- continue
- incrementer = self.counter._to_global\
- ['inc_%s' % counter_name]
- getter = self.counter._to_global\
- ['get_%s' % counter_name]
- incrementer(TEST_ZONE_NAME_STR)
- self.assertEqual(getter(TEST_ZONE_NAME_STR), 1)
- # checks disable/enable
- self.counter.disable()
- incrementer(TEST_ZONE_NAME_STR)
- self.assertEqual(getter(TEST_ZONE_NAME_STR), 1)
- self.counter.enable()
- incrementer(TEST_ZONE_NAME_STR)
- self.assertEqual(getter(TEST_ZONE_NAME_STR), 2)
- for zone_str in (self._entire_server, TEST_ZONE_NAME_STR):
- isc.cc.data.set(\
- self._statistics_data,
- '%s/%s/%s' % (self._perzone_prefix,
- zone_str,
- counter_name), 2)
- # checks other counters
- for counter_name in self._zones_item_list:
- getter = self.counter._to_global\
- ['get_%s' % counter_name]
- self.assertGreaterEqual(getter(TEST_ZONE_NAME_STR), 0)
- self.check_dump_statistics()
-
- def test_xfrrunning_counters(self):
- # for counters of xfer running
- for counter_name in self._xfrrunning_names:
- incrementer = self.counter._to_global\
- ['inc_%s' % counter_name]
- getter = self.counter._to_global\
- ['get_%s' % counter_name]
- decrementer = self.counter._to_global\
- ['dec_%s' % counter_name]
- incrementer()
- self.assertEqual(getter(), 1)
- decrementer()
- self.assertEqual(getter(), 0)
- # checks disable/enable
- self.counter.disable()
- incrementer()
- self.assertEqual(getter(), 0)
- self.counter.enable()
- incrementer()
- self.assertEqual(getter(), 1)
- self.counter.disable()
- decrementer()
- self.assertEqual(getter(), 1)
- self.counter.enable()
- decrementer()
- self.assertEqual(getter(), 0)
- self._statistics_data[counter_name] = 0
- self.check_dump_statistics()
-
def check_dump_statistics(self):
"""Checks no differences between the value returned from
dump_statistics() and locally collected statistics data. Also
@@ -241,94 +164,120 @@ class BaseTestCounter():
# Idempotency check
self.assertEqual(self.counter.dump_statistics(),
self._statistics_data)
- self.assertTrue(self._module_spec.validate_statistics(
- False, self._statistics_data))
+ if self.TEST_SPECFILE_LOCATION:
+ self.assertTrue(isc.config.module_spec_from_file(
+ self.TEST_SPECFILE_LOCATION).validate_statistics(
+ False, self._statistics_data))
+ else:
+ self.assertTrue(isc.config.ModuleSpec(
+ {'module_name': 'Foo',
+ 'statistics': self.counter._statistics._spec}
+ ).validate_statistics(
+ False, self._statistics_data))
+
+ def test_perzone_counters(self):
+ # for per-zone counters
+ for name in self.counter._zones_item_list:
+ args = (self._perzone_prefix, TEST_ZONE_NAME_STR, name)
+ if name.find('time_to_') == 0:
+ self.counter.start(*args)
+ self.counter.stop(*args)
+ self.assertGreater(self.counter.get(*args), 0)
+ sec = self.counter.get(*args)
+ for zone_str in (self._entire_server, TEST_ZONE_NAME_STR):
+ isc.cc.data.set(self._statistics_data,
+ '%s/%s/%s' % (args[0], zone_str, name), sec)
+ # twice exec stopper, then second is not changed
+ self.counter.stop(*args)
+ self.assertEqual(self.counter.get(*args), sec)
+ else:
+ self.counter.inc(*args)
+ self.assertEqual(self.counter.get(*args), 1)
+ # checks disable/enable
+ self.counter.disable()
+ self.counter.inc(*args)
+ self.assertEqual(self.counter.get(*args), 1)
+ self.counter.enable()
+ self.counter.inc(*args)
+ self.assertEqual(self.counter.get(*args), 2)
+ for zone_str in (self._entire_server, TEST_ZONE_NAME_STR):
+ isc.cc.data.set(self._statistics_data,
+ '%s/%s/%s' % (args[0], zone_str, name), 2)
+ self.check_dump_statistics()
- def test_unixsocket_counters(self):
- # for unixsocket counters
- for counter_name in self._unixsocket_names:
- incrementer = self.counter._to_global\
- ['inc_unixsocket_%s' % counter_name]
- getter = self.counter._to_global\
- ['get_unixsocket_%s' % counter_name]
- incrementer()
- self.assertEqual(getter(), 1)
+ def test_xfrrunning_counters(self):
+ # for counters of xfer running
+ _suffix = 'xfr_running'
+ _xfrrunning_names = \
+ isc.config.spec_name_list(self.counter._statistics._spec,
+ "", True)
+ for name in _xfrrunning_names:
+ if name.find(_suffix) != 1: continue
+ args = name.split('/')
+ self.counter.inc(*args)
+ self.assertEqual(self.counter.get(*args), 1)
+ self.counter.dec(*args)
+ self.assertEqual(self.counter.get(*args), 0)
# checks disable/enable
self.counter.disable()
- incrementer()
- self.assertEqual(getter(), 1)
+ self.counter.inc(*args)
+ self.assertEqual(self.counter.get(*args), 0)
self.counter.enable()
- incrementer()
- self.assertEqual(getter(), 2)
- isc.cc.data.set(
- self._statistics_data,
- 'socket/unixdomain/%s' % counter_name, 2)
- self.check_dump_statistics()
-
- def test_perzone_timers(self):
- # should not do this test unless there is no timer
- # parameter(time_to_xxx) in statistics spec
- has_timer = False
- for counter_name in self._zones_item_list:
- if counter_name.find('time_to_') == 0:
- has_timer = True
- if not has_timer: return
- # for timer counters
- for counter_name in self._zones_item_list:
- if counter_name.find('time_to_') == -1:
- isc.cc.data.set(\
- self._statistics_data,
- '%s/%s/%s' % (self._perzone_prefix,
- TEST_ZONE_NAME_STR,
- counter_name), 0)
- continue
- starter = self.counter._to_global\
- ['start_%s' % counter_name]
- stopper = self.counter._to_global\
- ['stop_%s' % counter_name]
- getter = self.counter._to_global\
- ['get_%s' % counter_name]
- starter(TEST_ZONE_NAME_STR)
- stopper(TEST_ZONE_NAME_STR)
- self.assertGreater(getter(TEST_ZONE_NAME_STR), 0)
- sec = getter(TEST_ZONE_NAME_STR)
- for zone_str in (self._entire_server, TEST_ZONE_NAME_STR):
- isc.cc.data.set(\
- self._statistics_data,
- '%s/%s/%s' % (self._perzone_prefix,
- zone_str,
- counter_name), sec)
- # twice exec stopper, then second is not changed
- stopper(TEST_ZONE_NAME_STR)
- self.assertEqual(getter(TEST_ZONE_NAME_STR), sec)
+ self.counter.inc(*args)
+ self.assertEqual(self.counter.get(*args), 1)
+ self.counter.disable()
+ self.counter.dec(*args)
+ self.assertEqual(self.counter.get(*args), 1)
+ self.counter.enable()
+ self.counter.dec(*args)
+ self.assertEqual(self.counter.get(*args), 0)
+ self._statistics_data[name] = 0
self.check_dump_statistics()
- def test_ipsocket_counters(self):
- # for ipsocket counters
- for counter_name in self._ipsocket_names:
- incrementer = self.counter._to_global\
- ['inc_%ssocket_%s' % counter_name]
- getter = self.counter._to_global\
- ['get_%ssocket_%s' % counter_name]
- incrementer()
- self.assertEqual(getter(), 1)
+ def test_socket_counters(self):
+ # for ipsocket/unixsocket counters
+ _prefix = 'socket/'
+ _socket_names = \
+ isc.config.spec_name_list(self.counter._statistics._spec,
+ "", True)
+ for name in _socket_names:
+ if name.find(_prefix) != 0: continue
+ args = name.split('/')
+ self.counter.inc(*args)
+ self.assertEqual(self.counter.get(*args), 1)
# checks disable/enable
self.counter.disable()
- incrementer()
- self.assertEqual(getter(), 1)
+ self.counter.inc(*args)
+ self.assertEqual(self.counter.get(*args), 1)
self.counter.enable()
- incrementer()
- self.assertEqual(getter(), 2)
+ self.counter.inc(*args)
+ self.assertEqual(self.counter.get(*args), 2)
isc.cc.data.set(
- self._statistics_data,
- 'socket/%s/tcp/%s' % counter_name, 2)
+ self._statistics_data, '/'.join(args), 2)
self.check_dump_statistics()
+ def test_undefined_item(self):
+ # test DataNotFoundError raising when specifying item defined
+ # in the specfile
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self.counter.inc, '__undefined__')
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self.counter.dec, '__undefined__')
+ self.counter.start('__undefined__')
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self.counter.stop, '__undefined__')
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self.counter.get, '__undefined__')
+
+class TestCounter0(unittest.TestCase, BaseTestCounter):
+ TEST_SPECFILE_LOCATION = None
+ def setUp(self):
+ BaseTestCounter.setUp(self)
+ def tearDown(self):
+ BaseTestCounter.tearDown(self)
+
class TestCounter1(unittest.TestCase, BaseTestCounter):
TEST_SPECFILE_LOCATION = TESTDATA_SRCDIR + os.sep + 'test_spec1.spec'
- @classmethod
- def setUpClass(cls):
- BaseTestCounter.setUpClass()
def setUp(self):
BaseTestCounter.setUp(self)
def tearDown(self):
@@ -336,9 +285,6 @@ class TestCounter1(unittest.TestCase, BaseTestCounter):
class TestCounter2(unittest.TestCase, BaseTestCounter):
TEST_SPECFILE_LOCATION = TESTDATA_SRCDIR + os.sep + 'test_spec2.spec'
- @classmethod
- def setUpClass(cls):
- BaseTestCounter.setUpClass()
def setUp(self):
BaseTestCounter.setUp(self)
def tearDown(self):
@@ -346,9 +292,6 @@ class TestCounter2(unittest.TestCase, BaseTestCounter):
class TestCounter3(unittest.TestCase, BaseTestCounter):
TEST_SPECFILE_LOCATION = TESTDATA_SRCDIR + os.sep + 'test_spec3.spec'
- @classmethod
- def setUpClass(cls):
- BaseTestCounter.setUpClass()
def setUp(self):
BaseTestCounter.setUp(self)
def tearDown(self):
More information about the bind10-changes
mailing list