Author: aconway
Date: Fri Jun 13 19:08:11 2014
New Revision: 1602493
URL: http://svn.apache.org/r1602493
Log:
NO-JIRA: Minor system test improvements.
- Replaced qdtest.in with tests/run_system_tests.py
- Use system_test framework to start router.
- Runs all installed system tests, doesn't need to be updated for new tests.
- Replaced qdstat_test.sh with tests/system_test_qdstat.py
- Added basic verification of qdstat output.
Added:
qpid/dispatch/trunk/tests/run_system_tests.py
qpid/dispatch/trunk/tests/system_tests_qdstat.py
Removed:
qpid/dispatch/trunk/tests/qdstat_test.sh
qpid/dispatch/trunk/tools/qdtest.in
Modified:
qpid/dispatch/trunk/CMakeLists.txt
qpid/dispatch/trunk/bin/test.sh
qpid/dispatch/trunk/tests/CMakeLists.txt
qpid/dispatch/trunk/tests/system_test.py
qpid/dispatch/trunk/tests/system_tests_broker.py
Modified: qpid/dispatch/trunk/CMakeLists.txt
URL:
http://svn.apache.org/viewvc/qpid/dispatch/trunk/CMakeLists.txt?rev=1602493&r1=1602492&r2=1602493&view=diff
==============================================================================
--- qpid/dispatch/trunk/CMakeLists.txt (original)
+++ qpid/dispatch/trunk/CMakeLists.txt Fri Jun 13 19:08:11 2014
@@ -100,9 +100,6 @@ configure_file(${CMAKE_CURRENT_SOURCE_DI
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tools/qdstat.in
${CMAKE_CURRENT_BINARY_DIR}/tools/qdstat)
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tools/qdtest.in
- ${CMAKE_CURRENT_BINARY_DIR}/tools/qdtest)
-
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/build_env.py.in
${CMAKE_CURRENT_BINARY_DIR}/build_env.py)
@@ -161,7 +158,6 @@ install(FILES etc/qdrouterd.conf DESTINA
##
set(TOOLS_EXECUTABLES
${CMAKE_CURRENT_BINARY_DIR}/tools/qdstat
- ${CMAKE_CURRENT_BINARY_DIR}/tools/qdtest
)
set(DOC_FILES
Modified: qpid/dispatch/trunk/bin/test.sh
URL:
http://svn.apache.org/viewvc/qpid/dispatch/trunk/bin/test.sh?rev=1602493&r1=1602492&r2=1602493&view=diff
==============================================================================
--- qpid/dispatch/trunk/bin/test.sh (original)
+++ qpid/dispatch/trunk/bin/test.sh Fri Jun 13 19:08:11 2014
@@ -36,4 +36,4 @@ cmake -D CMAKE_INSTALL_PREFIX=$INSTALL_D
make -j4
make install
ctest -VV
-qdtest
+python $INSTALL_DIR/lib/qpid-dispatch/tests/run_system_tests.py
Modified: qpid/dispatch/trunk/tests/CMakeLists.txt
URL:
http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/CMakeLists.txt?rev=1602493&r1=1602492&r2=1602493&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/CMakeLists.txt (original)
+++ qpid/dispatch/trunk/tests/CMakeLists.txt Fri Jun 13 19:08:11 2014
@@ -54,7 +54,7 @@ add_test(unit_tests unit_test
add_test(router_tests ${PYTHON_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/router_engine_test.py -v)
add_test(management_tests ${PYTHON_EXECUTABLE}
${CMAKE_BINARY_DIR}/build_env.py ${PYTHON_EXECUTABLE} -m unittest -v management)
-set(SYSTEM_TEST_FILES system_test.py system_tests_one_router.py
system_tests_two_routers.py system_tests_broker.py system_tests_management.py)
+set(SYSTEM_TEST_FILES run_system_tests.py system_test.py
system_tests_one_router.py system_tests_two_routers.py system_tests_broker.py
system_tests_management.py system_tests_qdstat.py)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config_build.sh.in
${CMAKE_CURRENT_BINARY_DIR}/config_build.sh)
@@ -65,10 +65,6 @@ install(FILES ${SYSTEM_TEST_FILES}
DESTINATION ${QPID_DISPATCH_HOME_INSTALLED}/tests
)
-install(FILES qdstat_test.sh
- DESTINATION ${QPID_DISPATCH_HOME_INSTALLED}/tests
- )
-
install(DIRECTORY config-1 config-2
DESTINATION ${QPID_DISPATCH_HOME_INSTALLED}/tests
PATTERN *.in EXCLUDE
Added: qpid/dispatch/trunk/tests/run_system_tests.py
URL:
http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/run_system_tests.py?rev=1602493&view=auto
==============================================================================
--- qpid/dispatch/trunk/tests/run_system_tests.py (added)
+++ qpid/dispatch/trunk/tests/run_system_tests.py Fri Jun 13 19:08:11 2014
@@ -0,0 +1,50 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License
+#
+
+"""
+Runs all scripts named system_tests_*.py in the same directory as this script.
+Note that each system test is an executable script, you can run them directly.
+"""
+
+import os
+import sys
+import re
+import unittest
+
+# Collect all system_tests_*.py scripts
+test_dir = os.path.normpath(os.path.dirname(__file__))
+os.environ.setdefault('QPID_DISPATCH_HOME', os.path.dirname(test_dir))
+tests = [[f] for f in os.listdir(test_dir) if re.match('^system_tests.*.py$',
f)]
+
+# Tests to re-run with extra parameters
+tests += [['system_tests_two_routers.py', '--ssl']]
+
+status = 0
+
+def run_test(script, *args):
+ global status
+ cmd = "%s %s -v %s"%(sys.executable, os.path.join(test_dir,script), "
".join(args))
+ sys.stderr.write("\nRunning %s\n"%cmd)
+ if os.system(cmd) != 0:
+ status = 1
+
+for test in tests:
+ run_test(*test)
+
+sys.exit(status)
Modified: qpid/dispatch/trunk/tests/system_test.py
URL:
http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/system_test.py?rev=1602493&r1=1602492&r2=1602493&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/system_test.py (original)
+++ qpid/dispatch/trunk/tests/system_test.py Fri Jun 13 19:08:11 2014
@@ -200,11 +200,22 @@ class Process(subprocess.Popen):
EXIT_FAIL = 3 # Exit status not 0
def __init__(self, name, args, expect=EXIT_OK, **kwargs):
+ """
+ Takes same arguments as subprocess.Popen. Some additional/special args:
+ @param expect: Raise error if process staus not as expected at end of
test:
+ L{RUNNING} - expect still running.
+ L{EXIT_OK} - expect proces to have terminated with 0 exit status.
+ L{EXIT_ERROR} - expect proces to have terminated with non-0 exit
status.
+ @keyword stdout: Defaults to the file name+".out"
+ @keyword stderr: Defaults to be the same as stdout
+ """
self.name, self.args, self.expect = name, args, expect
self.out = open(name+".out", 'w')
+ with open(name+".cmd", 'w') as f: f.write("%s\n" % ' '.join(args))
self.torndown = False
- super(Process, self).__init__(
- args, stdout=self.out, stderr=subprocess.STDOUT, **kwargs)
+ kwargs.setdefault('stdout', self.out)
+ kwargs.setdefault('stderr', kwargs['stdout'])
+ super(Process, self).__init__(args, **kwargs)
def assert_running(self):
"""Assert that the proces is still running"""
@@ -316,11 +327,17 @@ class Qdrouterd(Process):
return [dict(zip(attrs, values)) for values in
response.body['results']]
- def __init__(self, name, config=Config()):
+ def __init__(self, name, config=Config(), wait=True):
+ """
+ @param name: name used for for output files.
+ @param config: router configuration
+ @keyword wait: wait for router to be ready (call self.wait_ready())
+ """
self.config = copy(config)
super(Qdrouterd, self).__init__(
name, ['qdrouterd', '-c', config.write(name)],
expect=Process.RUNNING)
self._agent = None
+ if wait: self.wait_ready()
@property
def agent(self):
@@ -344,6 +361,11 @@ class Qdrouterd(Process):
"""Return amqp://host:port addresses for all listeners"""
return ["amqp://%s:%s"%(l['addr'], l['port']) for l in
self.config.sections('listener')]
+ @property
+ def hostports(self):
+ """Return host:port for all listeners"""
+ return ["%s:%s"%(l['addr'], l['port']) for l in
self.config.sections('listener')]
+
def is_connected(self, port, host='0.0.0.0'):
"""If router has a connection to host:port return the management info.
Otherwise return None"""
@@ -545,6 +567,7 @@ class TestCase(unittest.TestCase, Tester
if os.path.commonprefix([os.getcwd(), cls.base_dir()]) ==
cls.base_dir():
os.chdir(os.path.dirname(cls.base_dir()))
shutil.rmtree(cls.base_dir(), ignore_errors=True) # Clear old test
tree.
+ assert cls is not TestCase
cls.tester = Tester()
cls.tester.setup(os.path.join(cls.base_dir(), 'setup_class'))
@@ -552,6 +575,7 @@ class TestCase(unittest.TestCase, Tester
def tearDownClass(cls):
if inspect.isclass(cls):
cls.tester.teardown()
+ del cls.tester
def setUp(self):
# Hack to support setUpClass on older python.
Modified: qpid/dispatch/trunk/tests/system_tests_broker.py
URL:
http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/system_tests_broker.py?rev=1602493&r1=1602492&r2=1602493&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/system_tests_broker.py (original)
+++ qpid/dispatch/trunk/tests/system_tests_broker.py Fri Jun 13 19:08:11 2014
@@ -32,9 +32,9 @@ class DistributedQueueTest(system_test.T
def setUpClass(cls):
"""Start 3 qpidd brokers, wait for them to be ready."""
super(DistributedQueueTest, cls).setUpClass()
- cls.qpidd = [cls.tester.qpidd('qpidd%s'%i, port=cls.get_port())
+ cls.qpidds = [cls.tester.qpidd('qpidd%s'%i, port=cls.get_port())
for i in xrange(3)]
- for q in cls.qpidd:
+ for q in cls.qpidds:
wait_port(q.port)
@classmethod
@@ -64,7 +64,7 @@ class DistributedQueueTest(system_test.T
msgr.subscribe(a)
msgr.flush()
n = 20 # Messages per broker
- r = ["x-%02d"%i for i in range(n*len(self.qpidd))]
+ r = ["x-%02d"%i for i in range(n*len(self.qpidds))]
for b, a in zip(r, cycle(send_addresses)):
msgr.put(message(address=a, body=b))
msgr.flush()
@@ -72,7 +72,7 @@ class DistributedQueueTest(system_test.T
msgr.flush()
self.assertEqual(r, messages)
- qs = [q.agent.getQueue(self.testq) for q in self.qpidd]
+ qs = [q.agent.getQueue(self.testq) for q in self.qpidds]
enq = sum(q.msgTotalEnqueues for q in qs)
deq = sum(q.msgTotalDequeues for q in qs)
self.assertEquals((enq, deq), (len(r), len(r)))
@@ -82,7 +82,7 @@ class DistributedQueueTest(system_test.T
def test_distrbuted_queue(self):
"""Create a distributed queue with N routers and N brokers.
Each router is connected to all the brokers."""
- for q in self.qpidd:
+ for q in self.qpidds:
q.agent.addQueue(self.testq)
def router(i):
@@ -93,12 +93,12 @@ class DistributedQueueTest(system_test.T
('listener', {'port':self.get_port(), 'role':'normal'}),
('fixed-address', {'prefix':self.testq, 'phase':0,
'fanout':'single', 'bias':'spread'}),
('fixed-address', {'prefix':self.testq, 'phase':1,
'fanout':'single', 'bias':'spread'})]
- for q in self.qpidd:
+ for q in self.qpidds:
rconf += [
('connector', {'name':q.name, 'port':q.port}),
('waypoint', {'name':self.testq, 'out-phase':1,
'in-phase':0, 'connector':q.name})]
return self.qdrouterd(name, rconf)
- routers = [router(i) for i in xrange(len(self.qpidd))]
+ routers = [router(i) for i in xrange(len(self.qpidds))]
for r in routers: r.wait_ready()
addrs = [r.addresses[0]+"/"+self.testq for r in routers]
self.verify_equal_spread(addrs, addrs)
Added: qpid/dispatch/trunk/tests/system_tests_qdstat.py
URL:
http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/system_tests_qdstat.py?rev=1602493&view=auto
==============================================================================
--- qpid/dispatch/trunk/tests/system_tests_qdstat.py (added)
+++ qpid/dispatch/trunk/tests/system_tests_qdstat.py Fri Jun 13 19:08:11 2014
@@ -0,0 +1,69 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License
+#
+
+import re
+import system_test
+import unittest
+from subprocess import PIPE
+
+class QdstatTest(system_test.TestCase):
+ """Test qdstat tool output"""
+
+ @classmethod
+ def setUpClass(cls):
+ super(QdstatTest, cls).setUpClass()
+ config = system_test.Qdrouterd.Config([
+ ('listener', {'port': cls.tester.get_port()})
+ ])
+ cls.router = cls.tester.qdrouterd('test-router', config)
+
+ def run_qdstat(self, args, regexp=None):
+ p = self.popen('qdstat-'+self.id(),
+ ['qdstat', '--bus', self.router.hostports[0]]+args,
+ stdout=PIPE)
+ out = p.communicate()[0]
+ self.assertEqual(0, p.returncode, "qdstat exit status %s, output:\n%s"
% (p.returncode, out))
+ if regexp: assert re.search(regexp, out, re.I), "Can't find '%s' in
'%s'" % (regexp, out)
+ return out
+
+ def test_help(self):
+ self.run_qdstat(['--help'], r'Usage: qdstat')
+
+ def test_general(self):
+ self.run_qdstat(['--general'], r'(?s)Router
Statistics.*Mode\s*Endpoint')
+
+ def test_connections(self):
+ self.run_qdstat(['--connections'], r'state.*host.*container')
+
+ def test_links(self):
+ self.run_qdstat(['--links'], r'endpoint.*out.*local.*temp.')
+
+ def test_nodes(self):
+ self.run_qdstat(['--nodes'], r'router-id\s+next-hop\s+link')
+
+ def test_address(self):
+ self.run_qdstat(['--address'], r'local.*\$management')
+
+ def test_memory(self):
+ self.run_qdstat(['--memory'], r'qd_address_t\s+[0-9]+')
+
+
+
+if __name__ == '__main__':
+ unittest.main()
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]