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