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 2018/03/20 16:52:23 UTC
qpid-interop-test git commit: QPIDIT-46: Added encoding for AMQP list
and map types,
and which can contain other lists and maps. This has been completed on the
ProtonCpp and ProtonPython{2, 3} shims,
and RheaJs and AmqpNetLite have this test disabled for
Repository: qpid-interop-test
Updated Branches:
refs/heads/master 90944238f -> b87dc72a3
QPIDIT-46: Added encoding for AMQP list and map types, and which can contain other lists and maps. This has been completed on the ProtonCpp and ProtonPython{2,3} shims, and RheaJs and AmqpNetLite have this test disabled for now.
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/b87dc72a
Tree: http://git-wip-us.apache.org/repos/asf/qpid-interop-test/tree/b87dc72a
Diff: http://git-wip-us.apache.org/repos/asf/qpid-interop-test/diff/b87dc72a
Branch: refs/heads/master
Commit: b87dc72a330724d6d888d87faa567d003a2e5c07
Parents: 9094423
Author: Kim van der Riet <kv...@localhost.localdomain>
Authored: Tue Mar 20 12:52:00 2018 -0400
Committer: Kim van der Riet <kv...@localhost.localdomain>
Committed: Tue Mar 20 12:52:00 2018 -0400
----------------------------------------------------------------------
.../qpid-proton-cpp/src/qpidit/QpidItErrors.cpp | 4 +
.../qpid-proton-cpp/src/qpidit/QpidItErrors.hpp | 1 +
.../src/qpidit/amqp_types_test/Receiver.cpp | 314 +++++++++++--------
.../src/qpidit/amqp_types_test/Receiver.hpp | 7 +-
.../src/qpidit/amqp_types_test/Sender.cpp | 231 ++++++++------
.../src/qpidit/amqp_types_test/Sender.hpp | 27 +-
.../src/amqp_types_test/Receiver.py | 220 ++++++++++---
.../src/amqp_types_test/Sender.py | 162 +++++++---
src/python/qpid_interop_test/amqp_types_test.py | 77 ++---
9 files changed, 648 insertions(+), 395 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/b87dc72a/shims/qpid-proton-cpp/src/qpidit/QpidItErrors.cpp
----------------------------------------------------------------------
diff --git a/shims/qpid-proton-cpp/src/qpidit/QpidItErrors.cpp b/shims/qpid-proton-cpp/src/qpidit/QpidItErrors.cpp
index ed8bc09..71fb4e3 100644
--- a/shims/qpid-proton-cpp/src/qpidit/QpidItErrors.cpp
+++ b/shims/qpid-proton-cpp/src/qpidit/QpidItErrors.cpp
@@ -133,6 +133,10 @@ namespace qpidit
// --- InvalidTestValueError ---
+ InvalidTestValueError::InvalidTestValueError(const std::string& valueStr) :
+ std::runtime_error(MSG("Invalid element test value: \"" << valueStr << "\" is not in format \"amqp-type:value-as_str\""))
+ {}
+
InvalidTestValueError::InvalidTestValueError(const std::string& type, const std::string& valueStr) :
std::runtime_error(MSG("Invalid test value: \"" << valueStr << "\" is not valid for type " << type))
{}
http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/b87dc72a/shims/qpid-proton-cpp/src/qpidit/QpidItErrors.hpp
----------------------------------------------------------------------
diff --git a/shims/qpid-proton-cpp/src/qpidit/QpidItErrors.hpp b/shims/qpid-proton-cpp/src/qpidit/QpidItErrors.hpp
index 1779cce..7a1d2e2 100644
--- a/shims/qpid-proton-cpp/src/qpidit/QpidItErrors.hpp
+++ b/shims/qpid-proton-cpp/src/qpidit/QpidItErrors.hpp
@@ -108,6 +108,7 @@ namespace qpidit
class InvalidTestValueError: public std::runtime_error
{
public:
+ InvalidTestValueError(const std::string& valueStr);
InvalidTestValueError(const std::string& type, const std::string& valueStr);
virtual ~InvalidTestValueError() throw();
};
http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/b87dc72a/shims/qpid-proton-cpp/src/qpidit/amqp_types_test/Receiver.cpp
----------------------------------------------------------------------
diff --git a/shims/qpid-proton-cpp/src/qpidit/amqp_types_test/Receiver.cpp b/shims/qpid-proton-cpp/src/qpidit/amqp_types_test/Receiver.cpp
index e5fe3d0..6b6f2ba 100644
--- a/shims/qpid-proton-cpp/src/qpidit/amqp_types_test/Receiver.cpp
+++ b/shims/qpid-proton-cpp/src/qpidit/amqp_types_test/Receiver.cpp
@@ -65,95 +65,7 @@ namespace qpidit
void Receiver::on_message(proton::delivery &d, proton::message &m) {
try {
if (_received < _expected) {
- if (_amqpType.compare("null") == 0) {
- checkMessageType(m, proton::NULL_TYPE);
- _receivedValueList.append("None");
- } else if (_amqpType.compare("boolean") == 0) {
- checkMessageType(m, proton::BOOLEAN);
- _receivedValueList.append(proton::get<bool>(m.body()) ? "True": "False");
- } else if (_amqpType.compare("ubyte") == 0) {
- checkMessageType(m, proton::UBYTE);
- _receivedValueList.append(toHexStr<uint8_t>(proton::get<uint8_t>(m.body())));
- } else if (_amqpType.compare("ushort") == 0) {
- checkMessageType(m, proton::USHORT);
- _receivedValueList.append(toHexStr<uint16_t>(proton::get<uint16_t>(m.body())));
- } else if (_amqpType.compare("uint") == 0) {
- checkMessageType(m, proton::UINT);
- _receivedValueList.append(toHexStr<uint32_t>(proton::get<uint32_t>(m.body())));
- } else if (_amqpType.compare("ulong") == 0) {
- checkMessageType(m, proton::ULONG);
- _receivedValueList.append(toHexStr<uint64_t>(proton::get<uint64_t>(m.body())));
- } else if (_amqpType.compare("byte") == 0) {
- checkMessageType(m, proton::BYTE);
- _receivedValueList.append(toHexStr<int8_t>(proton::get<int8_t>(m.body())));
- } else if (_amqpType.compare("short") == 0) {
- checkMessageType(m, proton::SHORT);
- _receivedValueList.append(toHexStr<int16_t>(proton::get<int16_t>(m.body())));
- } else if (_amqpType.compare("int") == 0) {
- checkMessageType(m, proton::INT);
- _receivedValueList.append(toHexStr<int32_t>(proton::get<int32_t>(m.body())));
- } else if (_amqpType.compare("long") == 0) {
- checkMessageType(m, proton::LONG);
- _receivedValueList.append(toHexStr<int64_t>(proton::get<int64_t>(m.body())));
- } else if (_amqpType.compare("float") == 0) {
- checkMessageType(m, proton::FLOAT);
- float f = proton::get<float>(m.body());
- _receivedValueList.append(toHexStr<uint32_t>(*((uint32_t*)&f), true));
- } else if (_amqpType.compare("double") == 0) {
- checkMessageType(m, proton::DOUBLE);
- double d = proton::get<double>(m.body());
- _receivedValueList.append(toHexStr<uint64_t>(*((uint64_t*)&d), true));
- } else if (_amqpType.compare("decimal32") == 0) {
- checkMessageType(m, proton::DECIMAL32);
- _receivedValueList.append(byteArrayToHexStr(proton::get<proton::decimal32>(m.body())));
- } else if (_amqpType.compare("decimal64") == 0) {
- checkMessageType(m, proton::DECIMAL64);
- _receivedValueList.append(byteArrayToHexStr(proton::get<proton::decimal64>(m.body())));
- } else if (_amqpType.compare("decimal128") == 0) {
- checkMessageType(m, proton::DECIMAL128);
- _receivedValueList.append(byteArrayToHexStr(proton::get<proton::decimal128>(m.body())));
- } else if (_amqpType.compare("char") == 0) {
- checkMessageType(m, proton::CHAR);
- wchar_t c = proton::get<wchar_t>(m.body());
- std::stringstream oss;
- if (c < 0x7f && std::iswprint(c)) {
- oss << (char)c;
- } else {
- oss << "0x" << std::hex << c;
- }
- _receivedValueList.append(oss.str());
- } else if (_amqpType.compare("timestamp") == 0) {
- checkMessageType(m, proton::TIMESTAMP);
- std::ostringstream oss;
- oss << "0x" << std::hex << proton::get<proton::timestamp>(m.body()).milliseconds();
- _receivedValueList.append(oss.str());
- } else if (_amqpType.compare("uuid") == 0) {
- checkMessageType(m, proton::UUID);
- std::ostringstream oss;
- oss << proton::get<proton::uuid>(m.body());
- _receivedValueList.append(oss.str());
- } else if (_amqpType.compare("binary") == 0) {
- checkMessageType(m, proton::BINARY);
- _receivedValueList.append(std::string(proton::get<proton::binary>(m.body())));
- } else if (_amqpType.compare("string") == 0) {
- checkMessageType(m, proton::STRING);
- _receivedValueList.append(proton::get<std::string>(m.body()));
- } else if (_amqpType.compare("symbol") == 0) {
- checkMessageType(m, proton::SYMBOL);
- _receivedValueList.append(proton::get<proton::symbol>(m.body()));
- } else if (_amqpType.compare("list") == 0) {
- checkMessageType(m, proton::LIST);
- Json::Value jsonList(Json::arrayValue);
- _receivedValueList.append(getSequence(jsonList, m.body()));
- } else if (_amqpType.compare("map") == 0) {
- checkMessageType(m, proton::MAP);
- Json::Value jsonMap(Json::objectValue);
- _receivedValueList.append(getMap(jsonMap, m.body()));
- } else if (_amqpType.compare("array") == 0) {
- throw qpidit::UnsupportedAmqpTypeError(_amqpType);
- } else {
- throw qpidit::UnknownAmqpTypeError(_amqpType);
- }
+ _receivedValueList.append(getValue(_amqpType, m.body()));
}
_received++;
if (_received >= _expected) {
@@ -190,9 +102,40 @@ namespace qpidit
// protected
//static
- void Receiver::checkMessageType(const proton::message& msg, proton::type_id amqpType) {
- if (msg.body().type() != amqpType) {
- throw qpidit::IncorrectMessageBodyTypeError(amqpType, msg.body().type());
+ void Receiver::checkMessageType(const proton::value& val, proton::type_id amqpType) {
+ if (val.type() != amqpType) {
+ throw qpidit::IncorrectMessageBodyTypeError(amqpType, val.type());
+ }
+ }
+
+ //static
+ std::string Receiver::getAmqpType(const proton::value& val) {
+ switch(val.type()) {
+ case proton::NULL_TYPE: return "null";
+ case proton::BOOLEAN: return "boolean";
+ case proton::UBYTE: return "ubyte";
+ case proton::USHORT: return "ushort";
+ case proton::UINT: return "uint";
+ case proton::ULONG: return "ulong";
+ case proton::BYTE: return "byte";
+ case proton::SHORT: return "short";
+ case proton::INT: return "int";
+ case proton::LONG: return "long";
+ case proton::FLOAT: return "float";
+ case proton::DOUBLE: return "double";
+ case proton::DECIMAL32: return "decimal32";
+ case proton::DECIMAL64: return "decimal64";
+ case proton::DECIMAL128: return "decimal128";
+ case proton::CHAR: return "char";
+ case proton::TIMESTAMP: return "timestamp";
+ case proton::UUID: return "uuid";
+ case proton::BINARY: return "binary";
+ case proton::STRING: return "string";
+ case proton::SYMBOL: return "symbol";
+ case proton::LIST: return "list";
+ case proton::MAP: return "map";
+ case proton::ARRAY: return "array";
+ //default: throw qpidit::UnknownAmqpTypeError(val);
}
}
@@ -201,27 +144,28 @@ namespace qpidit
std::map<proton::value, proton::value> msgMap;
proton::get(val, msgMap);
for (std::map<proton::value, proton::value>::const_iterator i = msgMap.begin(); i != msgMap.end(); ++i) {
- switch (i->second.type()) {
- case proton::LIST:
- {
- Json::Value jsonSubList(Json::arrayValue);
- jsonMap[proton::get<std::string>(i->first)] = getSequence(jsonSubList, i->second);
- break;
- }
- case proton::MAP:
- {
- Json::Value jsonSubMap(Json::objectValue);
- jsonMap[proton::get<std::string>(i->first)] = getMap(jsonSubMap, i->second);
- break;
+
+ // Process key
+ Json::Value mapKey;
+ if (i->first.type() == proton::LIST || i->first.type() == proton::MAP || i->first.type() == proton::ARRAY) {
+ mapKey = getValue(i->first);
+ } else {
+ std::ostringstream oss;
+ oss << getAmqpType(i->first) << ":" << getValue(i->first).asString();
+ mapKey = oss.str();
}
- case proton::ARRAY:
- break;
- case proton::STRING:
- jsonMap[proton::get<std::string>(i->first)] = Json::Value(proton::get<std::string>(i->second));
- break;
- default:
- throw qpidit::IncorrectValueTypeError(i->second);
+
+ // Process value
+ Json::Value mapValue;
+ if (i->second.type() == proton::LIST || i->second.type() == proton::MAP || i->second.type() == proton::ARRAY) {
+ mapValue = getValue(i->second);
+ } else {
+ std::ostringstream oss;
+ oss << getAmqpType(i->second) << ":" << getValue(i->second).asString();
+ mapValue = oss.str();
}
+
+ jsonMap[mapKey.asString()] = mapValue;
}
return jsonMap;
}
@@ -231,39 +175,135 @@ namespace qpidit
std::vector<proton::value> msgList;
proton::get(val, msgList);
for (std::vector<proton::value>::const_iterator i=msgList.begin(); i!=msgList.end(); ++i) {
- switch ((*i).type()) {
- case proton::LIST:
- {
- Json::Value jsonSubList(Json::arrayValue);
- jsonList.append(getSequence(jsonSubList, *i));
- break;
- }
- case proton::MAP:
- {
- Json::Value jsonSubMap(Json::objectValue);
- jsonList.append(getMap(jsonSubMap, *i));
- break;
- }
- case proton::ARRAY:
- break;
- case proton::STRING:
- jsonList.append(Json::Value(proton::get<std::string>(*i)));
- break;
- default:
- throw qpidit::IncorrectValueTypeError(*i);
+ if (i->type() == proton::LIST || i->type() == proton::MAP || i->type() == proton::ARRAY) {
+ jsonList.append(getValue(*i));
+ } else {
+ std::ostringstream oss;
+ oss << getAmqpType(*i) << ":" << getValue(*i).asString();
+ jsonList.append(oss.str());
}
}
return jsonList;
}
//static
- std::string Receiver::stringToHexStr(const std::string& str) {
- std::ostringstream oss;
- oss << "0x" << std::hex;
- for (std::string::const_iterator i=str.begin(); i!=str.end(); ++i) {
- oss << std::setw(2) << std::setfill('0') << ((int)*i & 0xff);
+ Json::Value Receiver::getValue(const proton::value& val) {
+ return getValue(getAmqpType(val), val);
+ }
+
+ //static
+ Json::Value Receiver::getValue(const std::string& amqpType, const proton::value& val) {
+ if (amqpType.compare("null") == 0) {
+ checkMessageType(val, proton::NULL_TYPE);
+ return "None";
+ }
+ if (amqpType.compare("boolean") == 0) {
+ checkMessageType(val, proton::BOOLEAN);
+ return proton::get<bool>(val) ? "True" : "False";
+ }
+ if (amqpType.compare("ubyte") == 0) {
+ checkMessageType(val, proton::UBYTE);
+ return toHexStr<uint8_t>(proton::get<uint8_t>(val));
+ }
+ if (amqpType.compare("ushort") == 0) {
+ checkMessageType(val, proton::USHORT);
+ return toHexStr<uint16_t>(proton::get<uint16_t>(val));
+ }
+ if (amqpType.compare("uint") == 0) {
+ checkMessageType(val, proton::UINT);
+ return toHexStr<uint32_t>(proton::get<uint32_t>(val));
+ }
+ if (amqpType.compare("ulong") == 0) {
+ checkMessageType(val, proton::ULONG);
+ return toHexStr<uint64_t>(proton::get<uint64_t>(val));
+ }
+ if (amqpType.compare("byte") == 0) {
+ checkMessageType(val, proton::BYTE);
+ return toHexStr<int8_t>(proton::get<int8_t>(val));
+ }
+ if (amqpType.compare("short") == 0) {
+ checkMessageType(val, proton::SHORT);
+ return toHexStr<int16_t>(proton::get<int16_t>(val));
+ }
+ if (amqpType.compare("int") == 0) {
+ checkMessageType(val, proton::INT);
+ return toHexStr<int32_t>(proton::get<int32_t>(val));
+ }
+ if (amqpType.compare("long") == 0) {
+ checkMessageType(val, proton::LONG);
+ return toHexStr<int64_t>(proton::get<int64_t>(val));
+ }
+ if (amqpType.compare("float") == 0) {
+ checkMessageType(val, proton::FLOAT);
+ float f = proton::get<float>(val);
+ return toHexStr<uint32_t>(*((uint32_t*)&f), true);
+ }
+ if (amqpType.compare("double") == 0) {
+ checkMessageType(val, proton::DOUBLE);
+ double d = proton::get<double>(val);
+ return toHexStr<uint64_t>(*((uint64_t*)&d), true);
+ }
+ if (amqpType.compare("decimal32") == 0) {
+ checkMessageType(val, proton::DECIMAL32);
+ return byteArrayToHexStr(proton::get<proton::decimal32>(val));
+ }
+ if (amqpType.compare("decimal64") == 0) {
+ checkMessageType(val, proton::DECIMAL64);
+ return byteArrayToHexStr(proton::get<proton::decimal64>(val));
+ }
+ if (amqpType.compare("decimal128") == 0) {
+ checkMessageType(val, proton::DECIMAL128);
+ return byteArrayToHexStr(proton::get<proton::decimal128>(val));
+ }
+ if (amqpType.compare("char") == 0) {
+ checkMessageType(val, proton::CHAR);
+ wchar_t c = proton::get<wchar_t>(val);
+ std::stringstream oss;
+ if (c < 0x7f && std::iswprint(c)) {
+ oss << (char)c;
+ } else {
+ oss << "0x" << std::hex << c;
+ }
+ return oss.str();
+ }
+ if (amqpType.compare("timestamp") == 0) {
+ checkMessageType(val, proton::TIMESTAMP);
+ std::ostringstream oss;
+ oss << "0x" << std::hex << proton::get<proton::timestamp>(val).milliseconds();
+ return oss.str();
+ }
+ if (amqpType.compare("uuid") == 0) {
+ checkMessageType(val, proton::UUID);
+ std::ostringstream oss;
+ oss << proton::get<proton::uuid>(val);
+ return oss.str();
+ }
+ if (amqpType.compare("binary") == 0) {
+ checkMessageType(val, proton::BINARY);
+ return std::string(proton::get<proton::binary>(val));
+ }
+ if (amqpType.compare("string") == 0) {
+ checkMessageType(val, proton::STRING);
+ return proton::get<std::string>(val);
+ }
+ if (amqpType.compare("symbol") == 0) {
+ checkMessageType(val, proton::SYMBOL);
+ return proton::get<proton::symbol>(val);
+ }
+ if (amqpType.compare("list") == 0) {
+ checkMessageType(val, proton::LIST);
+ Json::Value jsonList(Json::arrayValue);
+ return getSequence(jsonList, val);
+ }
+ if (amqpType.compare("map") == 0) {
+ checkMessageType(val, proton::MAP);
+ Json::Value jsonMap(Json::objectValue);
+ return getMap(jsonMap, val);
+ }
+ if (amqpType.compare("array") == 0) {
+ throw qpidit::UnsupportedAmqpTypeError(amqpType);
}
- return oss.str();
+ throw qpidit::UnknownAmqpTypeError(amqpType);
}
} /* namespace amqp_types_test */
http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/b87dc72a/shims/qpid-proton-cpp/src/qpidit/amqp_types_test/Receiver.hpp
----------------------------------------------------------------------
diff --git a/shims/qpid-proton-cpp/src/qpidit/amqp_types_test/Receiver.hpp b/shims/qpid-proton-cpp/src/qpidit/amqp_types_test/Receiver.hpp
index 16c13c2..8b5b32d 100644
--- a/shims/qpid-proton-cpp/src/qpidit/amqp_types_test/Receiver.hpp
+++ b/shims/qpid-proton-cpp/src/qpidit/amqp_types_test/Receiver.hpp
@@ -55,10 +55,13 @@ namespace qpidit
void on_transport_error(proton::transport &t);
void on_error(const proton::error_condition &c);
protected:
- static void checkMessageType(const proton::message& msg, proton::type_id msgType);
+ //static void checkMessageType(const proton::message& msg, const proton::type_id amqpType);
+ static void checkMessageType(const proton::value& val, const proton::type_id amqpType);
+ static std::string getAmqpType(const proton::value& val);
static Json::Value& getMap(Json::Value& jsonMap, const proton::value& val);
static Json::Value& getSequence(Json::Value& jsonList, const proton::value& val);
- static std::string stringToHexStr(const std::string& str);
+ static Json::Value getValue(const proton::value& val);
+ static Json::Value getValue(const std::string& amqpType, const proton::value& val);
// Format signed numbers in negative hex format, ie -0xNNNN, positive numbers in 0xNNNN format
template<typename T> static std::string toHexStr(T val, bool fillFlag = false) {
http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/b87dc72a/shims/qpid-proton-cpp/src/qpidit/amqp_types_test/Sender.cpp
----------------------------------------------------------------------
diff --git a/shims/qpid-proton-cpp/src/qpidit/amqp_types_test/Sender.cpp b/shims/qpid-proton-cpp/src/qpidit/amqp_types_test/Sender.cpp
index 8cdb72c..d083791 100644
--- a/shims/qpid-proton-cpp/src/qpidit/amqp_types_test/Sender.cpp
+++ b/shims/qpid-proton-cpp/src/qpidit/amqp_types_test/Sender.cpp
@@ -21,6 +21,7 @@
#include "qpidit/amqp_types_test/Sender.hpp"
+#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <json/json.h>
@@ -65,53 +66,94 @@ namespace qpidit
proton::message& Sender::setMessage(proton::message& msg, const Json::Value& testValue) {
msg.id(_msgsSent + 1);
- if (_amqpType.compare("null") == 0) {
+ msg.body(convertAmqpValue(_amqpType, testValue));
+ return msg;
+ }
+
+ //static
+ std::string Sender::bytearrayToHexStr(const char* src, int len) {
+ std::ostringstream oss;
+ oss << "0x" << std::hex;
+ for (int i=0; i<len; ++i) {
+ oss << std::setw(2) << std::setfill('0') << ((int)src[i] & 0xff);
+ }
+ return oss.str();
+ }
+
+ //static
+ proton::value Sender::convertAmqpValue(const std::string& amqpType, const Json::Value& testValue) {
+ if (amqpType.compare("null") == 0) {
std::string testValueStr(testValue.asString());
- if (testValueStr.compare("None") != 0) { throw qpidit::InvalidTestValueError(_amqpType, testValueStr); }
+ if (testValueStr.compare("None") != 0) {
+ throw qpidit::InvalidTestValueError(amqpType, testValueStr);
+ }
proton::value v;
- msg.body(v);
- } else if (_amqpType.compare("boolean") == 0) {
+ return v;
+ }
+ if (amqpType.compare("boolean") == 0) {
std::string testValueStr(testValue.asString());
if (testValueStr.compare("True") == 0) {
- msg.body(true);
+ return true;
} else if (testValueStr.compare("False") == 0) {
- msg.body(false);
+ return false;
} else {
- throw qpidit::InvalidTestValueError(_amqpType, testValueStr);
+ throw qpidit::InvalidTestValueError(amqpType, testValueStr);
}
- } else if (_amqpType.compare("ubyte") == 0) {
- setIntegralValue<uint8_t>(msg, testValue.asString(), true);
- } else if (_amqpType.compare("ushort") == 0) {
- setIntegralValue<uint16_t>(msg, testValue.asString(), true);
- } else if (_amqpType.compare("uint") == 0) {
- setIntegralValue<uint32_t>(msg, testValue.asString(), true);
- } else if (_amqpType.compare("ulong") == 0) {
- setIntegralValue<uint64_t>(msg, testValue.asString(), true);
- } else if (_amqpType.compare("byte") == 0) {
- setIntegralValue<int8_t>(msg, testValue.asString(), false);
- } else if (_amqpType.compare("short") == 0) {
- setIntegralValue<int16_t>(msg, testValue.asString(), false);
- } else if (_amqpType.compare("int") == 0) {
- setIntegralValue<int32_t>(msg, testValue.asString(), false);
- } else if (_amqpType.compare("long") == 0) {
- setIntegralValue<int64_t>(msg, testValue.asString(), false);
- } else if (_amqpType.compare("float") == 0) {
- setFloatValue<float, uint32_t>(msg, testValue.asString());
- } else if (_amqpType.compare("double") == 0) {
- setFloatValue<double, uint64_t>(msg, testValue.asString());
- } else if (_amqpType.compare("decimal32") == 0) {
+ }
+ if (amqpType.compare("ubyte") == 0) {
+ return integralValue<uint8_t>(amqpType, testValue.asString(), true);
+ }
+ if (amqpType.compare("ushort") == 0) {
+ return integralValue<uint16_t>(amqpType, testValue.asString(), true);
+ }
+ if (amqpType.compare("uint") == 0) {
+ return integralValue<uint32_t>(amqpType, testValue.asString(), true);
+ }
+ if (amqpType.compare("ulong") == 0) {
+ return integralValue<uint64_t>(amqpType, testValue.asString(), true);
+ }
+ if (amqpType.compare("byte") == 0) {
+ return integralValue<int8_t>(amqpType, testValue.asString(), false);
+ }
+ if (amqpType.compare("short") == 0) {
+ return integralValue<int16_t>(amqpType, testValue.asString(), false);
+ }
+ if (amqpType.compare("int") == 0) {
+ return integralValue<int32_t>(amqpType, testValue.asString(), false);
+ }
+ if (amqpType.compare("long") == 0) {
+ return integralValue<int64_t>(amqpType, testValue.asString(), false);
+ }
+ if (amqpType.compare("float") == 0) {
+ const std::string testValueStr = testValue.asString();
+ if (testValueStr.find("0x") == std::string::npos) // regular decimal fraction
+ return std::strtof(testValueStr.c_str(), nullptr);
+ // hex representation of float
+ return floatValue<float, uint32_t>(amqpType, testValue.asString());
+ }
+ if (amqpType.compare("double") == 0) {
+ const std::string testValueStr = testValue.asString();
+ if (testValueStr.find("0x") == std::string::npos) // regular decimal fraction
+ return std::strtod(testValueStr.c_str(), nullptr);
+ // hex representation of float
+ return floatValue<double, uint64_t>(amqpType, testValue.asString());
+ }
+ if (amqpType.compare("decimal32") == 0) {
proton::decimal32 val;
hexStringToBytearray(val, testValue.asString().substr(2));
- msg.body(val);
- } else if (_amqpType.compare("decimal64") == 0) {
+ return val;
+ }
+ if (amqpType.compare("decimal64") == 0) {
proton::decimal64 val;
hexStringToBytearray(val, testValue.asString().substr(2));
- msg.body(val);
- } else if (_amqpType.compare("decimal128") == 0) {
+ return val;
+ }
+ if (amqpType.compare("decimal128") == 0) {
proton::decimal128 val;
hexStringToBytearray(val, testValue.asString().substr(2));
- msg.body(val);
- } else if (_amqpType.compare("char") == 0) {
+ return val;
+ }
+ if (amqpType.compare("char") == 0) {
std::string charStr = testValue.asString();
wchar_t val;
if (charStr.size() == 1) { // Single char "a"
@@ -121,11 +163,14 @@ namespace qpidit
} else {
//TODO throw format error
}
- msg.body(val);
- } else if (_amqpType.compare("timestamp") == 0) {
- proton::timestamp val(std::strtoul(testValue.asString().data(), NULL, 16));
- msg.body(val);
- } else if (_amqpType.compare("uuid") == 0) {
+ return val;
+ }
+ if (amqpType.compare("timestamp") == 0) {
+ const std::string testValueStr(testValue.asString());
+ bool xhexFlag = testValueStr.find("0x") != std::string::npos;
+ return proton::timestamp(std::strtoul(testValue.asString().data(), NULL, xhexFlag ? 16 : 10));
+ }
+ if (amqpType.compare("uuid") == 0) {
proton::uuid val;
std::string uuidStr(testValue.asString());
// Expected format: "00000000-0000-0000-0000-000000000000"
@@ -136,70 +181,35 @@ namespace qpidit
hexStringToBytearray(val, uuidStr.substr(14, 4), 6, 2);
hexStringToBytearray(val, uuidStr.substr(19, 4), 8, 2);
hexStringToBytearray(val, uuidStr.substr(24, 12), 10, 6);
- msg.body(val);
- } else if (_amqpType.compare("binary") == 0) {
- //setStringValue<proton::amqp_binary>(msg, testValue.asString());
- proton::binary val(testValue.asString());
- msg.body(val);
- } else if (_amqpType.compare("string") == 0) {
- //setStringValue<proton::amqp_string>(msg, testValue.asString());
- std::string val(testValue.asString());
- msg.body(val);
- } else if (_amqpType.compare("symbol") == 0) {
- //setStringValue<proton::amqp_symbol>(msg, testValue.asString());
- proton::symbol val(testValue.asString());
- msg.body(val);
- } else if (_amqpType.compare("list") == 0) {
+ return val;
+ }
+ if (amqpType.compare("binary") == 0) {
+ return proton::binary(testValue.asString());
+ }
+ if (amqpType.compare("string") == 0) {
+ return std::string(testValue.asString());
+ }
+ if (amqpType.compare("symbol") == 0) {
+ return proton::symbol(testValue.asString());
+ }
+ if (amqpType.compare("list") == 0) {
std::vector<proton::value> list;
processList(list, testValue);
- msg.body(list);
- } else if (_amqpType.compare("map") == 0) {
- std::map<std::string, proton::value> map;
+ return list;
+ } else if (amqpType.compare("map") == 0) {
+ std::map<proton::value, proton::value> map;
processMap(map, testValue);
- msg.body(map);
- } else if (_amqpType.compare("array") == 0) {
+ return map;
+ }
+ if (amqpType.compare("array") == 0) {
/*
std::vector<proton::value> array;
processArray(array, testValue);
- msg.body(proton::as<proton::ARRAY>(array));
+ return proton::as<proton::ARRAY>(array);
*/
- throw qpidit::UnsupportedAmqpTypeError(_amqpType);
- } else {
- throw qpidit::UnknownAmqpTypeError(_amqpType);
- }
- return msg;
- }
-
- //static
- std::string Sender::bytearrayToHexStr(const char* src, int len) {
- std::ostringstream oss;
- oss << "0x" << std::hex;
- for (int i=0; i<len; ++i) {
- oss << std::setw(2) << std::setfill('0') << ((int)src[i] & 0xff);
- }
- return oss.str();
- }
-
- //static
- proton::value Sender::extractProtonValue(const Json::Value& val) {
- switch (val.type()) {
- case Json::nullValue:
- {
- proton::value v; //proton::null n;
- return v; //proton::value(n);
- }
- case Json::intValue:
- return proton::value(val.asInt());
- case Json::uintValue:
- return proton::value(val.asUInt());
- case Json::realValue:
- return proton::value(val.asDouble());
- case Json::stringValue:
- return proton::value(val.asString());
- case Json::booleanValue:
- return proton::value(val.asBool());
- default:;
+ throw qpidit::UnsupportedAmqpTypeError(amqpType);
}
+ throw qpidit::UnknownAmqpTypeError(amqpType);
}
// //static
@@ -219,7 +229,7 @@ namespace qpidit
processArray(subArray, *i);
array.push_back(proton::value(subArray));
} else if ((*i).isObject()) {
- std::map<std::string, proton::value> subMap;
+ std::map<proton::value, proton::value> subMap;
processMap(subMap, *i);
array.push_back(proton::value(subMap));
} else {
@@ -244,6 +254,19 @@ namespace qpidit
}
//static
+ proton::value Sender::processElement(const Json::Value& testValue) {
+ const std::string testValueStr(testValue.asString());
+ // testValue has the format amqp-type:amqp-str-value
+ const std::size_t splitIndex = testValueStr.find_first_of(':');
+ if (splitIndex == std::string::npos) {
+ throw qpidit::InvalidTestValueError(testValueStr);
+ }
+ const std::string amqpType = testValueStr.substr(0, splitIndex);
+ const std::string amqpValueAsStr = testValueStr.substr(splitIndex + 1);
+ return convertAmqpValue(amqpType, amqpValueAsStr);
+ }
+
+ //static
void Sender::processList(std::vector<proton::value>& list, const Json::Value& testValues) {
for (Json::Value::const_iterator i = testValues.begin(); i != testValues.end(); ++i) {
if ((*i).isArray()) {
@@ -251,31 +274,31 @@ namespace qpidit
processList(subList, *i);
list.push_back(proton::value(subList));
} else if ((*i).isObject()) {
- std::map<std::string, proton::value> subMap;
+ std::map<proton::value, proton::value> subMap;
processMap(subMap, *i);
list.push_back(proton::value(subMap));
} else {
- list.push_back(extractProtonValue(*i));
+ list.push_back(processElement(*i));
}
}
- //std::cout << std::endl;
}
//static
- void Sender::processMap(std::map<std::string, proton::value>& map, const Json::Value& testValues) {
+ void Sender::processMap(std::map<proton::value, proton::value>& map, const Json::Value& testValues) {
Json::Value::Members keys = testValues.getMemberNames();
for (std::vector<std::string>::const_iterator i=keys.begin(); i!=keys.end(); ++i) {
+ proton::value key = processElement(*i);
Json::Value mapVal = testValues[*i];
if (mapVal.isArray()) {
std::vector<proton::value> subList;
processList(subList, mapVal);
- map[*i] = subList;
+ map[key] = subList;
} else if (mapVal.isObject()) {
- std::map<std::string, proton::value> subMap;
+ std::map<proton::value, proton::value> subMap;
processMap(subMap, mapVal);
- map[*i] = subMap;
+ map[key] = subMap;
} else {
- map[*i] = extractProtonValue(mapVal);
+ map[key] = processElement(mapVal);
}
}
}
http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/b87dc72a/shims/qpid-proton-cpp/src/qpidit/amqp_types_test/Sender.hpp
----------------------------------------------------------------------
diff --git a/shims/qpid-proton-cpp/src/qpidit/amqp_types_test/Sender.hpp b/shims/qpid-proton-cpp/src/qpidit/amqp_types_test/Sender.hpp
index 17879cd..88b81df 100644
--- a/shims/qpid-proton-cpp/src/qpidit/amqp_types_test/Sender.hpp
+++ b/shims/qpid-proton-cpp/src/qpidit/amqp_types_test/Sender.hpp
@@ -51,11 +51,12 @@ namespace qpidit
static void revMemcpy(char* dest, const char* src, int n);
static void uint64ToChar16(char* dest, uint64_t upper, uint64_t lower);
- static proton::value extractProtonValue(const Json::Value& val);
+ static proton::value convertAmqpValue(const std::string& amqpType, const Json::Value& testValue);
//static Json::Value::ValueType getArrayType(const Json::Value& val);
static void processArray(std::vector<proton::value>& array, const Json::Value& testValues);
+ static proton::value processElement(const Json::Value& testValue);
static void processList(std::vector<proton::value>& list, const Json::Value& testValues);
- static void processMap(std::map<std::string, proton::value>& map, const Json::Value& testValues);
+ static void processMap(std::map<proton::value, proton::value>& map, const Json::Value& testValues);
template<size_t N> static void hexStringToBytearray(proton::byte_array<N>& ba, const std::string s, size_t fromArrayIndex = 0, size_t arrayLen = N) {
for (size_t i=0; i<arrayLen; ++i) {
@@ -65,25 +66,19 @@ namespace qpidit
// 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> void setFloatValue(proton::message& msg, const std::string& testValueStr) {
+ template<typename T, typename U> static proton::value floatValue(const std::string& amqpType, const std::string& testValueStr) {
try {
U ival(std::strtoul(testValueStr.data(), NULL, 16));
- msg.body(T(*reinterpret_cast<T*>(&ival)));
- } catch (const std::exception& e) { throw qpidit::InvalidTestValueError(_amqpType, testValueStr); }
+ return proton::value(T(*reinterpret_cast<T*>(&ival)));
+ } catch (const std::exception& e) { throw qpidit::InvalidTestValueError(amqpType, testValueStr); }
}
- template<typename T> void setIntegralValue(proton::message& msg, const std::string& testValueStr, bool unsignedVal) {
+ template<typename T> static proton::value integralValue(const std::string& amqpType, const std::string& testValueStr, bool unsignedVal) {
+ const int base = (testValueStr.find("0x") != std::string::npos) ? 16 : 10;
try {
- T val(unsignedVal ? std::strtoul(testValueStr.data(), NULL, 16) : std::strtol(testValueStr.data(), NULL, 16));
- msg.body(val);
- } catch (const std::exception& e) { throw qpidit::InvalidTestValueError(_amqpType, testValueStr); }
- }
-
- template<typename T> void setStringValue(proton::message& msg, const std::string& testValueStr) {
- try {
- T val(testValueStr);
- msg.body(val);
- } catch (const std::exception& e) { throw qpidit::InvalidTestValueError(_amqpType, testValueStr); }
+ T val(unsignedVal ? std::strtoul(testValueStr.data(), NULL, base) : std::strtol(testValueStr.data(), NULL, base));
+ return val;
+ } catch (const std::exception& e) { throw qpidit::InvalidTestValueError(amqpType, testValueStr); }
}
};
http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/b87dc72a/shims/qpid-proton-python/src/amqp_types_test/Receiver.py
----------------------------------------------------------------------
diff --git a/shims/qpid-proton-python/src/amqp_types_test/Receiver.py b/shims/qpid-proton-python/src/amqp_types_test/Receiver.py
index 594d33a..5067de2 100755
--- a/shims/qpid-proton-python/src/amqp_types_test/Receiver.py
+++ b/shims/qpid-proton-python/src/amqp_types_test/Receiver.py
@@ -30,6 +30,7 @@ import string
import struct
import sys
import traceback
+import uuid
import proton
import proton.handlers
@@ -66,61 +67,178 @@ class AmqpTypesTestReceiver(proton.handlers.MessagingHandler):
"""Event callback when a message is received by the client"""
if event.message.id and event.message.id < self.received:
return # ignore duplicate message
- if self.received < self.expected:
- if self.amqp_type == 'null' or \
- self.amqp_type == 'boolean' or \
- self.amqp_type == 'uuid':
- self.received_value_list.append(str(event.message.body))
- elif self.amqp_type == 'ubyte' or \
- self.amqp_type == 'ushort' or \
- self.amqp_type == 'byte' or \
- self.amqp_type == 'short' or \
- self.amqp_type == 'int':
- self.received_value_list.append(hex(event.message.body))
- elif self.amqp_type == 'uint' or \
- self.amqp_type == 'ulong' or \
- 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
- else:
- self.received_value_list.append(hex_str)
- elif self.amqp_type == 'float':
- self.received_value_list.append('0x%08x' % struct.unpack('!L',
- struct.pack('!f', event.message.body))[0])
- elif self.amqp_type == 'double':
- self.received_value_list.append('0x%016x' % struct.unpack('!Q',
- struct.pack('!d', event.message.body))[0])
- elif self.amqp_type == 'decimal32':
- self.received_value_list.append('0x%08x' % event.message.body)
- elif self.amqp_type == 'decimal64':
- self.received_value_list.append('0x%016x' % event.message.body)
- elif self.amqp_type == 'decimal128':
- self.received_value_list.append('0x' + ''.join(['%02x' % _compat.byte_char_ord(c) \
- for c in event.message.body]).strip())
- elif self.amqp_type == 'char':
- if ord(event.message.body) < 0x80 and event.message.body in \
- string.digits + _compat.letters() + string.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':
- self.received_value_list.append(event.message.body.decode('utf-8'))
- elif self.amqp_type == 'string' or \
- self.amqp_type == 'symbol':
- self.received_value_list.append(event.message.body)
- elif self.amqp_type == 'list' or \
- self.amqp_type == 'map':
- self.received_value_list.append(event.message.body)
- else:
- print('receive: Unsupported AMQP type "%s"' % self.amqp_type)
- return
- self.received += 1
+ test_value = AmqpTypesTestReceiver.decode_amqp_type(self.amqp_type, event.message.body)
+ if test_value is None:
+ return
+ self.received_value_list.append(test_value)
+ self.received += 1
if self.received >= self.expected:
event.receiver.close()
event.connection.close()
+ @staticmethod
+ def longhex(amqp_value):
+ """Create a long hex string"""
+ hex_str = hex(int(amqp_value))
+ if len(hex_str) == 19 and hex_str[-1] == 'L':
+ return hex_str[:-1] # strip trailing 'L' if present on some ulongs
+ return hex_str
+
+ @staticmethod
+ def decode_amqp_type(amqp_type, amqp_value):
+ """Decode amqp type"""
+ if amqp_type == 'null':
+ return str(amqp_value)
+ if amqp_type == 'boolean':
+ return str(amqp_value)
+ if amqp_type == 'ubyte':
+ return hex(amqp_value)
+ if amqp_type == 'ushort':
+ return hex(amqp_value)
+ if amqp_type == 'uint':
+ return AmqpTypesTestReceiver.longhex(amqp_value)
+ if amqp_type == 'ulong':
+ return AmqpTypesTestReceiver.longhex(amqp_value)
+ if amqp_type == 'byte':
+ return hex(amqp_value)
+ if amqp_type == 'short':
+ return hex(amqp_value)
+ if amqp_type == 'int':
+ return hex(amqp_value)
+ if amqp_type == 'long':
+ return AmqpTypesTestReceiver.longhex(amqp_value)
+ if amqp_type == 'float':
+ return '0x%08x' % struct.unpack('!L', struct.pack('!f', amqp_value))[0]
+ if amqp_type == 'double':
+ return '0x%016x' % struct.unpack('!Q', struct.pack('!d', amqp_value))[0]
+ if amqp_type == 'decimal32':
+ return '0x%08x' % amqp_value
+ if amqp_type == 'decimal64':
+ return '0x%016x' % amqp_value
+ if amqp_type == 'decimal128':
+ return '0x' + ''.join(['%02x' % _compat.byte_char_ord(c) for c in amqp_value]).strip()
+ if amqp_type == 'char':
+ if ord(amqp_value) < 0x80 and amqp_value in string.digits + _compat.letters() + string.punctuation + ' ':
+ return amqp_value
+ return hex(ord(amqp_value))
+ if amqp_type == 'timestamp':
+ return AmqpTypesTestReceiver.longhex(amqp_value)
+ if amqp_type == 'uuid':
+ return str(amqp_value)
+ if amqp_type == 'binary':
+ return amqp_value.decode('utf-8')
+ if amqp_type == 'string':
+ return amqp_value
+ if amqp_type == 'symbol':
+ return amqp_value
+ if amqp_type == 'list':
+ return AmqpTypesTestReceiver.decode_amqp_list(amqp_value)
+ if amqp_type == 'map':
+ return AmqpTypesTestReceiver.decode_amqp_map(amqp_value)
+ if amqp_type == 'array':
+ #return AmqpTypesTestReceiver.decode_amqp_array(amqp_value)
+ print('receive: Unsupported AMQP type "%s"' % amqp_type)
+ return None
+ print('receive: Unknown AMQP type "%s"' % amqp_type)
+ return None
+
+ @staticmethod
+ def get_amqp_type(amqp_value):
+ """Get the AMQP type from the Python type"""
+ if amqp_value is None:
+ return "null"
+ if isinstance(amqp_value, bool):
+ return "boolean"
+ if isinstance(amqp_value, proton.ubyte):
+ return "ubyte"
+ if isinstance(amqp_value, proton.ushort):
+ return "ushort"
+ if isinstance(amqp_value, proton.uint):
+ return "uint"
+ if isinstance(amqp_value, proton.ulong):
+ return "ulong"
+ if isinstance(amqp_value, proton.byte):
+ return "byte"
+ if isinstance(amqp_value, proton.short):
+ return "short"
+ if isinstance(amqp_value, proton.int32):
+ return "int"
+ if isinstance(amqp_value, proton.float32):
+ return "float"
+ if isinstance(amqp_value, proton.decimal32):
+ return "decimal32"
+ if isinstance(amqp_value, proton.decimal64):
+ return "decimal64"
+ if isinstance(amqp_value, proton.decimal128):
+ return "decimal128"
+ if isinstance(amqp_value, proton.char):
+ return "char"
+ if isinstance(amqp_value, proton.timestamp):
+ return "timestamp"
+ if isinstance(amqp_value, uuid.UUID):
+ return "uuid"
+ if isinstance(amqp_value, proton.symbol):
+ return "symbol"
+ if isinstance(amqp_value, proton.Array):
+ return "array"
+ # Native types come last so that parent classes will not be found instead (issue using isinstance()
+ if _compat.IS_PY3:
+ if isinstance(amqp_value, int):
+ return "long"
+ if isinstance(amqp_value, bytes):
+ return "binary"
+ if isinstance(amqp_value, str):
+ return "string"
+ else:
+ import __builtin__
+ if isinstance(amqp_value, __builtin__.long):
+ return "long"
+ if isinstance(amqp_value, str):
+ return "binary"
+ if isinstance(amqp_value, unicode):
+ return "string"
+ if isinstance(amqp_value, float):
+ return "double"
+ if isinstance(amqp_value, list):
+ return "list"
+ if isinstance(amqp_value, dict):
+ return "map"
+
+ print('receive: Unmapped AMQP type: %s:%s' % (type(amqp_value), amqp_value))
+
+ @staticmethod
+ def decode_complex_amqp_element(amqp_value):
+ """Decode an element from a complex AMQP type from its Python value"""
+ amqp_type = AmqpTypesTestReceiver.get_amqp_type(amqp_value)
+ if amqp_type == "list":
+ return AmqpTypesTestReceiver.decode_amqp_list(amqp_value)
+ if amqp_type == "map":
+ return AmqpTypesTestReceiver.decode_amqp_map(amqp_value)
+ return "%s:%s" % (amqp_type, AmqpTypesTestReceiver.decode_amqp_type(amqp_type, amqp_value))
+
+ @staticmethod
+ def decode_amqp_list(amqp_value):
+ """Decode amqp list type"""
+# print('LIST:%s' % amqp_value)
+ amqp_list = []
+ for list_item in amqp_value:
+ amqp_list.append(AmqpTypesTestReceiver.decode_complex_amqp_element(list_item))
+ return amqp_list
+
+ @staticmethod
+ def decode_amqp_map(amqp_value):
+ """Decode amqp map type"""
+ amqp_map = {}
+ for key, value in amqp_value.items():
+ amqp_map[AmqpTypesTestReceiver.decode_complex_amqp_element(key)] = \
+ AmqpTypesTestReceiver.decode_complex_amqp_element(value)
+ return amqp_map
+
+ @staticmethod
+ def decode_amqp_array(amqp_value):
+ """Decode amqp array type"""
+ return amqp_value
+
def on_transport_error(self, event):
print('Receiver: Broker not found at %s' % self.broker_url)
http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/b87dc72a/shims/qpid-proton-python/src/amqp_types_test/Sender.py
----------------------------------------------------------------------
diff --git a/shims/qpid-proton-python/src/amqp_types_test/Sender.py b/shims/qpid-proton-python/src/amqp_types_test/Sender.py
index a4664b7..cd0384e 100755
--- a/shims/qpid-proton-python/src/amqp_types_test/Sender.py
+++ b/shims/qpid-proton-python/src/amqp_types_test/Sender.py
@@ -77,60 +77,122 @@ class AmqpTypesTestSender(proton.handlers.MessagingHandler):
Creates a single message with the test value translated from its string representation to the appropriate
AMQP value (set in self.amqp_type).
"""
- if self.amqp_type == 'null':
- return proton.Message(id=(self.sent+1), body=None)
- if self.amqp_type == 'boolean':
- return proton.Message(id=(self.sent+1), body=True if test_value == 'True' else False)
- if self.amqp_type == 'ubyte':
- return proton.Message(id=(self.sent+1), body=proton.ubyte(int(test_value, 16)))
- if self.amqp_type == 'ushort':
- return proton.Message(id=(self.sent+1), body=proton.ushort(int(test_value, 16)))
- if self.amqp_type == 'uint':
- return proton.Message(id=(self.sent+1), body=proton.uint(int(test_value, 16)))
- if self.amqp_type == 'ulong':
- return proton.Message(id=(self.sent+1), body=proton.ulong(int(test_value, 16)))
- if self.amqp_type == 'byte':
- return proton.Message(id=(self.sent+1), body=proton.byte(int(test_value, 16)))
- if self.amqp_type == 'short':
- return proton.Message(id=(self.sent+1), body=proton.short(int(test_value, 16)))
- if self.amqp_type == 'int':
- return proton.Message(id=(self.sent+1), body=proton.int32(int(test_value, 16)))
- if self.amqp_type == 'long':
- return proton.Message(id=(self.sent+1), body=_compat.long(test_value, 16))
- if self.amqp_type == 'float':
- return proton.Message(id=(self.sent+1),
- body=proton.float32(struct.unpack('!f', _compat.decode_hex(test_value[2:]))[0]))
- if self.amqp_type == 'double':
- return proton.Message(id=(self.sent+1), body=struct.unpack('!d', _compat.decode_hex(test_value[2:]))[0])
- if self.amqp_type == 'decimal32':
- return proton.Message(id=(self.sent+1), body=proton.decimal32(int(test_value[2:], 16)))
- if self.amqp_type == 'decimal64':
- l64 = _compat.long(test_value[2:], 16)
- return proton.Message(id=(self.sent+1), body=proton.decimal64(l64))
- if self.amqp_type == 'decimal128':
- return proton.Message(id=(self.sent+1), body=proton.decimal128(_compat.decode_hex(test_value[2:])))
- if self.amqp_type == 'char':
+ return proton.Message(id=(self.sent+1), body=self.encode_amqp_type(self.amqp_type, test_value))
+
+ @staticmethod
+ def encode_amqp_type(amqp_type, test_value):
+ """Encode an AMQP type from a stringified test_value"""
+ if amqp_type == 'null':
+ return None
+ if amqp_type == 'boolean':
+ return True if test_value == 'True' else False
+ if amqp_type == 'ubyte':
+ return proton.ubyte(int(test_value, 16))
+ if amqp_type == 'ushort':
+ return proton.ushort(int(test_value, 16))
+ if amqp_type == 'uint':
+ return proton.uint(int(test_value, 16))
+ if amqp_type == 'ulong':
+ return proton.ulong(int(test_value, 16))
+ if amqp_type == 'byte':
+ return proton.byte(int(test_value, 16))
+ if amqp_type == 'short':
+ return proton.short(int(test_value, 16))
+ if amqp_type == 'int':
+ return proton.int32(int(test_value, 16))
+ if amqp_type == 'long':
+ return _compat.long(test_value, 16)
+ if amqp_type == 'float':
+ return proton.float32(struct.unpack('!f', _compat.decode_hex(test_value[2:]))[0])
+ if amqp_type == 'double':
+ return struct.unpack('!d', _compat.decode_hex(test_value[2:]))[0]
+ if amqp_type == 'decimal32':
+ return proton.decimal32(int(test_value[2:], 16))
+ if amqp_type == 'decimal64':
+ return proton.decimal64(_compat.long(test_value[2:], 16))
+ if amqp_type == 'decimal128':
+ return proton.decimal128(_compat.decode_hex(test_value[2:]))
+ if amqp_type == 'char':
if len(test_value) == 1: # Format 'a'
- return proton.Message(id=(self.sent+1), body=proton.char(test_value))
+ return proton.char(test_value)
val = int(test_value, 16)
- return proton.Message(id=(self.sent+1), body=proton.char(_compat.unichr(val)))
- if self.amqp_type == 'timestamp':
- return proton.Message(id=(self.sent+1), body=proton.timestamp(int(test_value, 16)))
- if self.amqp_type == 'uuid':
- return proton.Message(id=(self.sent+1), body=uuid.UUID(test_value))
- if self.amqp_type == 'binary':
- return proton.Message(id=(self.sent+1), body=test_value.encode('utf-8'))
- if self.amqp_type == 'string':
- return proton.Message(id=(self.sent+1), body=_compat.unicode(test_value))
- if self.amqp_type == 'symbol':
- return proton.Message(id=(self.sent+1), body=proton.symbol(test_value))
- if self.amqp_type == 'list':
- return proton.Message(id=(self.sent+1), body=test_value)
- if self.amqp_type == 'map':
- return proton.Message(id=(self.sent+1), body=test_value)
- print('send: Unsupported AMQP type "%s"' % self.amqp_type)
+ return proton.char(_compat.unichr(val))
+ if amqp_type == 'timestamp':
+ return proton.timestamp(int(test_value, 16))
+ if amqp_type == 'uuid':
+ return uuid.UUID(test_value)
+ if amqp_type == 'binary':
+ return test_value.encode('utf-8')
+ if amqp_type == 'string':
+ return _compat.unicode(test_value)
+ if amqp_type == 'symbol':
+ return proton.symbol(test_value)
+ if amqp_type == 'list':
+ return AmqpTypesTestSender.encode_amqp_list(test_value)
+ if amqp_type == 'map':
+ return AmqpTypesTestSender.encode_amqp_map(test_value)
+ if amqp_type == 'array':
+ #return AmqpTypesTestSender.encode_amqp_array(test_value)
+ print('send: Unsupported AMQP type "%s"' % amqp_type)
+ return None
+ print('send: Unknown AMQP type "%s"' % amqp_type)
return None
+ @staticmethod
+ def encode_complex_amqp_element(test_element, make_hashable=False):
+ """
+ Encode a single complex AMQP element (ie list or array member, map key or value)
+ A complex element may be one of:
+ str/unicode: 'amqp_type:amqp_value'
+ list: [...]
+ dict: {...}
+ """
+ if _compat.IS_PY3:
+ is_string = isinstance(test_element, str)
+ else:
+ is_string = isinstance(test_element, unicode)
+ if is_string:
+ split_list = test_element.split(':', 1)
+ return AmqpTypesTestSender.encode_amqp_type(split_list[0], split_list[1])
+ if isinstance(test_element, list):
+ enc_list = AmqpTypesTestSender.encode_amqp_list(test_element)
+ if make_hashable:
+ return tuple(enc_list) # Convert list to tuple
+ return enc_list
+ if isinstance(test_element, dict):
+ enc_dict = AmqpTypesTestSender.encode_amqp_map(test_element)
+ if make_hashable:
+ return tuple(enc_dict.items()) # Convert to tuple of k,v pairs
+ return enc_dict
+ else:
+ print('Unexpected complex amqp element type: %s, value=%s' % (type(test_element), str(test_element)))
+
+ @staticmethod
+ def encode_amqp_list(test_value):
+ """
+ Encode an AMQP list from the format [val1, val2, ...]
+ Each val is in the string format amqp_type:amqp_val_as_str
+ """
+ val_list = []
+ for val in test_value:
+ val_list.append(AmqpTypesTestSender.encode_complex_amqp_element(val))
+ return val_list
+
+ @staticmethod
+ def encode_amqp_map(test_value):
+ """Encode an AMQP map from the format {key1:val1, key2:val2, ...}"""
+ val_map = {}
+ for key, val in test_value.items():
+ encoded_key = AmqpTypesTestSender.encode_complex_amqp_element(key, True) # make keys hashable
+ encoded_val = AmqpTypesTestSender.encode_complex_amqp_element(val)
+ val_map[encoded_key] = encoded_val
+ return val_map
+
+ @staticmethod
+ def encode_amqp_array(test_value):
+ """Encode an AMQP array"""
+ return test_value
+
def on_accepted(self, event):
"""Event callback for when a sent message is accepted by the broker"""
self.confirmed += 1
http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/b87dc72a/src/python/qpid_interop_test/amqp_types_test.py
----------------------------------------------------------------------
diff --git a/src/python/qpid_interop_test/amqp_types_test.py b/src/python/qpid_interop_test/amqp_types_test.py
index 3bf5987..23a1880 100755
--- a/src/python/qpid_interop_test/amqp_types_test.py
+++ b/src/python/qpid_interop_test/amqp_types_test.py
@@ -175,52 +175,55 @@ class AmqpPrimitiveTypes(qpid_interop_test.qit_common.QitTestTypeMap):
'domain.0123456789.' * 100,
],
'list': [[],
- ['ubyte:1', 'int:-2', 'float:3.14'],
- ['string:a', 'string:b', 'string:c'],
- ['ulong:12345',
- 'timestamp:%d' % (time()*1000),
- 'short:-2500',
- 'uuid:%s' % uuid4(),
+ ['ubyte:0x1', 'int:-0x2', 'float:0x40490fdb'],
+ ['string:a', 'string:hello', 'string:world!', 'binary:\x01\x02\x03\x04\x05abcde'],
+ ['long:0x102030405',
+ 'timestamp:0x%x' % int(time()*1000),
+ 'short:-0x8000',
+ 'uuid:%s' % str(uuid4()),
'symbol:a.b.c',
- 'none:',
- 'decimal64:0x400921fb54442eea'
+ 'null:None',
+ 'ulong:0x400921fb54442eea',
+ #'decimal64:0x400921fb54442eea' # Decimal byte reversal issue: PROTON-1160
],
[[],
- 'none',
- ['ubyte:1', 'ubyte:2', 'ubyte:3'],
+ 'null:None',
+ ['ubyte:0x1', 'ubyte:0x2', 'ubyte:0x3'],
'boolean:True',
'boolean:False',
- {'string:hello': 'long:1234', 'string:goodbye': 'boolean:True'}
+ {},
+ {'string:hello': 'long:-0x1234', 'string:goodbye': 'boolean:True'}
],
[[], [[], [[], [], []], []], []],
- ['short:0',
- 'short:1',
- 'short:2',
- 'short:3',
- 'short:4',
- 'short:5',
- 'short:6',
- 'short:7',
- 'short:8',
- 'short:9'] * 10
+ ['short:0x0',
+ 'short:0x1',
+ 'short:0x2',
+ 'short:0x3',
+ 'short:0x4',
+ 'short:0x5',
+ 'short:0x6',
+ 'short:0x7',
+ 'short:0x8',
+ 'short:0x9'] * 10
],
'map': [{}, # Enpty map
# Map with string keys
- {'string:one': 'ubyte:1',
- 'string:two': 'ushort:2'},
+ {'string:one': 'ubyte:0x1',
+ 'string:two': 'ushort:0x2'},
# Map with other AMQP simple types as keys
- {'none:': 'string:None',
- 'string:None': 'none:',
- 'string:One': 'long:-1234567890',
- 'short:2': 'int:2',
+ {'null:None': 'string:None',
+ 'string:None': 'null:None',
+ 'string:One': 'long:-0x102030405',
+ 'short:0x2': 'int:0x2',
'boolean:True': 'string:True',
'string:False': 'boolean:False',
- #['string:AAA', 'ushort:5951']: 'string:list value',
+ #['string:AAA', 'ushort:0x5951']: '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'}},
+ 'string:list': ['byte:0x12', 'ushort:0x234', 'uuid:%s' % str(uuid4()), ],
+ 'string:map': {'char:A': 'int:0x1',
+ 'char:B': 'int:0x2'}
+ },
],
# array: Each array is constructed from the test values in this map. This list contains
# the keys to the array value types to be included in the test. See function create_test_arrays()
@@ -268,10 +271,14 @@ class AmqpPrimitiveTypes(qpid_interop_test.qit_common.QitTestTypeMap):
}
client_skip = {
- 'char': {'AmqpNetLite': 'Char types not supported: https://github.com/Azure/amqpnetlite/issues/259', },
- 'decimal32': {'AmqpNetLite': 'Decimal types not supported: https://github.com/Azure/amqpnetlite/issues/223', },
- 'decimal64': {'AmqpNetLite': 'Decimal types not supported: https://github.com/Azure/amqpnetlite/issues/223', },
- 'decimal128': {'AmqpNetLite': 'Decimal types not supported: https://github.com/Azure/amqpnetlite/issues/223', },
+ 'char': {'AmqpNetLite': 'Char type and decimal types to be added to shim: QPIDIT-118', },
+ 'decimal32': {'AmqpNetLite': 'Char type and decimal types to be added to shim: QPIDIT-118', },
+ 'decimal64': {'AmqpNetLite': 'Char type and decimal types to be added to shim: QPIDIT-118', },
+ 'decimal128': {'AmqpNetLite': 'Char type and decimal types to be added to shim: QPIDIT-118', },
+ 'list': {'AmqpNetLite': 'Encoding/decoding of complex types not yet complete: QPIDIT-46',
+ 'RheaJs': 'Encoding/decoding of complex types not yet complete: QPIDIT-46'},
+ 'map': {'AmqpNetLite': 'Encoding/decoding of complex types not yet complete: QPIDIT-46',
+ 'RheaJs': 'Encoding/decoding of complex types not yet complete: QPIDIT-46'},
}
def create_array(self, array_amqp_type, repeat):
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org