BIND 10 trac2225_statistics, updated. 0c8094b0e3e9ecae8fe44cb889b959ed467bac8b [2225_statistics] change the variable names

BIND 10 source code commits bind10-changes at lists.isc.org
Fri Dec 7 02:32:45 UTC 2012


The branch, trac2225_statistics has been updated
       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)
      from  ad4eae2bc3410084b4ea07dd96118c7c1da17a25 (commit)

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

- Log -----------------------------------------------------------------
commit 0c8094b0e3e9ecae8fe44cb889b959ed467bac8b
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 13:02:12 2012 +0900

    [2225_statistics] change the variable names
    
    `number` to `concurrency` and `cycle` to `number`

commit cf41749b421bd09330ca5cbec3e3e9a3cdae06d7
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 12:55:43 2012 +0900

    [2225_statistics] correct the variable names from the counter object

commit 02e63b13f8e523d913de3a516c442677dc15e4c6
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 12:54:22 2012 +0900

    [2225_statistics] remove the unnecessary parameters

commit 1e45b7161d9405b25072a4b6e979a18fa26981ce
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 12:53:00 2012 +0900

    [2225_statistics] manipulate the counter via incrementer and getter methods

commit e78b80b2a929ab815dee2d4ff6c7e29315a5f2f7
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 12:38:51 2012 +0900

    [2225_statistics] add checking validation of statistics data in case of no TEST_SPECFILE_LOCATION

commit 966b5ee5cf9512da8f4a4ea31f7f67ca3836df26
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 12:37:01 2012 +0900

    [2225_statistics] add a new test case TestCounter0() in case of no TEST_SPECFILE_LOCATION

commit b95523d5350585a707693d680152903ede08bb0a
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 16:42:35 2012 +0900

    [2225_statistics] add the new test methods according to the new interface:
    
    test_perzone_counters()
    test_xfrrunning_counters()
    test_socket_counters()
    test_unknown_item()

commit 58771328093e3bb51463437cae9555da0ed945cc
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 12:27:24 2012 +0900

    [2225_statistics] remove the obsolete test methods:
    
    test_perzone_counters()
    test_xfrrunning_counters()
    test_unixsocket_counters()
    test_perzone_timers()
    test_ipsocket_counters()

commit 17e0f403185b1e0136cf1059856c1f30a5bdfdec
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 13:08:38 2012 +0900

    [2225_statistics] remove the unnecessary parameters

commit 1150b0ef4bae79e2ffe254dddd5863690a71d60f
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 13:05:26 2012 +0900

    [2225_statistics] add Counter() constructors according to the update

commit 65a2fbba5becb20d276aeb90e5d13d02190828c7
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 12:12:13 2012 +0900

    [2225_statistics] remove the unnecessary setUpClass() methods

commit 32bb433cb895fd5013c050612abfe62fb09a689c
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 12:07:17 2012 +0900

    [2225_statistics] update the docstring

commit 525dc51879ae8164ed085f5f6c48f8566853b230
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 11:58:12 2012 +0900

    [2225_statistics] correct the variable names from the statistics class

commit 9a08bfa4933a435a4911cef029e63f57deed0dc3
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 11:56:20 2012 +0900

    [2225_statistics] change the default statistics spec in case of a spec file specified in the constructor

commit e1aca7e9404c4064f0125b7596d67cbd8af932e5
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 21:56:47 2012 +0900

    [2225_statistics] add _Statistics() class having default statistics data set

commit f5dc6575c10281b39320167809689df16ae913cf
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 11:49:34 2012 +0900

    [2225_statistics] rename _Counter() to Counter() and change its interface

commit 46dba3a3c60b81e609ee7ac2acc9641a8b62c9f3
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 16:59:22 2012 +0900

    [2225_statistics] rename _stoptimer() to stop(), change its interface, and update the description
    
    It doesn't raise DataNotFound if the timer isn't started but it raises if the
    timer is stopped, which isn't defined in the spec file.

commit 96ee507bbc179b6e3732114dfad67e6c5168c538
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 11:30:30 2012 +0900

    [2225_statistics] rename _starttimer() to start() and change its interface

commit 3836cadb5368169a86a27e8af12374c8b715f5a5
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 16:38:57 2012 +0900

    [2225_statistics] rename _getter() to get() and change its interface

commit 02e9061387eff505391762b5568c2e9700b021e5
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 16:34:16 2012 +0900

    [2225_statistics] rename _decrementer() to dec() and change its interface

commit b53ecd7c2508d159e92bf890f9d3b2e3747d053b
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 16:32:42 2012 +0900

    [2225_statistics] rename _incrementer() to inc() and change its interface

commit a1fcd146a64717e59311eaeae9b97fb66857e636
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 11:22:38 2012 +0900

    [2225_statistics] remove the unnecessary parameters

commit 0e4b3df29c59a4b4cf4c75f37fd3c3180332e7fb
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 11:20:38 2012 +0900

    [2225_statistics] remove the unnecessary Counter() class

commit 13c2eb59454d17b9d00c3cc7205ba19e8b69ec8f
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 11:45:28 2012 +0900

    [2225_statistics] remove _parse_stats_spec()

commit 8e0ebda2f002e9ef7530ac16ab7947104767d20d
Author: Naoki Kambe <kambe at jprs.co.jp>
Date:   Thu Dec 6 11:03:20 2012 +0900

    [2225_statistics] remove the unnecessary functor creators

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

Summary of changes:
 src/lib/python/isc/statistics/counter.py           |  350 +++++++-------------
 .../python/isc/statistics/tests/counter_test.py    |  297 +++++++----------
 2 files changed, 244 insertions(+), 403 deletions(-)

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