You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by kp...@apache.org on 2015/11/11 21:02:34 UTC
qpid-interop-test git commit: QPIDIT-20: Added ability to detect
broker and automatically exclude tests that fail for that broker
Repository: qpid-interop-test
Updated Branches:
refs/heads/master 899a9a863 -> 6c8ab3b0a
QPIDIT-20: Added ability to detect broker and automatically exclude tests that fail for that broker
Project: http://git-wip-us.apache.org/repos/asf/qpid-interop-test/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-interop-test/commit/6c8ab3b0
Tree: http://git-wip-us.apache.org/repos/asf/qpid-interop-test/tree/6c8ab3b0
Diff: http://git-wip-us.apache.org/repos/asf/qpid-interop-test/diff/6c8ab3b0
Branch: refs/heads/master
Commit: 6c8ab3b0a25b549de355a85f09e83dde6aa5cd19
Parents: 899a9a8
Author: Kim van der Riet <kp...@apache.org>
Authored: Wed Nov 11 15:00:58 2015 -0500
Committer: Kim van der Riet <kp...@apache.org>
Committed: Wed Nov 11 15:00:58 2015 -0500
----------------------------------------------------------------------
src/py/qpid-interop-test/__init__.py | 4 +-
src/py/qpid-interop-test/broker_properties.py | 55 +++
.../qpid-interop-test/jms/jms_message_tests.py | 49 ++-
src/py/qpid-interop-test/shim_utils.py | 388 -------------------
src/py/qpid-interop-test/test_type_map.py | 80 ++++
.../types/simple_type_tests.py | 53 ++-
6 files changed, 199 insertions(+), 430 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/6c8ab3b0/src/py/qpid-interop-test/__init__.py
----------------------------------------------------------------------
diff --git a/src/py/qpid-interop-test/__init__.py b/src/py/qpid-interop-test/__init__.py
index 404056b..7b8aee3 100644
--- a/src/py/qpid-interop-test/__init__.py
+++ b/src/py/qpid-interop-test/__init__.py
@@ -17,7 +17,9 @@
# under the License.
#
-import shim_utils
+import broker_properties
+import interop_test_errors
+import test_type_map
import types
import jms
http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/6c8ab3b0/src/py/qpid-interop-test/broker_properties.py
----------------------------------------------------------------------
diff --git a/src/py/qpid-interop-test/broker_properties.py b/src/py/qpid-interop-test/broker_properties.py
new file mode 100644
index 0000000..86b092a
--- /dev/null
+++ b/src/py/qpid-interop-test/broker_properties.py
@@ -0,0 +1,55 @@
+"""
+Module containing a small client which connects to the broker and
+gets the broker connection properties so as to identify the broker.
+"""
+
+#
+# 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 proton.handlers import MessagingHandler
+from proton.reactor import Container
+
+class BrokerClient(MessagingHandler):
+ """
+ Client to connect to broker and collect connection properties, used to identify the test broker
+ """
+ def __init__(self, url):
+ super(BrokerClient, self).__init__()
+ self.url = url
+ self.remote_properties = None
+
+ def on_start(self, event):
+ """Event loop start"""
+ event.container.create_sender(self.url)
+
+ def on_sendable(self, event):
+ """Sender link has credit, can send messages. Get connection properties, then close connection"""
+ self.remote_properties = event.sender.connection.remote_properties
+ event.sender.connection.close()
+
+ def get_connection_properties(self):
+ """Return the connection properties"""
+ return self.remote_properties
+
+
+def getBrokerProperties(broker_url):
+ """Start client, then return its connection properties"""
+ MSG_HANDLER = BrokerClient(broker_url)
+ Container(MSG_HANDLER).run()
+ return MSG_HANDLER.get_connection_properties()
http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/6c8ab3b0/src/py/qpid-interop-test/jms/jms_message_tests.py
----------------------------------------------------------------------
diff --git a/src/py/qpid-interop-test/jms/jms_message_tests.py b/src/py/qpid-interop-test/jms/jms_message_tests.py
index 1e53145..7ba2854 100755
--- a/src/py/qpid-interop-test/jms/jms_message_tests.py
+++ b/src/py/qpid-interop-test/jms/jms_message_tests.py
@@ -31,10 +31,15 @@ from json import dumps, loads
from os import getenv, path
from subprocess import check_output, CalledProcessError
+from proton import symbol
+from test_type_map import TestTypeMap
+import broker_properties
+
+
# TODO - propose a sensible default when installation details are worked out
QPID_INTEROP_TEST_HOME = getenv('QPID_INTEROP_TEST_HOME')
-class JmsMessageTypes(object):
+class JmsMessageTypes(TestTypeMap):
"""
Class which contains all the described JMS message types and the test values to be used in testing.
"""
@@ -113,6 +118,7 @@ class JmsMessageTypes(object):
'Charlie\'s "peach"',
'The quick brown fox jumped over the lazy dog 0123456789.' * 100]
}
+
TYPE_MAP = {
'JMS_BYTESMESSAGE_TYPE': TYPE_SUBMAP,
'JMS_MAPMESSAGE_TYPE': TYPE_SUBMAP,
@@ -169,17 +175,7 @@ class JmsMessageTypes(object):
'The quick brown fox jumped over the lazy dog 0123456789.' * 100]}
}
- @staticmethod
- def get_type_list():
- """Return a list of JMS message types which this test suite supports"""
- return JmsMessageTypes.TYPE_MAP.keys()
-
- @staticmethod
- def get_test_value_map(jms_messagae_type):
- """Return a list of test values to use when testing the supplied JMS message type."""
- if jms_messagae_type not in JmsMessageTypes.TYPE_MAP.keys():
- return None
- return JmsMessageTypes.TYPE_MAP[jms_messagae_type]
+ BROKER_SKIP = {}
class JmsMessageTypeTestCase(unittest.TestCase):
@@ -211,7 +207,7 @@ class JmsMessageTypeTestCase(unittest.TestCase):
self.fail('Type %s has no test values' % jms_message_type)
-def create_testcase_class(broker_addr, jms_message_type, test_values, shim_product):
+def create_testcase_class(broker_name, types, broker_addr, jms_message_type, shim_product):
"""
Class factory function which creates new subclasses to JmsMessageTypeTestCase.
"""
@@ -223,6 +219,8 @@ def create_testcase_class(broker_addr, jms_message_type, test_values, shim_produ
def add_test_method(cls, send_shim, receive_shim):
"""Function which creates a new test method in class cls"""
+ @unittest.skipIf(types.skip_test(jms_message_type, broker_name),
+ types.skip_test_message(jms_message_type, broker_name))
def inner_test_method(self):
self.run_test(self.broker_addr, self.jms_message_type, self.test_values, send_shim, receive_shim)
@@ -237,7 +235,7 @@ def create_testcase_class(broker_addr, jms_message_type, test_values, shim_produ
'__doc__': 'Test case for JMS message type \'%s\'' % jms_message_type,
'jms_message_type': jms_message_type,
'broker_addr': broker_addr,
- 'test_values': test_values}
+ 'test_values': types.get_test_values(jms_message_type)}
new_class = type(class_name, (JmsMessageTypeTestCase,), class_dict)
for send_shim, receive_shim in shim_product:
add_test_method(new_class, send_shim, receive_shim)
@@ -391,7 +389,17 @@ class TestOptions(object):
if __name__ == '__main__':
ARGS = TestOptions().args
- #print 'ARGS:', ARGS # DEBUG
+ #print 'ARGS:', ARGS # debug
+
+ # Connect to broker to find broker type
+ CONNECTION_PROPS = broker_properties.getBrokerProperties(ARGS.broker)
+ print 'Test Broker: %s v.%s on %s' % (CONNECTION_PROPS[symbol(u'product')],
+ CONNECTION_PROPS[symbol(u'version')],
+ CONNECTION_PROPS[symbol(u'platform')])
+ print
+ BROKER = CONNECTION_PROPS[symbol(u'product')]
+
+ TYPES = JmsMessageTypes()
# TEST_CASE_CLASSES is a list that collects all the test classes that are constructed. One class is constructed
# per AMQP type used as the key in map JmsMessageTypes.TYPE_MAP.
@@ -406,11 +414,12 @@ if __name__ == '__main__':
for shim in ARGS.exclude_shim:
SHIM_MAP.pop(shim)
# Create test classes dynamically
- for at in sorted(JmsMessageTypes.get_type_list()):
- if ARGS.exclude_type is None or at not in ARGS.exclude_type:
- test_case_class = create_testcase_class(ARGS.broker,
- at,
- JmsMessageTypes.get_test_value_map(at),
+ for jmt in sorted(TYPES.get_type_list()):
+ if ARGS.exclude_type is None or jmt not in ARGS.exclude_type:
+ test_case_class = create_testcase_class(BROKER,
+ TYPES,
+ ARGS.broker,
+ jmt,
product(SHIM_MAP.values(), repeat=2))
TEST_CASE_CLASSES.append(test_case_class)
TEST_SUITE.addTest(unittest.makeSuite(test_case_class))
http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/6c8ab3b0/src/py/qpid-interop-test/shim_utils.py
----------------------------------------------------------------------
diff --git a/src/py/qpid-interop-test/shim_utils.py b/src/py/qpid-interop-test/shim_utils.py
deleted file mode 100755
index 14d3a96..0000000
--- a/src/py/qpid-interop-test/shim_utils.py
+++ /dev/null
@@ -1,388 +0,0 @@
-#!/usr/bin/env python
-
-"""
-Module containing utilities for the shims used in qpid-interop.
-"""
-
-#
-# 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 sys
-import proton
-from ast import literal_eval
-from uuid import UUID
-
-class StrToObj(object):
- """
- Class StrObj consumes the characters from a string iterator str_itr
- and interprets the string so as to create the equivalent python
- object(s) in a manner similar to ast.leteral_eval(). The difference
- is that this version supports proton types as a part of the
- interpretation, so that a string such as
-
- '[1, char('a'), timestamp(1234567)]'
-
- can be parsed.
-
- The following compound python types can be handled:
- [...] list
- (...) tuple
- {...} dict
- which may contain any legal combination of simple python types
- including strings, embedded lists, tuples and dicts, and the
- supported proton types. All of the simple types must be supported
- by ast.leteral_eval() to be supported in this class.
-
- The following proton types are handled:
- proton.char
- proton.symbol
- proton.timestamp
- proton.ulong
-
- Typical usage:
- -------------
- For a python string object str containing the string to be parsed,
- it is necessary to obtain an iterator to the individual characters
- of the string. This can be done as follows:
-
- obj = StrToObj(list(str).__iter__()).run()
-
- where obj will contain an instance of the object described in the
- string. The run() method starts the process of consuming characters
- from the iterator and interpreting them.
-
- This class is also the parent class of a number of more specialized
- subclasses for handling sub-sections of the string interpretation:
-
- StrToObj (this class)
- ^
- |
- +----------+-------------+
- | | |
- StrToStr StrToType StrToSeq
- ^
- |
- +-------------+-----------+
- | | |
- StrToList StrToTuple StrToDict
-
- and which make up all the elements of the composite types needed
- for this application. Simple types are handled by calling
- ast.literal_evel(), and the types that can be handled are
- determined by that function.
- """
-
- def __init__(self, str_itr):
- self._str_itr = str_itr
- self._done = False
- self._obj = None
- self._str_buff = ''
-
- def get_obj(self):
- """
- Return object created as a result of parsing the string
- supplied to the constructor and using the run() method.
- """
- return self._obj
-
- def run(self):
- """
- Starts the process of 'consuming' characters from the supplied
- string iterator and of interpreting them in the context of the
- previous characters.
- """
- try:
- while not self._done:
- char = self._str_itr.next()
- if not self._process_char(char):
- self._str_buff += char
- except StopIteration:
- if len(self._str_buff) > 0 and self._obj is None:
- self._obj = literal_eval(self._str_buff)
- self._str_buff = ''
- return self._obj
-
- def _add_elt(self, elt):
- """
- Sets the object itself to parameter elt. This function is
- frequently overloaded by its subclasses.
- """
- self._obj = elt
-
- def _process_char(self, char):
- """
- Consume and process a single character in the context of those
- that have passed before. This function is overloaded by its
- subclasses to provide either additional or alternative
- processing.
-
- This function checks for the characters that start a list
- ('['), a dict ('{'), a tuple ('(' when preceded only by
- whitespace), a string ('\'' or '"') or special proton types
- ('(' when preceded by a constructor string).
-
- If any of these chars are found, a new object of the
- appropriate class is constructed to handle the processing of
- that type, and when its run() function completes, a constructed
- object will be returned.
- """
- if char == '[':
- self._add_elt(StrToList(char, self._str_itr).run())
- return True
- if char == '{':
- self._add_elt(StrToDict(char, self._str_itr).run())
- return True
- if char == '(':
- if len(self._str_buff.strip()) == 0:
- self._add_elt(StrToTuple(char, self._str_itr).run())
- else:
- self._add_elt(StrToType(char, self._str_itr,
- self._str_buff).run())
- self._str_buff = ''
- return True
- if char == '\'' or char == '"':
- str_prefix = None
- if len(self._str_buff.strip()) > 0:
- str_prefix = self._str_buff.strip()
- self._add_elt(StrToStr(char, self._str_itr, str_prefix).run())
- self._str_buff = ''
- return True
- return False
-
-
-class StrToStr(StrToObj):
- """
- Class to consume a string delimited by either ' or " chars.
- """
-
- def __init__(self, delim_char, str_itr, str_prefix):
- super(StrToStr, self).__init__(str_itr)
- self._delim_char = delim_char
- self._str_prefix = str_prefix
- self._escape_flag = False
-
- def _process_char(self, char):
- """
- This function processes a python string type, and continues
- consuming characters until another matching delimiter character
- ('\'' or '"') is encountered. A delimiter character that is
- preceded by an escape character ('\\') is excluded.
-
- The entire string may have a prefix of one or more characters.
- Only the u prefix (eg u'hello') has any effect; the b prefix
- has no effect in Python 2.x but paves the way for Python 3.x
- where it does have significance, and the r prefix affects the
- display or printing of strings only.
- """
- if char == '\\':
- self._escape_flag = not self._escape_flag
- elif char == self._delim_char and not self._escape_flag:
- if self._str_prefix is None:
- self._obj = self._str_buff
- elif 'u' in self._str_prefix or 'U' in self._str_prefix:
- self._obj = unicode(self._str_buff)
- else:
- self._obj = self._str_buff # Ignore other prefixes (b, B, r, R)
- self._str_buff = ''
- self._done = True
- return True
- else:
- self._escape_flag = False
- return False
-
-
-class StrToType(StrToObj):
- """
- Class for processing special proton python types.
- """
-
- def __init__(self, _, str_itr, type_str):
- super(StrToType, self).__init__(str_itr)
- self._type_str = type_str.strip()
- self._val = None
-
- def _add_elt(self, elt):
- """
- Sets the value portion of the type to elt. This is then used
- in the constructor of the type.
- """
- self._val = elt
-
- def _process_char(self, char):
- """
- Process characters to identify the value to the constructor of
- the proton type being processed. The proton type string is
- passed to the constructor, and when the '(' char is encountered,
- this function is used until the matching ')' char is reached.
-
- The parent StrToObj._process_char() is called first to process
- any compound types and strings which may be present as a
- constructor value.
- """
- if super(StrToType, self)._process_char(char):
- return True
- if char == ')':
- if len(self._str_buff.strip()) > 0:
- if self._val is not None:
- # This condition should not ever arise, either
- # self._val is set OR self._str_buff contains a
- # value, but not both.
- raise RuntimeError('self._val=%s and self._str_buff=%s' %
- (self._val, self._str_buff))
- self._val = literal_eval(
- self._str_buff[self._str_buff.find('(')+1:])
- if self._type_str == 'ubyte':
- self._obj = proton.ubyte(self._val)
- elif self._type_str == 'ushort':
- self._obj = proton.ushort(self._val)
- elif self._type_str == 'uint':
- self._obj = proton.uint(self._val)
- elif self._type_str == 'ulong':
- self._obj = proton.ulong(self._val)
- elif self._type_str == 'byte':
- self._obj = proton.byte(self._val)
- elif self._type_str == 'short':
- self._obj = proton.short(self._val)
- elif self._type_str == 'int32':
- self._obj = proton.int32(self._val)
- elif self._type_str == 'float32':
- self._obj = proton.float32(self._val)
- elif self._type_str == 'decimal32':
- self._obj = proton.decimal32(self._val)
- elif self._type_str == 'decimal64':
- self._obj = proton.decimal64(self._val)
- elif self._type_str == 'decimal128':
- self._obj = proton.decimal128(self._val)
- elif self._type_str == 'char':
- self._obj = proton.char(self._val)
- elif self._type_str == 'symbol':
- self._obj = proton.symbol(self._val)
- elif self._type_str == 'timestamp':
- self._obj = proton.timestamp(self._val)
- elif self._type_str == 'UUID':
- self._obj = UUID(self._val)
- else:
- raise ValueError('StrToType: unknown type \'%s\'' % self._type_str)
- self._str_buff = ''
- self._done = True
- return True
-
-
-class StrToSeq(StrToObj):
- """
- Class which consumes comma-delimited sequence types such as lists,
- dicts and tuples.
- """
-
- def __init__(self, _, str_itr, close_char, seq_type):
- super(StrToSeq, self).__init__(str_itr)
- self._close_char = close_char
- self._obj = seq_type()
-
- def _process_char(self, char):
- """
- Processing for container sequence types that use a ','
- character as an element delimiter. Individual elements may be
- any legal type, including proton types and nested containers.
- """
- if super(StrToSeq, self)._process_char(char):
- return True
- if char == ',' or char == self._close_char:
- if char == self._close_char:
- self._done = True
- if len(self._str_buff.strip()) > 0:
- self._add_elt(literal_eval(self._str_buff.strip()))
- self._str_buff = ''
- return True
- return False
-
-class StrToList(StrToSeq):
- """
- Class which consumes a list of the form '[...]'.
- """
-
- def __init__(self, char, str_itr):
- super(StrToList, self).__init__(char, str_itr, ']', list)
-
- def _add_elt(self, elt):
- """
- Adds an additional element into the list object.
- """
- self._obj.append(elt)
-
-class StrToTuple(StrToSeq):
- """
- Class which consumes a tuple of the form '(...)'. Tuples without
- the enclosing braces are not currently supported, however.
- """
-
- def __init__(self, char, str_itr):
- super(StrToTuple, self).__init__(char, str_itr, ')', tuple)
-
- def _add_elt(self, elt):
- """
- Adds an additional element into the tuple object.
- """
- self._obj = self._obj + (elt,)
-
-class StrToDict(StrToSeq):
- """
- Class which consumed a dict of the form '{...}'.
- """
-
- def __init__(self, c, str_itr):
- super(StrToDict, self).__init__(c, str_itr, '}', dict)
- self._key = None
-
- def _add_elt(self, elt):
- """
- Called twice for dicts; the first call sets the key object,
- and the second call sets the value object and then inserts
- the entire key:value pair into the map.
- """
- if self._key is None:
- self._key = elt
- else:
- self._obj[self._key] = elt
- self._key = None
-
- def _process_char(self, c):
- """
- Processing of characters for the python dict type using the
- 'key:value' syntax. The key and value may be any legal python
- or proton type, including embedded containers.
- """
- if super(StrToDict, self)._process_char(c):
- return True
- if c == ':':
- if len(self._str_buff.strip()) > 0:
- self._add_elt(literal_eval(self._str_buff.strip()))
- self._str_buff = ''
- return True
- return False
-
-# --- main ---
-
-# This command-line entry point is for testing only, it does not
-# provide any useful functionality on its own.
-
-#if len(sys.argv) == 2:
-# print '%r' % StrToObj(list(sys.argv[1]).__iter__()).run()
-#else:
-# print 'Usage: shim_utils <string>'
http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/6c8ab3b0/src/py/qpid-interop-test/test_type_map.py
----------------------------------------------------------------------
diff --git a/src/py/qpid-interop-test/test_type_map.py b/src/py/qpid-interop-test/test_type_map.py
new file mode 100644
index 0000000..33894fc
--- /dev/null
+++ b/src/py/qpid-interop-test/test_type_map.py
@@ -0,0 +1,80 @@
+"""
+Module containing Error classes for interop testing
+"""
+from reportlab.lib.randomtext import BLAH
+
+#
+# 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.
+#
+
+class TestTypeMap(object):
+ """
+ Class which contains all the described types and the test values to be used in testing against those types.
+ """
+
+ # TYPE_MAP: Map containing all described types as the indecies, and a list of values to be used in testing
+ # that type as a list of values.
+ #
+ # Format: {'type_1' : [val_1_1, val_1_2, ...],
+ # 'type_2' : [val_2_1, val_2_2, ...],
+ # ...
+ # }
+ TYPE_MAP = {}
+
+ # BROKER_SKIP: For know broker issues where a type would cause a test to fail or hang,
+ # entries in BROKER_SKIP will cause the test to be skipped with a message.
+ # This is a map containing AMQP types as a key, and a list of brokers for which this
+ # type should be skipped.
+ # Format: {'jms_msg_type_1' : {'broker_1' : 'skip msg for broker_1',
+ # 'broker_2' : 'skip msg for broker_2',
+ # ...
+ # },
+ # 'jms_msg_type_2' : {'broker_1' : 'skip msg for broker_1',
+ # 'broker_2' : 'skip msg for broker_2',
+ # ...
+ # },
+ # ...
+ # }
+ # where broker_1, broker_2, ... are broker product names as defined by the
+ # connection property string it returns.
+ BROKER_SKIP = {}
+
+ def __init__(self):
+ pass
+
+ def get_type_list(self):
+ """Return a list of types which this test suite supports"""
+ return self.TYPE_MAP.keys()
+
+ def get_test_values(self, test_type):
+ """Return test values to use when testing the supplied type."""
+ if test_type not in self.TYPE_MAP.keys():
+ return None
+ return self.TYPE_MAP[test_type]
+
+ def skip_test_message(self, test_type, broker_name):
+ """Return the message to use if a test is skipped"""
+ if test_type in self.BROKER_SKIP.keys():
+ if broker_name in self.BROKER_SKIP[test_type]:
+ return str(self.BROKER_SKIP[test_type][broker_name])
+ return None
+
+ def skip_test(self, test_type, broker_name):
+ """Return boolean True if test should be skipped"""
+ return test_type in self.BROKER_SKIP.keys() and \
+ broker_name in self.BROKER_SKIP[test_type]
http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/6c8ab3b0/src/py/qpid-interop-test/types/simple_type_tests.py
----------------------------------------------------------------------
diff --git a/src/py/qpid-interop-test/types/simple_type_tests.py b/src/py/qpid-interop-test/types/simple_type_tests.py
index 59d2790..cc8fbf2 100755
--- a/src/py/qpid-interop-test/types/simple_type_tests.py
+++ b/src/py/qpid-interop-test/types/simple_type_tests.py
@@ -33,10 +33,16 @@ from subprocess import check_output, CalledProcessError
from time import mktime, time
from uuid import UUID, uuid4
+from proton import symbol
+from test_type_map import TestTypeMap
+import broker_properties
+
+
# TODO - propose a sensible default when installation details are worked out
QPID_INTEROP_TEST_HOME = getenv('QPID_INTEROP_TEST_HOME')
-class AmqpPrimitiveTypes(object):
+
+class AmqpPrimitiveTypes(TestTypeMap):
"""
Class which contains all the described AMQP primitive types and the test values to be used in testing.
"""
@@ -121,8 +127,6 @@ class AmqpPrimitiveTypes(object):
# decimal32, decimal64, decimal128:
# Until more formal support for decimal32, decimal64 and decimal128 are included in Python, we use
# a hex format for basic tests, and treat the data as a binary blob.
- # Note that IEE-754 allows for two binary encodings of these numbers without any way to determine which
- # of them is in use. Thus the encoding used must be by convention or agreed upon in advance by the clients.
'decimal32': ['0x00000000',
'0x40490fdb',
'0xc02df854',
@@ -137,8 +141,7 @@ class AmqpPrimitiveTypes(object):
'Z',
'\x01',
'\x7f'],
- # timestamp
- # Must be in milliseconds since the unix epoch
+ # timestamp: Must be in milliseconds since the Unix epoch
'timestamp': ['0',
'%d' % int(mktime((2000, 1, 1, 0, 0, 0, 5, 1, 0))*1000),
'%d' % int(time()*1000)],
@@ -183,17 +186,12 @@ class AmqpPrimitiveTypes(object):
#'array': [[], [1,2,3], ['Hello', 'world']] # TODO: Not yet implemented
}
- @staticmethod
- def get_type_list():
- """Return a list of simple AMQP types which this test suite supports"""
- return AmqpPrimitiveTypes.TYPE_MAP.keys()
+ BROKER_SKIP = {'decimal32': {'qpid-cpp': 'decimal32 not supported on qpid-cpp broker: QPIDIT-5, QPID-6328',},
+ 'decimal64': {'qpid-cpp': 'decimal64 not supported on qpid-cpp broker: QPIDIT-6, QPID-6328',},
+ 'decimal128': {'qpid-cpp': 'decimal128 not supported on qpid-cpp broker: QPIDIT-3, QPID-6328',},
+ 'char': {'qpid-cpp': 'char not supported on qpid-cpp broker: QPIDIT-4, QPID-6328',},
+ }
- @staticmethod
- def get_test_value_list(amqp_type):
- """Return a list of test values to use when testing the supplied AMQP type."""
- if amqp_type not in AmqpPrimitiveTypes.TYPE_MAP.keys():
- return None
- return AmqpPrimitiveTypes.TYPE_MAP[amqp_type]
class AmqpTypeTestCase(unittest.TestCase):
@@ -221,7 +219,7 @@ class AmqpTypeTestCase(unittest.TestCase):
self.fail('Type %s has no test values' % amqp_type)
-def create_testcase_class(broker_addr, amqp_type, test_value_list, shim_product):
+def create_testcase_class(broker_name, types, broker_addr, amqp_type, shim_product):
"""
Class factory function which creates new subclasses to AmqpTypeTestCase.
"""
@@ -233,6 +231,8 @@ def create_testcase_class(broker_addr, amqp_type, test_value_list, shim_product)
def add_test_method(cls, send_shim, receive_shim):
"""Function which creates a new test method in class cls"""
+ @unittest.skipIf(types.skip_test(amqp_type, broker_name),
+ types.skip_test_message(amqp_type, broker_name))
def inner_test_method(self):
self.run_test(self.broker_addr, self.amqp_type, self.test_value_list, send_shim, receive_shim)
@@ -247,7 +247,7 @@ def create_testcase_class(broker_addr, amqp_type, test_value_list, shim_product)
'__doc__': 'Test case for AMQP 1.0 simple type \'%s\'' % amqp_type,
'amqp_type': amqp_type,
'broker_addr': broker_addr,
- 'test_value_list': test_value_list}
+ 'test_value_list': types.get_test_values(amqp_type)}
new_class = type(class_name, (AmqpTypeTestCase,), class_dict)
for send_shim, receive_shim in shim_product:
add_test_method(new_class, send_shim, receive_shim)
@@ -395,7 +395,17 @@ class TestOptions(object):
if __name__ == '__main__':
ARGS = TestOptions().args
- #print 'ARGS:', ARGS
+ #print 'ARGS:', ARGS # debug
+
+ # Connect to broker to find broker type
+ CONNECTION_PROPS = broker_properties.getBrokerProperties(ARGS.broker)
+ print 'Test Broker: %s v.%s on %s' % (CONNECTION_PROPS[symbol(u'product')],
+ CONNECTION_PROPS[symbol(u'version')],
+ CONNECTION_PROPS[symbol(u'platform')])
+ print
+ BROKER = CONNECTION_PROPS[symbol(u'product')]
+
+ TYPES = AmqpPrimitiveTypes()
# TEST_CASE_CLASSES is a list that collects all the test classes that are constructed. One class is constructed
# per AMQP type used as the key in map AmqpPrimitiveTypes.TYPE_MAP.
@@ -410,11 +420,12 @@ if __name__ == '__main__':
for shim in ARGS.exclude_shim:
SHIM_MAP.pop(shim)
# Create test classes dynamically
- for at in sorted(AmqpPrimitiveTypes.get_type_list()):
+ for at in sorted(TYPES.get_type_list()):
if ARGS.exclude_type is None or at not in ARGS.exclude_type:
- test_case_class = create_testcase_class(ARGS.broker,
+ test_case_class = create_testcase_class(BROKER,
+ TYPES,
+ ARGS.broker,
at,
- AmqpPrimitiveTypes.get_test_value_list(at),
product(SHIM_MAP.values(), repeat=2))
TEST_CASE_CLASSES.append(test_case_class)
TEST_SUITE.addTest(unittest.makeSuite(test_case_class))
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org