|
@@ -17,19 +17,49 @@
|
|
|
|
|
|
import unittest
|
|
|
import threading
|
|
|
+from datetime import timedelta
|
|
|
import isc.config
|
|
|
import xfrout
|
|
|
+import xfrin
|
|
|
|
|
|
TEST_ZONE_NAME_STR = "example.com."
|
|
|
|
|
|
from isc.statistics import counter
|
|
|
|
|
|
-class TestCounter(unittest.TestCase):
|
|
|
+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(number, cycle, 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):
|
|
|
+ threads.append(threading.Thread(\
|
|
|
+ target=setup_functor, \
|
|
|
+ args=(event, cycle, functor,) + args))
|
|
|
+ for th in threads: th.start()
|
|
|
+ event.set()
|
|
|
+ for th in threads: th.join()
|
|
|
|
|
|
+class TestCounter(unittest.TestCase):
|
|
|
def setUp(self):
|
|
|
- module_spec = isc.config.module_spec_from_file(\
|
|
|
- xfrout.SPECFILE_LOCATION)
|
|
|
- self.counter = counter.Counter(module_spec)
|
|
|
+ self.counter = counter.Counter()
|
|
|
+ self._statistics_data = {}
|
|
|
+ self._start_time = {}
|
|
|
+ self._counter_name = "counter"
|
|
|
+ self._timer_name = "seconds"
|
|
|
+ self._statistics_spec = [{ "item_name": self._counter_name,
|
|
|
+ "item_type": "integer",
|
|
|
+ "item_optional": False,
|
|
|
+ "item_default": 0 },
|
|
|
+ { "item_name": self._timer_name,
|
|
|
+ "item_type": "real",
|
|
|
+ "item_optional": False,
|
|
|
+ "item_default": 0.0 }]
|
|
|
|
|
|
def test_clear_counters(self):
|
|
|
self.counter._statistics_data = {'counter': 1}
|
|
@@ -44,128 +74,242 @@ class TestCounter(unittest.TestCase):
|
|
|
self.counter.enable()
|
|
|
self.assertFalse(self.counter._disabled)
|
|
|
|
|
|
-class TestXfroutCounter(unittest.TestCase):
|
|
|
- _number = 3 # number of the threads
|
|
|
- _cycle = 10000 # number of counting per thread
|
|
|
+ def test_add_counter_normal(self):
|
|
|
+ element = {'counter' : 1}
|
|
|
+ self.assertEqual(\
|
|
|
+ counter._add_counter(element, [], 'counter'), 1)
|
|
|
|
|
|
- def setUp(self):
|
|
|
- self._module_spec = isc.config.module_spec_from_file(\
|
|
|
- xfrout.SPECFILE_LOCATION)
|
|
|
- self._statistics_spec = \
|
|
|
- self._module_spec.get_statistics_spec()
|
|
|
- self.xfrout_counter = \
|
|
|
- counter.init(xfrout.SPECFILE_LOCATION)
|
|
|
- self._entire_server = self.xfrout_counter._entire_server
|
|
|
- self._perzone_prefix = self.xfrout_counter._perzone_prefix
|
|
|
- self._xfrrunning_names = self.xfrout_counter._xfrrunning_names
|
|
|
- self._unixsocket_names = self.xfrout_counter._unixsocket_names
|
|
|
- self._started = threading.Event()
|
|
|
+ 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"""
|
|
|
+ number = 3 # number of the threads
|
|
|
+ cycle = 10000 # number of counting per thread
|
|
|
+ self.counter._statistics_data = self._statistics_data
|
|
|
+ self.counter._statistics_spec = self._statistics_spec
|
|
|
+ self._start_time = counter._start_timer()
|
|
|
+ start_functor(number, cycle, self.counter._incrementer,
|
|
|
+ self._counter_name)
|
|
|
+ counter._stop_timer(self._start_time,
|
|
|
+ self._statistics_data,
|
|
|
+ self._statistics_spec,
|
|
|
+ self._timer_name)
|
|
|
+ self.assertEqual(
|
|
|
+ counter._get_counter(self._statistics_data,
|
|
|
+ self._counter_name),
|
|
|
+ number * cycle)
|
|
|
+ self.assertGreater(
|
|
|
+ counter._get_counter(self._statistics_data,
|
|
|
+ self._timer_name), 0)
|
|
|
|
|
|
- def test_dump_default_statistics(self):
|
|
|
- self.assertTrue(\
|
|
|
- self._module_spec.validate_statistics(\
|
|
|
- True,
|
|
|
- counter.dump_default_statistics(),
|
|
|
- )
|
|
|
- )
|
|
|
-
|
|
|
- def setup_functor(self, incrementer, *args):
|
|
|
- self._started.wait()
|
|
|
- for i in range(self._cycle): incrementer(*args)
|
|
|
-
|
|
|
- def start_functor(self, incrementer, *args):
|
|
|
- threads = []
|
|
|
- for i in range(self._number):
|
|
|
- threads.append(threading.Thread(\
|
|
|
- target=self.setup_functor, \
|
|
|
- args=(incrementer,) + args \
|
|
|
- ))
|
|
|
- for th in threads: th.start()
|
|
|
- self._started.set()
|
|
|
- for th in threads: th.join()
|
|
|
-
|
|
|
- def get_count(self, zone_name, counter_name):
|
|
|
- return isc.cc.data.find(\
|
|
|
- counter.dump_statistics(),\
|
|
|
- '%s/%s/%s' % (self._perzone_prefix,\
|
|
|
- zone_name, counter_name))
|
|
|
-
|
|
|
- def test_functors(self):
|
|
|
+class BaseTestXfrCounter():
|
|
|
+
|
|
|
+ def test_perzone_counters(self):
|
|
|
# for per-zone counters
|
|
|
- result = { self._entire_server: {},
|
|
|
- TEST_ZONE_NAME_STR: {} }
|
|
|
- self._perzone_counters = isc.config.spec_name_list(\
|
|
|
- isc.config.find_spec_part(\
|
|
|
- self._statistics_spec, self._perzone_prefix)\
|
|
|
- ['named_set_item_spec']['map_item_spec'])
|
|
|
- for counter_name in self._perzone_counters:
|
|
|
- incrementer = getattr(counter,'inc_%s' % counter_name)
|
|
|
- self.start_functor(incrementer, TEST_ZONE_NAME_STR)
|
|
|
- getter = getattr(counter,'get_%s' % counter_name)
|
|
|
- self.assertEqual(getter(TEST_ZONE_NAME_STR),
|
|
|
- self._number * self._cycle)
|
|
|
- self.assertEqual(self.get_count(self._entire_server,
|
|
|
- counter_name), self._number * self._cycle)
|
|
|
+ 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
|
|
|
- counter.disable()
|
|
|
+ self.counter.disable()
|
|
|
incrementer(TEST_ZONE_NAME_STR)
|
|
|
- self.assertEqual(getter(TEST_ZONE_NAME_STR),
|
|
|
- self._number * self._cycle)
|
|
|
- counter.enable()
|
|
|
+ self.assertEqual(getter(TEST_ZONE_NAME_STR), 1)
|
|
|
+ self.counter.enable()
|
|
|
incrementer(TEST_ZONE_NAME_STR)
|
|
|
- self.assertEqual(getter(TEST_ZONE_NAME_STR),
|
|
|
- self._number * self._cycle + 1)
|
|
|
- result[self._entire_server][counter_name] = \
|
|
|
- result[TEST_ZONE_NAME_STR][counter_name] = \
|
|
|
- self._number * self._cycle + 1
|
|
|
+ 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()
|
|
|
|
|
|
- statistics_data = {self._perzone_prefix: result}
|
|
|
+ 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)
|
|
|
+ self.assertTrue(self._module_spec.validate_statistics(
|
|
|
+ False, self._statistics_data))
|
|
|
|
|
|
+class TestXfroutCounter(unittest.TestCase, BaseTestXfrCounter):
|
|
|
+
|
|
|
+ def setUp(self):
|
|
|
+ self._module_spec = isc.config.module_spec_from_file(\
|
|
|
+ xfrout.SPECFILE_LOCATION)
|
|
|
+ self._statistics_spec = \
|
|
|
+ self._module_spec.get_statistics_spec()
|
|
|
+ self.counter = \
|
|
|
+ counter.XfroutCounter(self._module_spec)
|
|
|
+ self._statistics_data = {}
|
|
|
+ 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._started = threading.Event()
|
|
|
+ self._zones_item_list = self.counter._zones_item_list
|
|
|
+
|
|
|
+ def test_xfrrunning_counters(self):
|
|
|
# for {a|i}xfrrunning counters
|
|
|
for counter_name in self._xfrrunning_names:
|
|
|
- incrementer = getattr(counter,'inc_%s' % counter_name)
|
|
|
- self.start_functor(incrementer)
|
|
|
- getter = getattr(counter,'get_%s' % counter_name)
|
|
|
- self.assertEqual(getter(), self._number * self._cycle)
|
|
|
- decrementer = getattr(counter,'dec_%s' % counter_name)
|
|
|
- self.start_functor(decrementer)
|
|
|
+ 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
|
|
|
- counter.disable()
|
|
|
+ self.counter.disable()
|
|
|
incrementer()
|
|
|
self.assertEqual(getter(), 0)
|
|
|
- counter.enable()
|
|
|
+ self.counter.enable()
|
|
|
incrementer()
|
|
|
- self.assertGreater(getter(), 0)
|
|
|
- counter.disable()
|
|
|
+ self.assertEqual(getter(), 1)
|
|
|
+ self.counter.disable()
|
|
|
decrementer()
|
|
|
- self.assertGreater(getter(), 0)
|
|
|
- counter.enable()
|
|
|
+ self.assertEqual(getter(), 1)
|
|
|
+ self.counter.enable()
|
|
|
decrementer()
|
|
|
self.assertEqual(getter(), 0)
|
|
|
- statistics_data[counter_name] = 0
|
|
|
+ self._statistics_data[counter_name] = 0
|
|
|
+ self.check_dump_statistics()
|
|
|
|
|
|
+ def test_unixsocket_counters(self):
|
|
|
# for unixsocket counters
|
|
|
- statistics_data.update({'socket': {'unixdomain': {}}})
|
|
|
for counter_name in self._unixsocket_names:
|
|
|
- incrementer = getattr(counter, 'inc_unixsocket_%s' % counter_name)
|
|
|
- self.start_functor(incrementer)
|
|
|
- getter = getattr(counter, 'get_unixsocket_%s' % counter_name)
|
|
|
- self.assertEqual(getter(), self._number * self._cycle)
|
|
|
+ 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)
|
|
|
# checks disable/enable
|
|
|
- counter.disable()
|
|
|
+ self.counter.disable()
|
|
|
incrementer()
|
|
|
- self.assertEqual(getter(), self._number * self._cycle)
|
|
|
- counter.enable()
|
|
|
+ self.assertEqual(getter(), 1)
|
|
|
+ self.counter.enable()
|
|
|
incrementer()
|
|
|
- self.assertEqual(getter(), self._number * self._cycle + 1)
|
|
|
- statistics_data['socket']['unixdomain'][counter_name] = \
|
|
|
- self._number * self._cycle + 1
|
|
|
-
|
|
|
- # totally chacking
|
|
|
- self.assertEqual(counter.dump_statistics(), statistics_data)
|
|
|
- self.assertTrue(self._module_spec.validate_statistics(\
|
|
|
- True, statistics_data))
|
|
|
+ self.assertEqual(getter(), 2)
|
|
|
+ isc.cc.data.set(
|
|
|
+ self._statistics_data,
|
|
|
+ 'socket/unixdomain/%s' % counter_name, 2)
|
|
|
+ self.check_dump_statistics()
|
|
|
+
|
|
|
+class TestXfrinCounter(unittest.TestCase, BaseTestXfrCounter):
|
|
|
+
|
|
|
+ def setUp(self):
|
|
|
+ self._module_spec = isc.config.module_spec_from_file(\
|
|
|
+ xfrin.SPECFILE_LOCATION)
|
|
|
+ self._statistics_spec = \
|
|
|
+ self._module_spec.get_statistics_spec()
|
|
|
+ self._statistics_data = {}
|
|
|
+ self.counter = \
|
|
|
+ counter.XfrinCounter(self._module_spec)
|
|
|
+ self._entire_server = self.counter._entire_server
|
|
|
+ self._perzone_prefix = self.counter._perzone_prefix
|
|
|
+ self._zones_item_list = self.counter._zones_item_list
|
|
|
+ self._started = threading.Event()
|
|
|
+ self._zones_item_list = self.counter._zones_item_list
|
|
|
+
|
|
|
+ def test_perzone_timers(self):
|
|
|
+ # 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.check_dump_statistics()
|
|
|
|
|
|
if __name__== "__main__":
|
|
|
unittest.main()
|