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 2015/12/02 00:25:11 UTC

qpid-proton git commit: PROTON-1059: ruby binding broken in 0.11 release and on master

Repository: qpid-proton
Updated Branches:
  refs/heads/master 8117f18e3 -> eb63824fd


PROTON-1059: ruby binding broken in 0.11 release and on master

Re-organized swig binding to avoid use of the pre-processor in %inline sections.
Now works with ccache and non-ccache swig.

NOTE: According to ccache-swig man page: "Known problems are using
preprocessor directives within %inline blocks and the use of ’#pragma SWIG’."
This includes using macros in an %inline section.

Added automatic example test, needs extension to cover all examples.
Updated option and error handling in some examples to support auto-testing.


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/eb63824f
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/eb63824f
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/eb63824f

Branch: refs/heads/master
Commit: eb63824fd9eb6d3b516ae68065bf05c222b49d95
Parents: 8117f18
Author: Alan Conway <ac...@redhat.com>
Authored: Mon Nov 23 17:13:12 2015 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Tue Dec 1 18:06:12 2015 -0500

----------------------------------------------------------------------
 examples/ruby/example_test.rb       | 90 ++++++++++++++++++++++++++++++++
 examples/ruby/reactor/broker.rb     |  2 +-
 examples/ruby/reactor/client.rb     | 16 +++++-
 examples/ruby/reactor/helloworld.rb |  4 ++
 examples/ruby/reactor/server.rb     | 24 ++++++---
 proton-c/CMakeLists.txt             | 26 +++++----
 proton-c/bindings/python/cproton.i  |  4 +-
 proton-c/bindings/ruby/ruby.i       | 87 ++++++++++++++++--------------
 8 files changed, 195 insertions(+), 58 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/eb63824f/examples/ruby/example_test.rb
----------------------------------------------------------------------
diff --git a/examples/ruby/example_test.rb b/examples/ruby/example_test.rb
new file mode 100755
index 0000000..9a01964
--- /dev/null
+++ b/examples/ruby/example_test.rb
@@ -0,0 +1,90 @@
+#!/usr/bin/enc ruby
+#
+# 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.
+#
+
+require 'test/unit'
+require 'qpid_proton'
+require 'socket'
+
+$port = Random.new.rand(10000) + 10000
+
+class ExampleTest < Test::Unit::TestCase
+
+  def run_script(script, port)
+    assert File.exist? script
+    cmd = [RbConfig.ruby, script]
+    cmd += ["-a", ":#{port}/examples"] if port
+    return IO.popen(cmd)
+  end
+
+
+  def assert_output(script, want, port=nil)
+    out = run_script(script, port)
+    assert_equal want, out.read.strip
+  end
+
+  def test_helloworld
+    assert_output("reactor/helloworld.rb", "Hello world!", $port)
+  end
+
+  def test_send_recv
+    assert_output("reactor/simple_send.rb", "All 100 messages confirmed!", $port)
+    want = (0..99).reduce("") { |x,y| x << "Received: sequence #{y}\n" }
+    assert_output("reactor/simple_recv.rb", want.strip, $port)
+  end
+
+  def test_client_server
+    want =  <<EOS
+-> Twas brillig, and the slithy toves
+<- TWAS BRILLIG, AND THE SLITHY TOVES
+-> Did gire and gymble in the wabe.
+<- DID GIRE AND GYMBLE IN THE WABE.
+-> All mimsy were the borogroves,
+<- ALL MIMSY WERE THE BOROGROVES,
+-> And the mome raths outgrabe.
+<- AND THE MOME RATHS OUTGRABE.
+EOS
+    srv = run_script("reactor/server.rb", $port)
+    assert_output("reactor/client.rb", want.strip, $port)
+
+  ensure
+    Process.kill :TERM, srv.pid if srv
+  end
+end
+
+begin
+  broker = spawn("#{RbConfig.ruby} reactor/broker.rb -a :#{$port}")
+  # Wait for the broker to be listening.
+  while true
+    begin
+      s = TCPSocket.open "", $port
+      puts "Broker ready at #{$port}"
+      s.close
+      break
+    rescue Errno::ECONNREFUSED
+      puts "Retry connection to #{$port}"
+      sleep(0.1)
+    end
+  end
+
+  Test::Unit::AutoRunner.run
+
+ensure
+  Process.kill :TERM, broker if broker
+end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/eb63824f/examples/ruby/reactor/broker.rb
----------------------------------------------------------------------
diff --git a/examples/ruby/reactor/broker.rb b/examples/ruby/reactor/broker.rb
index 9d7e5be..7882d9a 100644
--- a/examples/ruby/reactor/broker.rb
+++ b/examples/ruby/reactor/broker.rb
@@ -117,7 +117,7 @@ class Broker < Qpid::Proton::Handler::MessagingHandler
     debug("link is#{event.link.sender? ? '' : ' not'} a sender") if $options[:debug]
     if event.link.sender?
       if event.link.remote_source.dynamic?
-        address = generate_uuid
+        address = SecureRandom.uuid
         event.link.source.address = address
         q = Exchange.new(true)
         @queues[address] = q

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/eb63824f/examples/ruby/reactor/client.rb
----------------------------------------------------------------------
diff --git a/examples/ruby/reactor/client.rb b/examples/ruby/reactor/client.rb
index 8bb58da..8c38f38 100644
--- a/examples/ruby/reactor/client.rb
+++ b/examples/ruby/reactor/client.rb
@@ -18,6 +18,7 @@
 #++
 
 require 'qpid_proton'
+require 'optparse'
 
 class Client < Qpid::Proton::Handler::MessagingHandler
 
@@ -58,6 +59,10 @@ class Client < Qpid::Proton::Handler::MessagingHandler
     end
   end
 
+  def on_transport_error(event)
+    raise "Connection error: #{event.transport.condition}"
+  end
+
 end
 
 REQUESTS = ["Twas brillig, and the slithy toves",
@@ -65,4 +70,13 @@ REQUESTS = ["Twas brillig, and the slithy toves",
             "All mimsy were the borogroves,",
             "And the mome raths outgrabe."]
 
-Qpid::Proton::Reactor::Container.new(Client.new("0.0.0.0:5672/examples", REQUESTS)).run
+options = {
+  :address => "localhost:5672/examples",
+}
+
+OptionParser.new do |opts|
+  opts.banner = "Usage: client.rb [options]"
+  opts.on("-a", "--address=ADDRESS", "Send messages to ADDRESS (def. #{options[:address]}).") { |address| options[:address] = address }
+end.parse!
+
+Qpid::Proton::Reactor::Container.new(Client.new(options[:address], REQUESTS)).run

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/eb63824f/examples/ruby/reactor/helloworld.rb
----------------------------------------------------------------------
diff --git a/examples/ruby/reactor/helloworld.rb b/examples/ruby/reactor/helloworld.rb
index 03eb561..9b02e8a 100644
--- a/examples/ruby/reactor/helloworld.rb
+++ b/examples/ruby/reactor/helloworld.rb
@@ -45,6 +45,10 @@ class HelloWorld < Qpid::Proton::Handler::MessagingHandler
     puts event.message.body
     event.connection.close
   end
+
+  def on_transport_error(event)
+    raise "Connection error: #{event.transport.condition}"
+  end
 end
 
 options = {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/eb63824f/examples/ruby/reactor/server.rb
----------------------------------------------------------------------
diff --git a/examples/ruby/reactor/server.rb b/examples/ruby/reactor/server.rb
index e149dba..9373272 100644
--- a/examples/ruby/reactor/server.rb
+++ b/examples/ruby/reactor/server.rb
@@ -18,20 +18,20 @@
 #++
 
 require 'qpid_proton'
+require 'optparse'
 
 class Server < Qpid::Proton::Handler::MessagingHandler
 
-  def initialize(url, address)
+  def initialize(url)
     super()
-    @url = url
-    @address = address
+    @url = Qpid::Proton::URL.new url
+    @address = @url.path
     @senders = {}
   end
 
   def on_start(event)
-    puts "Listening on #{@url}"
     @container = event.container
-    @conn = @container.connect(:address => @url)
+    @conn = @container.connect(:url => @url)
     @receiver = @container.create_receiver(@conn, :source => @address)
     @relay = nil
   end
@@ -59,6 +59,18 @@ class Server < Qpid::Proton::Handler::MessagingHandler
     sender.send(reply)
   end
 
+  def on_transport_error(event)
+    raise "Connection error: #{event.transport.condition}"
+  end
 end
 
-Qpid::Proton::Reactor::Container.new(Server.new("0.0.0.0:5672", "examples")).run()
+options = {
+  :address => "localhost:5672/examples",
+}
+
+OptionParser.new do |opts|
+  opts.banner = "Usage: server.rb [options]"
+  opts.on("-a", "--address=ADDRESS", "Send messages to ADDRESS (def. #{options[:address]}).") { |address| options[:address] = address }
+end.parse!
+
+Qpid::Proton::Reactor::Container.new(Server.new(options[:address])).run()

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/eb63824f/proton-c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/CMakeLists.txt b/proton-c/CMakeLists.txt
index d80d60a..d897951 100644
--- a/proton-c/CMakeLists.txt
+++ b/proton-c/CMakeLists.txt
@@ -586,19 +586,25 @@ endif (BUILD_PYTHON)
 
 find_program(RUBY_EXE "ruby")
 if (RUBY_EXE AND BUILD_RUBY)
+  set (rb_root "${pn_test_root}/ruby")
+  set (rb_src "${CMAKE_CURRENT_SOURCE_DIR}/bindings/ruby")
+  set (rb_lib "${CMAKE_CURRENT_SOURCE_DIR}/bindings/ruby/lib")
+  set (rb_bin "${CMAKE_CURRENT_BINARY_DIR}/bindings/ruby")
+  set (rb_bld "$<TARGET_FILE_DIR:qpid-proton>")
+  set (rb_path $ENV{PATH} ${rb_bin} ${rb_bld})
+  set (rb_rubylib ${rb_root} ${rb_src} ${rb_bin} ${rb_bld} ${rb_lib})
+  to_native_path("${rb_path}" rb_path)
+  to_native_path("${rb_rubylib}" rb_rubylib)
+
+  # ruby example tests have no dependencies other than standard ruby.
+  add_test(NAME ruby-example-test
+    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/examples/ruby
+    COMMAND ${env_py} -- "PATH=${rb_path}" "RUBYLIB=${rb_rubylib}"
+    ${RUBY_EXE} example_test.rb -v)
+
   # ruby unit tests:  tests/ruby/proton-test
   # only enable the tests if the Ruby gem dependencies were found
   if (DEFAULT_RUBY_TESTING)
-    set (rb_root "${pn_test_root}/ruby")
-    set (rb_src "${CMAKE_CURRENT_SOURCE_DIR}/bindings/ruby")
-    set (rb_lib "${CMAKE_CURRENT_SOURCE_DIR}/bindings/ruby/lib")
-    set (rb_bin "${CMAKE_CURRENT_BINARY_DIR}/bindings/ruby")
-    set (rb_bld "$<TARGET_FILE_DIR:qpid-proton>")
-    set (rb_path $ENV{PATH} ${rb_bin} ${rb_bld})
-    set (rb_rubylib ${rb_root} ${rb_src} ${rb_bin} ${rb_bld} ${rb_lib})
-    to_native_path("${rb_path}" rb_path)
-    to_native_path("${rb_rubylib}" rb_rubylib)
-
     add_test (NAME ruby-unit-test
               COMMAND ${env_py} "PATH=${rb_path}" "RUBYLIB=${rb_rubylib}"
                       "${rb_root}/proton-test")

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/eb63824f/proton-c/bindings/python/cproton.i
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/cproton.i b/proton-c/bindings/python/cproton.i
index f7f56e3..1485801 100644
--- a/proton-c/bindings/python/cproton.i
+++ b/proton-c/bindings/python/cproton.i
@@ -37,10 +37,10 @@ NOTE: According to ccache-swig man page: "Known problems are using
 preprocessor directives within %inline blocks and the use of ’#pragma SWIG’."
 This includes using macros in an %inline section.
 
-Do any preprocessor work or macro expansions here before we get into the %inline sections.
+Keep preprocessor directives and macro expansions in the normal header section.
 */
-PN_HANDLE(PNI_PYTRACER);
 
+PN_HANDLE(PNI_PYTRACER);
 %}
 
 %include <cstring.i>

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/eb63824f/proton-c/bindings/ruby/ruby.i
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/ruby.i b/proton-c/bindings/ruby/ruby.i
index eddd529..9edbdb2 100644
--- a/proton-c/bindings/ruby/ruby.i
+++ b/proton-c/bindings/ruby/ruby.i
@@ -28,49 +28,16 @@
 #include <proton/url.h>
 #include <proton/reactor.h>
 #include <proton/handlers.h>
-
+%}
 
 /*
 NOTE: According to ccache-swig man page: "Known problems are using
 preprocessor directives within %inline blocks and the use of ’#pragma SWIG’."
-This includes using any macros in an %inline section.
+This includes using macros in an %inline section.
 
-Do any preprocessor work or macro expansions here before we get into the %inline sections.
+Keep preprocessor directives and macro expansions in the normal header section.
 */
 
-#define CID_Pn_rbkey CID_pn_void
-
-typedef struct {
-  void *registry;
-  char *method;
-  char *key_value;
-} Pn_rbkey_t;
-
-void Pn_rbkey_initialize(Pn_rbkey_t *rbkey) {
-  assert(rbkey);
-  rbkey->registry = NULL;
-  rbkey->method = NULL;
-  rbkey->key_value = NULL;
-}
-
-void Pn_rbkey_finalize(Pn_rbkey_t *rbkey) {
-  if(rbkey && rbkey->registry && rbkey->method && rbkey->key_value) {
-    rb_funcall((VALUE )rbkey->registry, rb_intern(rbkey->method), 1, rb_str_new2(rbkey->key_value));
-  }
-  if(rbkey->key_value) {
-    free(rbkey->key_value);
-    rbkey->key_value = NULL;
-  }
-}
-
-#define Pn_rbkey_inspect NULL
-#define Pn_rbkey_compare NULL
-#define Pn_rbkey_hashcode NULL
-
-PN_CLASSDEF(Pn_rbkey)
-
-%}
-
 %include <cstring.i>
 
 %cstring_output_withsize(char *OUTPUT, size_t *OUTPUT_SIZE)
@@ -504,8 +471,53 @@ bool pn_ssl_get_protocol_name(pn_ssl_t *ssl, char *OUTPUT, size_t MAX_OUTPUT_SIZ
 %ignore pn_messenger_recv;
 %ignore pn_messenger_work;
 
+%{
+typedef struct Pn_rbkey_t {
+  void *registry;
+  char *method;
+  char *key_value;
+} Pn_rbkey_t;
+
+void Pn_rbkey_initialize(Pn_rbkey_t *rbkey) {
+  assert(rbkey);
+  rbkey->registry = NULL;
+  rbkey->method = NULL;
+  rbkey->key_value = NULL;
+}
+
+void Pn_rbkey_finalize(Pn_rbkey_t *rbkey) {
+  if(rbkey && rbkey->registry && rbkey->method && rbkey->key_value) {
+    rb_funcall((VALUE )rbkey->registry, rb_intern(rbkey->method), 1, rb_str_new2(rbkey->key_value));
+  }
+  if(rbkey->key_value) {
+    free(rbkey->key_value);
+    rbkey->key_value = NULL;
+  }
+}
+
+/* NOTE: no macro or preprocessor definitions in %inline sections */
+#define CID_Pn_rbkey CID_pn_void
+#define Pn_rbkey_inspect NULL
+#define Pn_rbkey_compare NULL
+#define Pn_rbkey_hashcode NULL
+
+pn_class_t* Pn_rbkey__class(void) {
+    static pn_class_t clazz = PN_CLASS(Pn_rbkey);
+    return &clazz;
+}
+
+Pn_rbkey_t *Pn_rbkey_new(void) {
+    return (Pn_rbkey_t *) pn_class_new(Pn_rbkey__class(), sizeof(Pn_rbkey_t));
+}
+%}
+
+pn_class_t* Pn_rbkey__class(void);
+Pn_rbkey_t *Pn_rbkey_new(void);
+
 %inline %{
 
+Pn_rbkey_t *Pn_rbkey_new(void);
+
 void Pn_rbkey_set_registry(Pn_rbkey_t *rbkey, void *registry) {
   assert(rbkey);
   rbkey->registry = registry;
@@ -579,8 +591,7 @@ int pn_ssl_get_peer_hostname(pn_ssl_t *ssl, char *OUTPUT, size_t *OUTPUT_SIZE);
   }
 
   VALUE pni_ruby_get_from_registry(VALUE key) {
-
-      return rb_funcall(pni_ruby_get_proton_module(), rb_intern("get_from_registry"), 1, key);
+    rb_funcall(pni_ruby_get_proton_module(), rb_intern("get_from_registry"), 1, key);
   }
 
   void pni_ruby_delete_from_registry(VALUE stored_key) {


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org