[svn] commit: r2453 - in /branches/trac191: ./ src/bin/stats/ src/bin/stats/tests/
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Jul 9 09:16:16 UTC 2010
Author: naokikambe
Date: Fri Jul 9 09:16:16 2010
New Revision: 2453
Log:
- add stub script, which behaves as a sender to Stats module and which can talk with the stats module in order to testing and verification of stats module, so not to be started by boss process
- adopt Listener pattern and Observer pattern model in stats.py
- add some changes which stats module can receive statistics information from other module via cfgmgr, stats module can send dynamic valuable like datetime and counter
- add definition statistics items and more commands which stats module and other sender modules use via bindctl or cfgmgr
- add some changes to test script for more strictly testing
- add minor changes like mismatch from coding guidelines
- add some change to unittest_fakesession.py in order to be more like real session.py
- delete some dead code
Added:
branches/trac191/src/bin/stats/run_b10-stats_stub.sh.in
branches/trac191/src/bin/stats/stats_stub.py.in
branches/trac191/src/bin/stats/tests/b10-stats_stub_test.py
Modified:
branches/trac191/configure.ac
branches/trac191/src/bin/stats/Makefile.am
branches/trac191/src/bin/stats/stats.py.in
branches/trac191/src/bin/stats/stats.spec.pre.in
branches/trac191/src/bin/stats/tests/Makefile.am
branches/trac191/src/bin/stats/tests/b10-stats_test.py
branches/trac191/src/bin/stats/tests/stats_test.in
branches/trac191/src/bin/stats/tests/unittest_fakesession.py
Modified: branches/trac191/configure.ac
==============================================================================
--- branches/trac191/configure.ac (original)
+++ branches/trac191/configure.ac Fri Jul 9 09:16:16 2010
@@ -439,8 +439,10 @@
src/bin/xfrout/tests/xfrout_test
src/bin/xfrout/run_b10-xfrout.sh
src/bin/stats/stats.py
+ src/bin/stats/stats_stub.py
src/bin/stats/stats.spec.pre
src/bin/stats/run_b10-stats.sh
+ src/bin/stats/run_b10-stats_stub.sh
src/bin/stats/tests/stats_test
src/bin/bind10/bind10.py
src/bin/bind10/tests/bind10_test
@@ -470,6 +472,7 @@
chmod +x src/bin/xfrout/run_b10-xfrout.sh
chmod +x src/bin/stats/tests/stats_test
chmod +x src/bin/stats/run_b10-stats.sh
+ chmod +x src/bin/stats/run_b10-stats_stub.sh
chmod +x src/bin/bind10/run_bind10.sh
chmod +x src/bin/cmdctl/tests/cmdctl_test
chmod +x src/bin/xfrin/tests/xfrin_test
Modified: branches/trac191/src/bin/stats/Makefile.am
==============================================================================
--- branches/trac191/src/bin/stats/Makefile.am (original)
+++ branches/trac191/src/bin/stats/Makefile.am Fri Jul 9 09:16:16 2010
@@ -3,11 +3,12 @@
pkglibexecdir = $(libexecdir)/@PACKAGE@
pkglibexec_SCRIPTS = b10-stats
+noinst_SCRIPTS = b10-stats_stub
b10_statsdir = $(DESTDIR)$(pkgdatadir)
b10_stats_DATA = stats.spec
-CLEANFILES = b10-stats b10-stats.pyc stats stats.pyc stats.spec
+CLEANFILES = stats.spec b10-stats stats.pyc stats.pyo b10-stats_stub stats_stub.pyc stats_stub.pyo
man_MANS = b10-stats.8
EXTRA_DIST = $(man_MANS) b10-stats.xml
@@ -28,3 +29,8 @@
$(SED) -e "s|@@PYTHONPATH@@|@pyexecdir@|" \
-e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" stats.py >$@
chmod a+x $@
+
+b10-stats_stub: stats_stub.py
+ $(SED) -e "s|@@PYTHONPATH@@|@pyexecdir@|" \
+ -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" stats_stub.py >$@
+ chmod a+x $@
Modified: branches/trac191/src/bin/stats/stats.py.in
==============================================================================
--- branches/trac191/src/bin/stats/stats.py.in (original)
+++ branches/trac191/src/bin/stats/stats.py.in Fri Jul 9 09:16:16 2010
@@ -15,16 +15,18 @@
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+# $Id$
+__version__ = "$Revision$"
+
import sys; sys.path.append ('@@PYTHONPATH@@')
-
import os
+import signal
+import select
+import time
from optparse import OptionParser, OptionValueError
-import signal
-import time
-import isc
-import isc.cc
-from isc.config.ccsession import ModuleCCSession, create_answer, COMMAND_SHUTDOWN
-from isc.cc import SessionError
+from collections import defaultdict
+from isc.config.ccsession import ModuleCCSession, create_answer
+from isc.cc import Session, SessionError
# If B10_FROM_SOURCE is set in the environment, we use data files
# from a directory relative to that, otherwise we use the ones
@@ -36,175 +38,348 @@
DATAROOTDIR = "@datarootdir@"
SPECFILE_LOCATION = "@datadir@/@PACKAGE@/stats.spec".replace("${datarootdir}", DATAROOTDIR).replace("${prefix}", PREFIX)
-class Stats:
- """
- Stats module
- """
- def __init__(self, cc_session=None, verbose=False):
- """
- creates & initialize a stats module
- """
- self._boottime=self.get_datetime()
+class Singleton(type):
+ """
+ A abstract class of singleton pattern
+ """
+ def __init__(self, *args):
+ type.__init__(self, *args)
+ self._instances = {}
+
+ def __call__(self, *args):
+ if not args in self._instances:
+ self._instances[args] = type.__call__(self, *args)
+ return self._instances[args]
+
+class Callback():
+ """
+ A Callback handler class
+ """
+ def __init__(self, name, callback=None, *args, **kwargs):
+ self.name=name
+ self.callback=callback
+ self.args=args
+ self.kwargs=kwargs
+
+ def __call__(self, *args, **kwargs):
+ if args:
+ self.args=args
+ if kwargs:
+ self.kwargs=kwargs
+ if self.callback:
+ return self.callback(*self.args, **self.kwargs)
+
+class Subject():
+ """
+ A abstract subject class of observer pattern
+ """
+ def __init__(self, verbose=False):
self.verbose=verbose
- if self.verbose:
- sys.stdout.write("[b10-stats] initialize a stats module\n")
-
- if cc_session:
- ccss = ModuleCCSession(SPECFILE_LOCATION,
- self.config_handler,
- self.command_handler,
- cc_session)
+ self._listeners = []
+
+ def attach(self, listener):
+ if not listener in self._listeners:
+ self._listeners.append(listener)
+
+ def detach(self, listener):
+ try:
+ self._listeners.remove(listener)
+ except ValueError:
+ pass
+
+ def notify(self, event, modifier=None):
+ for listener in self._listeners:
+ if modifier != listener:
+ listener.update(event)
+
+class Listener():
+ """
+ A abstract listener class of observer pattern
+ """
+ def __init__(self, subject):
+ self.subject = subject
+ self.subject.attach(self)
+ self.events = {}
+
+ def update(self, name):
+ if name in self.events:
+ callback = self.events[name]
+ return callback()
+
+ def add_event(self, event):
+ self.events[event.name]=event
+
+class SessionSubject(Subject):
+ """
+ A concrete subject class which creates CC session object
+ """
+ __metaclass__ = Singleton
+ def __init__(self, session=None, verbose=False):
+ Subject.__init__(self)
+ self.verbose = verbose
+ if session is None:
+ self.session = Session()
else:
- ccss = ModuleCCSession(SPECFILE_LOCATION,
- self.config_handler,
- self.command_handler)
-
- self.ccss=ccss
- self._session=ccss._session
+ self.session = session
self.running = False
- def get_boottime(self):
- """
- datetime when stats module starts
- """
- return self._boottime
-
- def get_lname(self):
- """
- Return local_name of CCSession
- """
- return self._session.lname
-
- def get_statsspec(self):
- """
- Return dictionary of stat_spec
- """
- spec=self.ccss.get_module_spec().get_full_spec()
- return spec['stats_spec']
+ def start(self):
+ self.running = True
+ self.notify('start')
+
+ def stop(self):
+ self.running = False
+ self.notify('stop')
+
+ def check(self):
+ self.notify('check')
+
+class CCSessionListener(Listener):
+ """
+ A concrete listener class which creates SessionSubject object and
+ ModuleCCSession object
+ """
+ def __init__(self, subject, verbose=False):
+ Listener.__init__(self, subject)
+ self.verbose = verbose
+ self.subject = subject
+ self.session = subject.session
+
+ # create ModuleCCSession object
+ self.cc_session = ModuleCCSession(SPECFILE_LOCATION,
+ self.config_handler,
+ self.command_handler,
+ self.session)
+
+ # initialize internal data
+ self.stats_spec = self.get_full_spec()['stats_spec']
+ self.stats_data = self.initialize_data(self.stats_spec)
+
+ # add event handler invoked via SessionSubject object
+ self.add_event(Callback('start', self.start))
+ self.add_event(Callback('stop', self.stop))
+ self.add_event(Callback('check', self.check))
+
+ # add event handler related command_handler of ModuleCCSession
+ # invoked via bindctl
+ for c in self.get_full_spec()['commands']:
+ cmd = c["command_name"]
+ try:
+ self.add_event(Callback('command_'+cmd, eval("self.command_"+cmd)))
+ except NameError:
+ pass
def config_handler(self, new_config):
"""
handle a configure from the cc channel
"""
- answer = create_answer(0)
- return answer
+ # do nothing
+ return create_answer(0)
def command_handler(self, command, args):
"""
handle commands from the cc channel
"""
- self.command=command
- self.args=args
- if command == COMMAND_SHUTDOWN:
- ans=self.command_shutdown()
- elif command == "status":
- ans=self.command_status()
- elif command == "show":
- ans=self.command_show()
- elif command == "statsspec":
- ans=self.command_statsspec()
+ cmd = None
+ # add 'command_' suffix in order to prevent executing internal
+ # command via bindctl
+ name = 'command_'+command
+
+ if name in self.events:
+ event=self.events[name]
+ return event(args)
else:
- ans=self.command_unknown()
- return ans
+ return self.command_unknown(command, args)
def start(self):
"""
- start the stats module
- """
- if self.verbose:
- sys.stdout.write("[b10-stats] starting the stats module\n")
- self.boot_time=self.get_datetime()
- self.ccss.start()
- self.running = True
- while (self.running):
- self.ccss.check_command()
- self.ccss.close()
- return True
+ start the cc chanel
+ """
+ return self.cc_session.start()
def stop(self):
"""
- stop the stats module
- """
- if self.verbose:
- sys.stdout.write("[b10-stats] stopping the stats module\n")
- self.running = False
-
- def command_shutdown(self):
+ stop the cc chanel
+ """
+ return self.cc_session.close()
+
+ def check(self):
+ """
+ check the cc chanel
+ """
+ return self.cc_session.check_command()
+
+ def command_shutdown(self, args):
"""
handle shutdown command
"""
if self.verbose:
- sys.stdout.write("[b10-stats] got 'shutdown' command\n")
- self.stop()
- return create_answer(0)
-
- def command_status(self):
+ sys.stdout.write("[b10-stats] 'shutdown' command received\n")
+ self.subject.running = False
+ return create_answer(0)
+
+ def command_set(self, args):
+ """
+ handle set command
+ """
+ if self.verbose:
+ sys.stdout.write("[b10-stats] 'set' command received, args: "+str(args)+"\n")
+
+ data = self.stats_data
+ # Data type of the top level must be dictionary type
+ for k in args.keys():
+ data[k] = args[k]
+ self.stats_data = data
+ return create_answer(0)
+
+ def command_add(self, args):
+ """
+ handle add command
+ """
+ if self.verbose:
+ sys.stdout.write("[b10-stats] 'add' command received, args: "+str(args)+"\n")
+
+ # A internal private function adding for each element, which
+ # is called recursively
+ def __add_data(data, args):
+ # print(type(data), type(args))
+
+ if type(data) == type([]):
+ max = max(len(data), len(args))
+ for i in max:
+ if i in data and i in args:
+ data[i] = __add_data(data[i], args[i])
+ elif i in args:
+ data.extend(args[i:])
+ break
+ elif type(data) == type({}):
+ for k in args.keys():
+ if k in data:
+ data[k] = __add_data(data[k], args[k])
+ else:
+ data[k] = args[k]
+ else:
+ data = data + args
+ return data
+
+ # call a internal function
+ self.stats_data = __add_data(self.stats_data, args)
+ return create_answer(0)
+
+ def command_del(self, args):
+ """
+ handle add command
+ """
+ if self.verbose:
+ sys.stdout.write("[b10-stats] 'del' command received, args: "+str(args)+"\n")
+
+ # just remove one item
+ self.stats_data.pop(args)
+ return create_answer(0)
+
+ def command_spec(self, args):
+ """
+ handle show stats spec command
+ """
+ if self.verbose:
+ sys.stdout.write("[b10-stats] 'spec' command received\n")
+ return create_answer(0,dict(self.stats_spec))
+
+ def command_show(self, args):
+ """
+ handle show command
+ """
+ if self.verbose:
+ sys.stdout.write("[b10-stats] 'show' command received\n")
+
+ # overwrite information about stats module
+ self.stats_data['report_time'] = get_datetime()
+ self.stats_data['stats.timestamp'] = get_timestamp()
+ self.stats_data['stats.lname'] = self.session.lname
+
+ return create_answer(0, dict(self.stats_data))
+
+ def command_reset(self, args):
+ """
+ handle reset command
+ """
+ if self.verbose:
+ sys.stdout.write("[b10-stats] 'reset' command received\n")
+ # re-initialize data
+ self.stats_spec = self.get_full_spec()['stats_spec']
+ self.stats_data = self.initialize_data(self.stats_spec)
+ return create_answer(0)
+
+ def command_status(self, args):
"""
handle status command
"""
if self.verbose:
- sys.stdout.write("[b10-stats] got 'status' command\n")
- ret="I'm alive."
- return create_answer(0,ret)
-
- def command_show(self):
- """
- handle show command
- """
- if self.verbose:
- sys.stdout.write("[b10-stats] got 'show' command\n")
- ret={}
- for sspec in self.get_statsspec():
- name=sspec['name']
- if name == 'report_time':
- ret[name]=self.get_datetime()
- elif name == 'stats.boot_time':
- ret[name]=self.get_boottime()
- elif name == 'stats.timestamp':
- ret[name]=self.get_timestamp()
- elif name == 'stats.lname':
- ret[name]=self.get_lname()
- else:
- sys.stderr.write("[b10-stats] an errer while reading specfile")
- return create_answer(1, "an errer while reading specfile")
- return create_answer(0,ret)
-
- def command_statsspec(self):
- """
- handle stats_spec command
- """
- if self.verbose:
- sys.stdout.write("[b10-stats] got 'statsspec' command\n")
- return create_answer(0,self.get_statsspec())
-
- def command_unknown(self):
+ sys.stdout.write("[b10-stats] 'status' command received\n")
+ return create_answer(0, "I'm alive.")
+
+ def command_unknown(self, command, args):
"""
handle an unknown command
"""
if self.verbose:
- sys.stdout.write("[b10-stats] got unknown command\n")
- return create_answer(1, "Unknown command: '"+str(self.command)+"'")
-
- def get_timestamp(self):
- """
- get current timestamp
- """
- return time.time()
-
- def get_datetime(self):
- """
- get current datetime
- """
- return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
+ sys.stdout.write("[b10-stats] Unknown command received: '"
+ + str(command) + "'\n")
+ return create_answer(1, "Unknown command: '"+str(command)+"'")
+
+ def initialize_data(self, spec):
+ """
+ initialize stats data
+ """
+ t = spec.get('type')
+ if t == 'null':
+ return None
+ elif t == 'boolean':
+ return bool(spec.get('default', False))
+ elif t == 'string':
+ return str(spec.get('default', ''))
+ elif t in set(['number', 'integer']):
+ return int(spec.get('default', 0))
+ elif t in set(['float', 'double']):
+ return float(spec.get('default', 0.0))
+ elif t == 'array':
+ return [ self.initialize_data(x) for x in spec['items'] ]
+ elif t == 'object':
+ d = spec['properties']
+ return dict([ (k, self.initialize_data(d[k])) for k in d.keys() ])
+ else:
+ return spec.get('default')
+
+ def get_full_spec(self):
+ """
+ get full spec from cc_session
+ """
+ return self.cc_session.get_module_spec().get_full_spec()
+
+def get_timestamp():
+ """
+ get current timestamp
+ """
+ return time.time()
+
+def get_datetime():
+ """
+ get current datetime
+ """
+ return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
def main():
try:
- parser = OptionParser()
+ parser=OptionParser()
parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
help="display more about what is going on")
(options, args) = parser.parse_args()
- stats=Stats(verbose=options.verbose)
- stats.start()
+ subject = SessionSubject(verbose=options.verbose)
+ listener = CCSessionListener(subject, verbose=options.verbose)
+ subject.start()
+ while subject.running:
+ subject.check()
+ subject.stop()
except OptionValueError:
sys.stderr.write("[b10-stats] Error parsing options\n")
except SessionError as se:
@@ -212,7 +387,9 @@
+ "is the command channel daemon running?\n")
except KeyboardInterrupt as kie:
sys.stderr.write("[b10-stats] Interrupted, exiting\n")
+ finally:
+ if subject:
+ subject.stop()
if __name__ == "__main__":
main()
-
Modified: branches/trac191/src/bin/stats/stats.spec.pre.in
==============================================================================
--- branches/trac191/src/bin/stats/stats.spec.pre.in (original)
+++ branches/trac191/src/bin/stats/stats.spec.pre.in Fri Jul 9 09:16:16 2010
@@ -22,44 +22,74 @@
"command_args": []
},
{
- "command_name": "shutdown",
- "command_description": "Shut down stats module",
+ "command_name": "set",
+ "command_description": "Set statistics data",
"command_args": []
},
{
- "command_name": "statsspec",
- "command_description": "Show contents of stats_spec in specfile",
+ "command_name": "add",
+ "command_description": "Add statistics data",
+ "command_args": []
+ },
+ {
+ "command_name": "del",
+ "command_description": "Delete statistics data",
+ "command_args": []
+ },
+ {
+ "command_name": "reset",
+ "command_description": "Reset statistics data",
+ "command_args": []
+ },
+ {
+ "command_name": "shutdown",
+ "command_description": "Shutdown stats module",
+ "command_args": []
+ },
+ {
+ "command_name": "spec",
+ "command_description": "Show stats_spec module",
"command_args": []
}
],
- "stats_spec": [
- {
- "name": "report_time",
- "title": "Report time",
- "description": "A date time when stats module reports",
- "type": "string",
- "format": "date-time"
- },
- {
- "name": "stats.boot_time",
- "title": "stats.BootTime",
- "description": "A date time when b10-stats process starts",
- "type": "string",
- "format": "date-time"
- },
- {
- "name": "stats.timestamp",
- "title": "stats.Timestamp",
- "description": "Current timestamp since epoch time (1970-01-01T00:00:00Z)",
- "type": "float",
- "format": "second"
- },
- {
- "name": "stats.lname",
- "title": "stats.LocalName",
- "description": "A localname of stats module given via CC protocol",
- "type": "string"
+ "stats_spec": {
+ "description": "A specification of statistics",
+ "type": "object",
+ "properties": {
+ "report_time": {
+ "title": "Report time",
+ "description": "A date time when stats module reports",
+ "type": "string",
+ "format": "date-time"
+ },
+ "bind10.boot_time": {
+ "title": "stats.BootTime",
+ "description": "A date time when b10-stats process starts",
+ "type": "string",
+ "format": "date-time"
+ },
+ "stats.timestamp": {
+ "title": "stats.Timestamp",
+ "description": "Current timestamp since epoch time (1970-01-01T00:00:00Z)",
+ "type": "float",
+ "format": "second"
+ },
+ "stats.lname": {
+ "title": "stats.LocalName",
+ "description": "A localname of stats module given via CC protocol",
+ "type": "string"
+ },
+ "auth.queries.tcp": {
+ "title": "auth.queries.tcp",
+ "description": "A number of incremental query counts per a process which Auth servers receives in TCP since last sending",
+ "type": "number"
+ },
+ "auth.queries.udp": {
+ "title": "auth.queries.udp",
+ "description": "A number of incremental query counts per a process which Auth servers receives in UDP since last sending",
+ "type": "number"
+ }
}
- ]
+ }
}
}
Modified: branches/trac191/src/bin/stats/tests/Makefile.am
==============================================================================
--- branches/trac191/src/bin/stats/tests/Makefile.am (original)
+++ branches/trac191/src/bin/stats/tests/Makefile.am Fri Jul 9 09:16:16 2010
@@ -1,4 +1,4 @@
-PYTESTS = b10-stats_test.py
+PYTESTS = b10-stats_test.py b10-stats_stub_test.py
EXTRA_DIST = $(PYTESTS)
CLEANFILES = unittest_fakesession.pyc
@@ -9,7 +9,6 @@
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_srcdir)/src/bin/stats \
- CONFIG_TESTDATA_PATH=$(abs_top_srcdir)/src/lib/config/testdata \
B10_FROM_SOURCE=$(abs_top_srcdir) \
$(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
done
Modified: branches/trac191/src/bin/stats/tests/b10-stats_test.py
==============================================================================
--- branches/trac191/src/bin/stats/tests/b10-stats_test.py (original)
+++ branches/trac191/src/bin/stats/tests/b10-stats_test.py Fri Jul 9 09:16:16 2010
@@ -13,7 +13,8 @@
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-# $Id: cfgmgr_test.py 1860 2010-05-19 17:02:32Z jelte $
+# $Id$
+__version__ = "$Revision$"
#
# Tests for the stats module
@@ -22,90 +23,214 @@
import time
import re
import unittest
-import isc
from isc.config.ccsession import ModuleCCSessionError
from unittest_fakesession import FakeModuleCCSession
-from stats import Stats
+from stats import SessionSubject, CCSessionListener
class TestStats(unittest.TestCase):
- def test_stats(self):
- """
- Test for initialize, start, shutdown
+ def setUp(self):
+ self.session = FakeModuleCCSession()
+ self.subject = SessionSubject(session=self.session, verbose=False)
+ self.listener = CCSessionListener(self.subject, verbose=False)
+ self.stats_spec = self.listener.cc_session.get_module_spec().get_full_spec()['stats_spec']
+ self.stats_data = {
+ 'report_time' : get_datetime(),
+ 'bind10.boot_time' : '',
+ 'stats.timestamp' : float(int(get_timestamp())),
+ 'stats.lname' : self.session.lname,
+ 'auth.queries.tcp': 0,
+ 'auth.queries.udp': 0
+ }
+
+ def test_start(self):
+ """
+ Test for stats
"""
- fake_session = FakeModuleCCSession()
- stats = Stats(fake_session)
- ccss=stats.ccss
- self.assertEqual(len(fake_session.message_queue), 0)
- self.assertRaises(ModuleCCSessionError, stats.start)
- self.assertEqual(len(fake_session.message_queue), 2)
- self.assertEqual({"command": ["module_spec", ccss.specification._module_spec]},
- fake_session.get_message("ConfigManager", None))
+ session = self.session
+ subject = self.subject
+ listener = self.listener
+
+ self.assertEqual(len(subject.session.message_queue), 0)
+ self.assertFalse(subject.running)
+ self.assertRaises(ModuleCCSessionError, subject.start)
+ self.assertTrue(subject.running)
+ self.assertEqual(len(subject.session.message_queue), 2)
+ self.assertEqual({"command": ["module_spec", listener.cc_session.specification._module_spec]},
+ subject.session.get_message("ConfigManager", None))
self.assertEqual({"command": ["get_config", {"module_name": "Stats"}]},
- fake_session.get_message("ConfigManager", None))
- self.assertEqual(len(fake_session.message_queue), 0)
- fake_session.group_sendmsg({'result': [ 0 ]}, "Stats")
- fake_session.group_sendmsg({'result': [ 1, "just an error" ]}, "Stats")
- self.assertEqual(len(fake_session.message_queue), 2)
- fake_session.group_sendmsg({"command": [ "shutdown" ]}, "Stats")
- self.assertEqual(len(fake_session.message_queue), 3)
- self.assertFalse(stats.running)
- stats.start()
- self.assertFalse(stats.running)
-
- def test_spec(self):
- """
- Test for spec file
+ subject.session.get_message("ConfigManager", None))
+ self.assertEqual(len(subject.session.message_queue), 0)
+ session.group_sendmsg({'result': [ 0 ]}, "Stats")
+ session.group_sendmsg({'result': [ 1, "just an error" ]}, "Stats")
+ self.assertEqual(len(subject.session.message_queue), 2)
+ self.assertTrue(subject.running)
+ subject.start()
+ self.assertTrue(subject.running)
+ self.assertEqual(len(subject.session.message_queue), 2)
+ self.assertEqual({"command": ["module_spec", listener.cc_session.specification._module_spec]},
+ subject.session.get_message("ConfigManager", None))
+ self.assertEqual({"command": ["get_config", {"module_name": "Stats"}]},
+ subject.session.get_message("ConfigManager", None))
+ self.assertEqual(len(subject.session.message_queue), 0)
+ subject.check()
+ self.assertTrue(subject.running)
+
+ def test_commands(self):
+ """
+ Test for stats commands
"""
- fake_session = FakeModuleCCSession()
- stats = Stats(fake_session)
- names1=[ 'report_time',
- 'stats.boot_time',
- 'stats.timestamp',
- 'stats.lname' ]
- names1.sort()
- names2=[ sspec['name'] for sspec in stats.get_statsspec() ]
- names2.sort()
- self.assertTrue(names1==names2)
-
- def test_commands(self):
- """
- Test for command handlig
-
- """
- fake_session = FakeModuleCCSession()
- stats = Stats(fake_session)
- ccss=stats.ccss
- self.assertRaises(ModuleCCSessionError, stats.start)
- self.assertEqual({'result': [0]},
- stats.command_handler("shutdown", None))
- self.assertEqual({'result': [0, "I'm alive."]},
- stats.command_handler("status", None))
- self.assertEqual({'result': [0, ccss.specification._module_spec['stats_spec']]},
- stats.command_handler("statsspec", None))
- self.assertEqual({'result': [1, "Unknown command: 'unknown'"]},
- stats.command_handler("unknown", None))
- ret_stats=stats.command_handler("show", None)
- self.assertTrue('result' in ret_stats)
- self.assertTrue(ret_stats['result'])
- rs=ret_stats['result']
- self.assertEqual(len(ret_stats['result']), 2)
- self.assertEqual(ret_stats['result'][0], 0)
- self.assertTrue(ret_stats['result'][1])
- rs=ret_stats['result'][1]
- self.assertTrue('report_time' in rs)
- self.assertTrue('stats.boot_time' in rs)
- self.assertTrue('stats.timestamp' in rs)
- self.assertTrue('stats.lname' in rs)
- self.assertTrue(time.strptime(rs['report_time'], '%Y-%m-%dT%H:%M:%SZ'))
- self.assertTrue(time.strptime(rs['stats.boot_time'], '%Y-%m-%dT%H:%M:%SZ'))
- self.assertTrue(time.strptime(rs['report_time'], '%Y-%m-%dT%H:%M:%SZ'))
- self.assertTrue(time.time() - rs['stats.timestamp'] >=0)
- self.assertTrue(type(time.time() - rs['stats.timestamp'])==type(float(0.1)))
- self.assertTrue(re.match('^[^@]+@[^@]+$', rs['stats.lname']))
- self.assertEqual(ret_stats['result'][0], 0)
+ session = self.session
+ subject = self.subject
+ stats_spec = self.stats_spec.copy()
+ stats_data = self.stats_data.copy()
+
+ self.assertFalse(subject.running)
+ self.assertRaises(ModuleCCSessionError, subject.start)
+ self.assertTrue(subject.running)
+ for i in (0, 1):
+ subject.session.get_message("ConfigManager", None)
+
+ # test show command
+ session.group_sendmsg({"command": [ "show" ]}, "Stats")
+ self.assertEqual(len(subject.session.message_queue), 1)
+ subject.check()
+ result_data = subject.session.get_message("Stats", None)
+ result_data['result'][1]['stats.timestamp'] = float(int(result_data['result'][1]['stats.timestamp']))
+ self.assertEqual({ "result": [ 0, stats_data ]}, result_data)
+ self.assertEqual(len(subject.session.message_queue), 0)
+
+ # test set command
+ stats_data['atest'] = float(1.0)
+ session.group_sendmsg({"command":
+ [ "set",
+ {'atest' : stats_data['atest']}
+ ]}, "Stats")
+ self.assertEqual(len(subject.session.message_queue), 1)
+ subject.check()
+ self.assertEqual(result_ok(),
+ subject.session.get_message("Stats", None))
+ self.assertEqual(len(subject.session.message_queue), 0)
+
+ # test show command
+ session.group_sendmsg({"command": [ "show" ]}, "Stats")
+ self.assertEqual(len(subject.session.message_queue), 1)
+ subject.check()
+ result_data = subject.session.get_message("Stats", None)
+ result_data['result'][1]['stats.timestamp'] = float(int(result_data['result'][1]['stats.timestamp']))
+ self.assertEqual(result_ok(0, stats_data), result_data)
+ self.assertEqual(len(subject.session.message_queue), 0)
+
+ # test add command
+ stats_data['atest'] = stats_data['atest'] + float(0.1)
+ session.group_sendmsg({"command": [ "add", {'atest': float(0.1) } ]}, "Stats")
+ self.assertEqual(len(subject.session.message_queue), 1)
+ subject.check()
+ self.assertEqual(result_ok(),
+ subject.session.get_message("Stats", None))
+ self.assertEqual(len(subject.session.message_queue), 0)
+
+ # test show command
+ session.group_sendmsg({"command": [ "show" ]}, "Stats")
+ self.assertEqual(len(subject.session.message_queue), 1)
+ subject.check()
+ result_data = subject.session.get_message("Stats", None)
+ result_data['result'][1]['stats.timestamp'] = float(int(result_data['result'][1]['stats.timestamp']))
+ self.assertEqual({ "result": [ 0, stats_data ]}, result_data)
+ self.assertEqual(len(subject.session.message_queue), 0)
+
+ # test del command
+ stats_data.pop('atest')
+ session.group_sendmsg({"command": [ "del", 'atest' ]}, "Stats")
+ self.assertEqual(len(subject.session.message_queue), 1)
+ subject.check()
+ self.assertEqual(result_ok(),
+ subject.session.get_message("Stats", None))
+ self.assertEqual(len(subject.session.message_queue), 0)
+
+ # test show command
+ session.group_sendmsg({"command": [ "show" ]}, "Stats")
+ self.assertEqual(len(subject.session.message_queue), 1)
+ subject.check()
+ result_data = subject.session.get_message("Stats", None)
+ result_data['result'][1]['stats.timestamp'] = float(int(result_data['result'][1]['stats.timestamp']))
+ self.assertEqual({ "result": [ 0, stats_data ]}, result_data)
+ self.assertEqual(len(subject.session.message_queue), 0)
+
+ # test reset command
+ stats_data = self.stats_data.copy()
+ session.group_sendmsg({"command": [ "reset" ]}, "Stats")
+ self.assertEqual(len(subject.session.message_queue), 1)
+ subject.check()
+ self.assertEqual(result_ok(),
+ subject.session.get_message("Stats", None))
+ self.assertEqual(len(subject.session.message_queue), 0)
+
+ # test show command
+ session.group_sendmsg({"command": [ "show" ]}, "Stats")
+ self.assertEqual(len(subject.session.message_queue), 1)
+ subject.check()
+ result_data = subject.session.get_message("Stats", None)
+ result_data['result'][1]['stats.timestamp'] = float(int(result_data['result'][1]['stats.timestamp']))
+ self.assertEqual({ "result": [ 0, stats_data ]}, result_data)
+ self.assertEqual(len(subject.session.message_queue), 0)
+
+ # test show spec command
+ session.group_sendmsg({"command": [ "spec" ]}, "Stats")
+ self.assertEqual(len(subject.session.message_queue), 1)
+ subject.check()
+ self.assertEqual(result_ok(0, stats_spec),
+ subject.session.get_message("Stats", None))
+ self.assertEqual(len(subject.session.message_queue), 0)
+
+ # test status command
+ session.group_sendmsg({"command": [ "status" ]}, "Stats")
+ self.assertEqual(len(subject.session.message_queue), 1)
+ subject.check()
+ self.assertEqual(result_ok(0, "I'm alive."),
+ subject.session.get_message("Stats", None))
+ self.assertEqual(len(subject.session.message_queue), 0)
+
+ # test unknown command
+ session.group_sendmsg({"command": [ "hoge" ]}, "Stats")
+ self.assertEqual(len(subject.session.message_queue), 1)
+ subject.check()
+ self.assertEqual(result_ok(1, "Unknown command: 'hoge'"),
+ subject.session.get_message("Stats", None))
+ self.assertEqual(len(subject.session.message_queue), 0)
+
+ # test shutdown command
+ session.group_sendmsg({"command": [ "shutdown" ]}, "Stats")
+ self.assertEqual(len(subject.session.message_queue), 1)
+ self.assertTrue(subject.running)
+ subject.check()
+ self.assertFalse(subject.running)
+ self.assertEqual(result_ok(),
+ subject.session.get_message("Stats", None))
+ self.assertEqual(len(subject.session.message_queue), 0)
+
+ def tearDown(self):
+ self.session.close()
+
+def result_ok(*args):
+ if args:
+ return { 'result': list(args) }
+ else:
+ return { 'result': [ 0 ] }
+
+def get_timestamp():
+ """
+ get current timestamp
+ """
+ return time.time()
+
+def get_datetime():
+ """
+ get current datetime
+ """
+ return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
if __name__ == "__main__":
unittest.main()
Modified: branches/trac191/src/bin/stats/tests/stats_test.in
==============================================================================
--- branches/trac191/src/bin/stats/tests/stats_test.in (original)
+++ branches/trac191/src/bin/stats/tests/stats_test.in Fri Jul 9 09:16:16 2010
@@ -23,9 +23,6 @@
PYTHONPATH=@abs_top_srcdir@/src/lib/python:@abs_top_srcdir@/src/bin/stats
export PYTHONPATH
-CONFIG_TESTDATA_PATH=@abs_top_srcdir@/src/lib/config/testdata
-export CONFIG_TESTDATA_PATH
-
B10_FROM_SOURCE=@abs_top_srcdir@
export B10_FROM_SOURCE
# TODO: We need to do this feature based (ie. no general from_source)
@@ -36,3 +33,5 @@
cd ${BIND10_PATH}
${PYTHON_EXEC} -O ${STATS_PATH}/b10-stats_test.py $*
+
+${PYTHON_EXEC} -O ${STATS_PATH}/b10-stats_stub_test.py $*
Modified: branches/trac191/src/bin/stats/tests/unittest_fakesession.py
==============================================================================
--- branches/trac191/src/bin/stats/tests/unittest_fakesession.py (original)
+++ branches/trac191/src/bin/stats/tests/unittest_fakesession.py Fri Jul 9 09:16:16 2010
@@ -1,4 +1,8 @@
+# $Id$
+__version__ = "$Revision$"
+import os
+from isc.cc.session import SessionError
#
# We can probably use a more general version of this
@@ -8,7 +12,9 @@
self.subscriptions = {}
# each entry is of the form [ channel, instance, message ]
self.message_queue = []
- self._socket = "ok we just need something not-None here atm"
+ # set socket dummy data
+ cmd = 'for i in 0 1 2 3 4 5 6 7 8 9; do echo testing...; sleep 0; done'
+ self._socket = os.popen(cmd, 'r')
# set lname
self.lname='123abc at xxxx'
@@ -29,13 +35,19 @@
return False
def group_sendmsg(self, msg, channel, target = None):
+ if self._socket.closed:
+ raise SessionError("Session has been closed.")
self.message_queue.append([ channel, target, msg ])
def group_reply(self, env, msg):
+ if self._socket.closed:
+ raise SessionError("Session has been closed.")
if 'group' in env:
self.message_queue.append([ env['group'], None, msg])
def group_recvmsg(self, blocking, seq = None):
+ if self._socket.closed:
+ raise SessionError("Session has been closed.")
for qm in self.message_queue:
if qm[0] in self.subscriptions and (qm[1] == None or qm[1] in self.subscriptions[qm[0]]):
self.message_queue.remove(qm)
@@ -51,5 +63,6 @@
def close(self):
# need to pass along somehow that this function has been called,
- self._socket = "closed"
- pass
+ if not self._socket.closed:
+ buf = self._socket.readlines()
+ self._socket.close()
More information about the bind10-changes
mailing list