You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ch...@apache.org on 2019/01/23 21:29:36 UTC
[qpid-dispatch] branch master updated: DISPATCH-1255: Delete and
ignore configured output files
This is an automated email from the ASF dual-hosted git repository.
chug pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git
The following commit(s) were added to refs/heads/master by this push:
new 1fe7038 DISPATCH-1255: Delete and ignore configured output files
1fe7038 is described below
commit 1fe70381cc64c9d3e38cc9eff2a8a07c56736f82
Author: Chuck Rolke <ch...@apache.org>
AuthorDate: Wed Jan 23 16:28:04 2019 -0500
DISPATCH-1255: Delete and ignore configured output files
---
.gitignore | 2 +
tests/system_tests_authz_service_plugin.py | 208 -------------------
tests/system_tests_handle_failover.py | 309 -----------------------------
3 files changed, 2 insertions(+), 517 deletions(-)
diff --git a/.gitignore b/.gitignore
index 416e609..aa0aaa8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,8 @@ tests/system_test.dir/
tests/policy-1/policy-*.json
tests/authservice.py
tests/failoverserver.py
+tests/system_tests_authz_service_plugin.py
+tests/system_tests_handle_failover.py
*.iml
.idea
.metadata
diff --git a/tests/system_tests_authz_service_plugin.py b/tests/system_tests_authz_service_plugin.py
deleted file mode 100644
index 392e1a8..0000000
--- a/tests/system_tests_authz_service_plugin.py
+++ /dev/null
@@ -1,208 +0,0 @@
-#
-# 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.
-#
-
-from __future__ import unicode_literals
-from __future__ import division
-from __future__ import absolute_import
-from __future__ import print_function
-
-import unittest2 as unittest
-import os, json
-from subprocess import PIPE, Popen, STDOUT
-from system_test import TestCase, Qdrouterd, main_module, DIR, TIMEOUT, Process, SkipIfNeeded
-from proton import Array, Data, Message, SASL, symbol, UNDESCRIBED
-from proton.handlers import MessagingHandler
-from proton.reactor import Container
-
-
-class AuthServicePluginAuthzTest(TestCase):
- @classmethod
- def addUser(cls, user, password):
- # Create a sasl database.
- p = Popen(['saslpasswd2', '-c', '-p', '-f', 'users.sasldb', user],
- stdin=PIPE, stdout=PIPE, stderr=PIPE, universal_newlines=True)
- result = p.communicate(password)
- assert p.returncode == 0, "saslpasswd2 exit status %s, output:\n%s" % (p.returncode, result)
-
- @classmethod
- def createSaslFiles(cls):
- cls.addUser('guest', 'guest')
- cls.addUser('admin', 'admin')
- # Create a SASL configuration file.
- with open('tests-mech-SCRAM.conf', 'w') as sasl_conf:
- sasl_conf.write("""
-mech_list: SCRAM-SHA-1 PLAIN
-""")
- with open('proton-server.conf', 'w') as sasl_conf:
- sasl_conf.write("""
-pwcheck_method: auxprop
-auxprop_plugin: sasldb
-sasldb_path: users.sasldb
-mech_list: SCRAM-SHA-1 PLAIN
-""")
-
-
- @classmethod
- def setUpClass(cls):
- """
- Tests the delegation of sasl auth to an external auth service.
- """
- super(AuthServicePluginAuthzTest, cls).setUpClass()
-
- if not SASL.extended():
- return
-
- cls.createSaslFiles()
-
- cls.auth_service_port = cls.tester.get_port()
- cls.tester.popen(['/usr/bin/env', 'python', os.path.join(os.path.dirname(os.path.abspath(__file__)), 'authservice.py'), '-a', 'amqps://127.0.0.1:%d' % cls.auth_service_port, '-c', os.getcwd()], expect=Process.RUNNING)
-
- policy_config_path = os.path.join(DIR, 'policy-authz')
-
- cls.router_port = cls.tester.get_port()
- cls.tester.qdrouterd('router', Qdrouterd.Config([
- ('sslProfile', {'name':'myssl'}),
- ('policy', {'maxConnections': 2, 'policyDir': policy_config_path, 'enableVhostPolicy': 'true'}),
- # authService attribute has been deprecated. We are using it here to make sure that we are
- # still backward compatible.
- ('authServicePlugin', {'name':'myauth', 'sslProfile':'myssl', 'port': cls.auth_service_port, 'host': '127.0.0.1'}),
- ('listener', {'host': '0.0.0.0', 'port': cls.router_port, 'role': 'normal', 'saslPlugin':'myauth', 'saslMechanisms':'SCRAM-SHA-1 PLAIN'}),
- ('router', {'mode': 'standalone', 'id': 'router',
- 'saslConfigName': 'tests-mech-SCRAM',
- 'saslConfigPath': os.getcwd()})
- ])).wait_ready()
-
- @SkipIfNeeded(not SASL.extended(), "Cyrus library not available. skipping test")
- def test_authorized(self):
- container = Container()
- client = ConnectionHandler('foo', 1)
- container.connect("guest:guest@127.0.0.1:%d" % self.router_port, handler=client)
- container.run()
- self.assertEqual(1, client.sent)
- self.assertEqual(1, client.received)
- self.assertEqual(0, len(client.errors))
-
- @SkipIfNeeded(not SASL.extended(), "Cyrus library not available. skipping test")
- def test_unauthorized(self):
- container = Container()
- client = ConnectionHandler('bar', 1)
- container.connect("guest:guest@127.0.0.1:%d" % self.router_port, handler=client)
- container.run()
- self.assertEqual(0, client.sent)
- self.assertEqual(0, client.received)
- self.assertEqual(2, len(client.errors))
- self.assertEqual('amqp:unauthorized-access', client.errors[0])
- self.assertEqual('amqp:unauthorized-access', client.errors[1])
-
- @SkipIfNeeded(not SASL.extended(), "Cyrus library not available. skipping test")
- def test_wildcard(self):
- container = Container()
- client = ConnectionHandler('whatever', 1)
- container.connect("admin:admin@127.0.0.1:%d" % self.router_port, handler=client)
- container.run()
- self.assertEqual(1, client.sent)
- self.assertEqual(1, client.received)
- self.assertEqual(0, len(client.errors))
-
- @SkipIfNeeded(not SASL.extended(), "Cyrus library not available. skipping test")
- def test_dynamic_source_anonymous_sender(self):
- container = Container()
- client = DynamicSourceAnonymousSender()
- container.connect("admin:admin@127.0.0.1:%d" % self.router_port, handler=client)
- container.run()
- self.assertEqual('hello', client.message)
- self.assertEqual(0, len(client.errors))
-
-
-class AuthServicePluginAuthzDeprecatedTest(AuthServicePluginAuthzTest):
- @classmethod
- def setUpClass(cls):
- """
- Tests the delegation of sasl auth to an external auth service.
- """
- super(AuthServicePluginAuthzTest, cls).setUpClass()
-
- if not SASL.extended():
- return
-
- cls.createSaslFiles()
-
- cls.auth_service_port = cls.tester.get_port()
- cls.tester.popen(['/usr/bin/env', 'python', os.path.join(os.path.dirname(os.path.abspath(__file__)), 'authservice.py'), '-a', 'amqps://127.0.0.1:%d' % cls.auth_service_port, '-c', os.getcwd()], expect=Process.RUNNING)
-
- cls.router_port = cls.tester.get_port()
- cls.tester.qdrouterd('router', Qdrouterd.Config([
- ('sslProfile', {'name':'myssl'}),
- # authService and authSslProfile attributea have been deprecated.
- # We are using it here to make sure that we are backward compatible.
- ('authServicePlugin', {'name':'myauth', 'authSslProfile':'myssl', 'authService': '127.0.0.1:%d' % cls.auth_service_port}),
- ('listener', {'host': '0.0.0.0', 'port': cls.router_port, 'role': 'normal', 'saslPlugin':'myauth', 'saslMechanisms':'SCRAM-SHA-1 PLAIN'}),
- ('router', {'mode': 'standalone', 'id': 'router',
- 'saslConfigName': 'tests-mech-SCRAM',
- 'saslConfigPath': os.getcwd()})
- ])).wait_ready()
-class ConnectionHandler(MessagingHandler):
- def __init__(self, address, count):
- super(ConnectionHandler, self).__init__()
- self.address = address
- self.count = count
- self.received = 0
- self.sent = 0
- self.errors = []
-
- def on_message(self, event):
- self.received += 1
- if self.received == self.count:
- event.connection.close()
-
- def on_sendable(self, event):
- if self.sent < self.count:
- self.sent += 1
- event.sender.send(Message(body='msg-%s' %self.sent))
-
- def on_link_error(self, event):
- self.errors.append(event.link.remote_condition.name)
- event.connection.close()
-
- def on_connection_opened(self, event):
- event.container.create_receiver(event.connection, self.address)
- event.container.create_sender(event.connection, self.address)
-
-class DynamicSourceAnonymousSender(MessagingHandler):
- def __init__(self):
- super(DynamicSourceAnonymousSender, self).__init__()
- self.sender = None
- self.message = None
- self.errors = []
-
- def on_message(self, event):
- self.message = event.message.body;
- event.connection.close()
-
- def on_link_opened(self, event):
- if event.receiver:
- self.sender.send(Message(address=event.receiver.remote_source.address, body='hello'))
-
- def on_connection_opened(self, event):
- event.container.create_receiver(event.connection, None, dynamic=True)
- self.sender = event.container.create_sender(event.connection, None)
-
-if __name__ == '__main__':
- unittest.main(main_module())
-
diff --git a/tests/system_tests_handle_failover.py b/tests/system_tests_handle_failover.py
deleted file mode 100644
index 9020e7d..0000000
--- a/tests/system_tests_handle_failover.py
+++ /dev/null
@@ -1,309 +0,0 @@
-#
-# 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.
-#
-
-from __future__ import unicode_literals
-from __future__ import division
-from __future__ import absolute_import
-from __future__ import print_function
-
-import os
-from threading import Timer
-import unittest2 as unittest
-import json, re
-from system_test import main_module, TIMEOUT
-from system_test import TestCase, Qdrouterd, Process, TIMEOUT
-from subprocess import PIPE, STDOUT
-
-
-class FailoverTest(TestCase):
- inter_router_port = None
-
- @classmethod
- def router(cls, name, config):
- config = Qdrouterd.Config(config)
-
- cls.routers.append(cls.tester.qdrouterd(name, config, wait=True))
-
- @classmethod
- def setUpClass(cls):
- super(FailoverTest, cls).setUpClass()
-
- cls.routers = []
-
- cls.inter_router_port = cls.tester.get_port()
- cls.inter_router_port_1 = cls.tester.get_port()
- cls.backup_port = cls.tester.get_port()
- cls.backup_url = 'amqp://0.0.0.0:' + str(cls.backup_port)
- cls.my_server_port = cls.tester.get_port()
-
- cls.failover_list = 'amqp://third-host:5671, ' + cls.backup_url
-
- #
- # Router A tries to connect to Router B via its connectorToB. Router B responds with an open frame which will
- # have the failover-server-list as one of its connection properties like the following -
- # [0x13024d0]:0 <- @open(16) [container-id="Router.A", max-frame-size=16384, channel-max=32767,
- # idle-time-out=8000, offered-capabilities=:"ANONYMOUS-RELAY",
- # properties={:product="qpid-dispatch-router", :version="1.0.0",
- # :"failover-server-list"=[{:"network-host"="some-host", :port="35000"},
- # {:"network-host"="0.0.0.0", :port="25000"}]}]
- #
- # The suite of tests determine if the router receiving this open frame stores it properly and if the
- # original connection goes down, check that the router is trying to make connections to the failover urls.
- #
- FailoverTest.router('B', [
- ('router', {'mode': 'interior', 'id': 'B'}),
- ('listener', {'host': '0.0.0.0', 'role': 'inter-router', 'port': cls.inter_router_port,
- 'failoverUrls': cls.failover_list}),
- ('listener', {'host': '0.0.0.0', 'role': 'normal', 'port': cls.tester.get_port()}),
- ]
- )
-
- FailoverTest.router('A',
- [
- ('router', {'mode': 'interior', 'id': 'A'}),
- ('listener', {'host': '0.0.0.0', 'role': 'normal', 'port': cls.tester.get_port()}),
- ('connector', {'name': 'connectorToB', 'role': 'inter-router',
- 'port': cls.inter_router_port, 'verifyHostname': 'no'}),
- ]
- )
-
- FailoverTest.router('C', [
- ('router', {'mode': 'interior', 'id': 'C'}),
- ('listener', {'host': '0.0.0.0', 'role': 'inter-router', 'port': cls.backup_port}),
- ('listener', {'host': '0.0.0.0', 'role': 'normal', 'port': cls.tester.get_port()}),
- ]
- )
-
- cls.routers[1].wait_router_connected('B')
-
- def __init__(self, test_method):
- TestCase.__init__(self, test_method)
- self.success = False
- self.timer_delay = 2
- self.max_attempts = 10
- self.attempts = 0
-
- def address(self):
- return self.routers[1].addresses[0]
-
- def run_qdmanage(self, cmd, input=None, expect=Process.EXIT_OK, address=None):
- p = self.popen(
- ['qdmanage'] + cmd.split(' ') + ['--bus', address or self.address(), '--indent=-1', '--timeout', str(TIMEOUT)],
- stdin=PIPE, stdout=PIPE, stderr=STDOUT, expect=expect,
- universal_newlines=True)
- out = p.communicate(input)[0]
- try:
- p.teardown()
- except Exception as e:
- raise Exception("%s\n%s" % (e, out))
- return out
-
- def run_qdstat(self, args, regexp=None, address=None):
- p = self.popen(
- ['qdstat', '--bus', str(address or self.router.addresses[0]), '--timeout', str(TIMEOUT) ] + args,
- name='qdstat-'+self.id(), stdout=PIPE, expect=None,
- universal_newlines=True)
-
- out = p.communicate()[0]
- assert p.returncode == 0, \
- "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_1_connector_has_failover_list(self):
- """
- This is the most simple and straightforward case. Router A connects to Router B. Router B sends
- failover information to Router A.
- We make a qdmanage connector query to Router A which checks if Router A is storing the failover information
- received from Router B.The failover list must consist of the original connection info (from the connector)
- followed by the two items sent by the Router B (stored in cls.failover_list)
- The 'failoverUrls' is comma separated.
- """
- long_type = 'org.apache.qpid.dispatch.connector'
- query_command = 'QUERY --type=' + long_type
- output = json.loads(self.run_qdmanage(query_command))
- expected = "amqp://127.0.0.1:" + str(FailoverTest.inter_router_port) + ", " + FailoverTest.failover_list
-
- self.assertEqual(expected, output[0]['failoverUrls'])
-
- def schedule_B_to_C_failover_test(self):
- if self.attempts < self.max_attempts:
- if not self.success:
- Timer(self.timer_delay, self.check_C_connector).start()
- self.attempts += 1
-
- def check_C_connector(self):
- long_type = 'org.apache.qpid.dispatch.connector'
- query_command = 'QUERY --type=' + long_type
- output = json.loads(self.run_qdmanage(query_command, address=self.routers[1].addresses[0]))
-
- expected = FailoverTest.backup_url + ", " + "amqp://127.0.0.1:" + str(FailoverTest.inter_router_port) \
- + ", " + "amqp://third-host:5671"
-
- if output[0].get('failoverUrls') == expected:
- self.success = True
- else:
- self.schedule_B_to_C_failover_test()
-
- def can_terminate(self):
- if self.attempts == self.max_attempts:
- return True
-
- if self.success:
- return True
-
- return False
-
- def test_2_remove_router_B(self):
- """
- In this test, we are killing Router B. As a result, Router A should try to connect to Router C.
- Router C does NOT have a failover list, so the open frame that Router C sends to Router A will not contain
- the failover-server-list property..Hence the failoverUrls list will remain unchanged except that the order of
- the URLs would be different.
- """
-
- # First make sure there are no inter-router connections on router C
- outs = self.run_qdstat(['--connections'], address=self.routers[2].addresses[1])
-
- inter_router = 'inter-router' in outs
- self.assertFalse(inter_router)
-
- # Kill the router B
- FailoverTest.routers[0].teardown()
-
- # Schedule a test to make sure that the failover url is available
- # and Router C has an inter-router connection
- self.schedule_B_to_C_failover_test()
-
- while not self.can_terminate():
- pass
-
- self.assertTrue(self.success)
-
-
- def schedule_C_to_B_failover_test(self):
- if self.attempts < self.max_attempts:
- if not self.success:
- Timer(self.timer_delay, self.check_B_connector).start()
- self.attempts += 1
-
- def check_B_connector(self):
- # Router A should now try to connect to Router B again since we killed Router C.
- long_type = 'org.apache.qpid.dispatch.connector'
- query_command = 'QUERY --type=' + long_type
- output = json.loads(self.run_qdmanage(query_command, address=self.routers[1].addresses[0]))
-
- # The order that the URLs appear in the failoverUrls is important. This is the order in which the router
- # will attempt to make connections in case the existing connection goes down.
-
- expected = "amqp://127.0.0.1:" + str(FailoverTest.inter_router_port) + ", " + \
- FailoverTest.failover_list + \
- ', amqp://127.0.0.1:%d' % FailoverTest.my_server_port
-
- if output[0].get('failoverUrls') == expected:
- self.success = True
- else:
- self.schedule_C_to_B_failover_test()
-
- def test_3_reinstate_router_B(self):
- """
- In this test, we are restarting Router B and killing Router C. Router A should now try to connect back to
- Router B since it maintains the original connection info to Router B from the connector config information.
- Before starting Router B back again, we
- have a small config change to Router B wherein we are adding a new failover url to the original list.
- This new failover url
- points to our own server which will accept connections. This server will actually be used in the next test
- but this test maskes sure that the new server url also shows up in the failoverUrls list.
- """
- FailoverTest.router('B', [
- ('router', {'mode': 'interior', 'id': 'B'}),
- ('listener', {'host': '0.0.0.0', 'role': 'inter-router', 'port': FailoverTest.inter_router_port,
- 'failoverUrls': FailoverTest.failover_list + ', amqp://127.0.0.1:%d' % FailoverTest.my_server_port}),
- ('listener', {'host': '0.0.0.0', 'role': 'normal', 'port': FailoverTest.tester.get_port()}),
- ])
-
- FailoverTest.routers[3].wait_ready()
-
- # Kill the router C.
- # Now since Router B is up and running, router A should try to re-connect to Router B.
- # This will prove that the router A is preserving the original connector information specified in its config.
- FailoverTest.routers[2].teardown()
-
- self.success = False
- self.attempts = 0
-
- # Schedule a test to make sure that the failover url is available
- self.schedule_C_to_B_failover_test()
-
- while not self.can_terminate():
- pass
-
- self.assertTrue(self.success)
-
- def check_A_connector(self):
- # Router A should now try to connect to Router B again since we killed Router C.
- long_type = 'org.apache.qpid.dispatch.connector'
- query_command = 'QUERY --type=' + long_type
- output = json.loads(self.run_qdmanage(query_command, address=self.routers[1].addresses[0]))
-
- # The order that the URLs appear in the failoverUrls is important. This is the order in which the router
- # will attempt to make connections in case the existing connection goes down.
- expected = 'amqp://127.0.0.1:%d' % FailoverTest.my_server_port + ", " + "amqp://127.0.0.1:" + str(FailoverTest.inter_router_port)
-
- if output[0].get('failoverUrls') == expected:
- self.success = True
- else:
- self.schedule_B_to_my_server_failover_test()
-
- def schedule_B_to_my_server_failover_test(self):
- if self.attempts < self.max_attempts:
- if not self.success:
- Timer(self.timer_delay, self.check_A_connector).start()
- self.attempts += 1
-
- def test_4_remove_router_B_connect_to_my_server(self):
- """
- This test kills Router B again and makes sure that Router A now connects to our custom server that
- accepts connections. This custom server intentionally sends an empty list for failover-server-list
- Router A must look at this empty list and wipe out all failover information except the original connector information
- and the current connection info.
- """
-
-
- # Start MyServer
- proc = FailoverTest.tester.popen(
- ['/usr/bin/env', 'python', os.path.join(os.path.dirname(os.path.abspath(__file__)), 'failoverserver.py'), '-a',
- 'amqp://127.0.0.1:%d' % FailoverTest.my_server_port], expect=Process.RUNNING)
-
- # Kill the router B again
- FailoverTest.routers[3].teardown()
-
- self.success = False
- self.attempts = 0
-
- self.schedule_B_to_my_server_failover_test()
-
- while not self.can_terminate():
- pass
-
- self.assertTrue(self.success)
-
-
-if __name__ == '__main__':
- unittest.main(main_module())
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org