BIND 10 trac2225_xfrout, updated. 514cd120aa0ac15c4e2118255d6176e90add211b [2225_xfrout] s/dump_statistics/get_statistics/
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Jan 18 06:34:33 UTC 2013
The branch, trac2225_xfrout has been updated
discards 01c389aec693882f1b8233500cba1f7f65517fd0 (commit)
discards c3df8d055117b28da4fabc20e15a14d4def90c00 (commit)
discards 46478bcb06ce13b7e2c1b342e6b7e63764c1e225 (commit)
discards 89f99b959381e5d976199785cd4432b7aa82757d (commit)
discards da239e501ca0db170007d4d3462a96da2ccc3a99 (commit)
discards f27d218ea32e57bc08c4b1db77e0a7a05862345c (commit)
discards f516250903358f645c37f6ab0d313e3571c52d66 (commit)
discards c087ea5ba98e927b5c523a0b02f4b3858c602e8d (commit)
discards 64416e1d8bdd8cdf9c0535098b78eb96ce03fe26 (commit)
discards df8958f661691900968a43d344e0bd548703b9d5 (commit)
discards 5360d3c534c58a31223cba2a69265f93976f59c0 (commit)
discards 143b9517ac82f0682cc6b39a58bdd292e0c2ce8e (commit)
discards a3b6ba5f5ad3c2455635a8aff1ba475e3ce56337 (commit)
discards d929e11039128ce6f1e5b4798de81d3c967996d1 (commit)
discards 7c19613f47670a123ba3bb08b0f64b47086cec84 (commit)
discards 0eba3b5dfc1d263ad55e90a07c6b12c94fc09155 (commit)
discards c1473d95e39b86ebfa57eb47f7da8e96ebe55203 (commit)
discards 37391946e9c47b849e5f6e38345aa8298c963f87 (commit)
discards b25e2ffb1e511dacc6703935e819ed3ae922e293 (commit)
discards 77171e9cda20fab175b23359c7412c9df26d5107 (commit)
discards 6535b61e9ddc6325ccd7bbfd56e1c094a0f54335 (commit)
discards 216f61003202faf7381a627a1138d891a6d1e28a (commit)
discards cc098e6d33b092c46194dcb40179d5688655964f (commit)
discards 09c9166b4a26afa42b6b51070d4a05b2fea6e87e (commit)
via 514cd120aa0ac15c4e2118255d6176e90add211b (commit)
via b541596415b3a79c9ec5e7e2c32b2acb1a9be28c (commit)
via 9ca7f37f2fc5464446a38a7ebc9256b71fb8944f (commit)
via 17ace8323f227b86f9b3c376ffb0cdbd86075710 (commit)
via ca8b0515f7c638d9697b608965f18b5d1c5b5fa0 (commit)
via da7349e2f4f79a781365a4198f9425865c729d1a (commit)
via cb9e424c61fc7b42038fd2c5d49a22b3ca581a01 (commit)
via 52ec102b16ae6969c4aa405ec6617765336d69f1 (commit)
via 4a1c77d95ad8c51b4a47a379b273809e8e8e2621 (commit)
via b2a12049d34b061dff5027e9a78e6a00d751c773 (commit)
via 12ed470e0c12f4879c5398a52c7364e2fe4ce01c (commit)
via 657c926eaa761b234d648aa4eac99e7f99a4f1e7 (commit)
via 8a0613d11028d6eba72e08dd7d44aa08bcc682c2 (commit)
via 9de118b1aadb88902755c18ff7b584ceb84ac545 (commit)
via 32c40f54a0b1e833d8b03cfb43da064d39a7591c (commit)
via 1112a612b9df64344416a10730df3ed843b3c5de (commit)
via 58ce07ad5ba3d527384ca88a5139f5a6faee004a (commit)
via 7025d308cd3f2a68cc370835ba059b3a43051fc0 (commit)
via 8770765db4becde5c0347a055dd7db7bfd6120c0 (commit)
via f4c26bfac4daf9520d189259d0380c5fa814e0ae (commit)
via 1b87787e20f6333959235623754fbebae0445e43 (commit)
via 83c439eff853360e633b6e539c6d38ff9c49e971 (commit)
via fa4cd1a315d67c2f48f28bc487035bbe44f291d9 (commit)
via 34900ee9027ff21655fbaca820696f10a69b2f83 (commit)
via 7c1af32c1336e61c9546f8cd564ff9c660ccf203 (commit)
via a165423b537cf5771ea810dba64215a724050a5a (commit)
via bc8dde5aaed1b519e26a20b383cddec07c01369d (commit)
via 2a337c756ad1064af1cbcaa8cd2c79be65f0b4d5 (commit)
via 28a20a3ee754d03ea90f13f76fa8e6d44c696b69 (commit)
via 2ad5c3c52b9106f68a6fb24a2ebfc85067877a04 (commit)
via be258adbecd48f1d46e47566f54843db1b579b9c (commit)
via 02a31879b8d8db032883d6e28d57c2369f2299cf (commit)
via df03141495a568971ff26d78a229beaa5b373e19 (commit)
via cd917b3660e1d944d749fb2fb19ce9dfb622c39c (commit)
via cc0c7a0a7b9b4abdb94b7c5a2007334b914218f8 (commit)
via e12dee22bbc97e49c7e5641cf50e39f64e5cbed2 (commit)
via 927c2a94869d76fdbb30018861ba235ddf9389f2 (commit)
via 6443e079d1d0dd3b0de766196a2f9b711bd4f4f5 (commit)
via 78f11bb1db706b793f2b45d94da3c613c2f8ca9e (commit)
via 08d9023ba335f084034ec31cf7e304964b267acb (commit)
via dc7e03f9cca07ef79b5741f4353f570f383dbb9b (commit)
via bc768d296fbd5b86b9d100672792605c79c81739 (commit)
via a9f24702174e022332b528b8d39a21c203b67d3e (commit)
via ef7776ea48e1ddbfb3b727836722cbfc8b65f4fa (commit)
via f098bc21fd0c528fdd55bdbd8f99f6fec36c9222 (commit)
via 607d55c17a1d1becedf6e0fb81673627cab763f8 (commit)
via 903087f3c9e778e762483cf11992e4f5ddc9b7d1 (commit)
via 65bbcd0970063c0923f597ee4413ccbcc969ba58 (commit)
via e8ed9fd77960f2e3c4cfc5948d356b47524d441c (commit)
via 31b16f3568b95073fc15b68e435215572f25c5b8 (commit)
via 6fe2c80c65634db3c5b9ef7fab2e2f48a507fc94 (commit)
via 87ff7feca9801dc6c78a5553c090819a66afe918 (commit)
via 48974a8f8351415321dcabf039296e9e7854fbe1 (commit)
via 652859d50201a5fd7d7ec3bc4266ead82fc86c4b (commit)
via aa70659de52c486695a6fc822b673adf51a2abcf (commit)
via c9e1f35632323f09a1e61f96f88df384e337f885 (commit)
via ad322965f290c5d594e084eb57f9bf16eff87717 (commit)
via ad6e16d25942d9bb308fcc1cf4ec839769956981 (commit)
via 2b861742dc6b8461984a1c1c0437b46a313f672b (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 (01c389aec693882f1b8233500cba1f7f65517fd0)
\
N -- N -- N (514cd120aa0ac15c4e2118255d6176e90add211b)
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 514cd120aa0ac15c4e2118255d6176e90add211b
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Jan 18 15:31:29 2013 +0900
[2225_xfrout] s/dump_statistics/get_statistics/
Due to the the method name changed
commit b541596415b3a79c9ec5e7e2c32b2acb1a9be28c
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Jan 18 15:30:35 2013 +0900
[2225_xfrout] s/clear_counters/clear_all/
Due to the the method name changed
commit 9ca7f37f2fc5464446a38a7ebc9256b71fb8944f
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Jan 18 15:22:44 2013 +0900
[2225_xfrout] s/counter/counters/
Due to the class name changed
commit 17ace8323f227b86f9b3c376ffb0cdbd86075710
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 ca8b0515f7c638d9697b608965f18b5d1c5b5fa0
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 da7349e2f4f79a781365a4198f9425865c729d1a
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 cb9e424c61fc7b42038fd2c5d49a22b3ca581a01
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 52ec102b16ae6969c4aa405ec6617765336d69f1
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 4a1c77d95ad8c51b4a47a379b273809e8e8e2621
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 b2a12049d34b061dff5027e9a78e6a00d751c773
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 12ed470e0c12f4879c5398a52c7364e2fe4ce01c
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 657c926eaa761b234d648aa4eac99e7f99a4f1e7
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 8a0613d11028d6eba72e08dd7d44aa08bcc682c2
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 9de118b1aadb88902755c18ff7b584ceb84ac545
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 32c40f54a0b1e833d8b03cfb43da064d39a7591c
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 1112a612b9df64344416a10730df3ed843b3c5de
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 58ce07ad5ba3d527384ca88a5139f5a6faee004a
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 7025d308cd3f2a68cc370835ba059b3a43051fc0
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 8770765db4becde5c0347a055dd7db7bfd6120c0
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Sep 28 11:13:49 2012 +0900
[2225] removed duplicate tests
commit f4c26bfac4daf9520d189259d0380c5fa814e0ae
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 1b87787e20f6333959235623754fbebae0445e43
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 83c439eff853360e633b6e539c6d38ff9c49e971
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 fa4cd1a315d67c2f48f28bc487035bbe44f291d9
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 34900ee9027ff21655fbaca820696f10a69b2f83
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 7c1af32c1336e61c9546f8cd564ff9c660ccf203
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 a165423b537cf5771ea810dba64215a724050a5a
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 bc8dde5aaed1b519e26a20b383cddec07c01369d
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 | 72 ++--
src/bin/xfrout/xfrout.py.in | 40 +-
src/lib/python/isc/notify/notify_out.py | 8 +-
src/lib/python/isc/notify/tests/notify_out_test.py | 26 +-
src/lib/python/isc/statistics/Makefile.am | 2 +-
src/lib/python/isc/statistics/__init__.py | 2 +-
.../isc/statistics/{counter.py => counters.py} | 255 ++++++------
src/lib/python/isc/statistics/tests/Makefile.am | 2 +-
.../python/isc/statistics/tests/counter_test.py | 301 --------------
.../python/isc/statistics/tests/counters_test.py | 416 ++++++++++++++++++++
10 files changed, 634 insertions(+), 490 deletions(-)
rename src/lib/python/isc/statistics/{counter.py => counters.py} (57%)
delete mode 100644 src/lib/python/isc/statistics/tests/counter_test.py
create mode 100644 src/lib/python/isc/statistics/tests/counters_test.py
-----------------------------------------------------------------------
diff --git a/src/bin/xfrout/tests/xfrout_test.py.in b/src/bin/xfrout/tests/xfrout_test.py.in
index 53a80f9..7506095 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
- self.xfrsess._counter.clear_counters()
+ self.xfrsess._counters.clear_all()
class TestXfroutSession(TestXfroutSessionBase):
def test_quota_error(self):
@@ -380,7 +380,7 @@ class TestXfroutSession(TestXfroutSessionBase):
]))
# check the 'xfrrej' counter initially
self.assertRaises(isc.cc.data.DataNotFoundError,
- self.xfrsess._counter.get, 'zones',
+ self.xfrsess._counters.get, 'zones',
TEST_ZONE_NAME_STR, 'xfrrej')
# Localhost (the default in this test) is accepted
rcode, msg = self.xfrsess._parse_query_message(self.mdata)
@@ -396,7 +396,7 @@ 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.xfrsess._counter.get(
+ self.assertEqual(self.xfrsess._counters.get(
'zones', TEST_ZONE_NAME_STR, 'xfrrej'), 1)
# TSIG signed request
@@ -427,7 +427,7 @@ 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.xfrsess._counter.get(
+ self.assertEqual(self.xfrsess._counters.get(
'zones', TEST_ZONE_NAME_STR, 'xfrrej'), 2)
# ACL using TSIG: no TSIG; should be rejected
@@ -437,7 +437,7 @@ 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.xfrsess._counter.get(
+ self.assertEqual(self.xfrsess._counters.get(
'zones', TEST_ZONE_NAME_STR, 'xfrrej'), 3)
#
@@ -459,7 +459,7 @@ 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.xfrsess._counter.get(
+ self.assertEqual(self.xfrsess._counters.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,
@@ -467,7 +467,7 @@ 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.xfrsess._counter.get(
+ self.assertEqual(self.xfrsess._counters.get(
'zones', TEST_ZONE_NAME_STR, 'xfrrej'), 5)
# Neither address nor TSIG matches
self.xfrsess._remote = (socket.AF_INET, socket.SOCK_STREAM,
@@ -475,7 +475,7 @@ 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.xfrsess._counter.get(
+ self.assertEqual(self.xfrsess._counters.get(
'zones', TEST_ZONE_NAME_STR, 'xfrrej'), 6)
def test_transfer_acl(self):
@@ -860,10 +860,10 @@ class TestXfroutSession(TestXfroutSessionBase):
self.xfrsess._reply_xfrout_query = myreply
self.assertRaises(isc.cc.data.DataNotFoundError,
- self.xfrsess._counter.get,
+ self.xfrsess._counters.get,
'socket', 'unixdomain', 'senderr')
self.xfrsess.dns_xfrout_start(self.sock, self.mdata)
- self.assertEqual(self.xfrsess._counter.get(
+ self.assertEqual(self.xfrsess._counters.get(
'socket', 'unixdomain', 'senderr'), 1)
def test_dns_xfrout_start_noerror(self):
@@ -875,12 +875,12 @@ class TestXfroutSession(TestXfroutSessionBase):
self.sock.send(b"success")
self.assertRaises(isc.cc.data.DataNotFoundError,
- self.xfrsess._counter.get,
+ self.xfrsess._counters.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(self.xfrsess._counter.get(
+ self.assertGreater(self.xfrsess._counters.get(
'zones', TEST_ZONE_NAME_STR, 'xfrreqdone'), 0)
def test_reply_xfrout_query_axfr(self):
@@ -1138,7 +1138,7 @@ class TestXfroutSessionWithSQLite3(TestXfroutSessionBase):
def test_axfr_normal_session(self):
self.assertRaises(isc.cc.data.DataNotFoundError,
- self.xfrsess._counter.get, 'axfr_running')
+ self.xfrsess._counters.get, 'axfr_running')
XfroutSession._handle(self.xfrsess)
response = self.sock.read_msg(Message.PRESERVE_ORDER);
self.assertEqual(Rcode.NOERROR(), response.get_rcode())
@@ -1146,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,
- self.xfrsess._counter.get, 'ixfr_running')
- self.assertEqual(self.xfrsess._counter.get('axfr_running'), 0)
+ self.xfrsess._counters.get, 'ixfr_running')
+ self.assertEqual(self.xfrsess._counters.get('axfr_running'), 0)
def test_ixfr_to_axfr(self):
self.xfrsess._request_data = \
@@ -1167,9 +1167,9 @@ class TestXfroutSessionWithSQLite3(TestXfroutSessionBase):
self.xfrsess._request_data = \
self.create_request_data(ixfr=IXFR_OK_VERSION)
self.assertRaises(isc.cc.data.DataNotFoundError,
- self.xfrsess._counter.get, 'axfr_running')
+ self.xfrsess._counters.get, 'axfr_running')
self.assertRaises(isc.cc.data.DataNotFoundError,
- self.xfrsess._counter.get, 'ixfr_running')
+ self.xfrsess._counters.get, 'ixfr_running')
XfroutSession._handle(self.xfrsess)
response = self.sock.read_msg(Message.PRESERVE_ORDER)
actual_records = response.get_section(Message.SECTION_ANSWER)
@@ -1188,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,
- self.xfrsess._counter.get, 'axfr_running')
- self.assertEqual(self.xfrsess._counter.get('ixfr_running'), 0)
+ self.xfrsess._counters.get, 'axfr_running')
+ self.assertEqual(self.xfrsess._counters.get('ixfr_running'), 0)
def ixfr_soa_only_common_checks(self, request_serial):
self.xfrsess._request_data = \
@@ -1217,7 +1217,7 @@ class MyUnixSockServer(UnixSockServer):
self._common_init()
self._cc = MyCCSession()
self.update_config_data(self._cc.get_full_config())
- self._counter = xfrout.Counter(xfrout.SPECFILE_LOCATION)
+ self._counters = xfrout.Counters(xfrout.SPECFILE_LOCATION)
class TestUnixSockServer(unittest.TestCase):
def setUp(self):
@@ -1578,57 +1578,57 @@ class TestUnixSockServerForCounter(unittest.TestCase):
super,
self.orig_process_request,
self.orig_select )
- self.unix._counter.clear_counters()
+ self.unix._counters.clear_all()
def test_open(self):
# open
self.assertEqual(
- self.unix._counter.get('socket', 'unixdomain', 'open'), 1)
+ self.unix._counters.get('socket', 'unixdomain', 'open'), 1)
self.assertRaises(isc.cc.data.DataNotFoundError,
- self.unix._counter.get,
+ self.unix._counters.get,
'socket', 'unixdomain', 'openfail')
xfrout.ThreadingUnixStreamServer = DummySocketserverException
self.unix = UnixSockServer(None, None, None, None, None)
self.assertEqual(
- self.unix._counter.get('socket', 'unixdomain', 'open'), 1)
+ self.unix._counters.get('socket', 'unixdomain', 'open'), 1)
self.assertEqual(
- self.unix._counter.get('socket', 'unixdomain', 'openfail'), 1)
+ self.unix._counters.get('socket', 'unixdomain', 'openfail'), 1)
def test_close(self):
# close
self.assertRaises(isc.cc.data.DataNotFoundError,
- self.unix._counter.get,
+ self.unix._counters.get,
'socket','unixdomain', 'close')
self.unix.shutdown()
self.assertEqual(
- self.unix._counter.get('socket', 'unixdomain', 'close'), 1)
+ self.unix._counters.get('socket', 'unixdomain', 'close'), 1)
def test_bindfail(self):
# bindfail
self.assertRaises(isc.cc.data.DataNotFoundError,
- self.unix._counter.get,
+ self.unix._counters.get,
'socket', 'unixdomain', 'bindfail')
self.assertRaises(Exception, self.unix.server_bind)
self.assertEqual(
- self.unix._counter.get('socket', 'unixdomain', 'bindfail'), 1)
+ self.unix._counters.get('socket', 'unixdomain', 'bindfail'), 1)
def test_accept(self):
# accept
self.assertRaises(isc.cc.data.DataNotFoundError,
- self.unix._counter.get,
+ self.unix._counters.get,
'socket', 'unixdomain', 'accept')
self.unix.get_request()
self.assertEqual(
- self.unix._counter.get('socket', 'unixdomain', 'accept'), 1)
+ self.unix._counters.get('socket', 'unixdomain', 'accept'), 1)
# acceptfail
self.assertRaises(isc.cc.data.DataNotFoundError,
- self.unix._counter.get,
+ self.unix._counters.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(
- self.unix._counter.get('socket', 'unixdomain', 'acceptfail'), 1)
+ self.unix._counters.get('socket', 'unixdomain', 'acceptfail'), 1)
def test_senderr(self):
# do inside of above TestXfroutSession
@@ -1637,13 +1637,13 @@ class TestUnixSockServerForCounter(unittest.TestCase):
def test_recverr(self):
# recverr
self.assertRaises(isc.cc.data.DataNotFoundError,
- self.unix._counter.get,
+ self.unix._counters.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(self.unix._counter.get(
+ self.assertEqual(self.unix._counters.get(
'socket', 'unixdomain', 'recverr'), 1)
class TestInitialization(unittest.TestCase):
@@ -1694,7 +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)
+ self._counters = xfrout.Counters(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 8d51438..b834982 100755
--- a/src/bin/xfrout/xfrout.py.in
+++ b/src/bin/xfrout/xfrout.py.in
@@ -27,7 +27,7 @@ from socketserver import *
import os
from isc.config.ccsession import *
from isc.cc import SessionError, SessionTimeout
-from isc.statistics import Counter
+from isc.statistics import Counters
from isc.notify import notify_out
import isc.util.process
import socket
@@ -169,9 +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
+ # Creation of self.counters should be done before of
# invoking self._handle()
- self._counter = Counter(SPECFILE_LOCATION)
+ self._counters = Counters(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
- self._counter.inc('zones', zone_name.to_text(), 'xfrrej')
+ self._counters.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():
- self._counter.inc('axfr_running')
+ self._counters.inc('axfr_running')
else:
- self._counter.inc('ixfr_running')
+ self._counters.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
- self._counter.inc('socket', 'unixdomain', 'senderr')
+ self._counters.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():
- self._counter.dec('axfr_running')
+ self._counters.dec('axfr_running')
else:
- self._counter.dec('ixfr_running')
+ self._counters.dec('ixfr_running')
# count done Xfr requests by each zone name
- self._counter.inc('zones', zone_name.to_text(), 'xfrreqdone')
+ self._counters.inc('zones', zone_name.to_text(), 'xfrreqdone')
logger.info(XFROUT_XFR_TRANSFER_DONE, self._request_typestr,
format_addrinfo(self._remote), zone_str)
@@ -659,14 +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)
+ self._counters = Counters(SPECFILE_LOCATION)
try:
ThreadingUnixStreamServer.__init__(self, sock_file, \
handle_class)
except:
- self._counter.inc('socket', 'unixdomain', 'openfail')
+ self._counters.inc('socket', 'unixdomain', 'openfail')
else:
- self._counter.inc('socket', 'unixdomain', 'open')
+ self._counters.inc('socket', 'unixdomain', 'open')
self._shutdown_event = shutdown_event
self._write_sock, self._read_sock = socket.socketpair()
self._common_init()
@@ -683,7 +683,7 @@ class UnixSockServer(socketserver_mixin.NoPollMixIn,
return super().server_bind()
except:
# count bind failed unixsockets
- self._counter.inc('socket', 'unixdomain', 'bindfail')
+ self._counters.inc('socket', 'unixdomain', 'bindfail')
raise
def get_request(self):
@@ -695,11 +695,11 @@ class UnixSockServer(socketserver_mixin.NoPollMixIn,
# ThreadingUnixStreamServer
ret = super().get_request()
# count successfully accepted unixsockets
- self._counter.inc('socket', 'unixdomain', 'accept')
+ self._counters.inc('socket', 'unixdomain', 'accept')
return ret
except:
# count failed accepted unixsockets
- self._counter.inc('socket', 'unixdomain', 'acceptfail')
+ self._counters.inc('socket', 'unixdomain', 'acceptfail')
raise
def _common_init(self):
@@ -769,7 +769,7 @@ class UnixSockServer(socketserver_mixin.NoPollMixIn,
break
except Exception as pre:
# count unixsockets receive errors
- self._counter.inc('socket', 'unixdomain', 'recverr')
+ self._counters.inc('socket', 'unixdomain', 'recverr')
logger.error(XFROUT_PROCESS_REQUEST_ERROR, pre)
break
@@ -896,7 +896,7 @@ class UnixSockServer(socketserver_mixin.NoPollMixIn,
super().shutdown() # call the shutdown() of class socketserver_mixin.NoPollMixIn
try:
# count closed unixsockets
- self._counter.inc('socket', 'unixdomain', 'close')
+ self._counters.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))
@@ -999,7 +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)
+ self._counters = Counters(SPECFILE_LOCATION)
def _start_xfr_query_listener(self):
'''Start a new thread to accept xfr query. '''
@@ -1095,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, self._counter.dump_statistics())
+ answer = create_answer(0, self._counters.get_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 64f9186..fdd9bb9 100644
--- a/src/lib/python/isc/notify/notify_out.py
+++ b/src/lib/python/isc/notify/notify_out.py
@@ -25,7 +25,7 @@ from isc.datasrc import DataSourceClient
from isc.net import addr
import isc
from isc.log_messages.notify_out_messages import *
-from isc.statistics import Counter
+from isc.statistics import Counters
logger = isc.log.Logger("notify_out")
@@ -143,7 +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()
+ self._counters = Counters()
def _init_notify_out(self, datasrc_file):
'''Get all the zones name and its notify target's address.
@@ -482,10 +482,10 @@ 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:
- self._counter.inc('zones', zone_notify_info.zone_name,
+ self._counters.inc('zones', zone_notify_info.zone_name,
'notifyoutv4')
elif zone_notify_info.get_socket().family == socket.AF_INET6:
- self._counter.inc('zones', zone_notify_info.zone_name,
+ self._counters.inc('zones', zone_notify_info.zone_name,
'notifyoutv6')
logger.info(NOTIFY_OUT_SENDING_NOTIFY, addrinfo[0],
addrinfo[1])
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 149096c..08663d4 100644
--- a/src/lib/python/isc/notify/tests/notify_out_test.py
+++ b/src/lib/python/isc/notify/tests/notify_out_test.py
@@ -112,7 +112,7 @@ class TestNotifyOut(unittest.TestCase):
com_ch_info.notify_slaves.append(('1.1.1.1', 5353))
def tearDown(self):
- self._notify._counter.clear_counters()
+ self._notify._counters.clear_all()
def test_send_notify(self):
notify_out._MAX_NOTIFY_NUM = 2
@@ -267,10 +267,10 @@ class TestNotifyOut(unittest.TestCase):
example_com_info = self._notify._notify_infos[('example.net.', 'IN')]
self.assertRaises(isc.cc.data.DataNotFoundError,
- self._notify._counter.get,
+ self._notify._counters.get,
'zones', 'example.net.', 'notifyoutv4')
self.assertRaises(isc.cc.data.DataNotFoundError,
- self._notify._counter.get,
+ self._notify._counters.get,
'zones', 'example.net.', 'notifyoutv6')
example_com_info.prepare_notify_out()
@@ -278,38 +278,38 @@ class TestNotifyOut(unittest.TestCase):
('192.0.2.1', 53))
self.assertTrue(ret)
self.assertEqual(socket.AF_INET, example_com_info.sock_family)
- self.assertEqual(self._notify._counter.get(
+ self.assertEqual(self._notify._counters.get(
'zones', 'example.net.', 'notifyoutv4'), 1)
- self.assertEqual(self._notify._counter.get(
+ self.assertEqual(self._notify._counters.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.assertRaises(isc.cc.data.DataNotFoundError,
- self._notify._counter.get,
+ self._notify._counters.get,
'zones', 'example.net.', 'notifyoutv4')
self.assertRaises(isc.cc.data.DataNotFoundError,
- self._notify._counter.get,
+ self._notify._counters.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(self._notify._counter.get(
+ self.assertEqual(self._notify._counters.get(
'zones', 'example.net.', 'notifyoutv4'), 0)
- self.assertEqual(self._notify._counter.get(
+ self.assertEqual(self._notify._counters.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.assertRaises(isc.cc.data.DataNotFoundError,
- self._notify._counter.get,
+ self._notify._counters.get,
'zones', 'example.net.', 'notifyoutv4')
self.assertRaises(isc.cc.data.DataNotFoundError,
- self._notify._counter.get,
+ self._notify._counters.get,
'zones', 'example.net.', 'notifyoutv6')
# As long as the underlying data source validates RDATA this shouldn't
@@ -321,10 +321,10 @@ class TestNotifyOut(unittest.TestCase):
self.assertFalse(ret)
self.assertRaises(isc.cc.data.DataNotFoundError,
- self._notify._counter.get,
+ self._notify._counters.get,
'zones', 'example.net.', 'notifyoutv4')
self.assertRaises(isc.cc.data.DataNotFoundError,
- self._notify._counter.get,
+ self._notify._counters.get,
'zones', 'example.net.', 'notifyoutv4')
def test_zone_notify_handler(self):
diff --git a/src/lib/python/isc/statistics/Makefile.am b/src/lib/python/isc/statistics/Makefile.am
index e269b1e..9be1312 100644
--- a/src/lib/python/isc/statistics/Makefile.am
+++ b/src/lib/python/isc/statistics/Makefile.am
@@ -1,6 +1,6 @@
SUBDIRS = . tests
-python_PYTHON = __init__.py counter.py
+python_PYTHON = __init__.py counters.py
pythondir = $(pyexecdir)/isc/statistics
CLEANDIRS = __pycache__
diff --git a/src/lib/python/isc/statistics/__init__.py b/src/lib/python/isc/statistics/__init__.py
index 2daa4b7..9e77ed6 100644
--- a/src/lib/python/isc/statistics/__init__.py
+++ b/src/lib/python/isc/statistics/__init__.py
@@ -1 +1 @@
-from isc.statistics.counter import *
+from isc.statistics.counters import *
diff --git a/src/lib/python/isc/statistics/counter.py b/src/lib/python/isc/statistics/counter.py
deleted file mode 100644
index 5946790..0000000
--- a/src/lib/python/isc/statistics/counter.py
+++ /dev/null
@@ -1,370 +0,0 @@
-# Copyright (C) 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
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
-# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
-# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
-# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""BIND 10 Statistics counter module
-
-This module handles the statistics counters for BIND 10 modules. For
-using the module `counter.py`, firstly the init() method should be
-invoked in each module like b10-xfrin or b10-xfrout after importing
-this module.
-
- from isc.statistics import Counter
- self.counter = Counter(/path/to/foo.spec)
-
-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 is
-callable. Since these methods requires the string of the zone name in
-the first argument, in the b10-xfrout,
-
- self.counter.inc('zones', zone_name, 'xfrreqdone')
-
-then the counter for xfrreqdone corresponding to zone_name was
-incremented. For getting the current number of this counter, we can do
-this,
-
- 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 callable. This method is used for decrementing the
-counter number. Regarding the item `axfr_running`, an argument like
-zone name is not required.
-
- self.counter.dec('axfr_running')
-
-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
-as the following can be invoked via other module like notify_out.py,
-which is firstly imported in the main module.
-
- 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
-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`.
-"""
-
-import threading
-import isc.config
-from datetime import datetime
-
-# static internal functions
-def _add_counter(element, spec, identifier):
- """Returns value of the identifier if the identifier is in the
- element. Otherwise, sets a default value from the spec then
- returns it. If the top-level type of the identifier is named_set
- and the second-level type is map, it sets a set of default values
- under the level and then returns the default value of the
- identifier. Raises DataNotFoundError if the element is invalid for
- spec."""
- try:
- return isc.cc.data.find(element, identifier)
- except isc.cc.data.DataNotFoundError:
- pass
- try:
- isc.config.find_spec_part(spec, identifier)
- except isc.cc.data.DataNotFoundError:
- # spec or identifier is wrong
- raise
- # examine spec of the top-level item first
- spec_ = isc.config.find_spec_part(
- spec, '%s' % identifier.split('/')[0])
- if spec_['item_type'] == 'named_set' and \
- spec_['named_set_item_spec']['item_type'] == 'map':
- map_spec = spec_['named_set_item_spec']['map_item_spec']
- for name in isc.config.spec_name_list(map_spec):
- spec_ = isc.config.find_spec_part(map_spec, name)
- id_str = '%s/%s/%s' % \
- tuple(identifier.split('/')[0:2] + [name])
- isc.cc.data.set(element, id_str, spec_['item_default'])
- else:
- spec_ = isc.config.find_spec_part(spec, identifier)
- isc.cc.data.set(element, identifier, spec_['item_default'])
- return isc.cc.data.find(element, identifier)
-
-def _set_counter(element, spec, identifier, value):
- """Invokes _add_counter() for checking whether the identifier is
- in the element. If not, it creates a new identifier in the element
- and set the default value from the spec. After that, it sets the
- value specified in the arguments."""
- _add_counter(element, spec, identifier)
- isc.cc.data.set(element, identifier, value)
-
-def _get_counter(element, identifier):
- """Returns the value of the identifier in the element"""
- return isc.cc.data.find(element, identifier)
-
-def _inc_counter(element, spec, identifier, step=1):
- """Increments the value of the identifier in the element to the
- step from the current value. If the identifier isn't in the
- element, it creates a new identifier in the element."""
- isc.cc.data.set(element, identifier,
- _add_counter(element, spec, identifier) + step)
-
-def _start_timer():
- """Returns the current datetime as a datetime object."""
- return datetime.now()
-
-def _stop_timer(start_time, element, spec, identifier):
- """Sets duration time in seconds as a value of the identifier in
- the element, which is in seconds between start_time and the
- current time and is float-type."""
- delta = datetime.now() - start_time
- sec = round(delta.days * 86400 + delta.seconds + \
- delta.microseconds * 1E-6, 6)
- _set_counter(element, spec, identifier, sec)
-
-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():
- """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
- counters is assumed to be like this:
-
- zones/example.com./notifyoutv4
- zones/example.com./notifyoutv6
- zones/example.com./xfrrej
- zones/example.com./xfrreqdone
- zones/example.com./soaoutv4
- zones/example.com./soaoutv6
- zones/example.com./axfrreqv4
- zones/example.com./axfrreqv6
- zones/example.com./ixfrreqv4
- zones/example.com./ixfrreqv6
- zones/example.com./xfrsuccess
- zones/example.com./xfrfail
- zones/example.com./time_to_ixfr
- zones/example.com./time_to_axfr
- ixfr_running
- axfr_running
- socket/unixdomain/open
- socket/unixdomain/openfail
- socket/unixdomain/close
- socket/unixdomain/bindfail
- socket/unixdomain/acceptfail
- socket/unixdomain/accept
- socket/unixdomain/senderr
- socket/unixdomain/recverr
- socket/ipv4/tcp/open
- socket/ipv4/tcp/openfail
- socket/ipv4/tcp/close
- socket/ipv4/tcp/connfail
- socket/ipv4/tcp/conn
- socket/ipv4/tcp/senderr
- socket/ipv4/tcp/recverr
- socket/ipv6/tcp/open
- socket/ipv6/tcp/openfail
- socket/ipv6/tcp/close
- socket/ipv6/tcp/connfail
- socket/ipv6/tcp/conn
- socket/ipv6/tcp/senderr
- socket/ipv6/tcp/recverr
- """
-
- # '_SERVER_' is a special zone name representing an entire
- # count. It doesn't mean a specific zone, but it means an
- # entire count in the server.
- _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=None):
- self._zones_item_list = []
- self._start_time = {}
- self._disabled = False
- self._rlock = threading.RLock()
- 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):
- self._zones_item_list = isc.config.spec_name_list(
- isc.config.find_spec_part(
- self._statistics._spec, self._perzone_prefix)\
- ['named_set_item_spec']['map_item_spec'])
-
- def clear_counters(self):
- """clears all statistics data"""
- with self._rlock:
- self._statistics._data = {}
-
- def disable(self):
- """disables incrementing/decrementing counters"""
- self._disabled = True
-
- def enable(self):
- """enables incrementing/decrementing counters"""
- self._disabled = False
-
- 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,
- 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 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 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 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. 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(
- 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]]
-
- def dump_statistics(self):
- """Calculates an entire server counts, and returns statistics
- data format to send out the stats module including each
- counter. If there is no counts, then it returns an empty
- dictionary."""
- # entire 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,
- self._perzone_prefix)
- zones_attrs = zones_spec['item_default'][self._entire_server]
- zones_data = {}
- for attr in zones_attrs:
- id_str = '%s/%s' % (self._entire_server, attr)
- sum_ = 0
- for name in zones:
- if attr in zones[name]:
- sum_ += zones[name][attr]
- if sum_ > 0:
- _set_counter(zones_data, zones_spec,
- id_str, sum_)
- # insert entire-sever counts
- statistics_data[self._perzone_prefix] = dict(
- statistics_data[self._perzone_prefix],
- **zones_data)
- return statistics_data
-
diff --git a/src/lib/python/isc/statistics/counters.py b/src/lib/python/isc/statistics/counters.py
new file mode 100644
index 0000000..8da0b1e
--- /dev/null
+++ b/src/lib/python/isc/statistics/counters.py
@@ -0,0 +1,399 @@
+# Copyright (C) 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
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""BIND 10 statistics counters module
+
+This module handles the statistics counters for BIND 10 modules. For
+using the module `counter.py`, first a counters object should be created
+in each module (like b10-xfrin or b10-xfrout) after importing this
+module. A spec file can be specified as an argument when creating the
+counters object:
+
+ from isc.statistics import Counters
+ self.counters = Counters("/path/to/foo.spec")
+
+The first argument of Counters() can be specified, which is the location
+of the specification file (like src/bin/xfrout/xfrout.spec). If Counters
+is constructed this way, 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 are
+callable. Since these methods require the string of the zone name in the
+first argument, if we have the following code in b10-xfrout:
+
+ self.counters.inc('zones', zone_name, 'xfrreqdone')
+
+then the counter for xfrreqdone corresponding to zone_name is
+incremented. For getting the current number of this counter, we can use
+the following code:
+
+ number = self.counters.get('zones', zone_name, 'xfrreqdone')
+
+then the current count is obtained and set in the variable
+`number`. Such a getter method would be mainly used for unit-testing.
+As other example, for the item `axfr_running`, the decrementer method is
+also callable. This method is used for decrementing a counter. For the
+item `axfr_running`, an argument like zone name is not required:
+
+ self.counters.dec('axfr_running')
+
+These methods are effective in other modules. For example, in case that
+this module `counter.py` is once imported in a main module such as
+b10-xfrout, then for the item `notifyoutv4`, the `inc()` method can be
+invoked in another module such as notify_out.py, which is firstly
+imported in the main module.
+
+ self.counters.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 another
+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`.
+"""
+
+import threading
+import isc.config
+from datetime import datetime
+
+# static internal functions
+def _add_counter(element, spec, identifier):
+ """Returns value of the identifier if the identifier is in the
+ element. Otherwise, sets a default value from the spec and
+ returns it. If the top-level type of the identifier is named_set
+ and the second-level type is map, it sets a set of default values
+ under the level and then returns the default value of the
+ identifier. This method raises DataNotFoundError if the element is
+ invalid for spec."""
+ try:
+ return isc.cc.data.find(element, identifier)
+ except isc.cc.data.DataNotFoundError:
+ pass
+ # check whether spec and identifier are correct
+ isc.config.find_spec_part(spec, identifier)
+ # examine spec of the top-level item first
+ spec_ = isc.config.find_spec_part(spec, identifier.split('/')[0])
+ if spec_['item_type'] == 'named_set' and \
+ spec_['named_set_item_spec']['item_type'] == 'map':
+ map_spec = spec_['named_set_item_spec']['map_item_spec']
+ for name in isc.config.spec_name_list(map_spec):
+ spec_ = isc.config.find_spec_part(map_spec, name)
+ id_str = '%s/%s/%s' % \
+ tuple(identifier.split('/')[0:2] + [name])
+ isc.cc.data.set(element, id_str, spec_['item_default'])
+ else:
+ spec_ = isc.config.find_spec_part(spec, identifier)
+ isc.cc.data.set(element, identifier, spec_['item_default'])
+ return isc.cc.data.find(element, identifier)
+
+def _set_counter(element, spec, identifier, value):
+ """Invokes _add_counter() for checking whether the identifier is
+ in the element. If not, it creates a new identifier in the element
+ and set the default value from the spec. After that, it sets the
+ value specified in the arguments."""
+ _add_counter(element, spec, identifier)
+ isc.cc.data.set(element, identifier, value)
+
+def _get_counter(element, identifier):
+ """Returns the value of the identifier in the element"""
+ return isc.cc.data.find(element, identifier)
+
+def _inc_counter(element, spec, identifier, step=1):
+ """Increments the value of the identifier in the element to the
+ step from the current value. If the identifier isn't in the
+ element, it creates a new identifier in the element."""
+ isc.cc.data.set(element, identifier,
+ _add_counter(element, spec, identifier) + step)
+
+def _start_timer():
+ """Returns the current datetime as a datetime object."""
+ return datetime.now()
+
+def _stop_timer(start_time, element, spec, identifier):
+ """Sets duration time in seconds as a value of the identifier in
+ the element, which is in seconds between start_time and the
+ current time and is float-type."""
+ delta = datetime.now() - start_time
+ sec = round(delta.days * 86400 + delta.seconds + \
+ delta.microseconds * 1E-6, 6)
+ _set_counter(element, spec, identifier, sec)
+
+def _concat(*args, sep='/'):
+ """A helper function that is used to generate an identifier for
+ statistics item names. It concatenates words in args with a
+ separator('/')
+ """
+ return sep.join(args)
+
+class _Statistics():
+ """Statistics data set"""
+ # default statistics data
+ _data = {}
+ # default statistics spec used in case the specfile is omitted when
+ # constructing a Counters() object
+ _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 Counters():
+ """A class for holding and manipulating all statistics counters
+ for a module. A Counters object may be created by specifying a spec
+ file of the module in argument. According to statistics
+ specification in the spec file, a counter value can be incremented,
+ decremented or obtained. Methods such as inc(), dec() and get() are
+ useful for this. Counters objects also have timer functionality.
+ The timer can be started and stopped, and the duration between
+ start and stop can be obtained. Methods such as start_timer(),
+ stop_timer() and get() are useful for this. Saved counters can be
+ cleared by the method clear_all(). Manipulating counters and
+ timers can be temporarily disabled. If disabled, counter values are
+ not changed even if methods to update them are invoked. Including
+ per-zone counters, a list of counters which can be handled in the
+ class are like the following:
+
+ zones/example.com./notifyoutv4
+ zones/example.com./notifyoutv6
+ zones/example.com./xfrrej
+ zones/example.com./xfrreqdone
+ zones/example.com./soaoutv4
+ zones/example.com./soaoutv6
+ zones/example.com./axfrreqv4
+ zones/example.com./axfrreqv6
+ zones/example.com./ixfrreqv4
+ zones/example.com./ixfrreqv6
+ zones/example.com./xfrsuccess
+ zones/example.com./xfrfail
+ zones/example.com./time_to_ixfr
+ zones/example.com./time_to_axfr
+ ixfr_running
+ axfr_running
+ socket/unixdomain/open
+ socket/unixdomain/openfail
+ socket/unixdomain/close
+ socket/unixdomain/bindfail
+ socket/unixdomain/acceptfail
+ socket/unixdomain/accept
+ socket/unixdomain/senderr
+ socket/unixdomain/recverr
+ socket/ipv4/tcp/open
+ socket/ipv4/tcp/openfail
+ socket/ipv4/tcp/close
+ socket/ipv4/tcp/connfail
+ socket/ipv4/tcp/conn
+ socket/ipv4/tcp/senderr
+ socket/ipv4/tcp/recverr
+ socket/ipv6/tcp/open
+ socket/ipv6/tcp/openfail
+ socket/ipv6/tcp/close
+ socket/ipv6/tcp/connfail
+ socket/ipv6/tcp/conn
+ socket/ipv6/tcp/senderr
+ socket/ipv6/tcp/recverr
+ """
+
+ # '_SERVER_' is a special zone name representing an entire
+ # count. It doesn't mean a specific zone, but it means an
+ # entire count in the server.
+ _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=None):
+ """A constructor for the Counters class. A path to the spec file
+ can be specified in spec_file_name. Statistics data based on
+ statistics spec can be accumulated if spec_file_name is
+ specified. If omitted, a default statistics spec is used. The
+ default statistics spec is defined in a hidden class named
+ _Statistics().
+ """
+ self._zones_item_list = []
+ self._start_time = {}
+ self._disabled = False
+ self._rlock = threading.RLock()
+ 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):
+ self._zones_item_list = isc.config.spec_name_list(
+ isc.config.find_spec_part(
+ self._statistics._spec, self._perzone_prefix)\
+ ['named_set_item_spec']['map_item_spec'])
+
+ def clear_all(self):
+ """clears all statistics data"""
+ with self._rlock:
+ self._statistics._data = {}
+
+ def disable(self):
+ """disables incrementing/decrementing counters"""
+ with self._rlock:
+ self._disabled = True
+
+ def enable(self):
+ """enables incrementing/decrementing counters"""
+ with self._rlock:
+ self._disabled = False
+
+ def _incdec(self, *args, step=1):
+ """A common helper function for incrementing or decrementing a
+ counter. It acquires a lock to support multi-threaded
+ use. isc.cc.data.DataNotFoundError is raised when incrementing
+ the counter of the item undefined in the spec file."""
+ identifier = _concat(*args)
+ with self._rlock:
+ if self._disabled: return
+ _inc_counter(self._statistics._data,
+ self._statistics._spec,
+ identifier, step)
+
+ def inc(self, *args):
+ """An incrementer for a counter. It acquires a lock to support
+ multi-threaded use. isc.cc.data.DataNotFoundError is raised when
+ incrementing the counter of the item undefined in the spec file."""
+ return self._incdec(*args)
+
+ def dec(self, *args):
+ """A decrementer for a counter. It acquires a lock to support
+ multi-threaded use. isc.cc.data.DataNotFoundError is raised when
+ decrementing the counter of the item undefined in the spec file."""
+ return self._incdec(*args, step=-1)
+
+ 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 = _concat(*args)
+ return _get_counter(self._statistics._data, identifier)
+
+ def start_timer(self, *args):
+ """Starts a timer which is identified by args and keeps it
+ running until stop_timer() is called. It acquires a lock to
+ support multi-threaded use."""
+ identifier = _concat(*args)
+ with self._rlock:
+ if self._disabled: return
+ isc.cc.data.set(self._start_time, identifier, _start_timer())
+
+ def stop_timer(self, *args):
+ """Stops a timer which is identified by args. It acquires a lock
+ to support multi-threaded use. If the timer isn't started by
+ start_timer() yet, it raises no exception. However if args
+ aren't defined in the spec file, it raises DataNotFoundError.
+ """
+ identifier = _concat(*args)
+ with self._rlock:
+ if self._disabled: return
+ 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
+ return
+ # set the end time
+ _stop_timer(
+ start_time,
+ self._statistics._data,
+ self._statistics._spec,
+ identifier)
+ # A datetime value of once used timer should be deleted
+ # for a future use.
+ # Here, names of branch and leaf are obtained from a
+ # string of identifier. The branch name is equivalent to
+ # the position of datetime to be deleted and the leaf name
+ # is equivalent to the value of datetime to be deleted.
+ (branch, leaf) = identifier.rsplit('/', 1)
+ # Then map of branch is obtained from self._start_time by
+ # using isc.cc.data.find().
+ branch_map = isc.cc.data.find(self._start_time, branch)
+ # Finally a value of the leaf name is deleted from the
+ # map.
+ del branch_map[leaf]
+
+ def get_statistics(self):
+ """Calculates an entire server's counts, and returns statistics
+ data in a format to send out to the stats module, including each
+ counter. If nothing is counted yet, then it returns an empty
+ dictionary."""
+ # entire copy
+ statistics_data = self._statistics._data.copy()
+ # If there is no 'zones' found in statistics_data,
+ # i.e. statistics_data contains no per-zone counter, it just
+ # returns statistics_data because calculating total counts
+ # across the zone names isn't necessary.
+ 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,
+ self._perzone_prefix)
+ zones_attrs = zones_spec['item_default'][self._entire_server]
+ zones_data = {}
+ for attr in zones_attrs:
+ id_str = '%s/%s' % (self._entire_server, attr)
+ sum_ = 0
+ for name in zones:
+ if attr in zones[name]:
+ sum_ += zones[name][attr]
+ if sum_ > 0:
+ _set_counter(zones_data, zones_spec,
+ id_str, sum_)
+ # insert entire-server counts
+ statistics_data[self._perzone_prefix] = dict(
+ statistics_data[self._perzone_prefix],
+ **zones_data)
+ return statistics_data
diff --git a/src/lib/python/isc/statistics/tests/Makefile.am b/src/lib/python/isc/statistics/tests/Makefile.am
index 7e2252b..8dcc296 100644
--- a/src/lib/python/isc/statistics/tests/Makefile.am
+++ b/src/lib/python/isc/statistics/tests/Makefile.am
@@ -1,5 +1,5 @@
PYCOVERAGE_RUN=@PYCOVERAGE_RUN@
-PYTESTS = counter_test.py
+PYTESTS = counters_test.py
EXTRA_DIST = $(PYTESTS)
EXTRA_DIST += testdata/test_spec1.spec
EXTRA_DIST += testdata/test_spec2.spec
diff --git a/src/lib/python/isc/statistics/tests/counter_test.py b/src/lib/python/isc/statistics/tests/counter_test.py
deleted file mode 100644
index 090188a..0000000
--- a/src/lib/python/isc/statistics/tests/counter_test.py
+++ /dev/null
@@ -1,301 +0,0 @@
-# Copyright (C) 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
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
-# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
-# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
-# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-'''Tests for isc.statistics.counter'''
-
-import unittest
-import threading
-from datetime import timedelta
-import os
-import imp
-import isc.config
-
-TEST_ZONE_NAME_STR = "example.com."
-TESTDATA_SRCDIR = os.getenv("TESTDATASRCDIR")
-
-from isc.statistics import counter
-
-def setup_functor(event, cycle, functor, *args):
- """Waits until the event is started, and then invokes the functor
- by times of the cycle with args."""
- event.wait()
- for i in range(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(concurrency):
- threads.append(threading.Thread(\
- target=setup_functor, \
- args=(event, number, functor,) + args))
- for th in threads: th.start()
- event.set()
- for th in threads: th.join()
-
-class TestBasicMethods(unittest.TestCase):
- TEST_SPECFILE_LOCATION = TESTDATA_SRCDIR + os.sep + 'test_spec1.spec'
-
- def setUp(self):
- self.counter = counter.Counter(self.TEST_SPECFILE_LOCATION)
-
- def tearDown(self):
- self.counter.clear_counters()
-
- def test_clear_counters(self):
- 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.assertRaises(isc.cc.data.DataNotFoundError,
- self.counter.get, 'counter')
-
- def test_enablediable(self):
- self.assertFalse(self.counter._disabled)
- self.counter.disable()
- self.assertTrue(self.counter._disabled)
- self.counter.enable()
- self.assertFalse(self.counter._disabled)
-
- def test_add_counter_normal(self):
- element = {'counter' : 1}
- self.assertEqual(\
- counter._add_counter(element, [], 'counter'), 1)
-
- def test_add_counter_wrongspec(self):
- self.assertRaises(isc.cc.data.DataNotFoundError,
- counter._add_counter,
- {}, [], 'counter')
-
- def test_add_counter_empty(self):
- self.assertEqual(\
- counter._add_counter(
- {},
- [ { 'item_name' : 'counter',
- 'item_type' : 'integer',
- 'item_default' : 0 } ],
- 'counter'), 0)
-
- def test_add_counter_empty_namedset(self):
- elem = {}
- spec = [ { 'item_name': 'dirs',
- 'item_type': 'named_set',
- 'named_set_item_spec': {
- 'item_name': 'dir',
- 'item_type': 'map',
- 'map_item_spec': [
- { 'item_name': 'counter1',
- 'item_type': 'integer',
- 'item_default': 0 },
- { 'item_name': 'counter2',
- 'item_type': 'integer',
- 'item_default': 0 } ]}
- }]
- self.assertEqual(\
- counter._add_counter(elem, spec, 'dirs/foo/counter1'), 0)
- self.assertEqual(\
- counter._add_counter(elem, spec, 'dirs/bar/counter2'), 0)
-
- def test_timer(self):
- t1 = counter._start_timer()
- t2 = t1 - timedelta(seconds=1)
- self.assertEqual((t1 - t2).seconds, 1)
- elem = {}
- spec = [{ 'item_name': 'time',
- 'item_type': 'real',
- 'item_default': 0.0 }]
- counter._stop_timer(t2, elem, spec, 'time')
- self.assertGreater(counter._get_counter(elem,'time'), 1)
-
- def test_rasing_incrementers(self):
- """ use Thread"""
- concurrency = 3 # number of the threads
- number = 10000 # number of counting per thread
- counter_name = "counter"
- timer_name = "seconds"
- start_time = counter._start_timer()
- start_functor(concurrency, number, self.counter.inc,
- counter_name)
- counter._stop_timer(start_time,
- self.counter._statistics._data,
- self.counter._statistics._spec,
- timer_name)
- self.assertEqual(
- counter._get_counter(self.counter._statistics._data,
- counter_name),
- concurrency * number)
- self.assertGreater(
- counter._get_counter(self.counter._statistics._data,
- timer_name), 0)
-
-class BaseTestCounter():
-
- def setUp(self):
- 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
-
- def tearDown(self):
- self.counter.clear_counters()
-
- def check_dump_statistics(self):
- """Checks no differences between the value returned from
- dump_statistics() and locally collected statistics data. Also
- checks the result isn't changed even after the method is
- invoked twice. Finally checks it is valid for the the
- statistics spec."""
- self.assertEqual(self.counter.dump_statistics(),
- self._statistics_data)
- # Idempotency check
- self.assertEqual(self.counter.dump_statistics(),
- 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_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()
- self.counter.inc(*args)
- self.assertEqual(self.counter.get(*args), 0)
- self.counter.enable()
- 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_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()
- 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)
- isc.cc.data.set(
- 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'
- def setUp(self):
- BaseTestCounter.setUp(self)
- def tearDown(self):
- BaseTestCounter.tearDown(self)
-
-class TestCounter2(unittest.TestCase, BaseTestCounter):
- TEST_SPECFILE_LOCATION = TESTDATA_SRCDIR + os.sep + 'test_spec2.spec'
- def setUp(self):
- BaseTestCounter.setUp(self)
- def tearDown(self):
- BaseTestCounter.tearDown(self)
-
-class TestCounter3(unittest.TestCase, BaseTestCounter):
- TEST_SPECFILE_LOCATION = TESTDATA_SRCDIR + os.sep + 'test_spec3.spec'
- def setUp(self):
- BaseTestCounter.setUp(self)
- def tearDown(self):
- BaseTestCounter.tearDown(self)
-
-if __name__== "__main__":
- unittest.main()
diff --git a/src/lib/python/isc/statistics/tests/counters_test.py b/src/lib/python/isc/statistics/tests/counters_test.py
new file mode 100644
index 0000000..ff15efc
--- /dev/null
+++ b/src/lib/python/isc/statistics/tests/counters_test.py
@@ -0,0 +1,416 @@
+# Copyright (C) 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
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+'''Tests for isc.statistics.counter'''
+
+import unittest
+import threading
+from datetime import timedelta
+import os
+import imp
+import isc.config
+
+TEST_ZONE_NAME_STR = "example.com."
+TESTDATA_SRCDIR = os.getenv("TESTDATASRCDIR")
+
+from isc.statistics import counters
+
+def setup_functor(event, cycle, functor, *args):
+ """Waits until the event is started, and then invokes the functor
+ by times of the cycle with args."""
+ event.wait()
+ for i in range(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(concurrency):
+ threads.append(threading.Thread(\
+ target=setup_functor, \
+ args=(event, number, functor,) + args))
+ for th in threads: th.start()
+ event.set()
+ for th in threads: th.join()
+
+class TestBasicMethods(unittest.TestCase):
+ TEST_SPECFILE_LOCATION = TESTDATA_SRCDIR + os.sep + 'test_spec1.spec'
+
+ def setUp(self):
+ imp.reload(counters)
+ self.counters = counters.Counters(self.TEST_SPECFILE_LOCATION)
+
+ def tearDown(self):
+ self.counters.clear_all()
+
+ def test_clear_counters(self):
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self.counters.get, 'counter')
+ self.counters.inc('counter')
+ self.assertEqual(self.counters.get('counter'), 1)
+ self.counters.clear_all()
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self.counters.get, 'counter')
+
+ def test_enablediable(self):
+ self.assertFalse(self.counters._disabled)
+ self.counters.disable()
+ self.assertTrue(self.counters._disabled)
+ self.counters.enable()
+ self.assertFalse(self.counters._disabled)
+
+ def test_add_counter_normal(self):
+ element = {'counter' : 1}
+ self.assertEqual(\
+ counters._add_counter(element, [], 'counter'), 1)
+
+ def test_add_counter_wrongspec(self):
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ counters._add_counter,
+ {}, [], 'counter')
+
+ def test_add_counter_empty(self):
+ self.assertEqual(\
+ counters._add_counter(
+ {},
+ [ { 'item_name' : 'counter',
+ 'item_type' : 'integer',
+ 'item_default' : 0 } ],
+ 'counter'), 0)
+
+ def test_add_counter_empty_namedset(self):
+ elem = {}
+ spec = [ { 'item_name': 'dirs',
+ 'item_type': 'named_set',
+ 'named_set_item_spec': {
+ 'item_name': 'dir',
+ 'item_type': 'map',
+ 'map_item_spec': [
+ { 'item_name': 'counter1',
+ 'item_type': 'integer',
+ 'item_default': 0 },
+ { 'item_name': 'counter2',
+ 'item_type': 'integer',
+ 'item_default': 0 } ]}
+ }]
+ self.assertEqual(\
+ counters._add_counter(elem, spec, 'dirs/foo/counter1'), 0)
+ self.assertEqual(\
+ counters._add_counter(elem, spec, 'dirs/bar/counter2'), 0)
+
+ def test_timer(self):
+ t1 = counters._start_timer()
+ t2 = t1 - timedelta(seconds=1)
+ self.assertEqual((t1 - t2).seconds, 1)
+ elem = {}
+ spec = [{ 'item_name': 'time',
+ 'item_type': 'real',
+ 'item_default': 0.0 }]
+ counters._stop_timer(t2, elem, spec, 'time')
+ self.assertGreater(counters._get_counter(elem,'time'), 1)
+
+ def test_rasing_incrementers(self):
+ """ use Thread"""
+ concurrency = 3 # number of the threads
+ number = 10000 # number of counting per thread
+ counter_name = "counter"
+ timer_name = "seconds"
+ start_time = counters._start_timer()
+ start_functor(concurrency, number, self.counters.inc,
+ counter_name)
+ counters._stop_timer(start_time,
+ self.counters._statistics._data,
+ self.counters._statistics._spec,
+ timer_name)
+ self.assertEqual(
+ counters._get_counter(self.counters._statistics._data,
+ counter_name),
+ concurrency * number)
+ self.assertGreater(
+ counters._get_counter(self.counters._statistics._data,
+ timer_name), 0)
+
+ def test_concat(self):
+ # only strings
+ a = ( 'a','b','c','d' )
+ self.assertEqual('a/b/c/d', counters._concat(*a))
+ self.assertEqual('aTbTcTd', counters._concat(*a, sep='T'))
+ self.assertEqual('a\\b\\c\\d', counters._concat(*a, sep='\\'))
+ # mixed with other types
+ b = a + (1,)
+ self.assertRaises(TypeError, counters._concat, *b)
+ b = a + (1.1,)
+ self.assertRaises(TypeError, counters._concat, *b)
+ b = a + ([],)
+ self.assertRaises(TypeError, counters._concat, *b)
+ b = a + ({},)
+ self.assertRaises(TypeError, counters._concat, *b)
+
+class BaseTestCounters():
+
+ def setUp(self):
+ imp.reload(counters)
+ self._statistics_data = {}
+ self.counters = counters.Counters(self.TEST_SPECFILE_LOCATION)
+ self._entire_server = self.counters._entire_server
+ self._perzone_prefix = self.counters._perzone_prefix
+
+ def tearDown(self):
+ self.counters.clear_all()
+
+ def check_get_statistics(self):
+ """Checks no differences between the value returned from
+ get_statistics() and locally collected statistics data. Also
+ checks the result isn't changed even after the method is
+ invoked twice. Finally checks it is valid for the the
+ statistics spec."""
+ self.assertEqual(self.counters.get_statistics(),
+ self._statistics_data)
+ # Idempotency check
+ self.assertEqual(self.counters.get_statistics(),
+ 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.counters._statistics._spec}
+ ).validate_statistics(
+ False, self._statistics_data))
+
+ def test_perzone_counters(self):
+ # for per-zone counters
+ for name in self.counters._zones_item_list:
+ args = (self._perzone_prefix, TEST_ZONE_NAME_STR, name)
+ if name.find('time_to_') == 0:
+ self.counters.start_timer(*args)
+ self.counters.stop_timer(*args)
+ self.assertGreater(self.counters.get(*args), 0)
+ sec = self.counters.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.counters.stop_timer(*args)
+ self.assertEqual(self.counters.get(*args), sec)
+ else:
+ self.counters.inc(*args)
+ self.assertEqual(self.counters.get(*args), 1)
+ # checks disable/enable
+ self.counters.disable()
+ self.counters.inc(*args)
+ self.assertEqual(self.counters.get(*args), 1)
+ self.counters.enable()
+ self.counters.inc(*args)
+ self.assertEqual(self.counters.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_get_statistics()
+
+ def test_xfrrunning_counters(self):
+ # for counters of xfer running
+ _suffix = 'xfr_running'
+ _xfrrunning_names = \
+ isc.config.spec_name_list(self.counters._statistics._spec,
+ "", True)
+ for name in _xfrrunning_names:
+ if name.find(_suffix) != 1: continue
+ args = name.split('/')
+ self.counters.inc(*args)
+ self.assertEqual(self.counters.get(*args), 1)
+ self.counters.dec(*args)
+ self.assertEqual(self.counters.get(*args), 0)
+ # checks disable/enable
+ self.counters.disable()
+ self.counters.inc(*args)
+ self.assertEqual(self.counters.get(*args), 0)
+ self.counters.enable()
+ self.counters.inc(*args)
+ self.assertEqual(self.counters.get(*args), 1)
+ self.counters.disable()
+ self.counters.dec(*args)
+ self.assertEqual(self.counters.get(*args), 1)
+ self.counters.enable()
+ self.counters.dec(*args)
+ self.assertEqual(self.counters.get(*args), 0)
+ self._statistics_data[name] = 0
+ self.check_get_statistics()
+
+ def test_socket_counters(self):
+ # for ipsocket/unixsocket counters
+ _prefix = 'socket/'
+ _socket_names = \
+ isc.config.spec_name_list(self.counters._statistics._spec,
+ "", True)
+ for name in _socket_names:
+ if name.find(_prefix) != 0: continue
+ args = name.split('/')
+ self.counters.inc(*args)
+ self.assertEqual(self.counters.get(*args), 1)
+ # checks disable/enable
+ self.counters.disable()
+ self.counters.inc(*args)
+ self.assertEqual(self.counters.get(*args), 1)
+ self.counters.enable()
+ self.counters.inc(*args)
+ self.assertEqual(self.counters.get(*args), 2)
+ isc.cc.data.set(
+ self._statistics_data, '/'.join(args), 2)
+ self.check_get_statistics()
+
+ def test_undefined_item(self):
+ # test DataNotFoundError raising when specifying item defined
+ # in the specfile
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self.counters.inc, '__undefined__')
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self.counters.dec, '__undefined__')
+ self.counters.start_timer('__undefined__')
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self.counters.stop_timer, '__undefined__')
+ self.assertRaises(isc.cc.data.DataNotFoundError,
+ self.counters.get, '__undefined__')
+
+class TestCounters0(unittest.TestCase, BaseTestCounters):
+ TEST_SPECFILE_LOCATION = None
+ def setUp(self):
+ BaseTestCounters.setUp(self)
+ def tearDown(self):
+ BaseTestCounters.tearDown(self)
+
+class TestCounters1(unittest.TestCase, BaseTestCounters):
+ TEST_SPECFILE_LOCATION = TESTDATA_SRCDIR + os.sep + 'test_spec1.spec'
+ def setUp(self):
+ BaseTestCounters.setUp(self)
+ def tearDown(self):
+ BaseTestCounters.tearDown(self)
+
+class TestCounters2(unittest.TestCase, BaseTestCounters):
+ TEST_SPECFILE_LOCATION = TESTDATA_SRCDIR + os.sep + 'test_spec2.spec'
+ def setUp(self):
+ BaseTestCounters.setUp(self)
+ def tearDown(self):
+ BaseTestCounters.tearDown(self)
+
+class TestCounters3(unittest.TestCase, BaseTestCounters):
+ TEST_SPECFILE_LOCATION = TESTDATA_SRCDIR + os.sep + 'test_spec3.spec'
+ @classmethod
+ def setUpClass(cls):
+ imp.reload(counters)
+ def setUp(self):
+ BaseTestCounters.setUp(self)
+ def tearDown(self):
+ BaseTestCounters.tearDown(self)
+
+class BaseDummyModule():
+ """A base dummy class"""
+ TEST_SPECFILE_LOCATION = TESTDATA_SRCDIR + os.sep + 'test_spec2.spec'
+ def __init__(self):
+ self.counters = counters.Counters(self.TEST_SPECFILE_LOCATION)
+
+ def get_counters(self):
+ return self.counters.get_statistics()
+
+ def clear_counters(self):
+ self.counters.clear_all()
+
+class DummyNotifyOut(BaseDummyModule):
+ """A dummy class equivalent to notify.notify_out.NotifyOut"""
+ def __init__(self):
+ self.counters = counters.Counters()
+
+ def inc_counters(self):
+ """increments counters"""
+ self.counters.inc('zones', TEST_ZONE_NAME_STR, 'notifyoutv4')
+ self.counters.inc('zones', TEST_ZONE_NAME_STR, 'notifyoutv6')
+
+class DummyXfroutSession(BaseDummyModule):
+ """A dummy class equivalent to XfroutSession in b10-xfrout"""
+ def inc_counters(self):
+ """increments counters"""
+ self.counters.inc('zones', TEST_ZONE_NAME_STR, 'xfrreqdone')
+ self.counters.inc('zones', TEST_ZONE_NAME_STR, 'xfrrej')
+ self.counters.inc('axfr_running')
+ self.counters.inc('ixfr_running')
+ self.counters.dec('axfr_running')
+ self.counters.dec('ixfr_running')
+
+class DummyUnixSockServer(BaseDummyModule):
+ """A dummy class equivalent to UnixSockServer in b10-xfrout"""
+ def inc_counters(self):
+ """increments counters"""
+ self.counters.inc('socket', 'unixdomain', 'open')
+ self.counters.inc('socket', 'unixdomain', 'close')
+
+class DummyXfroutServer(BaseDummyModule):
+ """A dummy class equivalent to XfroutServer in b10-xfrout"""
+ def __init__(self):
+ super().__init__()
+ self.xfrout_sess = DummyXfroutSession()
+ self.unix_socket_server = DummyUnixSockServer()
+ self.notifier = DummyNotifyOut()
+
+ def inc_counters(self):
+ self.xfrout_sess.inc_counters()
+ self.unix_socket_server.inc_counters()
+ self.notifier.inc_counters()
+
+class TestDummyNotifyOut(unittest.TestCase):
+ """Tests counters are incremented in which the spec file is not
+ loaded"""
+ def setUp(self):
+ imp.reload(counters)
+ self.notifier = DummyNotifyOut()
+ self.notifier.inc_counters()
+
+ def tearDown(self):
+ self.notifier.clear_counters()
+
+ def test_counters(self):
+ self.assertEqual(
+ {'zones': {'_SERVER_': {'notifyoutv4': 1, 'notifyoutv6': 1},
+ TEST_ZONE_NAME_STR: {'notifyoutv4': 1, 'notifyoutv6': 1}}},
+ self.notifier.get_counters())
+
+class TestDummyXfroutServer(unittest.TestCase):
+ """Tests counters are incremented or decremented in which the same
+ spec file is multiply loaded in each child class"""
+ def setUp(self):
+ imp.reload(counters)
+ self.xfrout_server = DummyXfroutServer()
+ self.xfrout_server.inc_counters()
+
+ def tearDown(self):
+ self.xfrout_server.clear_counters()
+
+ def test_counters(self):
+ self.assertEqual(
+ {'axfr_running': 0, 'ixfr_running': 0,
+ 'socket': {'unixdomain': {'open': 1, 'close': 1}},
+ 'zones': {'_SERVER_': {'notifyoutv4': 1,
+ 'notifyoutv6': 1,
+ 'xfrrej': 1, 'xfrreqdone': 1},
+ TEST_ZONE_NAME_STR: {'notifyoutv4': 1,
+ 'notifyoutv6': 1,
+ 'xfrrej': 1,
+ 'xfrreqdone': 1}}},
+ self.xfrout_server.get_counters())
+
+if __name__== "__main__":
+ unittest.main()
More information about the bind10-changes
mailing list