nn-core 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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==
|