Commit eab1ff6c authored by Jelte Jansen's avatar Jelte Jansen
Browse files
parents cd1a6e39 32e4aaa9
206. [func] shane
Add the ability to list the running BIND 10 processes using the
command channel. To try this, use "Boss show_processes".
(Trac #648, git 451bbb67c2b5d544db2f7deca4315165245d2b3b)
205. [bug] jinmei
b10-auth, src/lib/datasrc: fixed a bug where b10-auth could return
an empty additional section for delegation even if some glue is
......
......@@ -720,8 +720,6 @@ AC_OUTPUT([doc/version.ent
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
src/bin/bind10/tests/bind10_test.py
src/bin/bind10/run_bind10.sh
src/bin/bindctl/run_bindctl.sh
src/bin/bindctl/bindctl_main.py
......
#!@PYTHON@
# Copyright (C) 2010 Internet Systems Consortium.
# Copyright (C) 2010,2011 Internet Systems Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
......@@ -139,7 +139,8 @@ class ProcessInfo:
self.restart_schedule = RestartSchedule()
self.uid = uid
self.username = username
self._spawn()
self.process = None
self.pid = None
def _preexec_work(self):
"""Function used before running a program that needs to run as a
......@@ -186,6 +187,11 @@ class ProcessInfo:
self.pid = self.process.pid
self.restart_schedule.set_run_start_time()
# spawn() and respawn() are the same for now, but in the future they
# may have different functionality
def spawn(self):
self._spawn()
def respawn(self):
self._spawn()
......@@ -280,6 +286,14 @@ class BoB:
answer = isc.config.ccsession.create_answer(0)
return answer
def get_processes(self):
pids = list(self.processes.keys())
pids.sort()
process_list = [ ]
for pid in pids:
process_list.append([pid, self.processes[pid].name])
return process_list
def command_handler(self, command, args):
if self.verbose:
sys.stdout.write("[bind10] Boss got command: " + command + "\n")
......@@ -290,8 +304,13 @@ class BoB:
if command == "shutdown":
self.runnable = False
answer = isc.config.ccsession.create_answer(0)
elif command == "ping":
answer = isc.config.ccsession.create_answer(0, "pong")
elif command == "show_processes":
answer = isc.config.ccsession. \
create_answer(0, self.get_processes())
else:
answer = isc.config.ccsession.create_answer(1,
answer = isc.config.ccsession.create_answer(1,
"Unknown command")
return answer
......@@ -379,6 +398,7 @@ class BoB:
c_channel = ProcessInfo("b10-msgq", ["b10-msgq"], c_channel_env,
True, not self.verbose, uid=self.uid,
username=self.username)
c_channel.spawn()
self.processes[c_channel.pid] = c_channel
self.log_started(c_channel.pid)
......@@ -408,6 +428,7 @@ class BoB:
bind_cfgd = ProcessInfo("b10-cfgmgr", args,
c_channel_env, uid=self.uid,
username=self.username)
bind_cfgd.spawn()
self.processes[bind_cfgd.pid] = bind_cfgd
self.log_started(bind_cfgd.pid)
......@@ -442,6 +463,7 @@ class BoB:
"""
self.log_starting(name, port, address)
newproc = ProcessInfo(name, args, c_channel_env)
newproc.spawn()
self.processes[newproc.pid] = newproc
self.log_started(newproc.pid)
......
......@@ -21,6 +21,16 @@
"command_name": "shutdown",
"command_description": "Shut down BIND 10",
"command_args": []
},
{
"command_name": "ping",
"command_description": "Ping the boss process",
"command_args": []
},
{
"command_name": "show_processes",
"command_description": "List the running BIND 10 processes",
"command_args": []
}
]
}
......
......@@ -13,5 +13,6 @@ endif
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_builddir)/src/bin/bind10 \
$(PYCOVERAGE_RUN) $(abs_srcdir)/$$pytest || exit ; \
BIND10_MSGQ_SOCKET_FILE=$(abs_top_builddir)/msgq_socket \
$(PYCOVERAGE_RUN) $(abs_srcdir)/$$pytest || exit ; \
done
#! /bin/sh
# Copyright (C) 2010 Internet Systems Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
PYTHON_EXEC=${PYTHON_EXEC:-@PYTHON@}
export PYTHON_EXEC
BIND10_PATH=@abs_top_srcdir@/src/bin/bind10
PATH=@abs_top_srcdir@/src/bin/msgq:@abs_top_srcdir@/src/bin/auth:@abs_top_srcdir@/src/bin/bind-cfgd:$PATH
export PATH
PYTHONPATH=@abs_top_srcdir@/src/lib/python:@abs_top_srcdir@/src/bin/bind10
export PYTHONPATH
cd ${BIND10_PATH}/tests
${PYTHON_EXEC} -O bind10_test.py $*
exec ${PYTHON_EXEC} -O args_test.py $*
# Copyright (C) 2011 Internet Systems Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
from bind10 import ProcessInfo, BoB, parse_args, dump_pid, unlink_pid_file
# XXX: environment tests are currently disabled, due to the preprocessor
......@@ -31,6 +46,7 @@ class TestProcessInfo(unittest.TestCase):
def test_init(self):
pi = ProcessInfo('Test Process', [ '/bin/echo', 'foo' ])
pi.spawn()
os.dup2(self.old_stdout, sys.stdout.fileno())
self.assertEqual(pi.name, 'Test Process')
self.assertEqual(pi.args, [ '/bin/echo', 'foo' ])
......@@ -51,12 +67,14 @@ class TestProcessInfo(unittest.TestCase):
def test_setting_null_stdout(self):
pi = ProcessInfo('Test Process', [ '/bin/echo', 'foo' ],
dev_null_stdout=True)
pi.spawn()
os.dup2(self.old_stdout, sys.stdout.fileno())
self.assertEqual(pi.dev_null_stdout, True)
self.assertEqual(os.read(self.pipes[0], 100), b"")
def test_respawn(self):
pi = ProcessInfo('Test Process', [ '/bin/echo', 'foo' ])
pi.spawn()
# wait for old process to work...
self.assertEqual(os.read(self.pipes[0], 100), b"foo\n")
# respawn it
......@@ -105,17 +123,19 @@ class TestBoB(unittest.TestCase):
self.assertEqual(bob.cfg_start_auth, True)
self.assertEqual(bob.cfg_start_resolver, False)
# Class for testing the BoB start/stop components routines.
# Class for testing the BoB without actually starting processes.
# This is used for testing the start/stop components routines and
# the BoB commands.
#
# Although testing that external processes start is outside the scope
# Testing that external processes start is outside the scope
# of the unit test, by overriding the process start methods we can check
# that the right processes are started depending on the configuration
# options.
class StartStopCheckBob(BoB):
class MockBob(BoB):
def __init__(self):
BoB.__init__(self)
# Set flags as to which of the overridden methods has been run.
# Set flags as to which of the overridden methods has been run.
self.msgq = False
self.cfgmgr = False
self.ccsession = False
......@@ -127,6 +147,7 @@ class StartStopCheckBob(BoB):
self.stats = False
self.cmdctl = False
self.c_channel_env = {}
self.processes = { }
def read_bind10_config(self):
# Configuration options are set directly
......@@ -134,65 +155,95 @@ class StartStopCheckBob(BoB):
def start_msgq(self, c_channel_env):
self.msgq = True
self.processes[2] = ProcessInfo('b10-msgq', ['/bin/false'])
def start_cfgmgr(self, c_channel_env):
self.cfgmgr = True
self.processes[3] = ProcessInfo('b10-cfgmgr', ['/bin/false'])
def start_ccsession(self, c_channel_env):
self.ccsession = True
self.processes[4] = ProcessInfo('b10-ccsession', ['/bin/false'])
def start_auth(self, c_channel_env):
self.auth = True
self.processes[5] = ProcessInfo('b10-auth', ['/bin/false'])
def start_resolver(self, c_channel_env):
self.resolver = True
self.processes[6] = ProcessInfo('b10-resolver', ['/bin/false'])
def start_xfrout(self, c_channel_env):
self.xfrout = True
self.processes[7] = ProcessInfo('b10-xfrout', ['/bin/false'])
def start_xfrin(self, c_channel_env):
self.xfrin = True
self.processes[8] = ProcessInfo('b10-xfrin', ['/bin/false'])
def start_zonemgr(self, c_channel_env):
self.zonemgr = True
self.processes[9] = ProcessInfo('b10-zonemgr', ['/bin/false'])
def start_stats(self, c_channel_env):
self.stats = True
self.processes[10] = ProcessInfo('b10-stats', ['/bin/false'])
def start_cmdctl(self, c_channel_env):
self.cmdctl = True
self.processes[11] = ProcessInfo('b10-cmdctl', ['/bin/false'])
# We don't really use all of these stop_ methods. But it might turn out
# someone would add some stop_ method to BoB and we want that one overriden
# in case he forgets to update the tests.
def stop_msgq(self):
if self.msgq:
del self.processes[2]
self.msgq = False
def stop_cfgmgr(self):
if self.cfgmgr:
del self.processes[3]
self.cfgmgr = False
def stop_ccsession(self):
if self.ccssession:
del self.processes[4]
self.ccsession = False
def stop_auth(self):
if self.auth:
del self.processes[5]
self.auth = False
def stop_resolver(self):
if self.resolver:
del self.processes[6]
self.resolver = False
def stop_xfrout(self):
if self.xfrout:
del self.processes[7]
self.xfrout = False
def stop_xfrin(self):
if self.xfrin:
del self.processes[8]
self.xfrin = False
def stop_zonemgr(self):
if self.zonemgr:
del self.processes[9]
self.zonemgr = False
def stop_stats(self):
if self.stats:
del self.processes[10]
self.stats = False
def stop_cmdctl(self):
if self.cmdctl:
del self.processes[11]
self.cmdctl = False
class TestStartStopProcessesBob(unittest.TestCase):
......@@ -252,7 +303,7 @@ class TestStartStopProcessesBob(unittest.TestCase):
# is specified.
def test_start_none(self):
# Create BoB and ensure correct initialization
bob = StartStopCheckBob()
bob = MockBob()
self.check_preconditions(bob)
# Start processes and check what was started
......@@ -265,7 +316,7 @@ class TestStartStopProcessesBob(unittest.TestCase):
# Checks the processes started when starting only the auth process
def test_start_auth(self):
# Create BoB and ensure correct initialization
bob = StartStopCheckBob()
bob = MockBob()
self.check_preconditions(bob)
# Start processes and check what was started
......@@ -279,7 +330,7 @@ class TestStartStopProcessesBob(unittest.TestCase):
# Checks the processes started when starting only the resolver process
def test_start_resolver(self):
# Create BoB and ensure correct initialization
bob = StartStopCheckBob()
bob = MockBob()
self.check_preconditions(bob)
# Start processes and check what was started
......@@ -293,7 +344,7 @@ class TestStartStopProcessesBob(unittest.TestCase):
# Checks the processes started when starting both auth and resolver process
def test_start_both(self):
# Create BoB and ensure correct initialization
bob = StartStopCheckBob()
bob = MockBob()
self.check_preconditions(bob)
# Start processes and check what was started
......@@ -311,7 +362,7 @@ class TestStartStopProcessesBob(unittest.TestCase):
"""
# Create BoB and ensure correct initialization
bob = StartStopCheckBob()
bob = MockBob()
self.check_preconditions(bob)
# Start processes (nothing much should be started, as in
......@@ -376,7 +427,7 @@ class TestStartStopProcessesBob(unittest.TestCase):
Tests that a process is started only once.
"""
# Create BoB and ensure correct initialization
bob = StartStopCheckBob()
bob = MockBob()
self.check_preconditions(bob)
# Start processes (both)
......@@ -402,7 +453,7 @@ class TestStartStopProcessesBob(unittest.TestCase):
Test that processes are not started by the config handler before
startup.
"""
bob = StartStopCheckBob()
bob = MockBob()
self.check_preconditions(bob)
bob.start_auth = lambda: self.fail("Started auth again")
......@@ -413,6 +464,41 @@ class TestStartStopProcessesBob(unittest.TestCase):
bob.config_handler({'start_auth': True, 'start_resolver': True})
class TestBossCmd(unittest.TestCase):
def test_ping(self):
"""
Confirm simple ping command works.
"""
bob = MockBob()
answer = bob.command_handler("ping", None)
self.assertEqual(answer, {'result': [0, 'pong']})
def test_show_processes(self):
"""
Confirm getting a list of processes works.
"""
bob = MockBob()
answer = bob.command_handler("show_processes", None)
self.assertEqual(answer, {'result': [0, []]})
def test_show_processes_started(self):
"""
Confirm getting a list of processes works.
"""
bob = MockBob()
bob.start_all_processes()
answer = bob.command_handler("show_processes", None)
processes = [[2, 'b10-msgq'],
[3, 'b10-cfgmgr'],
[4, 'b10-ccsession'],
[5, 'b10-auth'],
[7, 'b10-xfrout'],
[8, 'b10-xfrin'],
[9, 'b10-zonemgr'],
[10, 'b10-stats'],
[11, 'b10-cmdctl']]
self.assertEqual(answer, {'result': [0, processes]})
class TestParseArgs(unittest.TestCase):
"""
This tests parsing of arguments of the bind10 master process.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment