updates statistics data. If specified data is invalid for
statistics spec of specified owner, it returns a list of error
messages. If there is no error or if neither owner nor data is
- specified in args, it returns None. The 'mid' argument is an identifier of
- the sender module in order for stats to identify which
+ specified in args, it returns None. The 'mid' argument is an
+ identifier of the sender module in order for stats to identify which
instance sends statistics data in the situation that multiple
instances are working.
"""
# Note:
# The fix of #1751 is for multiple instances working. It is
# assumed here that they send different statistics data with
- # each sender module id (mid). Stats should save their statistics data by
- # mid. The statistics data, which is the existing variable, is
+ # each sender module id (mid). Stats should save their statistics data
+ # by mid. The statistics data, which is the existing variable, is
# preserved by accumlating from statistics data by the mid. This
# is an ad-hoc fix because administrators can not see
# statistics by each instance via bindctl or HTTP/XML. These
__data[owner][mid] = {}
# use the isc.cc.data.set method
try:
- isc.cc.data.set(__data[owner][mid],
- _key, _val)
+ isc.cc.data.set(__data[owner][mid], _key, _val)
if self.modules[owner].validate_statistics(
False, __data[owner][mid], errors):
_data = __data
import isc.log
import isc.cc.session
from test_utils import BaseModules, ThreadingServerManager, MyStats, \
- SignalHandler, MyModuleCCSession, send_command
+ SimpleStats, SignalHandler, MyModuleCCSession, send_command
from isc.testutils.ccsession_mock import MockModuleCCSession
class TestUtilties(unittest.TestCase):
self.assertRaises(stats.StatsError, stats.Stats)
stats.SPECFILE_LOCATION = orig_spec_location
- class SimpleStat(stats.Stats):
- def __init__(self):
- stats.Stats.__init__(self, MyModuleCCSession)
-
- def _init_statistics_data(self):
- pass
-
- def get_datetime(self):
- return 42
-
def __send_command(self, stats, command_name, params=None):
'''Emulate a command arriving to stats by directly calling callback'''
return isc.config.ccsession.parse_answer(
raise CheckException # terminate the loop
# start without err
- stats = self.SimpleStat()
+ stats = SimpleStats()
self.assertFalse(stats.running)
stats._check_command = lambda: __check_start(stats)
# We are going to confirm start() will set running to True, avoidng
# override get_interval() so it won't go poll statistics
tested_stats.get_interval = lambda : 0
- stats = self.SimpleStat()
+ stats = SimpleStats()
stats._check_command = lambda: __check_shutdown(stats)
stats.start()
self.assertTrue(stats.mccs.stopped)
def test_handlers(self):
"""Test command_handler"""
- __stats = self.SimpleStat()
+ __stats = SimpleStats()
# 'show' command. We're going to check the expected methods are
# called in the expected order, and check the resulting response.
"item_name": "boot_time",
"item_type": "string",
"item_optional": False,
- "item_default": "1970-01-01T00:00:00Z",
+ # Use a different default so we can check it below
+ "item_default": "2013-01-01T00:00:01Z",
"item_title": "Boot time",
"item_description": "dummy desc",
"item_format": "date-time"
}]})
return answer, None
- self.stats = self.SimpleStat()
+ self.stats = SimpleStats()
self.stats.cc_session.group_sendmsg = __check_group_sendmsg
self.stats.cc_session.group_recvmsg = __check_group_recvmsg
self.stats.modules['Init'].get_statistics_spec())
self.assertTrue('boot_time' in my_statistics_data)
self.assertEqual(my_statistics_data['boot_time'],
- self.const_default_datetime)
+ "2013-01-01T00:00:01Z")
# Error case
orig_parse_answer = stats.isc.config.ccsession.parse_answer
where we set the expected data in statistics_data.
"""
- self.stats = self.SimpleStat()
+ self.stats = SimpleStats()
def __faked_update_modules():
self.stats.statistics_data = { \
'Stats': {
def test_update_statistics_data(self):
"""test for list-type statistics"""
- self.stats = stats.Stats()
+ self.stats = SimpleStats()
_test_exp1 = {
'zonename': 'test1.example',
'queries.tcp': 5,
def send_stopping(self):
self.stopped = True # just record it's called to inspect it later
+class SimpleStats(stats.Stats):
+ def __init__(self):
+ # Since we replace _init_statistics_data, this doesn't cause
+ # any network I/O
+ stats.Stats.__init__(self, MyModuleCCSession)
+
+ # replace some (faked) ModuleCCSession methods so we can avoid
+ # network I/O, then call _init_statistics_data. This will
+ # get the Stats module info from the file directly and some
+ # amount information about the Init and Auth modules (hardcoded below).
+ self.cc_session.group_sendmsg = self.__check_group_sendmsg
+ self.cc_session.group_recvmsg = self.__check_group_recvmsg
+ stats.Stats._init_statistics_data(self)
+
+ def _init_statistics_data(self):
+ pass
+
+ def get_datetime(self):
+ return 42
+
+ def __check_group_sendmsg(self, command, destination):
+ cmd, value = isc.config.ccsession.parse_command(command)
+ return 4200 # faked seq number
+
+ def __check_group_recvmsg(self, nonblocking, seq):
+ answer = isc.config.ccsession.create_answer(
+ 0, {'Init': [{
+ "item_name": "boot_time",
+ "item_type": "string",
+ "item_optional": False,
+ "item_default": "1970-01-01T00:00:00Z",
+ "item_title": "Boot time",
+ "item_description": "dummy desc",
+ "item_format": "date-time"
+ }],
+ 'Auth':
+ json.loads(MockAuth.spec_str)['module_spec']['statistics']
+ })
+ return answer, None
+
class MyStats(stats.Stats):
stats._BASETIME = CONST_BASETIME