nn-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +9 -0
- data/.rspec +4 -0
- data/Authors.txt +2 -0
- data/Gemfile +5 -0
- data/History.txt +4 -0
- data/README.md +57 -0
- data/Rakefile +6 -0
- data/lib/nn-core/constants.rb +85 -0
- data/lib/nn-core/libnanomsg.rb +59 -0
- data/lib/nn-core/structs.rb +121 -0
- data/lib/nn-core/version.rb +3 -0
- data/lib/nn-core.rb +6 -0
- data/nn-core.gemspec +26 -0
- data/spec/nn_bind_spec.rb +106 -0
- data/spec/nn_close_spec.rb +40 -0
- data/spec/nn_connect_spec.rb +112 -0
- data/spec/nn_getsockopt_spec.rb +109 -0
- data/spec/nn_init_spec.rb +11 -0
- data/spec/nn_recv_spec.rb +66 -0
- data/spec/nn_send_spec.rb +53 -0
- data/spec/nn_setsockopt_spec.rb +72 -0
- data/spec/nn_shutdown_spec.rb +54 -0
- data/spec/nn_socket_spec.rb +59 -0
- data/spec/nn_term_spec.rb +17 -0
- data/spec/nn_version_spec.rb +25 -0
- data/spec/spec_helper.rb +25 -0
- metadata +176 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Authors.txt
ADDED
data/Gemfile
ADDED
data/History.txt
ADDED
data/README.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
nn-core
|
2
|
+
-------
|
3
|
+
|
4
|
+
nn-core is a very thin FFI wrapper around the nanomsg library. The intention is to provide a very
|
5
|
+
simple wrapper that hews as close to the C API as possible. Other gems that want to offer a more
|
6
|
+
idiomatic API for Ruby should require this gem and build a nice Ruby API with it.
|
7
|
+
|
8
|
+
For more information on nanomsg, please visit its website:
|
9
|
+
|
10
|
+
http://nanomsg.org
|
11
|
+
|
12
|
+
Installation
|
13
|
+
------------
|
14
|
+
|
15
|
+
1. Make sure to build libnanomsg first by following these instructions:
|
16
|
+
|
17
|
+
http://github.com/250bpm/nanomsg
|
18
|
+
|
19
|
+
2. git clone git://github.com/chuckremes/nn-core.git
|
20
|
+
|
21
|
+
3. cd nn-core
|
22
|
+
|
23
|
+
4. ruby -S gem build nn-core.gemspec
|
24
|
+
|
25
|
+
5. ruby -S gem install nn-core*.gem
|
26
|
+
|
27
|
+
6. In your code, do:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
require "nn-core"
|
31
|
+
```
|
32
|
+
|
33
|
+
License
|
34
|
+
-------
|
35
|
+
|
36
|
+
(The MIT License)
|
37
|
+
|
38
|
+
Copyright (c) 2013 Chuck Remes
|
39
|
+
|
40
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
41
|
+
a copy of this software and associated documentation files (the
|
42
|
+
'Software'), to deal in the Software without restriction, including
|
43
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
44
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
45
|
+
permit persons to whom the Software is furnished to do so, subject to
|
46
|
+
the following conditions:
|
47
|
+
|
48
|
+
The above copyright notice and this permission notice shall be
|
49
|
+
included in all copies or substantial portions of the Software.
|
50
|
+
|
51
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
52
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
53
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
54
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
55
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
56
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
57
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
module NNCore
|
2
|
+
NN_HAUSNUMERO = 156384712
|
3
|
+
|
4
|
+
# SP address families
|
5
|
+
AF_SP = 1
|
6
|
+
AF_SP_RAW = 2
|
7
|
+
|
8
|
+
# Transport types
|
9
|
+
NN_INPROC = -1
|
10
|
+
NN_IPC = -2
|
11
|
+
NN_TCP = -3
|
12
|
+
|
13
|
+
# Protocols
|
14
|
+
NN_PAIR_ID = 1
|
15
|
+
NN_PAIR = (NN_PAIR_ID * 16 + 0)
|
16
|
+
|
17
|
+
NN_PUBSUB_ID = 2
|
18
|
+
NN_PUB = (NN_PUBSUB_ID * 16 + 0)
|
19
|
+
NN_SUB = (NN_PUBSUB_ID * 16 + 1)
|
20
|
+
|
21
|
+
NN_REQREP_ID = 3
|
22
|
+
NN_REQ = (NN_REQREP_ID * 16 + 0)
|
23
|
+
NN_REP = (NN_REQREP_ID * 16 + 1)
|
24
|
+
|
25
|
+
NN_FANIN_ID = 4
|
26
|
+
NN_SOURCE = (NN_FANIN_ID * 16 + 0)
|
27
|
+
NN_SINK = (NN_FANIN_ID * 16 + 1)
|
28
|
+
NN_FANOUT_ID = 5
|
29
|
+
NN_PUSH = (NN_FANOUT_ID * 16 + 0)
|
30
|
+
NN_PULL = (NN_FANOUT_ID * 16 + 1)
|
31
|
+
|
32
|
+
NN_SURVEY_ID = 6
|
33
|
+
NN_SURVEYOR = (NN_SURVEY_ID * 16 + 0)
|
34
|
+
NN_RESPONDENT = (NN_SURVEY_ID * 16 + 1)
|
35
|
+
|
36
|
+
# Socket Option Levels (SOL)
|
37
|
+
NN_SOL_SOCKET = 0
|
38
|
+
|
39
|
+
# Socket options
|
40
|
+
NN_LINGER = 1
|
41
|
+
NN_SNDBUF = 2
|
42
|
+
NN_RCVBUF = 3
|
43
|
+
NN_SNDTIMEO = 4
|
44
|
+
NN_RCVTIMEO = 5
|
45
|
+
NN_RECONNECT_IVL = 6
|
46
|
+
NN_RECONNECT_IVL_MAX = 7
|
47
|
+
NN_SNDPRIO = 8
|
48
|
+
#NN_SNDFD = 10
|
49
|
+
#NN_RCVFD = 11
|
50
|
+
|
51
|
+
# Send/recv options
|
52
|
+
NN_DONTWAIT = 1
|
53
|
+
NN_MSG = -1
|
54
|
+
|
55
|
+
# Socket errors
|
56
|
+
ENOTSUP = Errno::ENOTSUP::Errno rescue NN_HAUSNUMERO + 1
|
57
|
+
EPROTONOSUPPORT = Errno::EPROTONOSUPPORT::Errno rescue NN_HAUSNUMERO + 2
|
58
|
+
ENOBUFS = Errno::ENOBUFS::Errno rescue NN_HAUSNUMERO + 3
|
59
|
+
ENETDOWN = Errno::ENETDOWN::Errnow rescue NN_HAUSNUMERO + 4
|
60
|
+
EADDRINUSE = Errno::EADDRINUSE::Errno rescue NN_HAUSNUMERO + 5
|
61
|
+
EADDRNOTAVAIL = Errno::EADDRNOTAVAIL::Errno rescue NN_HAUSNUMERO + 6
|
62
|
+
ECONNREFUSED = Errno::ECONNREFUSED::Errno rescue NN_HAUSNUMERO + 7
|
63
|
+
EINPROGRESS = Errno::EINPROGRESS::Errno rescue NN_HAUSNUMERO + 8
|
64
|
+
ENOTSOCK = Errno::ENOTSOCK::Errno rescue NN_HAUSNUMERO + 9
|
65
|
+
EAFNOSUPPORT = Errno::EAFNOSUPPORT::Errno rescue NN_HAUSNUMERO + 10
|
66
|
+
EPROTO = Errno::EPROTO::Errno rescue NN_HAUSNUMERO + 11
|
67
|
+
|
68
|
+
ETIMEDOUT = Errno::ETIMEDOUT::Errno
|
69
|
+
EAGAIN = Errno::EAGAIN::Errno
|
70
|
+
EINVAL = Errno::EINVAL::Errno
|
71
|
+
ENOMEM = Errno::ENOMEM::Errno
|
72
|
+
ENODEV = Errno::ENODEV::Errno
|
73
|
+
EFAULT = Errno::EFAULT::Errno
|
74
|
+
# EINTR = Errno::EINTR::Errno
|
75
|
+
EBADF = Errno::EBADF::Errno
|
76
|
+
ENOPROTOOPT = Errno::ENOPROTOOPT::Errno
|
77
|
+
ENAMETOOLONG = Errno::ENAMETOOLONG::Errno
|
78
|
+
|
79
|
+
# Library errors
|
80
|
+
ETERM = Errno::ETERM::Errno rescue NN_HAUSNUMERO + 53
|
81
|
+
EFSM = Errno::EFSM::Errno rescue NN_HAUSNUMERO + 54
|
82
|
+
|
83
|
+
# Miscellaneous
|
84
|
+
NN_INPROCB_NAMELEN_MAX = 64
|
85
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
|
2
|
+
module NNCore
|
3
|
+
module LibNanomsg
|
4
|
+
extend FFI::Library
|
5
|
+
|
6
|
+
begin
|
7
|
+
# bias the library discovery to a path inside the gem first, then
|
8
|
+
# to the usual system paths
|
9
|
+
inside_gem = File.join(File.dirname(__FILE__), '..', '..', 'ext')
|
10
|
+
local_path = FFI::Platform::IS_WINDOWS ? ENV['PATH'].split(';') : ENV['PATH'].split(':')
|
11
|
+
library_name = "libnanomsg"
|
12
|
+
LIB_PATHS = [
|
13
|
+
inside_gem, '/usr/local/lib', '/opt/local/lib', '/usr/local/homebrew/lib', '/usr/lib64'
|
14
|
+
].map{|path| "#{path}/#{library_name}.#{FFI::Platform::LIBSUFFIX}"}
|
15
|
+
ffi_lib(LIB_PATHS + [library_name])
|
16
|
+
rescue LoadError
|
17
|
+
if LIB_PATHS.push(*local_path).any? {|path|
|
18
|
+
File.file? File.join(path, "#{library_name}.#{FFI::Platform::LIBSUFFIX}")}
|
19
|
+
warn "Unable to load this gem. The #{library_name} library exists, but cannot be loaded."
|
20
|
+
warn "If this is Windows:"
|
21
|
+
warn "- Check that you have MSVC runtime installed or statically linked"
|
22
|
+
warn "- Check that your DLL is compiled for #{FFI::Platform::ADDRESS_SIZE} bit"
|
23
|
+
else
|
24
|
+
warn "Unable to load this gem. The #{library_name} library (or DLL) could not be found."
|
25
|
+
warn "If this is a Windows platform, make sure #{library_name}.dll is on the PATH."
|
26
|
+
warn "If the DLL was built with mingw, make sure the other two dependent DLLs,"
|
27
|
+
warn "libgcc_s_sjlj-1.dll and libstdc++6.dll, are also on the PATH."
|
28
|
+
warn "For non-Windows platforms, make sure #{library_name} is located in this search path:"
|
29
|
+
warn LIB_PATHS.inspect
|
30
|
+
end
|
31
|
+
raise LoadError, "The #{library_name} library (or DLL) could not be loaded"
|
32
|
+
end
|
33
|
+
# Size_t not working properly on Windows
|
34
|
+
find_type(:size_t) rescue typedef(:ulong, :size_t)
|
35
|
+
|
36
|
+
attach_function :nn_version, [:pointer, :pointer, :pointer], :int
|
37
|
+
|
38
|
+
attach_function :nn_init, [], :int
|
39
|
+
attach_function :nn_term, [], :int
|
40
|
+
attach_function :nn_errno, [], :int
|
41
|
+
attach_function :nn_strerror, [:int], :string
|
42
|
+
attach_function :nn_socket, [:int, :int], :int
|
43
|
+
attach_function :nn_close, [:int], :int
|
44
|
+
|
45
|
+
attach_function :nn_getsockopt, [:int, :int, :int, :pointer, :pointer], :int
|
46
|
+
attach_function :nn_setsockopt, [:int, :int, :int, :pointer, :size_t], :int
|
47
|
+
attach_function :nn_bind, [:int, :string], :int
|
48
|
+
attach_function :nn_connect, [:int, :string], :int
|
49
|
+
attach_function :nn_shutdown, [:int, :int], :int
|
50
|
+
attach_function :nn_send, [:int, :pointer, :size_t, :int], :int
|
51
|
+
attach_function :nn_recv, [:int, :pointer, :size_t, :int], :int
|
52
|
+
|
53
|
+
# functions for working with raw buffers
|
54
|
+
attach_function :nn_sendmsg, [:int, :pointer, :int], :int
|
55
|
+
attach_function :nn_recvmsg, [:int, :pointer, :int], :int
|
56
|
+
attach_function :nn_allocmsg, [:size_t, :int], :pointer
|
57
|
+
attach_function :nn_freemsg, [:pointer], :int
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
|
2
|
+
module NNCore
|
3
|
+
module LibNanomsg
|
4
|
+
|
5
|
+
# Structs for working with raw buffers (not recommended)
|
6
|
+
module NNIOVecLayout
|
7
|
+
def self.included(base)
|
8
|
+
base.class_eval do
|
9
|
+
layout :iov_base, :pointer,
|
10
|
+
:iov_len, :size_t
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class NNIOVec < FFI::Struct
|
16
|
+
include NNIOVecLayout
|
17
|
+
|
18
|
+
def iov_base
|
19
|
+
self[:iov_base]
|
20
|
+
end
|
21
|
+
|
22
|
+
def iov_base=(pointer)
|
23
|
+
self[:iov_base] = pointer
|
24
|
+
end
|
25
|
+
|
26
|
+
def iov_len
|
27
|
+
self[:iov_len]
|
28
|
+
end
|
29
|
+
|
30
|
+
def iov_len=(length)
|
31
|
+
self[:iov_len] = length
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
module NNMsgHdrLayout
|
36
|
+
def self.included(base)
|
37
|
+
base.class_eval do
|
38
|
+
layout :msg_iov, NNIOVec.ptr,
|
39
|
+
:msg_iovlen, :int,
|
40
|
+
:msg_control, :pointer,
|
41
|
+
:msg_controllen, :size_t
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class NNMsgHdr < FFI::Struct
|
47
|
+
include NNMsgHdrLayout
|
48
|
+
|
49
|
+
def msg_iov
|
50
|
+
self[:msg_iov]
|
51
|
+
end
|
52
|
+
|
53
|
+
def msg_iov=(structure)
|
54
|
+
self[:msg_iov] = structure
|
55
|
+
end
|
56
|
+
|
57
|
+
def msg_iovlen
|
58
|
+
self[:msg_iovlen]
|
59
|
+
end
|
60
|
+
|
61
|
+
def msg_iovlen=(length)
|
62
|
+
self[:msg_iovlen] = length
|
63
|
+
end
|
64
|
+
|
65
|
+
def msg_control
|
66
|
+
self[:msg_control]
|
67
|
+
end
|
68
|
+
|
69
|
+
def msg_control=(pointer)
|
70
|
+
self[:msg_control] = pointer
|
71
|
+
end
|
72
|
+
|
73
|
+
def msg_controllen
|
74
|
+
self[:msg_controllen]
|
75
|
+
end
|
76
|
+
|
77
|
+
def msg_controllen=(value)
|
78
|
+
self[:msg_controllen] = value
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
module NNCMsgHdrLayout
|
83
|
+
def self.included(base)
|
84
|
+
base.class_eval do
|
85
|
+
layout :cmsg_len, :size_t,
|
86
|
+
:cmsg_level, :int,
|
87
|
+
:cmsg_type, :int
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class NNCMsgHdr < FFI::Struct
|
93
|
+
include NNCMsgHdrLayout
|
94
|
+
|
95
|
+
def cmsg_len
|
96
|
+
self[:cmsg_len]
|
97
|
+
end
|
98
|
+
|
99
|
+
def cmsg_len=(length)
|
100
|
+
self[:csmg_len] = length
|
101
|
+
end
|
102
|
+
|
103
|
+
def cmsg_level
|
104
|
+
self[:cmsg_level]
|
105
|
+
end
|
106
|
+
|
107
|
+
def cmsg_level=(level)
|
108
|
+
self[:cmsg_level] = level
|
109
|
+
end
|
110
|
+
|
111
|
+
def cmsg_type
|
112
|
+
self[:cmsg_type]
|
113
|
+
end
|
114
|
+
|
115
|
+
def cmsg_type=(type)
|
116
|
+
self[:cmsg_type] = type
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
data/lib/nn-core.rb
ADDED
data/nn-core.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "nn-core/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "nn-core"
|
7
|
+
s.version = NNCore::VERSION
|
8
|
+
s.authors = ["Chuck Remes"]
|
9
|
+
s.email = ["git@chuckremes.com"]
|
10
|
+
s.homepage = "http://github.com/chuckremes/nn-core"
|
11
|
+
s.summary = %q{Wraps the nanomsg networking library using Ruby FFI (foreign function interface).}
|
12
|
+
s.description = %q{Wraps the nanomsg networking library using the ruby FFI (foreign
|
13
|
+
function interface). It only exposes the native C API to Ruby. Other gems should use this gem
|
14
|
+
to build an API using Ruby idioms.}
|
15
|
+
|
16
|
+
s.rubyforge_project = "nn-core"
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
|
23
|
+
s.add_runtime_dependency "ffi"
|
24
|
+
s.add_development_dependency "rspec", ["~> 2.6"]
|
25
|
+
s.add_development_dependency "rake"
|
26
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module NNCore
|
4
|
+
describe "nn_bind" do
|
5
|
+
|
6
|
+
context "given an initialized library and" do
|
7
|
+
before(:each) { LibNanomsg.nn_init }
|
8
|
+
after(:each) { LibNanomsg.nn_term }
|
9
|
+
|
10
|
+
|
11
|
+
context "given a valid socket" do
|
12
|
+
before(:each) do
|
13
|
+
LibNanomsg.nn_init
|
14
|
+
@socket = LibNanomsg.nn_socket(AF_SP, NN_PUB)
|
15
|
+
end
|
16
|
+
|
17
|
+
after(:each) do
|
18
|
+
LibNanomsg.nn_close(@socket)
|
19
|
+
LibNanomsg.nn_term
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns a non-zero endpoint number for a valid INPROC address" do
|
23
|
+
rc = LibNanomsg.nn_bind(@socket, "inproc://some_address")
|
24
|
+
rc.should > 0
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns a non-zero endpoint number for a valid IPC address" do
|
28
|
+
rc = LibNanomsg.nn_bind(@socket, "ipc:///tmp/some_address")
|
29
|
+
rc.should > 0
|
30
|
+
end
|
31
|
+
|
32
|
+
it "returns a non-zero endpoint number for a valid TCP address" do
|
33
|
+
rc = LibNanomsg.nn_bind(@socket, "tcp://127.0.0.1:5555")
|
34
|
+
rc.should > 0
|
35
|
+
end
|
36
|
+
|
37
|
+
it "returns -1 for an invalid INPROC address" do
|
38
|
+
rc = LibNanomsg.nn_bind(@socket, "inproc:/missing_first_slash")
|
39
|
+
rc.should == -1
|
40
|
+
LibNanomsg.nn_errno.should == EINVAL
|
41
|
+
end
|
42
|
+
|
43
|
+
it "returns -1 for an invalid INPROC address (too long)" do
|
44
|
+
rc = LibNanomsg.nn_bind(@socket, "inproc://#{'a' * (NN_INPROCB_NAMELEN_MAX + 1)}")
|
45
|
+
rc.should == -1
|
46
|
+
LibNanomsg.nn_errno.should == ENAMETOOLONG
|
47
|
+
end
|
48
|
+
|
49
|
+
it "returns -1 for an invalid IPC address" do
|
50
|
+
rc = LibNanomsg.nn_bind(@socket, "ipc:/missing_slashes)")
|
51
|
+
rc.should == -1
|
52
|
+
LibNanomsg.nn_errno.should == EINVAL
|
53
|
+
end
|
54
|
+
|
55
|
+
it "returns -1 for an invalid TCP address (missing address)" do
|
56
|
+
rc = LibNanomsg.nn_bind(@socket, "tcp://")
|
57
|
+
rc.should == -1
|
58
|
+
LibNanomsg.nn_errno.should == EINVAL
|
59
|
+
end
|
60
|
+
|
61
|
+
it "returns -1 for an invalid TCP address (non-numeric port)" do
|
62
|
+
rc = LibNanomsg.nn_bind(@socket, "tcp://192.168.0.1:port")
|
63
|
+
rc.should == -1
|
64
|
+
LibNanomsg.nn_errno.should == EINVAL
|
65
|
+
end
|
66
|
+
|
67
|
+
it "returns -1 for an invalid TCP address (port number is out of range)" do
|
68
|
+
rc = LibNanomsg.nn_bind(@socket, "tcp://192.168.0.1:65536")
|
69
|
+
rc.should == -1
|
70
|
+
LibNanomsg.nn_errno.should == EINVAL
|
71
|
+
end
|
72
|
+
|
73
|
+
it "returns -1 for an unsupported transport protocol" do
|
74
|
+
rc = LibNanomsg.nn_bind(@socket, "zmq://192.168.0.1:65536")
|
75
|
+
rc.should == -1
|
76
|
+
LibNanomsg.nn_errno.should == EPROTONOSUPPORT
|
77
|
+
end
|
78
|
+
|
79
|
+
it "returns -1 for specifying a non-existent device using TCP transport" do
|
80
|
+
rc = LibNanomsg.nn_bind(@socket, "tcp://eth5:5555")
|
81
|
+
rc.should == -1
|
82
|
+
LibNanomsg.nn_errno.should == ENODEV
|
83
|
+
end
|
84
|
+
|
85
|
+
it "returns -1 when binding to an existing endpoint" do
|
86
|
+
rc = LibNanomsg.nn_bind(@socket, "inproc://some_endpoint")
|
87
|
+
rc = LibNanomsg.nn_bind(@socket, "inproc://some_endpoint")
|
88
|
+
rc.should == -1
|
89
|
+
LibNanomsg.nn_errno.should == EADDRINUSE
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
context "given an invalid file descriptor" do
|
95
|
+
|
96
|
+
it "returns -1 and sets nn_errno to EBADF" do
|
97
|
+
rc = LibNanomsg.nn_bind(0, "inproc://some_endpoint")
|
98
|
+
rc.should == -1
|
99
|
+
LibNanomsg.nn_errno.should == EBADF
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module NNCore
|
4
|
+
describe "nn_close" do
|
5
|
+
|
6
|
+
context "given an unitialized library" do
|
7
|
+
before(:each) { LibNanomsg.nn_term }
|
8
|
+
|
9
|
+
it "returns -1 and sets nn_errno to EFAULT" do
|
10
|
+
LibNanomsg.nn_close(0).should == -1
|
11
|
+
LibNanomsg.nn_errno.should == EFAULT
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
context "given an initialized library and" do
|
17
|
+
before(:each) { LibNanomsg.nn_init }
|
18
|
+
after(:each) { LibNanomsg.nn_term }
|
19
|
+
|
20
|
+
context "given a valid socket" do
|
21
|
+
before(:each) { @socket = LibNanomsg.nn_socket(AF_SP, NN_PUB) }
|
22
|
+
|
23
|
+
it "returns 0" do
|
24
|
+
LibNanomsg.nn_close(@socket).should be_zero
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
context "given an invalid file descriptor" do
|
30
|
+
|
31
|
+
it "returns -1 and sets nn_errno to EBADF" do
|
32
|
+
LibNanomsg.nn_close(0).should == -1
|
33
|
+
LibNanomsg.nn_errno.should == EBADF
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# NOTE!
|
4
|
+
#
|
5
|
+
# Any specs added to this file should be mirrored in the nn_bind_spec.rb file too
|
6
|
+
# so that coverage remains complete.
|
7
|
+
#
|
8
|
+
|
9
|
+
module NNCore
|
10
|
+
describe "nn_connect" do
|
11
|
+
|
12
|
+
context "given an initialized library and" do
|
13
|
+
before(:each) { LibNanomsg.nn_init }
|
14
|
+
after(:each) { LibNanomsg.nn_term }
|
15
|
+
|
16
|
+
|
17
|
+
context "given a valid socket" do
|
18
|
+
before(:each) do
|
19
|
+
LibNanomsg.nn_init
|
20
|
+
@socket = LibNanomsg.nn_socket(AF_SP, NN_PUB)
|
21
|
+
end
|
22
|
+
|
23
|
+
after(:each) do
|
24
|
+
LibNanomsg.nn_close(@socket)
|
25
|
+
LibNanomsg.nn_term
|
26
|
+
end
|
27
|
+
|
28
|
+
it "returns a non-zero endpoint number for a valid INPROC address" do
|
29
|
+
rc = LibNanomsg.nn_connect(@socket, "inproc://some_address")
|
30
|
+
rc.should > 0
|
31
|
+
end
|
32
|
+
|
33
|
+
it "returns a non-zero endpoint number for a valid IPC address" do
|
34
|
+
rc = LibNanomsg.nn_connect(@socket, "ipc:///tmp/some_address")
|
35
|
+
rc.should > 0
|
36
|
+
end
|
37
|
+
|
38
|
+
it "returns a non-zero endpoint number for a valid TCP address" do
|
39
|
+
rc = LibNanomsg.nn_connect(@socket, "tcp://127.0.0.1:5555")
|
40
|
+
rc.should > 0
|
41
|
+
end
|
42
|
+
|
43
|
+
it "returns -1 for an invalid INPROC address" do
|
44
|
+
rc = LibNanomsg.nn_connect(@socket, "inproc:/missing_first_slash")
|
45
|
+
rc.should == -1
|
46
|
+
LibNanomsg.nn_errno.should == EINVAL
|
47
|
+
end
|
48
|
+
|
49
|
+
it "returns -1 for an invalid INPROC address (too long)" do
|
50
|
+
rc = LibNanomsg.nn_connect(@socket, "inproc://#{'a' * (NN_INPROCB_NAMELEN_MAX + 1)}")
|
51
|
+
rc.should == -1
|
52
|
+
LibNanomsg.nn_errno.should == ENAMETOOLONG
|
53
|
+
end
|
54
|
+
|
55
|
+
it "returns -1 for an invalid IPC address" do
|
56
|
+
rc = LibNanomsg.nn_connect(@socket, "ipc:/missing_slashes)")
|
57
|
+
rc.should == -1
|
58
|
+
LibNanomsg.nn_errno.should == EINVAL
|
59
|
+
end
|
60
|
+
|
61
|
+
# it "returns -1 for an invalid TCP address (missing port)" do
|
62
|
+
# rc = LibNanomsg.nn_connect(@socket, "tcp://*:")
|
63
|
+
# rc.should == -1
|
64
|
+
# LibNanomsg.nn_errno.should == EINVAL
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# it "returns -1 for an invalid TCP address (non-numeric port)" do
|
68
|
+
# rc = LibNanomsg.nn_connect(@socket, "tcp://192.168.0.1:port")
|
69
|
+
# rc.should == -1
|
70
|
+
# LibNanomsg.nn_errno.should == EINVAL
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# it "returns -1 for an invalid TCP address (port number is out of range)" do
|
74
|
+
# rc = LibNanomsg.nn_connect(@socket, "tcp://192.168.0.1:65536")
|
75
|
+
# rc.should == -1
|
76
|
+
# LibNanomsg.nn_errno.should == EINVAL
|
77
|
+
# end
|
78
|
+
|
79
|
+
it "returns -1 for an unsupported transport protocol" do
|
80
|
+
rc = LibNanomsg.nn_connect(@socket, "zmq://192.168.0.1:65536")
|
81
|
+
rc.should == -1
|
82
|
+
LibNanomsg.nn_errno.should == EPROTONOSUPPORT
|
83
|
+
end
|
84
|
+
|
85
|
+
it "returns -1 for specifying a non-existent device using TCP transport" do
|
86
|
+
pending # currently fails
|
87
|
+
rc = LibNanomsg.nn_connect(@socket, "tcp://doesntexist:5555")
|
88
|
+
rc.should == -1
|
89
|
+
LibNanomsg.nn_errno.should == ENODEV
|
90
|
+
end
|
91
|
+
|
92
|
+
it "returns 2 when connecting twice to an existing endpoint" do
|
93
|
+
rc = LibNanomsg.nn_connect(@socket, "inproc://some_endpoint")
|
94
|
+
rc = LibNanomsg.nn_connect(@socket, "inproc://some_endpoint")
|
95
|
+
rc.should == 2
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
context "given an invalid file descriptor" do
|
101
|
+
|
102
|
+
it "returns -1 and sets nn_errno to EBADF" do
|
103
|
+
rc = LibNanomsg.nn_connect(0, "inproc://some_endpoint")
|
104
|
+
rc.should == -1
|
105
|
+
LibNanomsg.nn_errno.should == EBADF
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module NNCore
|
4
|
+
describe "nn_getsockopt" do
|
5
|
+
|
6
|
+
context "given an initialized library and" do
|
7
|
+
before(:each) { LibNanomsg.nn_init }
|
8
|
+
after(:each) { LibNanomsg.nn_term }
|
9
|
+
|
10
|
+
|
11
|
+
context "given a valid socket" do
|
12
|
+
before(:each) do
|
13
|
+
LibNanomsg.nn_init
|
14
|
+
@socket = LibNanomsg.nn_socket(AF_SP, NN_PUB)
|
15
|
+
@option = FFI::MemoryPointer.new(:int32)
|
16
|
+
@size = FFI::MemoryPointer.new :size_t
|
17
|
+
@size.write_int(4)
|
18
|
+
end
|
19
|
+
|
20
|
+
after(:each) do
|
21
|
+
LibNanomsg.nn_close(@socket)
|
22
|
+
LibNanomsg.nn_term
|
23
|
+
end
|
24
|
+
|
25
|
+
it "NN_LINGER returns a default of 1000" do
|
26
|
+
rc = LibNanomsg.nn_getsockopt(@socket, NN_SOL_SOCKET, NN_LINGER, @option, @size)
|
27
|
+
rc.should == 0
|
28
|
+
@option.read_int.should == 1000
|
29
|
+
end
|
30
|
+
|
31
|
+
it "NN_SNDBUF returns a default of 128KB" do
|
32
|
+
rc = LibNanomsg.nn_getsockopt(@socket, NN_SOL_SOCKET, NN_SNDBUF, @option, @size)
|
33
|
+
rc.should == 0
|
34
|
+
@option.read_int.should == 131072
|
35
|
+
end
|
36
|
+
|
37
|
+
it "NN_RCVBUF returns a default of 128KB" do
|
38
|
+
rc = LibNanomsg.nn_getsockopt(@socket, NN_SOL_SOCKET, NN_RCVBUF, @option, @size)
|
39
|
+
rc.should == 0
|
40
|
+
@option.read_int.should == 131072
|
41
|
+
end
|
42
|
+
|
43
|
+
it "NN_SNDTIMEO returns a default of -1" do
|
44
|
+
rc = LibNanomsg.nn_getsockopt(@socket, NN_SOL_SOCKET, NN_SNDTIMEO, @option, @size)
|
45
|
+
rc.should == 0
|
46
|
+
@option.read_int.should == -1
|
47
|
+
end
|
48
|
+
|
49
|
+
it "NN_RCVTIMEO returns a default of -1" do
|
50
|
+
rc = LibNanomsg.nn_getsockopt(@socket, NN_SOL_SOCKET, NN_RCVTIMEO, @option, @size)
|
51
|
+
rc.should == 0
|
52
|
+
@option.read_int.should == -1
|
53
|
+
end
|
54
|
+
|
55
|
+
it "NN_RECONNECT_IVL returns a default of 100 (units are milliseconds)" do
|
56
|
+
rc = LibNanomsg.nn_getsockopt(@socket, NN_SOL_SOCKET, NN_RECONNECT_IVL, @option, @size)
|
57
|
+
rc.should == 0
|
58
|
+
@option.read_int.should == 100
|
59
|
+
end
|
60
|
+
|
61
|
+
it "NN_RECONNECT_IVL_MAX returns a default of 0 (units are milliseconds)" do
|
62
|
+
rc = LibNanomsg.nn_getsockopt(@socket, NN_SOL_SOCKET, NN_RECONNECT_IVL_MAX, @option, @size)
|
63
|
+
rc.should == 0
|
64
|
+
@option.read_int.should == 0
|
65
|
+
end
|
66
|
+
|
67
|
+
it "NN_SNDPRIO returns a default of 8" do
|
68
|
+
rc = LibNanomsg.nn_getsockopt(@socket, NN_SOL_SOCKET, NN_SNDPRIO, @option, @size)
|
69
|
+
rc.should == 0
|
70
|
+
@option.read_int.should == 8
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
context "given an unsupported socket level" do
|
75
|
+
|
76
|
+
SOCKET_OPTIONS.keys.each do |socket_option|
|
77
|
+
it "socket option #{socket_option} returns -1 and set nn_errno to EBADF" do
|
78
|
+
option = FFI::MemoryPointer.new(:int32)
|
79
|
+
size = FFI::MemoryPointer.new :size_t
|
80
|
+
size.write_int(4)
|
81
|
+
|
82
|
+
rc = LibNanomsg.nn_getsockopt(@socket, 100, SOCKET_OPTIONS[socket_option], option, size)
|
83
|
+
rc.should == -1
|
84
|
+
LibNanomsg.nn_errno.should == ENOPROTOOPT
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
context "given a bad socket file descriptor" do
|
93
|
+
|
94
|
+
SOCKET_OPTIONS.keys.each do |socket_option|
|
95
|
+
it "socket option #{socket_option} returns -1 and set nn_errno to EBADF" do
|
96
|
+
option = FFI::MemoryPointer.new(:int32)
|
97
|
+
size = FFI::MemoryPointer.new :size_t
|
98
|
+
size.write_int(4)
|
99
|
+
|
100
|
+
rc = LibNanomsg.nn_getsockopt(0, NN_SOL_SOCKET, SOCKET_OPTIONS[socket_option], option, size)
|
101
|
+
rc.should == -1
|
102
|
+
LibNanomsg.nn_errno.should == EBADF
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module NNCore
|
4
|
+
describe "nn_recv" do
|
5
|
+
|
6
|
+
context "given an initialized library and" do
|
7
|
+
before(:each) { LibNanomsg.nn_init }
|
8
|
+
after(:each) { LibNanomsg.nn_term }
|
9
|
+
|
10
|
+
|
11
|
+
context "given a valid connected sender and receiver socket pair" do
|
12
|
+
before(:each) do
|
13
|
+
LibNanomsg.nn_init
|
14
|
+
@socket = LibNanomsg.nn_socket(AF_SP, NN_PAIR)
|
15
|
+
@sender = LibNanomsg.nn_socket(AF_SP, NN_PAIR)
|
16
|
+
@endpoint = LibNanomsg.nn_bind(@socket, "inproc://some_endpoint")
|
17
|
+
LibNanomsg.nn_connect(@sender, "inproc://some_endpoint")
|
18
|
+
end
|
19
|
+
|
20
|
+
after(:each) do
|
21
|
+
LibNanomsg.nn_close(@socket)
|
22
|
+
LibNanomsg.nn_close(@sender)
|
23
|
+
LibNanomsg.nn_term
|
24
|
+
end
|
25
|
+
|
26
|
+
context "given a pre-allocated buffer" do
|
27
|
+
|
28
|
+
it "returns the number of bytes received" do
|
29
|
+
string = "ABC"
|
30
|
+
LibNanomsg.nn_send(@sender, string, string.size, 0)
|
31
|
+
|
32
|
+
buffer = FFI::MemoryPointer.new(5)
|
33
|
+
nbytes = LibNanomsg.nn_recv(@socket, buffer, 5, 0)
|
34
|
+
nbytes.should == 3
|
35
|
+
buffer.read_string.should == string
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "given no pre-allocated buffer" do
|
40
|
+
|
41
|
+
|
42
|
+
it "returns the number of bytes received and returns the buffer" do
|
43
|
+
string = "ABC"
|
44
|
+
LibNanomsg.nn_send(@sender, string, string.size, 0)
|
45
|
+
|
46
|
+
buffer = FFI::MemoryPointer.new(:pointer)
|
47
|
+
nbytes = LibNanomsg.nn_recv(@socket, buffer, NN_MSG, 0)
|
48
|
+
nbytes.should == 3
|
49
|
+
buffer.get_pointer(0).read_string.should == string
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "given an invalid socket" do
|
55
|
+
|
56
|
+
it "returns -1 and sets nn_errno to EBADF" do
|
57
|
+
rc = LibNanomsg.nn_send(0, "ABC", 3, 0)
|
58
|
+
rc.should == -1
|
59
|
+
LibNanomsg.nn_errno.should == EBADF
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module NNCore
|
4
|
+
describe "nn_send" do
|
5
|
+
|
6
|
+
context "given an initialized library and" do
|
7
|
+
before(:each) { LibNanomsg.nn_init }
|
8
|
+
after(:each) { LibNanomsg.nn_term }
|
9
|
+
|
10
|
+
|
11
|
+
context "given a valid socket" do
|
12
|
+
before(:each) do
|
13
|
+
LibNanomsg.nn_init
|
14
|
+
@socket = LibNanomsg.nn_socket(AF_SP, NN_PUB)
|
15
|
+
end
|
16
|
+
|
17
|
+
after(:each) do
|
18
|
+
LibNanomsg.nn_close(@socket)
|
19
|
+
LibNanomsg.nn_term
|
20
|
+
end
|
21
|
+
|
22
|
+
context "given a valid endpoint" do
|
23
|
+
before(:each) do
|
24
|
+
@endpoint = LibNanomsg.nn_bind(@socket, "inproc://some_endpoint")
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns the number of bytes sent" do
|
28
|
+
nbytes = LibNanomsg.nn_send(@socket, "ABC", 3, 0)
|
29
|
+
nbytes.should == 3
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "disconnected from all endpoints" do
|
34
|
+
it "returns the number of bytes queued" do
|
35
|
+
nbytes = LibNanomsg.nn_send(@socket, "ABC", 3, 0)
|
36
|
+
nbytes.should == 3
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "given an invalid socket" do
|
42
|
+
|
43
|
+
it "returns -1 and sets nn_errno to EBADF" do
|
44
|
+
rc = LibNanomsg.nn_send(0, "ABC", 3, 0)
|
45
|
+
rc.should == -1
|
46
|
+
LibNanomsg.nn_errno.should == EBADF
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module NNCore
|
4
|
+
describe "nn_setsockopt" do
|
5
|
+
|
6
|
+
context "given an initialized library and" do
|
7
|
+
before(:each) { LibNanomsg.nn_init }
|
8
|
+
after(:each) { LibNanomsg.nn_term }
|
9
|
+
|
10
|
+
|
11
|
+
context "given a valid socket" do
|
12
|
+
before(:each) do
|
13
|
+
LibNanomsg.nn_init
|
14
|
+
@socket = LibNanomsg.nn_socket(AF_SP, NN_PUB)
|
15
|
+
@option = FFI::MemoryPointer.new(:int32)
|
16
|
+
@size = FFI::MemoryPointer.new :size_t
|
17
|
+
@size.write_int(4)
|
18
|
+
end
|
19
|
+
|
20
|
+
after(:each) do
|
21
|
+
LibNanomsg.nn_close(@socket)
|
22
|
+
LibNanomsg.nn_term
|
23
|
+
end
|
24
|
+
|
25
|
+
SOCKET_OPTIONS.keys.each do |socket_option|
|
26
|
+
|
27
|
+
it "#{socket_option} overrides the default" do
|
28
|
+
@option.write_int(10)
|
29
|
+
rc = LibNanomsg.nn_setsockopt(@socket, NN_SOL_SOCKET, SOCKET_OPTIONS[socket_option], @option, 4)
|
30
|
+
rc.should == 0
|
31
|
+
rc = LibNanomsg.nn_getsockopt(@socket, NN_SOL_SOCKET, SOCKET_OPTIONS[socket_option], @option, @size)
|
32
|
+
rc.should == 0
|
33
|
+
|
34
|
+
@option.read_int.should == 10
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
context "given an unsupported socket level" do
|
40
|
+
|
41
|
+
SOCKET_OPTIONS.keys.each do |socket_option|
|
42
|
+
it "socket option #{socket_option} returns -1 and set nn_errno to EBADF" do
|
43
|
+
option = FFI::MemoryPointer.new(:int32)
|
44
|
+
|
45
|
+
rc = LibNanomsg.nn_setsockopt(@socket, 100, SOCKET_OPTIONS[socket_option], option, 4)
|
46
|
+
rc.should == -1
|
47
|
+
LibNanomsg.nn_errno.should == ENOPROTOOPT
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
context "given a bad socket file descriptor" do
|
56
|
+
|
57
|
+
SOCKET_OPTIONS.keys.each do |socket_option|
|
58
|
+
it "socket option #{socket_option} returns -1 and set nn_errno to EBADF" do
|
59
|
+
option = FFI::MemoryPointer.new(:int32)
|
60
|
+
size = FFI::MemoryPointer.new :size_t
|
61
|
+
size.write_int(4)
|
62
|
+
|
63
|
+
rc = LibNanomsg.nn_getsockopt(0, NN_SOL_SOCKET, SOCKET_OPTIONS[socket_option], option, size)
|
64
|
+
rc.should == -1
|
65
|
+
LibNanomsg.nn_errno.should == EBADF
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module NNCore
|
4
|
+
describe "nn_shutdown" do
|
5
|
+
|
6
|
+
context "given an initialized library and" do
|
7
|
+
before(:each) { LibNanomsg.nn_init }
|
8
|
+
after(:each) { LibNanomsg.nn_term }
|
9
|
+
|
10
|
+
|
11
|
+
context "given a valid socket and" do
|
12
|
+
before(:each) do
|
13
|
+
LibNanomsg.nn_init
|
14
|
+
@socket = LibNanomsg.nn_socket(AF_SP, NN_PUB)
|
15
|
+
end
|
16
|
+
|
17
|
+
after(:each) do
|
18
|
+
LibNanomsg.nn_close(@socket)
|
19
|
+
LibNanomsg.nn_term
|
20
|
+
end
|
21
|
+
|
22
|
+
context "given a valid endpoint" do
|
23
|
+
before(:each) do
|
24
|
+
@endpoint = LibNanomsg.nn_bind(@socket, "inproc://some_endpoint")
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns 0" do
|
28
|
+
rc = LibNanomsg.nn_shutdown(@socket, @endpoint)
|
29
|
+
rc.should == 0
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "given an invalid endpoint" do
|
34
|
+
it "returns -1 and set nn_errno to EINVAL" do
|
35
|
+
rc = LibNanomsg.nn_shutdown(@socket, 0)
|
36
|
+
rc.should == -1
|
37
|
+
LibNanomsg.nn_errno.should == EINVAL
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "given an invalid socket" do
|
43
|
+
|
44
|
+
it "returns -1 and sets nn_errno to EBADF" do
|
45
|
+
rc = LibNanomsg.nn_shutdown(0, 0)
|
46
|
+
rc.should == -1
|
47
|
+
LibNanomsg.nn_errno.should == EBADF
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module NNCore
|
4
|
+
describe "nn_socket" do
|
5
|
+
|
6
|
+
context "given an initialized library and" do
|
7
|
+
before(:each) { LibNanomsg.nn_init }
|
8
|
+
after(:each) { LibNanomsg.nn_term }
|
9
|
+
|
10
|
+
PROTOCOLS.keys.each do |protocol|
|
11
|
+
|
12
|
+
context "given a supported protocol #{protocol} and address family AF_SP" do
|
13
|
+
|
14
|
+
it "returns a non-zero file descriptor for the socket" do
|
15
|
+
@socket = LibNanomsg.nn_socket(AF_SP, PROTOCOLS[protocol])
|
16
|
+
|
17
|
+
@socket.should == 0
|
18
|
+
|
19
|
+
LibNanomsg.nn_close(@socket)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "given a supported protocol #{protocol} and address family AF_SP_RAW" do
|
24
|
+
|
25
|
+
it "returns -1 and sets nn_errno to EINVAL" do
|
26
|
+
@socket = LibNanomsg.nn_socket(AF_SP_RAW, PROTOCOLS[protocol])
|
27
|
+
|
28
|
+
@socket.should == -1
|
29
|
+
LibNanomsg.nn_errno.should == EINVAL
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
context "given an unsupported address family" do
|
36
|
+
|
37
|
+
# it "nn_socket returns -1 and sets nn_errno to EAFNOSUPPORT" do
|
38
|
+
# LibNanomsg.nn_socket(0, NN_PUB).should == -1
|
39
|
+
# LibNanomsg.nn_errno.should == EAFNOSUPPORT
|
40
|
+
# end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "given an unsupported protocol and a supported address family" do
|
44
|
+
|
45
|
+
it "AF_SP returns -1 and sets nn_errno to EINVAL" do
|
46
|
+
LibNanomsg.nn_socket(AF_SP, 0).should == -1
|
47
|
+
LibNanomsg.nn_errno.should == EINVAL
|
48
|
+
end
|
49
|
+
|
50
|
+
it "AF_SP_RAW returns -1 and sets nn_errno to EINVAL" do
|
51
|
+
LibNanomsg.nn_socket(AF_SP_RAW, 0).should == -1
|
52
|
+
LibNanomsg.nn_errno.should == EINVAL
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module NNCore
|
4
|
+
describe "nn_term" do
|
5
|
+
|
6
|
+
context "given an initialized library and" do
|
7
|
+
before(:each) { LibNanomsg.nn_init }
|
8
|
+
after(:each) { LibNanomsg.nn_term }
|
9
|
+
|
10
|
+
it "returns 0 for successful library termination" do
|
11
|
+
LibNanomsg.nn_term.should be_zero
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module NNCore
|
4
|
+
describe "nn_bind" do
|
5
|
+
|
6
|
+
context "given an initialized library" do
|
7
|
+
before(:each) { LibNanomsg.nn_init }
|
8
|
+
after(:each) { LibNanomsg.nn_term }
|
9
|
+
|
10
|
+
it "returns 0 and populates the pointers with the major, minor and patch version numbers" do
|
11
|
+
major = FFI::MemoryPointer.new(:int)
|
12
|
+
minor = FFI::MemoryPointer.new(:int)
|
13
|
+
patch = FFI::MemoryPointer.new(:int)
|
14
|
+
|
15
|
+
# there is no return value for this function
|
16
|
+
LibNanomsg.nn_version(major, minor, patch)
|
17
|
+
|
18
|
+
major.read_int.should >= 0
|
19
|
+
minor.read_int.should >= 0
|
20
|
+
patch.read_int.should >= 0
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'nn-core'
|
3
|
+
|
4
|
+
module NNCore
|
5
|
+
SOCKET_OPTIONS = {
|
6
|
+
:NN_LINGER => NN_LINGER,
|
7
|
+
:NN_SNDBUF => NN_SNDBUF,
|
8
|
+
:NN_RCVBUF => NN_RCVBUF,
|
9
|
+
:NN_SENDTIMEO => NN_SNDTIMEO,
|
10
|
+
:NN_RCVTIMEO => NN_RCVTIMEO,
|
11
|
+
:NN_RECONNECT_IVL => NN_RECONNECT_IVL,
|
12
|
+
:NN_RECONNECT_IVL_MAX => NN_RECONNECT_IVL_MAX,
|
13
|
+
:NN_SNDPRIO => NN_SNDPRIO
|
14
|
+
}
|
15
|
+
|
16
|
+
PROTOCOLS = {
|
17
|
+
:NN_PUB => NN_PUB,
|
18
|
+
:NN_SUB => NN_SUB
|
19
|
+
}
|
20
|
+
|
21
|
+
ADDRESS_FAMILIES = {
|
22
|
+
:AF_SP => AF_SP,
|
23
|
+
:AF_SP_RAW => AF_SP_RAW
|
24
|
+
}
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nn-core
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Chuck Remes
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-04 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
prerelease: false
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ! '>='
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
none: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
none: false
|
28
|
+
name: ffi
|
29
|
+
type: :runtime
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
prerelease: false
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ~>
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '2.6'
|
37
|
+
none: false
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ~>
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '2.6'
|
43
|
+
none: false
|
44
|
+
name: rspec
|
45
|
+
type: :development
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
prerelease: false
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ! '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
none: false
|
54
|
+
version_requirements: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
none: false
|
60
|
+
name: rake
|
61
|
+
type: :development
|
62
|
+
description: ! 'Wraps the nanomsg networking library using the ruby FFI (foreign
|
63
|
+
|
64
|
+
function interface). It only exposes the native C API to Ruby. Other gems should
|
65
|
+
use this gem
|
66
|
+
|
67
|
+
to build an API using Ruby idioms.'
|
68
|
+
email:
|
69
|
+
- git@chuckremes.com
|
70
|
+
executables: []
|
71
|
+
extensions: []
|
72
|
+
extra_rdoc_files: []
|
73
|
+
files:
|
74
|
+
- !binary |-
|
75
|
+
LmdpdGlnbm9yZQ==
|
76
|
+
- !binary |-
|
77
|
+
LnJzcGVj
|
78
|
+
- !binary |-
|
79
|
+
QXV0aG9ycy50eHQ=
|
80
|
+
- !binary |-
|
81
|
+
R2VtZmlsZQ==
|
82
|
+
- !binary |-
|
83
|
+
SGlzdG9yeS50eHQ=
|
84
|
+
- !binary |-
|
85
|
+
UkVBRE1FLm1k
|
86
|
+
- !binary |-
|
87
|
+
UmFrZWZpbGU=
|
88
|
+
- !binary |-
|
89
|
+
bGliL25uLWNvcmUucmI=
|
90
|
+
- !binary |-
|
91
|
+
bGliL25uLWNvcmUvY29uc3RhbnRzLnJi
|
92
|
+
- !binary |-
|
93
|
+
bGliL25uLWNvcmUvbGlibmFub21zZy5yYg==
|
94
|
+
- !binary |-
|
95
|
+
bGliL25uLWNvcmUvc3RydWN0cy5yYg==
|
96
|
+
- !binary |-
|
97
|
+
bGliL25uLWNvcmUvdmVyc2lvbi5yYg==
|
98
|
+
- !binary |-
|
99
|
+
bm4tY29yZS5nZW1zcGVj
|
100
|
+
- !binary |-
|
101
|
+
c3BlYy9ubl9iaW5kX3NwZWMucmI=
|
102
|
+
- !binary |-
|
103
|
+
c3BlYy9ubl9jbG9zZV9zcGVjLnJi
|
104
|
+
- !binary |-
|
105
|
+
c3BlYy9ubl9jb25uZWN0X3NwZWMucmI=
|
106
|
+
- !binary |-
|
107
|
+
c3BlYy9ubl9nZXRzb2Nrb3B0X3NwZWMucmI=
|
108
|
+
- !binary |-
|
109
|
+
c3BlYy9ubl9pbml0X3NwZWMucmI=
|
110
|
+
- !binary |-
|
111
|
+
c3BlYy9ubl9yZWN2X3NwZWMucmI=
|
112
|
+
- !binary |-
|
113
|
+
c3BlYy9ubl9zZW5kX3NwZWMucmI=
|
114
|
+
- !binary |-
|
115
|
+
c3BlYy9ubl9zZXRzb2Nrb3B0X3NwZWMucmI=
|
116
|
+
- !binary |-
|
117
|
+
c3BlYy9ubl9zaHV0ZG93bl9zcGVjLnJi
|
118
|
+
- !binary |-
|
119
|
+
c3BlYy9ubl9zb2NrZXRfc3BlYy5yYg==
|
120
|
+
- !binary |-
|
121
|
+
c3BlYy9ubl90ZXJtX3NwZWMucmI=
|
122
|
+
- !binary |-
|
123
|
+
c3BlYy9ubl92ZXJzaW9uX3NwZWMucmI=
|
124
|
+
- !binary |-
|
125
|
+
c3BlYy9zcGVjX2hlbHBlci5yYg==
|
126
|
+
homepage: http://github.com/chuckremes/nn-core
|
127
|
+
licenses: []
|
128
|
+
post_install_message:
|
129
|
+
rdoc_options: []
|
130
|
+
require_paths:
|
131
|
+
- lib
|
132
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - ! '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
none: false
|
138
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
140
|
+
- - ! '>='
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
none: false
|
144
|
+
requirements: []
|
145
|
+
rubyforge_project: nn-core
|
146
|
+
rubygems_version: 1.8.24
|
147
|
+
signing_key:
|
148
|
+
specification_version: 3
|
149
|
+
summary: Wraps the nanomsg networking library using Ruby FFI (foreign function interface).
|
150
|
+
test_files:
|
151
|
+
- !binary |-
|
152
|
+
c3BlYy9ubl9iaW5kX3NwZWMucmI=
|
153
|
+
- !binary |-
|
154
|
+
c3BlYy9ubl9jbG9zZV9zcGVjLnJi
|
155
|
+
- !binary |-
|
156
|
+
c3BlYy9ubl9jb25uZWN0X3NwZWMucmI=
|
157
|
+
- !binary |-
|
158
|
+
c3BlYy9ubl9nZXRzb2Nrb3B0X3NwZWMucmI=
|
159
|
+
- !binary |-
|
160
|
+
c3BlYy9ubl9pbml0X3NwZWMucmI=
|
161
|
+
- !binary |-
|
162
|
+
c3BlYy9ubl9yZWN2X3NwZWMucmI=
|
163
|
+
- !binary |-
|
164
|
+
c3BlYy9ubl9zZW5kX3NwZWMucmI=
|
165
|
+
- !binary |-
|
166
|
+
c3BlYy9ubl9zZXRzb2Nrb3B0X3NwZWMucmI=
|
167
|
+
- !binary |-
|
168
|
+
c3BlYy9ubl9zaHV0ZG93bl9zcGVjLnJi
|
169
|
+
- !binary |-
|
170
|
+
c3BlYy9ubl9zb2NrZXRfc3BlYy5yYg==
|
171
|
+
- !binary |-
|
172
|
+
c3BlYy9ubl90ZXJtX3NwZWMucmI=
|
173
|
+
- !binary |-
|
174
|
+
c3BlYy9ubl92ZXJzaW9uX3NwZWMucmI=
|
175
|
+
- !binary |-
|
176
|
+
c3BlYy9zcGVjX2hlbHBlci5yYg==
|