You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2017/05/24 19:44:34 UTC
[4/7] qpid-proton git commit: PROTON-1288: c++ reinstate engine_test
as connection_driver_test
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/master
Commit: f2df847b552685f80429715832e55207d68bbbcb
Parents: 48a5e47
Author: Alan Conway <ac...@redhat.com>
Authored: Fri May 19 11:04:44 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
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: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org