PROTON-1288: c++ reinstate engine_test as connection_driver_test
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/f2df847b Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/f2df847b Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/f2df847b Branch: refs/heads/PROTON-1488 Commit: f2df847b552685f80429715832e55207d68bbbcb Parents: 48a5e47 Author: Alan Conway <[email protected]> Authored: Fri May 19 11:04:44 2017 -0400 Committer: Alan Conway <[email protected]> Committed: Wed May 24 15:05:14 2017 -0400 ---------------------------------------------------------------------- examples/cpp/message_properties.cpp | 101 +++++++ proton-c/bindings/cpp/CMakeLists.txt | 2 +- .../bindings/cpp/include/proton/terminus.hpp | 2 +- .../bindings/cpp/src/connection_driver_test.cpp | 260 ++++++++++++++++++ proton-c/bindings/cpp/src/engine_test.cpp | 268 ------------------- .../bindings/cpp/src/include/proton_bits.hpp | 4 +- .../bindings/cpp/src/include/proton_event.hpp | 5 + .../cpp/src/include/test_dummy_container.hpp | 1 - 8 files changed, 370 insertions(+), 273 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f2df847b/examples/cpp/message_properties.cpp ---------------------------------------------------------------------- diff --git a/examples/cpp/message_properties.cpp b/examples/cpp/message_properties.cpp new file mode 100644 index 0000000..64d597b --- /dev/null +++ b/examples/cpp/message_properties.cpp @@ -0,0 +1,101 @@ +/* + * 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 <proton/message.hpp> +#include <proton/types.hpp> +#include <iostream> +#include <map> + +int main(int argc, char **argv) { + try { + proton::message m; + + // Setting properties: legal types are converted automatically to their + // AMQP counterpart. + m.properties().put("short", int16_t(123)); + m.properties().put("string", "foo"); + m.properties().put("symbol", proton::symbol("sym")); + m.properties().put("bool", true); + + // Examining properties using proton::get() + + // 1 argument get<>() template specifies expected type of property. + std::string s = proton::get<std::string>(m.properties().get("string")); + + // 2 argument get, property must have matching type to output argument. + int16_t i; + proton::get(m.properties().get("short"), i); + + // Checking property types + proton::type_id type = m.properties().get("symbol").type(); + if (type != proton::SYMBOL) { + throw std::logic_error("wrong type!"); + } + + // proton::scalar has its own ostream << + std::cout << "using put/get:" + << " short=" << i + << " string=" << s + << " symbol=" << m.properties().get("symbol") + << " bool=" << m.properties().get("bool") + << std::endl; + + // Converting properties to a compatible type + std::cout << "using coerce:" + << " short(as int)=" << proton::coerce<int>(m.properties().get("short")) + << " bool(as int)=" << proton::coerce<int>(m.properties().get("bool")) + << std::endl; + + // Extract the properties map for more complex map operations. + proton::property_std_map props; + proton::get(m.properties().value(), props); + for (proton::property_std_map::iterator i = props.begin(); i != props.end(); ++i) { + std::cout << "props[" << i->first << "]=" << i->second << std::endl; + } + props["string"] = "bar"; + props["short"] = 42; + // Update the properties in the message from props + m.properties().value() = props; + + std::cout << "short=" << m.properties().get("short") + << " string=" << m.properties().get("string") + << std::endl; + + // proton::get throws an exception if types do not match exactly. + try { + proton::get<uint32_t>(m.properties().get("short")); // bad: uint32_t != int16_t + throw std::logic_error("expected exception"); + } catch (const proton::conversion_error& e) { + std::cout << "expected conversion_error: \"" << e.what() << '"' << std::endl; + } + + // proton::coerce throws an exception if types are not convertible. + try { + proton::get<uint32_t>(m.properties().get("string")); // bad: string to uint32_t + throw std::logic_error("expected exception"); + } catch (const proton::conversion_error& e) { + std::cout << "expected conversion_error: \"" << e.what() << '"' << std::endl; + } + + return 0; + } catch (const std::exception& e) { + std::cerr << "unexpected exception: " << e.what() << std::endl; + return 1; + } +} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f2df847b/proton-c/bindings/cpp/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/CMakeLists.txt b/proton-c/bindings/cpp/CMakeLists.txt index 0cc4024..04cb568 100644 --- a/proton-c/bindings/cpp/CMakeLists.txt +++ b/proton-c/bindings/cpp/CMakeLists.txt @@ -172,7 +172,7 @@ macro(add_cpp_test test) endmacro(add_cpp_test) add_cpp_test(codec_test) -#add_cpp_test(engine_test) +add_cpp_test(connection_driver_test) add_cpp_test(thread_safe_test) add_cpp_test(interop_test ${CMAKE_SOURCE_DIR}/tests) add_cpp_test(message_test) http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f2df847b/proton-c/bindings/cpp/include/proton/terminus.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/include/proton/terminus.hpp b/proton-c/bindings/cpp/include/proton/terminus.hpp index b63a8ad..e339b84 100644 --- a/proton-c/bindings/cpp/include/proton/terminus.hpp +++ b/proton-c/bindings/cpp/include/proton/terminus.hpp @@ -94,7 +94,7 @@ class terminus { PN_CPP_EXTERN value node_properties() const; protected: - pn_terminus_t *pn_object() { return object_; } + pn_terminus_t *pn_object() const { return object_; } private: pn_terminus_t* object_; pn_link_t* parent_; http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f2df847b/proton-c/bindings/cpp/src/connection_driver_test.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/connection_driver_test.cpp b/proton-c/bindings/cpp/src/connection_driver_test.cpp new file mode 100644 index 0000000..372240b --- /dev/null +++ b/proton-c/bindings/cpp/src/connection_driver_test.cpp @@ -0,0 +1,260 @@ +/* + * 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 "test_bits.hpp" +#include "proton_bits.hpp" + +#include "proton/io/connection_driver.hpp" +#include "proton/io/link_namer.hpp" +#include "proton/link.hpp" +#include "proton/messaging_handler.hpp" +#include "proton/receiver_options.hpp" +#include "proton/sender_options.hpp" +#include "proton/source_options.hpp" +#include "proton/types_fwd.hpp" +#include "proton/uuid.hpp" + +#include <deque> +#include <algorithm> + +namespace { + +using namespace std; +using namespace proton; + +using proton::io::connection_driver; +using proton::io::const_buffer; +using proton::io::mutable_buffer; + +typedef std::deque<char> byte_stream; + +/// In memory connection_driver that reads and writes from byte_streams +struct in_memory_driver : public connection_driver { + + byte_stream& reads; + byte_stream& writes; + + in_memory_driver(byte_stream& rd, byte_stream& wr) : reads(rd), writes(wr) {} + + void do_read() { + mutable_buffer rbuf = read_buffer(); + size_t size = std::min(reads.size(), rbuf.size); + if (size) { + copy(reads.begin(), reads.begin()+size, static_cast<char*>(rbuf.data)); + read_done(size); + reads.erase(reads.begin(), reads.begin()+size); + } + } + + void do_write() { + const_buffer wbuf = write_buffer(); + if (wbuf.size) { + writes.insert(writes.begin(), + static_cast<const char*>(wbuf.data), + static_cast<const char*>(wbuf.data) + wbuf.size); + write_done(wbuf.size); + } + } + + void process() { + if (!dispatch()) + throw std::runtime_error("unexpected close: "+connection().error().what()); + do_read(); + do_write(); + dispatch(); + } +}; + +/// A pair of drivers that talk to each other in-memory, simulating a connection. +struct driver_pair { + byte_stream ab, ba; + in_memory_driver a, b; + + driver_pair(const connection_options& oa, const connection_options& ob) + : a(ba, ab), b(ab, ba) + { + a.connect(oa); + b.accept(ob); + } + + void process() { a.process(); b.process(); } +}; + +template <class S> typename S::value_type quick_pop(S& s) { + ASSERT(!s.empty()); + typename S::value_type x = s.front(); + s.pop_front(); + return x; +} + +/// A handler that records incoming endpoints, errors etc. +struct record_handler : public messaging_handler { + std::deque<proton::receiver> receivers; + std::deque<proton::sender> senders; + std::deque<proton::session> sessions; + std::deque<std::string> unhandled_errors, transport_errors, connection_errors; + + void on_receiver_open(receiver &l) PN_CPP_OVERRIDE { + receivers.push_back(l); + } + + void on_sender_open(sender &l) PN_CPP_OVERRIDE { + senders.push_back(l); + } + + void on_session_open(session &s) PN_CPP_OVERRIDE { + sessions.push_back(s); + } + + void on_transport_error(transport& t) PN_CPP_OVERRIDE { + transport_errors.push_back(t.error().what()); + } + + void on_connection_error(connection& c) PN_CPP_OVERRIDE { + connection_errors.push_back(c.error().what()); + } + + void on_error(const proton::error_condition& c) PN_CPP_OVERRIDE { + unhandled_errors.push_back(c.what()); + } +}; + +struct namer : public io::link_namer { + char name; + namer(char c) : name(c) {} + std::string link_name() { return std::string(1, name++); } +}; + +void test_driver_link_id() { + record_handler ha, hb; + driver_pair e(ha, hb); + e.a.connect(ha); + e.b.accept(hb); + + namer na('x'); + namer nb('b'); + connection ca = e.a.connection(); + connection cb = e.b.connection(); + set_link_namer(ca, na); + set_link_namer(cb, nb); + + e.b.connection().open(); + + e.a.connection().open_sender("foo"); + while (ha.senders.empty() || hb.receivers.empty()) e.process(); + sender s = quick_pop(ha.senders); + ASSERT_EQUAL("x", s.name()); + + ASSERT_EQUAL("x", quick_pop(hb.receivers).name()); + + e.a.connection().open_receiver("bar"); + while (ha.receivers.empty() || hb.senders.empty()) e.process(); + ASSERT_EQUAL("y", quick_pop(ha.receivers).name()); + ASSERT_EQUAL("y", quick_pop(hb.senders).name()); + + e.b.connection().open_receiver(""); + while (ha.senders.empty() || hb.receivers.empty()) e.process(); + ASSERT_EQUAL("b", quick_pop(ha.senders).name()); + ASSERT_EQUAL("b", quick_pop(hb.receivers).name()); +} + +void test_endpoint_close() { + record_handler ha, hb; + driver_pair e(ha, hb); + e.a.connection().open_sender("x"); + e.a.connection().open_receiver("y"); + while (ha.senders.size()+ha.receivers.size() < 2 || + hb.senders.size()+hb.receivers.size() < 2) e.process(); + proton::link ax = quick_pop(ha.senders), ay = quick_pop(ha.receivers); + proton::link bx = quick_pop(hb.receivers), by = quick_pop(hb.senders); + + // Close a link + ax.close(proton::error_condition("err", "foo bar")); + while (!bx.closed()) e.process(); + proton::error_condition c = bx.error(); + ASSERT_EQUAL("err", c.name()); + ASSERT_EQUAL("foo bar", c.description()); + ASSERT_EQUAL("err: foo bar", c.what()); + + // Close a link with an empty condition + ay.close(proton::error_condition()); + while (!by.closed()) e.process(); + ASSERT(by.error().empty()); + + // Close a connection + connection ca = e.a.connection(), cb = e.b.connection(); + ca.close(proton::error_condition("conn", "bad connection")); + while (!cb.closed()) e.process(); + ASSERT_EQUAL("conn: bad connection", cb.error().what()); + ASSERT_EQUAL(1u, hb.connection_errors.size()); + ASSERT_EQUAL("conn: bad connection", hb.connection_errors.front()); +} + +void test_driver_disconnected() { + // driver.disconnected() aborts the connection and calls the local on_transport_error() + record_handler ha, hb; + driver_pair e(ha, hb); + e.a.connect(ha); + e.b.accept(hb); + while (!e.a.connection().active() || !e.b.connection().active()) + e.process(); + + // Close a with an error condition. The AMQP connection is still open. + e.a.disconnected(proton::error_condition("oops", "driver failure")); + ASSERT(!e.a.dispatch()); + ASSERT(!e.a.connection().closed()); + ASSERT(e.a.connection().error().empty()); + ASSERT_EQUAL(0u, ha.connection_errors.size()); + ASSERT_EQUAL("oops: driver failure", e.a.transport().error().what()); + ASSERT_EQUAL(1u, ha.transport_errors.size()); + ASSERT_EQUAL("oops: driver failure", ha.transport_errors.front()); + + // In a real app the IO code would detect the abort and do this: + e.b.disconnected(proton::error_condition("broken", "it broke")); + ASSERT(!e.b.dispatch()); + ASSERT(!e.b.connection().closed()); + ASSERT(e.b.connection().error().empty()); + ASSERT_EQUAL(0u, hb.connection_errors.size()); + // Proton-C adds (connection aborted) if transport closes too early, + // and provides a default message if there is no user message. + ASSERT_EQUAL("broken: it broke (connection aborted)", e.b.transport().error().what()); + ASSERT_EQUAL(1u, hb.transport_errors.size()); + ASSERT_EQUAL("broken: it broke (connection aborted)", hb.transport_errors.front()); +} + +void test_no_container() { + // An driver with no container should throw, not crash. + connection_driver e; + try { + e.connection().container(); + FAIL("expected error"); + } catch (proton::error) {} +} + +} + +int main(int, char**) { + int failed = 0; + RUN_TEST(failed, test_driver_link_id()); + RUN_TEST(failed, test_endpoint_close()); + RUN_TEST(failed, test_driver_disconnected()); + RUN_TEST(failed, test_no_container()); + return failed; +} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f2df847b/proton-c/bindings/cpp/src/engine_test.cpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/engine_test.cpp b/proton-c/bindings/cpp/src/engine_test.cpp deleted file mode 100644 index 991836d..0000000 --- a/proton-c/bindings/cpp/src/engine_test.cpp +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - - -#include "test_bits.hpp" -#include "test_dummy_container.hpp" -#include "proton_bits.hpp" - -#include "proton/container.hpp" -#include "proton/uuid.hpp" -#include "proton/io/connection_driver.hpp" -#include "proton/io/link_namer.hpp" -#include "proton/messaging_handler.hpp" -#include "proton/types_fwd.hpp" -#include "proton/link.hpp" -#include <deque> -#include <algorithm> - -namespace { - -using namespace std; -using namespace proton; - -using proton::io::connection_driver; -using proton::io::const_buffer; -using proton::io::mutable_buffer; - -using test::dummy_container; - -typedef std::deque<char> byte_stream; - -/// In memory connection_driver that reads and writes from byte_streams -struct in_memory_engine : public connection_driver { - - byte_stream& reads; - byte_stream& writes; - - in_memory_engine(byte_stream& rd, byte_stream& wr, class container& cont) : - connection_driver(cont), reads(rd), writes(wr) {} - - void do_read() { - mutable_buffer rbuf = read_buffer(); - size_t size = std::min(reads.size(), rbuf.size); - if (size) { - copy(reads.begin(), reads.begin()+size, static_cast<char*>(rbuf.data)); - read_done(size); - reads.erase(reads.begin(), reads.begin()+size); - } - } - - void do_write() { - const_buffer wbuf = write_buffer(); - if (wbuf.size) { - writes.insert(writes.begin(), - static_cast<const char*>(wbuf.data), - static_cast<const char*>(wbuf.data) + wbuf.size); - write_done(wbuf.size); - } - } - - void process() { - if (!dispatch()) - throw std::runtime_error("unexpected close: "+connection().error().what()); - do_read(); - do_write(); - dispatch(); - } -}; - -/// A pair of engines that talk to each other in-memory, simulating a connection. -struct engine_pair { - dummy_container conta, contb; - byte_stream ab, ba; - in_memory_engine a, b; - - engine_pair(const connection_options& oa, const connection_options& ob, - const std::string& name="" - ) : - conta(name+"a"), contb(name+"b"), a(ba, ab, conta), b(ab, ba, contb) - { - a.connect(oa); - b.accept(ob); - } - - void process() { a.process(); b.process(); } -}; - -template <class S> typename S::value_type quick_pop(S& s) { - ASSERT(!s.empty()); - typename S::value_type x = s.front(); - s.pop_front(); - return x; -} - -/// A handler that records incoming endpoints, errors etc. -struct record_handler : public messaging_handler { - std::deque<proton::receiver> receivers; - std::deque<proton::sender> senders; - std::deque<proton::session> sessions; - std::deque<std::string> unhandled_errors, transport_errors, connection_errors; - - void on_receiver_open(receiver &l) PN_CPP_OVERRIDE { - receivers.push_back(l); - } - - void on_sender_open(sender &l) PN_CPP_OVERRIDE { - senders.push_back(l); - } - - void on_session_open(session &s) PN_CPP_OVERRIDE { - sessions.push_back(s); - } - - void on_transport_error(transport& t) PN_CPP_OVERRIDE { - transport_errors.push_back(t.error().what()); - } - - void on_connection_error(connection& c) PN_CPP_OVERRIDE { - connection_errors.push_back(c.error().what()); - } - - void on_error(const proton::error_condition& c) PN_CPP_OVERRIDE { - unhandled_errors.push_back(c.what()); - } -}; - -struct namer : public io::link_namer { - char name; - namer(char c) : name(c) {} - std::string link_name() { return std::string(1, name++); } -}; - -void test_engine_container_link_id() { - record_handler ha, hb; - engine_pair e(ha, hb, "ids-"); - e.a.connect(ha); - e.b.accept(hb); - - namer na('x'); - namer nb('b'); - connection ca = e.a.connection(); - connection cb = e.b.connection(); - set_link_namer(ca, na); - set_link_namer(cb, nb); - - ASSERT_EQUAL("ids-a", e.a.connection().container_id()); - e.b.connection().open(); - ASSERT_EQUAL("ids-b", e.b.connection().container_id()); - - e.a.connection().open_sender("foo"); - while (ha.senders.empty() || hb.receivers.empty()) e.process(); - sender s = quick_pop(ha.senders); - ASSERT_EQUAL("x", s.name()); - - ASSERT_EQUAL("x", quick_pop(hb.receivers).name()); - - e.a.connection().open_receiver("bar"); - while (ha.receivers.empty() || hb.senders.empty()) e.process(); - ASSERT_EQUAL("y", quick_pop(ha.receivers).name()); - ASSERT_EQUAL("y", quick_pop(hb.senders).name()); - - e.b.connection().open_receiver(""); - while (ha.senders.empty() || hb.receivers.empty()) e.process(); - ASSERT_EQUAL("b", quick_pop(ha.senders).name()); - ASSERT_EQUAL("b", quick_pop(hb.receivers).name()); -} - -void test_endpoint_close() { - record_handler ha, hb; - engine_pair e(ha, hb); - e.a.connection().open_sender("x"); - e.a.connection().open_receiver("y"); - while (ha.senders.size()+ha.receivers.size() < 2 || - hb.senders.size()+hb.receivers.size() < 2) e.process(); - proton::link ax = quick_pop(ha.senders), ay = quick_pop(ha.receivers); - proton::link bx = quick_pop(hb.receivers), by = quick_pop(hb.senders); - - // Close a link - ax.close(proton::error_condition("err", "foo bar")); - while (!bx.closed()) e.process(); - proton::error_condition c = bx.error(); - ASSERT_EQUAL("err", c.name()); - ASSERT_EQUAL("foo bar", c.description()); - ASSERT_EQUAL("err: foo bar", c.what()); - - // Close a link with an empty condition - ay.close(proton::error_condition()); - while (!by.closed()) e.process(); - ASSERT(by.error().empty()); - - // Close a connection - connection ca = e.a.connection(), cb = e.b.connection(); - ca.close(proton::error_condition("conn", "bad connection")); - while (!cb.closed()) e.process(); - ASSERT_EQUAL("conn: bad connection", cb.error().what()); - ASSERT_EQUAL(1u, hb.connection_errors.size()); - ASSERT_EQUAL("conn: bad connection", hb.connection_errors.front()); -} - -void test_engine_disconnected() { - // engine.disconnected() aborts the connection and calls the local on_transport_error() - record_handler ha, hb; - engine_pair e(ha, hb, "disconnected"); - e.a.connect(ha); - e.b.accept(hb); - while (!e.a.connection().active() || !e.b.connection().active()) - e.process(); - - // Close a with an error condition. The AMQP connection is still open. - e.a.disconnected(proton::error_condition("oops", "engine failure")); - ASSERT(!e.a.dispatch()); - ASSERT(!e.a.connection().closed()); - ASSERT(e.a.connection().error().empty()); - ASSERT_EQUAL(0u, ha.connection_errors.size()); - ASSERT_EQUAL("oops: engine failure", e.a.transport().error().what()); - ASSERT_EQUAL(1u, ha.transport_errors.size()); - ASSERT_EQUAL("oops: engine failure", ha.transport_errors.front()); - - // In a real app the IO code would detect the abort and do this: - e.b.disconnected(proton::error_condition("broken", "it broke")); - ASSERT(!e.b.dispatch()); - ASSERT(!e.b.connection().closed()); - ASSERT(e.b.connection().error().empty()); - ASSERT_EQUAL(0u, hb.connection_errors.size()); - // Proton-C adds (connection aborted) if transport closes too early, - // and provides a default message if there is no user message. - ASSERT_EQUAL("broken: it broke (connection aborted)", e.b.transport().error().what()); - ASSERT_EQUAL(1u, hb.transport_errors.size()); - ASSERT_EQUAL("broken: it broke (connection aborted)", hb.transport_errors.front()); -} - -void test_no_container() { - // An engine with no container should throw, not crash. - connection_driver e; - try { - e.connection().container(); - FAIL("expected error"); - } catch (proton::error) {} - ASSERT(make_thread_safe<connection>(e.connection()).get()); - ASSERT(!make_thread_safe<connection>(e.connection()).get()->event_loop()); -} - -} - -int main(int, char**) { - int failed = 0; - RUN_TEST(failed, test_engine_container_link_id()); - RUN_TEST(failed, test_endpoint_close()); - RUN_TEST(failed, test_engine_disconnected()); - RUN_TEST(failed, test_no_container()); - return failed; -} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f2df847b/proton-c/bindings/cpp/src/include/proton_bits.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/include/proton_bits.hpp b/proton-c/bindings/cpp/src/include/proton_bits.hpp index 97d4bee..53f2230 100644 --- a/proton-c/bindings/cpp/src/include/proton_bits.hpp +++ b/proton-c/bindings/cpp/src/include/proton_bits.hpp @@ -124,7 +124,7 @@ template <class T> class factory { public: static T wrap(typename wrapped<T>::type* t) { return t; } - static typename wrapped<T>::type* unwrap(T t) { return t.pn_object(); } + static typename wrapped<T>::type* unwrap(const T& t) { return t.pn_object(); } }; // Get attachments for various proton-c types @@ -142,7 +142,7 @@ template <class U> U make_wrapper(typename internal::wrapped<U>::type* t) { return internal::factory<U>::wrap(t); } template <class T> -typename internal::wrapped<T>::type* unwrap(T t) {return internal::factory<T>::unwrap(t); } +typename internal::wrapped<T>::type* unwrap(const T& t) { return internal::factory<T>::unwrap(t); } } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f2df847b/proton-c/bindings/cpp/src/include/proton_event.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/include/proton_event.hpp b/proton-c/bindings/cpp/src/include/proton_event.hpp index 00fdadf..374da85 100644 --- a/proton-c/bindings/cpp/src/include/proton_event.hpp +++ b/proton-c/bindings/cpp/src/include/proton_event.hpp @@ -272,12 +272,17 @@ class proton_event {} pn_event_t* pn_event() const { return pn_event_; } + + /** Return a reference to the container, throws proton::error if there is none. */ class container& container() const { if (!container_) throw proton::error("event does not have a container"); return *container_; } + /** Return a pointer to the container if there is one, NULL otherwise. */ + class container* container_ptr() const { return container_; } + /// Get type of event event_type type() const { return event_type(pn_event_type(pn_event_)); } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f2df847b/proton-c/bindings/cpp/src/include/test_dummy_container.hpp ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/src/include/test_dummy_container.hpp b/proton-c/bindings/cpp/src/include/test_dummy_container.hpp index 4af432a..daed435 100644 --- a/proton-c/bindings/cpp/src/include/test_dummy_container.hpp +++ b/proton-c/bindings/cpp/src/include/test_dummy_container.hpp @@ -28,7 +28,6 @@ namespace test { using namespace proton; - class dummy_container : public standard_container { public: dummy_container(const std::string cid="") : --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
