Repository: qpid-interop-test Updated Branches: refs/heads/master 6c8ab3b0a -> 5f7ac58b0
http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/5f7ac58b/shims/qpid-proton-cpp/src/qpidit/shim/JmsSender.cpp ---------------------------------------------------------------------- diff --git a/shims/qpid-proton-cpp/src/qpidit/shim/JmsSender.cpp b/shims/qpid-proton-cpp/src/qpidit/shim/JmsSender.cpp new file mode 100644 index 0000000..5c57b25 --- /dev/null +++ b/shims/qpid-proton-cpp/src/qpidit/shim/JmsSender.cpp @@ -0,0 +1,336 @@ +/* + * + * 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. + * + */ + +#include "qpidit/shim/JmsSender.hpp" + +#include <iostream> +#include <json/json.h> +#include "proton/container.hpp" +#include "qpidit/QpidItErrors.hpp" +#include <stdio.h> + +namespace qpidit +{ + namespace shim + { + //static + proton::amqp_symbol JmsSender::s_jmsMessageTypeAnnotationKey("x-opt-jms-msg-type"); + std::map<std::string, proton::amqp_byte>JmsSender::s_jmsMessageTypeAnnotationValues = { + {"JMS_MESSAGE_TYPE", 0}, + {"JMS_OBJECTMESSAGE_TYPE", 1}, + {"JMS_MAPMESSAGE_TYPE", 2}, + {"JMS_BYTESMESSAGE_TYPE", 3}, + {"JMS_STREAMMESSAGE_TYPE", 4}, + {"JMS_TEXTMESSAGE_TYPE", 5}}; + + JmsSender::JmsSender(const std::string& brokerUrl, + const std::string& jmsMessageType, + const Json::Value& testValueMap) : + _brokerUrl(brokerUrl), + _jmsMessageType(jmsMessageType), + _testValueMap(testValueMap), + _msgsSent(0), + _msgsConfirmed(0), + _totalMsgs(getTotalNumMessages(testValueMap)) + { + if (testValueMap.type() != Json::objectValue) { + throw qpidit::InvalidJsonRootNodeError(Json::objectValue, testValueMap.type()); + } + } + + JmsSender::~JmsSender() {} + + void JmsSender::on_start(proton::event &e) { + e.container().open_sender(_brokerUrl); + } + + void JmsSender::on_sendable(proton::event &e) { + if (_totalMsgs == 0) { + e.sender().connection().close(); + } else if (_msgsSent == 0) { + Json::Value::Members subTypes = _testValueMap.getMemberNames(); + std::sort(subTypes.begin(), subTypes.end()); + for (std::vector<std::string>::const_iterator i=subTypes.begin(); i!=subTypes.end(); ++i) { + sendMessages(e, *i, _testValueMap[*i]); + } + } + } + + void JmsSender::on_accepted(proton::event &e) { + _msgsConfirmed++; + if (_msgsConfirmed == _totalMsgs) { + e.connection().close(); + } + } + + void JmsSender::on_disconnected(proton::event &e) { + _msgsSent = _msgsConfirmed; + } + + // protected + + void JmsSender::sendMessages(proton::event &e, const std::string& subType, const Json::Value& testValues) { + uint32_t valueNumber = 0; + for (Json::Value::const_iterator i=testValues.begin(); i!=testValues.end(); ++i) { + if (e.sender().credit()) { + proton::message msg; + if (_jmsMessageType.compare("JMS_BYTESMESSAGE_TYPE") == 0) { + setBytesMessage(msg, subType, (*i).asString()); + } else if (_jmsMessageType.compare("JMS_MAPMESSAGE_TYPE") == 0) { + setMapMessage(msg, subType, (*i).asString(), valueNumber); + } else if (_jmsMessageType.compare("JMS_OBJECTMESSAGE_TYPE") == 0) { + setObjectMessage(msg, subType, *i); + } else if (_jmsMessageType.compare("JMS_STREAMMESSAGE_TYPE") == 0) { + setStreamMessage(msg, subType, (*i).asString()); + } else if (_jmsMessageType.compare("JMS_TEXTMESSAGE_TYPE") == 0) { + setTextMessage(msg, *i); + } else { + throw qpidit::UnknownJmsMessageTypeError(_jmsMessageType); + } + e.sender().send(msg); + _msgsSent += 1; + valueNumber += 1; + } + } + + } + + proton::message& JmsSender::setBytesMessage(proton::message& msg, const std::string& subType, const std::string& testValueStr) { + proton::amqp_binary bin; + if (subType.compare("boolean") == 0) { + if (testValueStr.compare("False") == 0) bin.assign("\x00", 1); + else if (testValueStr.compare("True") == 0) bin.assign("\x01", 1); + else throw InvalidTestValueError(subType, testValueStr); + } else if (subType.compare("byte") == 0) { + uint8_t val = getIntegralValue<int8_t>(testValueStr); + bin.assign((char*)&val, sizeof(val)); + } else if (subType.compare("bytes") == 0) { + bin.assign(testValueStr); + } else if (subType.compare("char") == 0) { + char val[2]; + val[0] = 0; + if (testValueStr[0] == '\\') { // Format: '\xNN' + val[1] = (char)getIntegralValue<char>(testValueStr.substr(2)); + } else { // Format: 'c' + val[1] = testValueStr[0]; + } + bin.assign(val, sizeof(val)); + } else if (subType.compare("double") == 0) { + uint64_t val; + try { + val = htobe64(std::stoul(testValueStr, nullptr, 16)); + } catch (const std::exception& e) { throw qpidit::InvalidTestValueError("double", testValueStr); } + bin.assign((char*)&val, sizeof(val)); + } else if (subType.compare("float") == 0) { + uint32_t val; + try { + val = htobe32((uint32_t)std::stoul(testValueStr, nullptr, 16)); + } catch (const std::exception& e) { throw qpidit::InvalidTestValueError("float", testValueStr); } + bin.assign((char*)&val, sizeof(val)); + } else if (subType.compare("long") == 0) { + uint64_t val = htobe64(getIntegralValue<uint64_t>(testValueStr)); + bin.assign((char*)&val, sizeof(val)); + } else if (subType.compare("int") == 0) { + uint32_t val = htobe32(getIntegralValue<uint32_t>(testValueStr)); + bin.assign((char*)&val, sizeof(val)); + } else if (subType.compare("short") == 0) { + uint16_t val = htobe16(getIntegralValue<int16_t>(testValueStr)); + bin.assign((char*)&val, sizeof(val)); + } else if (subType.compare("string") == 0) { + std::ostringstream oss; + uint16_t strlen = htobe16((uint16_t)testValueStr.size()); + oss.write((char*)&strlen, sizeof(strlen)); + oss << testValueStr; + bin.assign(oss.str()); + } else { + throw qpidit::UnknownJmsMessageSubTypeError(subType); + } + msg.body(bin); + msg.inferred(true); + msg.content_type(proton::amqp_symbol("application/octet-stream")); + msg.annotation(proton::amqp_symbol("x-opt-jms-msg-type"), s_jmsMessageTypeAnnotationValues["JMS_BYTESMESSAGE_TYPE"]); + return msg; + } + + proton::message& JmsSender::setMapMessage(proton::message& msg, const std::string& subType, const std::string& testValueStr, uint32_t valueNumber) { + std::ostringstream oss; + oss << subType << std::setw(3) << std::setfill('0') << valueNumber; + std::string mapKey(oss.str()); + std::map<std::string, proton::value> m; + if (subType.compare("boolean") == 0) { + if (testValueStr.compare("False") == 0) m[mapKey] = proton::amqp_boolean(false); + else if (testValueStr.compare("True") == 0) m[mapKey] = proton::amqp_boolean(true); + else throw InvalidTestValueError(subType, testValueStr); + } else if (subType.compare("byte") == 0) { + m[mapKey] = proton::amqp_byte(getIntegralValue<int8_t>(testValueStr)); + } else if (subType.compare("bytes") == 0) { + m[mapKey] = proton::amqp_binary(testValueStr); + } else if (subType.compare("char") == 0) { + wchar_t val; + if (testValueStr[0] == '\\') { // Format: '\xNN' + val = (wchar_t)getIntegralValue<wchar_t>(testValueStr.substr(2)); + } else { // Format: 'c' + val = testValueStr[0]; + } + m[mapKey] = proton::amqp_char(val); + } else if (subType.compare("double") == 0) { + m[mapKey] = proton::amqp_double(getFloatValue<double, uint64_t>(testValueStr)); + } else if (subType.compare("float") == 0) { + m[mapKey] = proton::amqp_float(getFloatValue<float, uint32_t>(testValueStr)); + } else if (subType.compare("int") == 0) { + m[mapKey] = proton::amqp_int(getIntegralValue<int32_t>(testValueStr)); + } else if (subType.compare("long") == 0) { + m[mapKey] = proton::amqp_long(getIntegralValue<int64_t>(testValueStr)); + } else if (subType.compare("short") == 0) { + m[mapKey] = proton::amqp_short(getIntegralValue<int16_t>(testValueStr)); + } else if (subType.compare("string") == 0) { + m[mapKey] = proton::amqp_string(testValueStr); + } else { + throw qpidit::UnknownJmsMessageSubTypeError(subType); + } + msg.inferred(false); + msg.body(m); + msg.annotation(proton::amqp_symbol("x-opt-jms-msg-type"), s_jmsMessageTypeAnnotationValues["JMS_MAPMESSAGE_TYPE"]); + return msg; + } + + proton::message& JmsSender::setObjectMessage(proton::message& msg, const std::string& subType, const Json::Value& testValue) { + msg.body(getJavaObjectBinary(subType, testValue.asString())); + msg.inferred(true); + msg.content_type(proton::amqp_symbol("application/x-java-serialized-object")); + msg.annotation(proton::amqp_symbol("x-opt-jms-msg-type"), s_jmsMessageTypeAnnotationValues["JMS_OBJECTMESSAGE_TYPE"]); + return msg; + } + + proton::message& JmsSender::setStreamMessage(proton::message& msg, const std::string& subType, const std::string& testValueStr) { + std::vector<proton::value> l; + if (subType.compare("boolean") == 0) { + if (testValueStr.compare("False") == 0) l.push_back(proton::amqp_boolean(false)); + else if (testValueStr.compare("True") == 0) l.push_back(proton::amqp_boolean(true)); + else throw InvalidTestValueError(subType, testValueStr); + } else if (subType.compare("byte") == 0) { + l.push_back(proton::amqp_byte(getIntegralValue<int8_t>(testValueStr))); + } else if (subType.compare("bytes") == 0) { + l.push_back(proton::amqp_binary(testValueStr)); + } else if (subType.compare("char") == 0) { + wchar_t val; + if (testValueStr[0] == '\\') { // Format: '\xNN' + val = (wchar_t)getIntegralValue<wchar_t>(testValueStr.substr(2)); + } else { // Format: 'c' + val = testValueStr[0]; + } + l.push_back(proton::amqp_char(val)); + } else if (subType.compare("double") == 0) { + l.push_back(proton::amqp_double(getFloatValue<double, uint64_t>(testValueStr))); + } else if (subType.compare("float") == 0) { + l.push_back(proton::amqp_float(getFloatValue<float, uint32_t>(testValueStr))); + } else if (subType.compare("int") == 0) { + l.push_back(proton::amqp_int(getIntegralValue<int32_t>(testValueStr))); + } else if (subType.compare("long") == 0) { + l.push_back(proton::amqp_long(getIntegralValue<int64_t>(testValueStr))); + } else if (subType.compare("short") == 0) { + l.push_back(proton::amqp_short(getIntegralValue<int16_t>(testValueStr))); + } else if (subType.compare("string") == 0) { + l.push_back(proton::amqp_string(testValueStr)); + } else { + throw qpidit::UnknownJmsMessageSubTypeError(subType); + } + msg.body(l); + msg.inferred(true); + msg.annotation(proton::amqp_symbol("x-opt-jms-msg-type"), s_jmsMessageTypeAnnotationValues["JMS_STREAMMESSAGE_TYPE"]); + return msg; + } + + proton::message& JmsSender::setTextMessage(proton::message& msg, const Json::Value& testValue) { + msg.body(testValue.asString()); + msg.inferred(false); + msg.annotation(proton::amqp_symbol("x-opt-jms-msg-type"), s_jmsMessageTypeAnnotationValues["JMS_TEXTMESSAGE_TYPE"]); + return msg; + } + + //static + proton::amqp_binary JmsSender::getJavaObjectBinary(const std::string& javaClassName, const std::string& valAsString) { + proton::amqp_binary javaObjectBinary; + char buf[1024]; + int bytesRead; + FILE* fp = ::popen("java -cp target/JavaObjUtils.jar org.apache.qpid.interop_test.obj_util.JavaObjToBytes javaClassStr", "rb"); + if (fp == nullptr) { throw qpidit::PopenError(errno); } + do { + bytesRead = ::fread(buf, 1, sizeof(buf), fp); + javaObjectBinary.append(buf, bytesRead); + } while (bytesRead == sizeof(buf)); + int status = ::pclose(fp); + if (status == -1) { + throw qpidit::PcloseError(errno); + } + return javaObjectBinary; + } + + // static + uint32_t JmsSender::getTotalNumMessages(const Json::Value& testValueMap) { + uint32_t tot = 0; + for (Json::Value::const_iterator i = testValueMap.begin(); i != testValueMap.end(); ++i) { + tot += (*i).size(); + } + return tot; + } + + } /* namespace shim */ +} /* namespace qpidit */ + + + +/* + * --- main --- + * Args: 1: Broker address (ip-addr:port) + * 2: Queue name + * 3: AMQP type + * 4: Test value(s) as JSON string + */ + +int main(int argc, char** argv) { +/* + for (int i=0; i<argc; ++i) { + std::cout << "*** argv[" << i << "] : " << argv[i] << std::endl; + } +*/ + // TODO: improve arg management a little... + if (argc != 5) { + throw qpidit::ArgumentError("Incorrect number of arguments"); + } + + std::ostringstream oss; + oss << argv[1] << "/" << argv[2]; + + try { + Json::Value testValueMap; + Json::Reader jsonReader; + if (not jsonReader.parse(argv[4], testValueMap, false)) { + throw qpidit::JsonParserError(jsonReader); + } + + qpidit::shim::JmsSender sender(oss.str(), argv[3], testValueMap); + proton::container(sender).run(); + } catch (const std::exception& e) { + std::cerr << "JmsSender error: " << e.what() << std::endl; + } + exit(0); +} http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/5f7ac58b/shims/qpid-proton-cpp/src/qpidit/shim/JmsSender.hpp ---------------------------------------------------------------------- diff --git a/shims/qpid-proton-cpp/src/qpidit/shim/JmsSender.hpp b/shims/qpid-proton-cpp/src/qpidit/shim/JmsSender.hpp new file mode 100644 index 0000000..a8e02e0 --- /dev/null +++ b/shims/qpid-proton-cpp/src/qpidit/shim/JmsSender.hpp @@ -0,0 +1,85 @@ +/* + * + * 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. + * + */ + +#ifndef SRC_QPIDIT_SHIM_JMSSENDER_HPP_ +#define SRC_QPIDIT_SHIM_JMSSENDER_HPP_ + +#include "json/value.h" +#include "proton/messaging_handler.hpp" +#include "qpidit/QpidItErrors.hpp" +#include <iostream> // DEBUG ONLY +#include <iomanip> // DEBUG ONLY + +namespace qpidit +{ + namespace shim + { + + class JmsSender : public proton::messaging_handler + { + protected: + static proton::amqp_symbol s_jmsMessageTypeAnnotationKey; + static std::map<std::string, proton::amqp_byte>s_jmsMessageTypeAnnotationValues; + + const std::string _brokerUrl; + const std::string _jmsMessageType; + const Json::Value _testValueMap; + uint32_t _msgsSent; + uint32_t _msgsConfirmed; + uint32_t _totalMsgs; + public: + JmsSender(const std::string& brokerUrl, const std::string& jmsMessageType, const Json::Value& testValues); + virtual ~JmsSender(); + void on_start(proton::event &e); + void on_sendable(proton::event &e); + void on_accepted(proton::event &e); + void on_disconnected(proton::event &e); + protected: + void sendMessages(proton::event &e, const std::string& subType, const Json::Value& testValueMap); + proton::message& setBytesMessage(proton::message& msg, const std::string& subType, const std::string& testValueStr); + proton::message& setMapMessage(proton::message& msg, const std::string& subType, const std::string& testValueStr, uint32_t valueNumber); + proton::message& setObjectMessage(proton::message& msg, const std::string& subType, const Json::Value& testValue); + proton::message& setStreamMessage(proton::message& msg, const std::string& subType, const std::string& testValue); + proton::message& setTextMessage(proton::message& msg, const Json::Value& testValue); + + static proton::amqp_binary getJavaObjectBinary(const std::string& javaClassName, const std::string& valAsString); + static uint32_t getTotalNumMessages(const Json::Value& testValueMap); + + // Set message body to floating type T through integral type U + // Used to convert a hex string representation of a float or double to a float or double + template<typename T, typename U> T getFloatValue(const std::string& testValueStr) { + try { + U ival(std::stoul(testValueStr, nullptr, 16)); + return T(*reinterpret_cast<T*>(&ival)); + } catch (const std::exception& e) { throw qpidit::InvalidTestValueError(typeid(T).name(), testValueStr); } + } + + template<typename T> T getIntegralValue(const std::string& testValueStr) { + try { + return T(std::stol(testValueStr, nullptr, 16)); + } catch (const std::exception& e) { throw qpidit::InvalidTestValueError(typeid(T).name(), testValueStr); } + } + }; + + } /* namespace shim */ +} /* namespace qpidit */ + +#endif /* SRC_QPIDIT_SHIM_JMSSENDER_HPP_ */ http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/5f7ac58b/shims/qpid-proton-python/src/JmsSenderShim.py ---------------------------------------------------------------------- diff --git a/shims/qpid-proton-python/src/JmsSenderShim.py b/shims/qpid-proton-python/src/JmsSenderShim.py index ca3d0a9..6f0d1be 100755 --- a/shims/qpid-proton-python/src/JmsSenderShim.py +++ b/shims/qpid-proton-python/src/JmsSenderShim.py @@ -61,6 +61,14 @@ class JmsSenderShim(MessagingHandler): if self._send_test_values(event, sub_type, self.test_value_map[sub_type]): return + def on_accepted(self, event): + self.confirmed += 1 + if self.confirmed == self.total: + event.connection.close() + + def on_disconnected(self, event): + self.sent = self.confirmed + def _get_total_num_msgs(self): total = 0 for key in self.test_value_map.keys(): @@ -213,13 +221,6 @@ class JmsSenderShim(MessagingHandler): body=unicode(test_value_text), annotations=create_annotation('JMS_TEXTMESSAGE_TYPE')) - def on_accepted(self, event): - self.confirmed += 1 - if self.confirmed == self.total: - event.connection.close() - - def on_disconnected(self, event): - self.sent = self.confirmed # --- main --- # Args: 1: Broker address (ip-addr:port) http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/5f7ac58b/shims/qpid-proton-python/src/TypesReceiverShim.py ---------------------------------------------------------------------- diff --git a/shims/qpid-proton-python/src/TypesReceiverShim.py b/shims/qpid-proton-python/src/TypesReceiverShim.py index e08ecdb..4196874 100755 --- a/shims/qpid-proton-python/src/TypesReceiverShim.py +++ b/shims/qpid-proton-python/src/TypesReceiverShim.py @@ -26,6 +26,7 @@ from json import dumps from proton.handlers import MessagingHandler from proton.reactor import Container from traceback import format_exc +from string import digits, letters, punctuation from struct import pack, unpack class Receiver(MessagingHandler): @@ -49,7 +50,6 @@ class Receiver(MessagingHandler): if self.expected == 0 or self.received < self.expected: if self.amqp_type == 'null' or \ self.amqp_type == 'boolean' or \ - self.amqp_type == 'timestamp' or \ self.amqp_type == 'uuid': self.received_value_list.append(str(event.message.body)) elif self.amqp_type == 'ubyte' or \ @@ -60,7 +60,8 @@ class Receiver(MessagingHandler): self.amqp_type == 'int': self.received_value_list.append(hex(event.message.body)) elif self.amqp_type == 'ulong' or \ - self.amqp_type == 'long': + self.amqp_type == 'long' or \ + self.amqp_type == 'timestamp': hex_str = hex(int(event.message.body)) if len(hex_str) == 19 and hex_str[-1] == 'L': self.received_value_list.append(hex_str[:-1]) # strip trailing 'L' if present on some ulongs @@ -76,8 +77,12 @@ class Receiver(MessagingHandler): self.received_value_list.append('0x%016x' % event.message.body) elif self.amqp_type == 'decimal128': self.received_value_list.append('0x' + ''.join(['%02x' % ord(c) for c in event.message.body]).strip()) - elif self.amqp_type == 'char' or \ - self.amqp_type == 'binary' or \ + elif self.amqp_type == 'char': + if ord(event.message.body) < 0x80 and event.message.body in digits + letters + punctuation: + self.received_value_list.append(event.message.body) + else: + self.received_value_list.append(hex(ord(event.message.body))) + elif self.amqp_type == 'binary' or \ self.amqp_type == 'string' or \ self.amqp_type == 'symbol': self.received_value_list.append(event.message.body) http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/5f7ac58b/shims/qpid-proton-python/src/TypesSenderShim.py ---------------------------------------------------------------------- diff --git a/shims/qpid-proton-python/src/TypesSenderShim.py b/shims/qpid-proton-python/src/TypesSenderShim.py index dd338b0..dd9920b 100755 --- a/shims/qpid-proton-python/src/TypesSenderShim.py +++ b/shims/qpid-proton-python/src/TypesSenderShim.py @@ -22,6 +22,7 @@ # * Capturing errors from client or broker import sys +import os.path from json import loads from proton import byte, char, decimal32, decimal64, decimal128, float32, int32, Message, short, symbol, timestamp, \ ubyte, uint, ulong, ushort @@ -89,9 +90,13 @@ class Sender(MessagingHandler): elif self.amqp_type == 'decimal128': return Message(id=(self.sent+1), body=decimal128(test_value[2:].decode('hex'))) elif self.amqp_type == 'char': - return Message(id=(self.sent+1), body=char(test_value)) + if len(test_value) == 1: # Format 'a' + return Message(id=(self.sent+1), body=char(test_value)) + else: + val = int(test_value, 16) + return Message(id=(self.sent+1), body=char(unichr(val))) elif self.amqp_type == 'timestamp': - return Message(id=(self.sent+1), body=timestamp(int(test_value))) + return Message(id=(self.sent+1), body=timestamp(int(test_value, 16))) elif self.amqp_type == 'uuid': return Message(id=(self.sent+1), body=UUID(test_value)) elif self.amqp_type == 'binary': @@ -127,6 +132,6 @@ try: except KeyboardInterrupt: pass except Exception as exc: - print 'proton-python-send EXCEPTION:', exc + print os.path.basename(sys.argv[0]), 'EXCEPTION:', exc print format_exc() \ No newline at end of file http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/5f7ac58b/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 7ba2854..cc08b46 100755 --- a/src/py/qpid-interop-test/jms/jms_message_tests.py +++ b/src/py/qpid-interop-test/jms/jms_message_tests.py @@ -122,50 +122,50 @@ class JmsMessageTypes(TestTypeMap): TYPE_MAP = { 'JMS_BYTESMESSAGE_TYPE': TYPE_SUBMAP, 'JMS_MAPMESSAGE_TYPE': TYPE_SUBMAP, - 'JMS_OBJECTMESSAGE_TYPE': { - 'java.lang.Boolean': ['true', - 'false'], - 'java.lang.Byte': ['-128', - '0', - '127'], - 'java.lang.Character': [u'a', - u'Z'], - 'java.lang.Double': ['0.0', - '3.141592654', - '-2.71828182846'], - 'java.lang.Float': ['0.0', - '3.14159', - '-2.71828'], - 'java.lang.Integer': ['-2147483648', - '-129', - '-128', - '-1', - '0', - '127', - '128', - '2147483647'], - 'java.lang.Long' : ['-9223372036854775808', - '-129', - '-128', - '-1', - '0', - '127', - '128', - '9223372036854775807'], - 'java.lang.Short': ['-32768', - '-129', - '-128', - '-1', - '0', - '127', - '128', - '32767'], - 'java.lang.String': [u'', - u'Hello, world', - u'"Hello, world"', - u"Charlie's \"peach\"", - u'Charlie\'s "peach"'] - }, +# 'JMS_OBJECTMESSAGE_TYPE': { +# 'java.lang.Boolean': ['true', +# 'false'], +# 'java.lang.Byte': ['-128', +# '0', +# '127'], +# 'java.lang.Character': [u'a', +# u'Z'], +# 'java.lang.Double': ['0.0', +# '3.141592654', +# '-2.71828182846'], +# 'java.lang.Float': ['0.0', +# '3.14159', +# '-2.71828'], +# 'java.lang.Integer': ['-2147483648', +# '-129', +# '-128', +# '-1', +# '0', +# '127', +# '128', +# '2147483647'], +# 'java.lang.Long' : ['-9223372036854775808', +# '-129', +# '-128', +# '-1', +# '0', +# '127', +# '128', +# '9223372036854775807'], +# 'java.lang.Short': ['-32768', +# '-129', +# '-128', +# '-1', +# '0', +# '127', +# '128', +# '32767'], +# 'java.lang.String': [u'', +# u'Hello, world', +# u'"Hello, world"', +# u"Charlie's \"peach\"", +# u'Charlie\'s "peach"'] +# }, 'JMS_STREAMMESSAGE_TYPE': TYPE_SUBMAP, 'JMS_TEXTMESSAGE_TYPE': {'text': ['', 'Hello, world', @@ -284,10 +284,12 @@ class Shim(object): output = check_output(arg_list) #print '<<<', output # DEBUG- useful to see text received from shim str_tvl = output.split('\n')[:-1] # remove trailing \n - if str_tvl[0] == jms_message_type: + if len(str_tvl) == 1: + return output + if len(str_tvl) == 2: return loads(str_tvl[1]) else: - return output # return error string + return loads("".join(str_tvl[1:])) except CalledProcessError as exc: return str(exc) + '\n\n' + exc.output except Exception as exc: @@ -304,6 +306,16 @@ class ProtonPythonShim(Shim): RECEIVE = [path.join(SHIM_LOC, 'JmsReceiverShim.py')] +class ProtonCppShim(Shim): + """ + Shim for qpid-proton Python client + """ + NAME = 'ProtonCpp' + SHIM_LOC = path.join(QPID_INTEROP_TEST_HOME, 'shims', 'qpid-proton-cpp', 'build', 'src') + SEND = [path.join(SHIM_LOC, 'JmsSender')] + RECEIVE = [path.join(SHIM_LOC, 'JmsReceiver')] + + class QpidJmsShim(Shim): """ Shim for qpid-jms JMS client @@ -351,7 +363,11 @@ class QpidJmsShim(Shim): # As new shims are added, add them into this map to have them included in the test cases. #SHIM_MAP = {ProtonPythonShim.NAME: ProtonPythonShim()} #SHIM_MAP = {QpidJmsShim.NAME: QpidJmsShim()} -SHIM_MAP = {ProtonPythonShim.NAME: ProtonPythonShim(), QpidJmsShim.NAME: QpidJmsShim()} +#SHIM_MAP = {ProtonPythonShim.NAME: ProtonPythonShim(), QpidJmsShim.NAME: QpidJmsShim()} +SHIM_MAP = {ProtonCppShim.NAME: ProtonCppShim(), + QpidJmsShim.NAME: QpidJmsShim(), + ProtonPythonShim.NAME: ProtonPythonShim()} +#SHIM_MAP = {ProtonCppShim.NAME: ProtonCppShim()} # TODO: Complete the test options to give fine control over running tests http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/5f7ac58b/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 cc8fbf2..b0ef92c 100755 --- a/src/py/qpid-interop-test/types/simple_type_tests.py +++ b/src/py/qpid-interop-test/types/simple_type_tests.py @@ -30,10 +30,11 @@ from itertools import product from json import dumps, loads from os import getenv, path from subprocess import check_output, CalledProcessError +from sys import exit from time import mktime, time from uuid import UUID, uuid4 -from proton import symbol +from proton import int32, symbol, timestamp, ulong from test_type_map import TestTypeMap import broker_properties @@ -137,14 +138,17 @@ class AmqpPrimitiveTypes(TestTypeMap): '0xffefffffffffffff'], 'decimal128': ['0x00000000000000000000000000000000', '0xff0102030405060708090a0b0c0d0e0f'], - 'char': ['a', - 'Z', - '\x01', - '\x7f'], + 'char': [u'a', + u'Z', + u'0x1', + u'0x7f', + u'0x16b5', # Rune 'G' + u'0x10ffff'], # 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)], + 'timestamp': ['0x0', + '0x%x' % int(mktime((2000, 1, 1, 0, 0, 0, 5, 1, 0))*1000), + '0x%x' % int(time()*1000) + ], 'uuid': [str(UUID(int=0x0)), str(UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')), str(uuid4())], @@ -152,38 +156,51 @@ class AmqpPrimitiveTypes(TestTypeMap): bytes(12345), b'Hello, world!', b'\\x01\\x02\\x03\\x04\\x05abcde\\x80\\x81\\xfe\\xff', - b'The quick brown fox jumped over the lazy dog 0123456789.' * 1000], + b'The quick brown fox jumped over the lazy dog 0123456789.' * 1000 + ], # strings must be unicode to comply with AMQP spec 'string': [u'', u'Hello, world!', u'"Hello, world!"', u"Charlie's peach", - u'The quick brown fox jumped over the lazy dog 0123456789.' * 1000], + u'The quick brown fox jumped over the lazy dog 0123456789.' * 1000 + ], 'symbol': ['', 'myDomain.123', 'domain.0123456789.' * 100], 'list': [[], - [1, -2, 3.14], - [u'a', u'b', u'c'], - #[ulong(12345), timestamp(int(time()*1000)), int32(-25), uuid4(), symbol('a.b.c')], - [[], None, [1, 2, 3], True, False], + ['ubyte:1', 'int:-2', 'float:3.14'], + ['string:a', 'string:b', 'string:c'], + ['ulong:12345', 'timestamp:%d' % (time()*1000), 'short:-2500', 'uuid:%s' % uuid4(), 'symbol:a.b.c', 'none:', 'decimal64:0x400921fb54442eea'], + [[], 'none', ['ubyte:1', 'ubyte:2', 'ubyte:3'], 'boolean:True', 'boolean:False', {'string:hello': 'long:1234', 'string:goodbye': 'boolean:True'}], [[], [[], [[], [], []], []], []], - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] * 1000 + ['short:0', 'short:1', 'short:2', 'short:3', 'short:4', 'short:5', 'short:6', 'short:7', 'short:8', 'short:9'] * 1000 ], - # TODO: Maps translate into object descriptions in JSON, so only string keys are allowed. Come up with - # a method to represent a Python map in JSON. 'map': [{}, - {u'one': 1, - u'two': 2}, - {u'None': None, - u'One': 1, - u'2': '2', - u'True': True, - u'False': False, - u'map': {u'A': 1, - u'B': 2}} + {'string:one': 'ubyte:1', + 'string:two': 'ushort:2'}, + {'none:': 'string:None', + 'string:None': 'none:', + 'string:One': 'long:-1234567890', + 'short:2': 'int:2', + 'boolean:True': 'string:True', + 'string:False': 'boolean:False', + #['string:AAA', 'ushort:5951']: 'string:list value', + #{'byte:-55': 'ubyte:200', + # 'boolean:True': 'string:Hello, world!'}: 'symbol:map.value', + #'string:list': [], + 'string:map': {'char:A': 'int:1', + 'char:B': 'int:2'}} ], - #'array': [[], [1,2,3], ['Hello', 'world']] # TODO: Not yet implemented + # TODO: Support all AMQP types in array (including keys) +# 'array': [[], +# [1, 2, 3], +# ['Hello', 'world'], +# [[1, 2, 3], +# ['a', 'b', 'c'], +# [2.3, 3.4, 4,5], +# [True, False, True, True]] +# ] } BROKER_SKIP = {'decimal32': {'qpid-cpp': 'decimal32 not supported on qpid-cpp broker: QPIDIT-5, QPID-6328',}, @@ -191,7 +208,7 @@ class AmqpPrimitiveTypes(TestTypeMap): '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',}, } - +# BROKER_SKIP = {} class AmqpTypeTestCase(unittest.TestCase): @@ -236,9 +253,7 @@ def create_testcase_class(broker_name, types, broker_addr, amqp_type, shim_produ def inner_test_method(self): self.run_test(self.broker_addr, self.amqp_type, self.test_value_list, send_shim, receive_shim) - inner_test_method.__name__ = 'test_%s_%s' % (send_shim.NAME, receive_shim.NAME) - inner_test_method.__doc__ = 'AMQP type \'%s\' interop test: %s -> %s' % \ - (amqp_type, send_shim.NAME, receive_shim.NAME) + inner_test_method.__name__ = 'test_%s_%s->%s' % (amqp_type, send_shim.NAME, receive_shim.NAME) setattr(cls, inner_test_method.__name__, inner_test_method) class_name = amqp_type.title() + 'TestCase' @@ -296,7 +311,12 @@ class Shim(object): output = check_output(arg_list) #print '<<<', output # DEBUG - useful to see text received from shim str_tvl = output.split('\n')[0:-1] # remove trailing \n - return loads(str_tvl[1]) + if len(str_tvl) == 1: + return output + if len(str_tvl) == 2: + return loads(str_tvl[1]) + else: + return loads("".join(str_tvl[1:])) except CalledProcessError as exc: return str(exc) + '\n\n' + exc.output except Exception as exc: @@ -307,12 +327,22 @@ class ProtonPythonShim(Shim): """ Shim for qpid-proton Python client """ - NAME = 'ProtonPython' + NAME = 'Python' SHIM_LOC = path.join(QPID_INTEROP_TEST_HOME, 'shims', 'qpid-proton-python', 'src') SEND = [path.join(SHIM_LOC, 'TypesSenderShim.py')] RECEIVE = [path.join(SHIM_LOC, 'TypesReceiverShim.py')] +class ProtonCppShim(Shim): + """ + Shim for qpid-proton C++ client + """ + NAME = 'C++' + SHIM_LOC = path.join(QPID_INTEROP_TEST_HOME, 'shims', 'qpid-proton-cpp', 'build', 'src') + SEND = [path.join(SHIM_LOC, 'AmqpSender')] + RECEIVE = [path.join(SHIM_LOC, 'AmqpReceiver')] + + class QpidJmsShim(Shim): """ Shim for qpid-jms JMS client @@ -354,11 +384,11 @@ class QpidJmsShim(Shim): # other shim in the list. # # As new shims are added, add them into this map to have them included in the test cases. -SHIM_MAP = {ProtonPythonShim.NAME: ProtonPythonShim()} -#SHIM_MAP = {QpidJmsShim.NAME: QpidJmsShim()} -#SHIM_MAP = {ProtonPythonShim.NAME: ProtonPythonShim(), -# QpidJmsShim.NAME: QpidJmsShim() -# } +#SHIM_MAP = {ProtonPythonShim.NAME: ProtonPythonShim()} +#SHIM_MAP = {ProtonPythonShim.NAME: ProtonCppShim()} +SHIM_MAP = {ProtonCppShim.NAME: ProtonCppShim(), + ProtonPythonShim.NAME: ProtonPythonShim() + } class TestOptions(object): @@ -399,6 +429,9 @@ if __name__ == '__main__': # Connect to broker to find broker type CONNECTION_PROPS = broker_properties.getBrokerProperties(ARGS.broker) + if CONNECTION_PROPS is None: + print 'ERROR: Unable to get connection properties - terminating' + exit(-1) print 'Test Broker: %s v.%s on %s' % (CONNECTION_PROPS[symbol(u'product')], CONNECTION_PROPS[symbol(u'version')], CONNECTION_PROPS[symbol(u'platform')]) --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
