corosync 0.0.3 → 0.1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,28 @@
1
+ require 'ffi'
2
+
3
+ # We create these 2 methods because of types like `size_t`. The type changes by platform, so we don't know which write/read method to use. So we create a generic read/write that we can pass a type to and it will figure out which method needs to be used.
4
+
5
+ class FFI::Pointer
6
+ def read_type(type)
7
+ type = FFI.find_type(type) if type.is_a?(Symbol)
8
+ type = type.native_type if type.is_a?(FFI::Type::Mapped)
9
+ raise ArgumentError, "Can only read built-in types (type=#{type})" unless type.is_a?(FFI::Type::Builtin)
10
+ name = type.inspect.match(/<#{type.class}:(\S+)/)[1].downcase
11
+ method = "read_#{name}".to_sym
12
+ self.send(method)
13
+ end
14
+ def write_type(type, value)
15
+ type = FFI.find_type(type) if type.is_a?(Symbol)
16
+ type = type.native_type if type.is_a?(FFI::Type::Mapped)
17
+ raise ArgumentError, "Can only write built-in types (type=#{type})" unless type.is_a?(FFI::Type::Builtin)
18
+ name = type.inspect.match(/<#{type.class}:(\S+)/)[1].downcase
19
+ method = "write_#{name}".to_sym
20
+ self.send(method, value)
21
+ end
22
+
23
+ # these are methods where the type name doesn't match the method
24
+ alias_method :write_float32, :write_float
25
+ alias_method :read_float32, :read_float
26
+ alias_method :write_float64, :write_double
27
+ alias_method :read_float64, :read_double
28
+ end
@@ -0,0 +1,99 @@
1
+ require 'spec_helper'
2
+ require 'timeout'
3
+
4
+ require 'corosync/cmap'
5
+ describe Corosync::CMAP do
6
+ before(:all) do
7
+ @cmap = Corosync::CMAP.new
8
+ @cmap.connect
9
+ end
10
+
11
+ around :each do |example|
12
+ Timeout::timeout(1) do
13
+ example.run
14
+ end
15
+ end
16
+
17
+ Corosync::CMAP::SIZEMAP.each do |type, info|
18
+ it "can set a #{type}" do
19
+ expect{@cmap.set("test.#{type}", type, info.max)}.to_not raise_error
20
+ end
21
+ it "can get a #{type}" do
22
+ expect(@cmap.get("test.#{type}")).to eq([type, info.max])
23
+ end
24
+ end
25
+ it 'can set a float' do
26
+ expect{@cmap.set('test.float', :float, 1234.4321)}.to_not raise_error
27
+ end
28
+ it 'can get a float' do
29
+ type, value = @cmap.get('test.float')
30
+ expect(type).to eq(:float)
31
+ expect(value).to be_within(0.00005).of(1234.4321)
32
+ end
33
+ it 'can set a double' do
34
+ expect{@cmap.set('test.double', :double, 12345.54321)}.to_not raise_error
35
+ end
36
+ it 'can get a double' do
37
+ type, value = @cmap.get('test.double')
38
+ expect(type).to eq(:double)
39
+ expect(value).to be_within(0.000005).of(12345.54321)
40
+ end
41
+ it 'cat set a string' do
42
+ expect{@cmap.set("test.string", :string, 'xyzzy')}.to_not raise_error
43
+ end
44
+ it 'can get a string' do
45
+ expect(@cmap.get("test.string")).to eq([:string, 'xyzzy'])
46
+ end
47
+
48
+ it 'can increment a value' do
49
+ @cmap.set('test.inc', :int32, 100)
50
+ expect{@cmap.inc('test.inc')}.to_not raise_error
51
+ expect(@cmap.get('test.inc')).to eq([:int32, 101])
52
+ end
53
+
54
+ it 'can decrement a value' do
55
+ @cmap.set('test.dec', :int32, 100)
56
+ expect{@cmap.dec('test.dec')}.to_not raise_error
57
+ expect(@cmap.get('test.dec')).to eq([:int32, 99])
58
+ end
59
+
60
+ it 'can delete a value' do
61
+ expect{@cmap.delete('test.string')}.to_not raise_error
62
+ expect{@cmap.get('test.string')}.to raise_error
63
+ end
64
+
65
+ it 'can list keys' do
66
+ keys = @cmap.keys
67
+
68
+ expect(keys).to be_a(Array)
69
+ keys.each do |key|
70
+ expect(key).to be_a(String)
71
+ end
72
+ end
73
+
74
+ it 'can track a value' do
75
+ @cmap.delete('test.track') rescue Exception
76
+
77
+ events = []
78
+ track_id = @cmap.track_add('test.track', [:add, :delete, :modify]) do |*args|
79
+ events << args
80
+ end
81
+
82
+ @cmap.set('test.track', :uint32, 1234)
83
+ @cmap.dispatch
84
+ @cmap.set('test.track', :int32, 1235)
85
+ @cmap.dispatch
86
+ @cmap.delete('test.track')
87
+ @cmap.dispatch
88
+
89
+ expect(events).to eq([
90
+ [:add, 'test.track', :uint32, 1234, nil, nil],
91
+ [:modify, 'test.track', :int32, 1235, :uint32, 1234],
92
+ [:delete, 'test.track', nil, nil, :int32, 1235]
93
+ ])
94
+
95
+ @cmap.track_delete(track_id)
96
+ @cmap.set('test.track', :uint32, 1236)
97
+ expect{@cmap.dispatch}.to raise_error # our timeout defined at the top should kick in
98
+ end
99
+ end
data/spec/corosync/cpg.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
+ require 'corosync/cpg'
3
4
  describe Corosync::CPG do
4
5
  context '#initialize offline' do
5
6
  before(:all) do
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ require 'corosync/quorum'
4
+ describe Corosync::Quorum do
5
+ context '#initialize offline' do
6
+ before(:all) do
7
+ @quorum = Corosync::Quorum.new
8
+ end
9
+
10
+ it 'creates a Quorum object' do
11
+ expect(@quorum).to be_an_instance_of(Corosync::Quorum)
12
+ expect(@quorum.fd).to be_nil
13
+ end
14
+
15
+ it 'connects' do
16
+ have_callback = false
17
+ @quorum.on_notify do
18
+ have_callback = true
19
+ end
20
+
21
+ @quorum.start(true)
22
+
23
+ expect(@quorum.fd).to be_an_instance_of(IO)
24
+ expect(have_callback).to be_true
25
+ end
26
+ end
27
+
28
+ context '#initialize with connect' do
29
+ before(:all) do
30
+ @quorum = Corosync::Quorum.new(true)
31
+ end
32
+
33
+ it 'connects' do
34
+ expect(@quorum).to be_an_instance_of(Corosync::Quorum)
35
+ expect(@quorum.fd).to_not be_nil
36
+ end
37
+
38
+ it 'gets quorum state' do
39
+ expect([TrueClass,FalseClass]).to include(@quorum.quorate?.class)
40
+ end
41
+
42
+ it 'responds to inquorate change' do
43
+ is_quorate = nil
44
+ @quorum.on_notify {|quorate| is_quorate = quorate}
45
+
46
+ handle = @quorum.instance_variable_get(:@handle)
47
+ view_list = FFI::MemoryPointer.new(FFI.find_type(:uint32), 1)
48
+ view_list.write_array_of_type(FFI.find_type(:uint32), :write_uint32, [1])
49
+ @quorum.send(:callback_notify, handle, 0, nil, 1, view_list)
50
+
51
+ expect(is_quorate).to eq(false)
52
+ end
53
+
54
+ it 'responds to quorate change' do
55
+ is_quorate = nil
56
+ @quorum.on_notify {|quorate| is_quorate = quorate}
57
+
58
+ handle = @quorum.instance_variable_get(:@handle)
59
+ view_list = FFI::MemoryPointer.new(FFI.find_type(:uint32), 2)
60
+ view_list.write_array_of_type(FFI.find_type(:uint32), :write_uint32, [1,2])
61
+ @quorum.send(:callback_notify, handle, 1, nil, 1, view_list)
62
+
63
+ expect(is_quorate).to eq(true)
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ require 'corosync/votequorum'
4
+ describe Corosync::Votequorum do
5
+ context '#initialize offline' do
6
+ before(:all) do
7
+ @vq = Corosync::Votequorum.new
8
+ end
9
+
10
+ it 'creates a Votequorum object' do
11
+ expect(@vq).to be_an_instance_of(Corosync::Votequorum)
12
+ expect(@vq.fd).to be_nil
13
+ end
14
+
15
+ it 'connects' do
16
+ have_callback = false
17
+ @vq.on_notify do
18
+ have_callback = true
19
+ end
20
+
21
+ @vq.start(true)
22
+
23
+ expect(@vq.fd).to be_an_instance_of(IO)
24
+ expect(have_callback).to be_true
25
+ end
26
+ end
27
+
28
+ context '#initialize with connect' do
29
+ before(:all) do
30
+ @vq = Corosync::Votequorum.new(true)
31
+ end
32
+
33
+ it 'connects' do
34
+ expect(@vq).to be_an_instance_of(Corosync::Votequorum)
35
+ expect(@vq.fd).to_not be_nil
36
+ end
37
+
38
+ it 'gets quorum state' do
39
+ expect([TrueClass,FalseClass]).to include(@vq.quorate?.class)
40
+ end
41
+
42
+ it 'responds to inquorate change' do
43
+ is_quorate = nil
44
+ @vq.on_notify {|quorate| is_quorate = quorate}
45
+
46
+ handle = @vq.instance_variable_get(:@handle)
47
+ node_states = {
48
+ 1 => Corosync::VOTEQUORUM_NODESTATE_DEAD,
49
+ }
50
+ node_list = FFI::MemoryPointer.new(Corosync::VotequorumNodeT, node_states.size)
51
+ node_states.to_a.each_with_index do |node_state, i|
52
+ node = Corosync::VotequorumNodeT.new(node_list + i * Corosync::VotequorumNodeT.size)
53
+ node[:nodeid] = node_state[0]
54
+ node[:state] = node_state[1]
55
+ end
56
+ @vq.send(:callback_notify, handle, nil, 0, node_states.size, node_list)
57
+
58
+ expect(is_quorate).to eq(false)
59
+ end
60
+
61
+ it 'responds to quorate change' do
62
+ is_quorate = nil
63
+ @vq.on_notify {|quorate| is_quorate = quorate}
64
+
65
+ handle = @vq.instance_variable_get(:@handle)
66
+ node_states = {
67
+ 1 => Corosync::VOTEQUORUM_NODESTATE_MEMBER,
68
+ 2 => Corosync::VOTEQUORUM_NODESTATE_MEMBER,
69
+ }
70
+ node_list = FFI::MemoryPointer.new(Corosync::VotequorumNodeT, node_states.size)
71
+ node_states.to_a.each_with_index do |node_state, i|
72
+ node = Corosync::VotequorumNodeT.new(node_list + i * Corosync::VotequorumNodeT.size)
73
+ node[:nodeid] = node_state[0]
74
+ node[:state] = node_state[1]
75
+ end
76
+ @vq.send(:callback_notify, handle, nil, 1, node_states.size, node_list)
77
+
78
+ expect(is_quorate).to eq(true)
79
+ end
80
+ end
81
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,2 +1,2 @@
1
1
  # we have to use the full path because rspec puts itself higher on the list, and we end up requiring `spec/corosync/cpg`
2
- require File.expand_path('../../lib/corosync/cpg', __FILE__)
2
+ $:.unshift(File.expand_path('../../lib', __FILE__))
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: corosync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrick Hemmer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-06 00:00:00.000000000 Z
11
+ date: 2014-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -36,21 +36,37 @@ files:
36
36
  - LICENSE
37
37
  - README.md
38
38
  - Rakefile
39
+ - VERSION
39
40
  - corosync.gemspec
40
- - examples/example.rb
41
+ - examples/cmap-cli.rb
42
+ - examples/cpg-chat.rb
43
+ - examples/cpg-monitor.rb
44
+ - ffi/cmap.i
45
+ - ffi/cmap.rb
41
46
  - ffi/common.i
42
47
  - ffi/common.rb
43
48
  - ffi/cpg.i
44
49
  - ffi/cpg.rb
50
+ - ffi/quorum.i
51
+ - ffi/quorum.rb
45
52
  - ffi/service.i.erb
53
+ - ffi/votequorum.i
54
+ - ffi/votequorum.rb
46
55
  - lib/corosync.rb
56
+ - lib/corosync/cmap.rb
47
57
  - lib/corosync/cpg.rb
48
58
  - lib/corosync/cpg/member.rb
49
59
  - lib/corosync/cpg/member_list.rb
50
- - lib/version.rb
60
+ - lib/corosync/exceptions.rb
61
+ - lib/corosync/quorum.rb
62
+ - lib/corosync/votequorum.rb
63
+ - lib/ffi_pointer.rb
64
+ - spec/corosync/cmap.rb
51
65
  - spec/corosync/cpg.rb
52
66
  - spec/corosync/cpg/member.rb
53
67
  - spec/corosync/cpg/member_list.rb
68
+ - spec/corosync/quorum.rb
69
+ - spec/corosync/votequorum.rb
54
70
  - spec/spec_helper.rb
55
71
  homepage: http://github.com/phemmer/ruby-corosync/
56
72
  licenses:
data/lib/version.rb DELETED
@@ -1,3 +0,0 @@
1
- module Corosync
2
- GEM_VERSION = '0.0.3'
3
- end