omf_common 6.0.0.pre.10 → 6.0.0.pre.11
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/monitor_topic.rb +80 -0
- data/bin/send_create.rb +94 -0
- data/bin/send_request.rb +58 -0
- data/example/engine_alt.rb +136 -0
- data/example/vm_alt.rb +65 -0
- data/lib/omf_common.rb +224 -3
- data/lib/omf_common/comm.rb +113 -46
- data/lib/omf_common/comm/amqp/amqp_communicator.rb +76 -0
- data/lib/omf_common/comm/amqp/amqp_topic.rb +91 -0
- data/lib/omf_common/comm/local/local_communicator.rb +64 -0
- data/lib/omf_common/comm/local/local_topic.rb +42 -0
- data/lib/omf_common/comm/topic.rb +190 -0
- data/lib/omf_common/{dsl/xmpp.rb → comm/xmpp/communicator.rb} +93 -53
- data/lib/omf_common/comm/xmpp/topic.rb +147 -0
- data/lib/omf_common/{dsl → comm/xmpp}/xmpp_mp.rb +2 -0
- data/lib/omf_common/eventloop.rb +94 -0
- data/lib/omf_common/eventloop/em.rb +57 -0
- data/lib/omf_common/eventloop/local_evl.rb +78 -0
- data/lib/omf_common/message.rb +112 -229
- data/lib/omf_common/message/json/json_message.rb +129 -0
- data/lib/omf_common/message/xml/message.rb +410 -0
- data/lib/omf_common/message/xml/relaxng_schema.rb +17 -0
- data/lib/omf_common/message/xml/topic_message.rb +20 -0
- data/lib/omf_common/protocol/6.0.rnc +11 -21
- data/lib/omf_common/protocol/6.0.rng +52 -119
- data/lib/omf_common/version.rb +1 -1
- data/omf_common.gemspec +4 -2
- data/test/fixture/pubsub.rb +19 -19
- data/test/omf_common/{dsl/xmpp_spec.rb → comm/xmpp/communicator_spec.rb} +47 -111
- data/test/omf_common/comm/xmpp/topic_spec.rb +113 -0
- data/test/omf_common/comm_spec.rb +1 -0
- data/test/omf_common/message/xml/message_spec.rb +136 -0
- data/test/omf_common/message_spec.rb +37 -131
- data/test/test_helper.rb +4 -1
- metadata +38 -28
- data/lib/omf_common/core_ext/object.rb +0 -21
- data/lib/omf_common/relaxng_schema.rb +0 -17
- data/lib/omf_common/topic.rb +0 -34
- data/lib/omf_common/topic_message.rb +0 -20
- data/test/omf_common/topic_message_spec.rb +0 -114
- data/test/omf_common/topic_spec.rb +0 -75
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'fixture/pubsub'
|
2
|
+
require 'em/minitest/spec'
|
3
|
+
|
4
|
+
require 'omf_common/comm/xmpp/topic'
|
5
|
+
|
6
|
+
describe OmfCommon::Comm::XMPP::Topic do
|
7
|
+
before do
|
8
|
+
@client = Blather::Client.new
|
9
|
+
@stream = MiniTest::Mock.new
|
10
|
+
@stream.expect(:send, true, [Blather::Stanza])
|
11
|
+
@client.post_init @stream, Blather::JID.new('n@d/r')
|
12
|
+
@xmpp = OmfCommon::Comm::XMPP::Communicator.new
|
13
|
+
|
14
|
+
OmfCommon.stub :comm, @xmpp do
|
15
|
+
Blather::Client.stub :new, @client do
|
16
|
+
@stream.expect(:send, true, [Blather::Stanza::PubSub::Create])
|
17
|
+
@topic = OmfCommon::Comm::XMPP::Topic.create(:test_topic)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "when calling operation method" do
|
23
|
+
it "must send create message" do
|
24
|
+
OmfCommon.stub :comm, @xmpp do
|
25
|
+
Blather::Client.stub :new, @client do
|
26
|
+
published = Blather::XMPPNode.parse(published_xml)
|
27
|
+
|
28
|
+
write_callback = proc do |event|
|
29
|
+
event.must_be_kind_of Blather::Stanza::PubSub::Publish
|
30
|
+
published.id = event.id
|
31
|
+
@client.receive_data published
|
32
|
+
end
|
33
|
+
|
34
|
+
@client.stub :write, write_callback do
|
35
|
+
@topic.create(:bob, { hrn: 'bob' })
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "when informed message received" do
|
43
|
+
include EM::MiniTest::Spec
|
44
|
+
|
45
|
+
it "must react to omf created message" do
|
46
|
+
OmfCommon.stub :comm, @xmpp do
|
47
|
+
Blather::Client.stub :new, @client do
|
48
|
+
omf_create = OmfCommon::Message.create(:create, { type: 'engine' })
|
49
|
+
omf_create.stub :mid, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
|
50
|
+
omf_created = Blather::XMPPNode.parse(omf_created_xml)
|
51
|
+
@client.receive_data omf_created
|
52
|
+
@topic.on_creation_ok(omf_create) do |n|
|
53
|
+
n.must_equal OmfCommon::Message.parse(omf_created.items.first.payload)
|
54
|
+
done!
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
wait!
|
60
|
+
end
|
61
|
+
|
62
|
+
it "must react to omf status message" do
|
63
|
+
OmfCommon.stub :comm, @xmpp do
|
64
|
+
Blather::Client.stub :new, @client do
|
65
|
+
omf_request = OmfCommon::Message.create(:request, [:bob])
|
66
|
+
omf_request.stub :mid, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
|
67
|
+
omf_status = Blather::XMPPNode.parse(omf_status_xml)
|
68
|
+
@client.receive_data omf_status
|
69
|
+
@topic.on_status(omf_request) do |n|
|
70
|
+
n.must_equal OmfCommon::Message.parse(omf_status.items.first.payload)
|
71
|
+
done!
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
wait!
|
77
|
+
end
|
78
|
+
|
79
|
+
it "must react to omf release message" do
|
80
|
+
OmfCommon.stub :comm, @xmpp do
|
81
|
+
Blather::Client.stub :new, @client do
|
82
|
+
omf_release = OmfCommon::Message.create(:release, nil, { res_id: '100' })
|
83
|
+
omf_release.stub :mid, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
|
84
|
+
omf_released = Blather::XMPPNode.parse(omf_released_xml)
|
85
|
+
@client.receive_data omf_released
|
86
|
+
@topic.on_released(omf_release) do |n|
|
87
|
+
n.must_equal OmfCommon::Message.parse(omf_released.items.first.payload)
|
88
|
+
done!
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
wait!
|
94
|
+
end
|
95
|
+
|
96
|
+
it "must react to omf failed message" do
|
97
|
+
OmfCommon.stub :comm, @xmpp do
|
98
|
+
Blather::Client.stub :new, @client do
|
99
|
+
omf_create = OmfCommon::Message.create(:create, { type: 'engine' })
|
100
|
+
omf_create.stub :mid, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
|
101
|
+
omf_failed = Blather::XMPPNode.parse(omf_failed_xml)
|
102
|
+
@client.receive_data omf_failed
|
103
|
+
@topic.on_creation_failed(omf_create) do |n|
|
104
|
+
n.must_equal OmfCommon::Message.parse(omf_failed.items.first.payload)
|
105
|
+
done!
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
wait!
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -3,6 +3,7 @@ require 'test_helper'
|
|
3
3
|
describe OmfCommon::Comm do
|
4
4
|
describe 'when initialised with a pubsub implementation' do
|
5
5
|
it 'must return a instance with all methods defined in corresponding module loaded' do
|
6
|
+
skip
|
6
7
|
@comm = OmfCommon::Comm.new(:xmpp)
|
7
8
|
%w(connect disconnect create_topic delete_topic subscribe unsubscribe publish affiliations).each do |m|
|
8
9
|
@comm.must_respond_to m
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'omf_common/message/xml/message'
|
3
|
+
|
4
|
+
include OmfCommon
|
5
|
+
|
6
|
+
describe OmfCommon::Message::XML::Message do
|
7
|
+
describe "when create message initialised" do
|
8
|
+
before do
|
9
|
+
# We will test prop value other than just strings
|
10
|
+
@message = Message::XML::Message.create(:create,
|
11
|
+
{ type: 'bob', p1: 'p1_value', p2: { unit: 'u', precision: 2 } },
|
12
|
+
{ rtype: 'bob', guard: { p1: 'p1_value' } })
|
13
|
+
end
|
14
|
+
|
15
|
+
it "must to be validated using relaxng schema" do
|
16
|
+
@message.valid?.must_equal true
|
17
|
+
end
|
18
|
+
|
19
|
+
it "must be able to be serialised as XML" do
|
20
|
+
@message.to_xml.must_match /^<create(.+)create>$/m
|
21
|
+
@message.to_xml.must_match /<rtype>bob<\/rtype>/m
|
22
|
+
@message.to_xml.must_match /<props(.+)props>/m
|
23
|
+
@message.to_xml.must_match /<guard(.+)guard>/m
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "when release message initialised" do
|
28
|
+
before do
|
29
|
+
# We will test prop value other than just strings
|
30
|
+
@message = Message::XML::Message.create(:release, {}, { res_id: 'bob', guard: { p1: 'p1_value' } })
|
31
|
+
end
|
32
|
+
|
33
|
+
it "must to be validated using relaxng schema" do
|
34
|
+
@message.valid?.must_equal true
|
35
|
+
end
|
36
|
+
|
37
|
+
it "must be able to be serialised as XML" do
|
38
|
+
@message.to_xml.must_match /^<release(.+)release>$/m
|
39
|
+
@message.to_xml.must_match /<res_id>bob<\/res_id>/m
|
40
|
+
@message.to_xml.must_match /<guard(.+)guard>/m
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "when asked to parse a XML element into Message::XML::Message object" do
|
45
|
+
before do
|
46
|
+
@xml = Message::XML::Message.create(
|
47
|
+
:create,
|
48
|
+
{ type: 'vm',
|
49
|
+
os: 'debian',
|
50
|
+
memory: { value: 1024, unit: 'mb', precision: 0 },
|
51
|
+
devices: [{ name: 'w0', driver: 'mod_bob'}, { name: 'w1', driver: ['mod1', 'mod2']} ],
|
52
|
+
true: true,
|
53
|
+
false: false,
|
54
|
+
empty: nil,
|
55
|
+
boolean_array: [false, true] },
|
56
|
+
{ rtype: 'vm', guard: { os_type: 'linux' } }).to_xml
|
57
|
+
|
58
|
+
@message = Message::XML::Message.parse(@xml)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "must create the object correctly" do
|
62
|
+
@message.must_be_kind_of Message::XML::Message
|
63
|
+
@message.operation.must_equal :create
|
64
|
+
end
|
65
|
+
|
66
|
+
it "must provide normal xml xpath query" do
|
67
|
+
@message.read_element("props").first.element_children.size.must_equal 8
|
68
|
+
# TODO how to handle complext xpath??? with ns...
|
69
|
+
# @message.read_content("//memory/unit").must_equal 'mb'
|
70
|
+
end
|
71
|
+
|
72
|
+
it "must provide unified message property access" do
|
73
|
+
@message["type"].must_equal 'vm'
|
74
|
+
@message[:type].must_equal 'vm'
|
75
|
+
end
|
76
|
+
|
77
|
+
it "must provide guard information" do
|
78
|
+
@message.guard[:os_type].must_equal 'linux'
|
79
|
+
end
|
80
|
+
|
81
|
+
it "must be able reconstruct complicate data" do
|
82
|
+
# Each property iterator
|
83
|
+
@message.each_property do |k, v|
|
84
|
+
%w(type os memory devices true false empty boolean_array).must_include k
|
85
|
+
end
|
86
|
+
|
87
|
+
memory = @message[:memory]
|
88
|
+
memory.must_be_kind_of Hashie::Mash
|
89
|
+
memory.value.must_equal 1024
|
90
|
+
memory.unit.must_equal 'mb'
|
91
|
+
memory.precision.must_equal 0
|
92
|
+
|
93
|
+
devices = @message[:devices]
|
94
|
+
devices.must_be_kind_of Array
|
95
|
+
devices.size.must_equal 2
|
96
|
+
devices.find { |v| v.name == 'w1'}.driver.size.must_equal 2
|
97
|
+
end
|
98
|
+
|
99
|
+
it "must be able ducktype string xml content for numbers, boolean, empty string" do
|
100
|
+
@message[:true].must_equal true
|
101
|
+
@message[:false].must_equal false
|
102
|
+
@message[:boolean_array].must_equal [false, true]
|
103
|
+
@message[:empty].must_equal nil
|
104
|
+
end
|
105
|
+
|
106
|
+
it "must fail if parse an empty xml" do
|
107
|
+
lambda { Message::XML::Message.parse("") }.must_raise ArgumentError
|
108
|
+
lambda { Message::XML::Message.parse(nil) }.must_raise ArgumentError
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "when creating request messages" do
|
113
|
+
it "must accept an array of properties instead of hash" do
|
114
|
+
request_m = Message::XML::Message.create(:request, [:p1, :p2])
|
115
|
+
request_m.valid?.must_equal true
|
116
|
+
request_m[:p1].must_be_nil
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "when parsing inform message" do
|
121
|
+
it "must validate against inform message schema" do
|
122
|
+
msg = Message::XML::Message.parse <<-XML
|
123
|
+
<inform xmlns="http://schema.mytestbed.net/omf/6.0/protocol" mid="bob">
|
124
|
+
<src>xmpp://bob@localhost</src>
|
125
|
+
<ts>100</ts>
|
126
|
+
<itype>CREATION.OK</itype>
|
127
|
+
</inform>
|
128
|
+
XML
|
129
|
+
|
130
|
+
msg.ts.must_equal "100"
|
131
|
+
msg.itype.must_equal "CREATION.OK"
|
132
|
+
|
133
|
+
msg.valid?.must_equal true
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -1,151 +1,57 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
include OmfCommon
|
4
|
-
|
5
|
-
PROP_ELEMENTS = %w(p1 p2 p3)
|
6
|
-
|
7
3
|
describe OmfCommon::Message do
|
8
|
-
describe "when
|
9
|
-
|
10
|
-
%w(
|
11
|
-
|
12
|
-
|
13
|
-
PROP_ELEMENTS.each_with_index do |prop_element, index|
|
14
|
-
if index == 0
|
15
|
-
m.property(prop_element, rand(100))
|
16
|
-
else
|
17
|
-
m.property(prop_element, rand(100)) do |p|
|
18
|
-
p.element('unit', 'test')
|
19
|
-
p.element('precision', 'test')
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
# Guard element optional
|
26
|
-
m.element(:guard) do |g|
|
27
|
-
g.property('p1', 1)
|
28
|
-
g.property('p2', 2)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
message.valid?.must_equal true
|
32
|
-
end
|
4
|
+
describe "when initialised" do
|
5
|
+
before do
|
6
|
+
@internal_attr = %w(type operation guard mid ts replyto cid itype)
|
7
|
+
@message = OmfCommon::Message.create(:create, { p1: 'p1_value', p2: 'p2_value' }, { rtype: :bob })
|
33
8
|
end
|
34
9
|
|
35
|
-
it "must
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
41
|
-
request.valid?.must_equal true
|
10
|
+
it "must be able to query internal properties" do
|
11
|
+
@message.type.must_equal :create
|
12
|
+
@message.operation.must_equal :create
|
13
|
+
@message.mid.wont_be_nil
|
14
|
+
@message.ts.wont_be_nil
|
42
15
|
end
|
43
16
|
|
44
|
-
it "must
|
45
|
-
|
46
|
-
|
17
|
+
it "must be able to get property value" do
|
18
|
+
@message[:p1].must_equal 'p1_value'
|
19
|
+
@message.read_property(:p1).must_equal 'p1_value'
|
47
20
|
end
|
48
21
|
|
49
|
-
it "must
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
m.property(prop_element, { current: 'test', target: 'test'})
|
55
|
-
end
|
56
|
-
end
|
57
|
-
inform.valid?.must_equal true
|
22
|
+
it "must be able to set property value" do
|
23
|
+
@message[:p1] = 'new_value'
|
24
|
+
@message[:p1].must_equal 'new_value'
|
25
|
+
@message.write_property(:p2, 'new_value')
|
26
|
+
@message[:p2].must_equal 'new_value'
|
58
27
|
end
|
59
28
|
|
60
|
-
it "
|
61
|
-
|
62
|
-
|
29
|
+
it "must be able to query internal message properties" do
|
30
|
+
@internal_attr.each do |name|
|
31
|
+
@message.must_respond_to name
|
63
32
|
end
|
64
|
-
m.resource_id.must_equal 'test'
|
65
|
-
m.context_id.must_equal '9012c3bc-68de-459a-ac9f-530cc7168e22'
|
66
33
|
end
|
67
34
|
|
68
|
-
it "must
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
35
|
+
it "must evaluate erb code when read property with evaluate option is true" do
|
36
|
+
skip
|
37
|
+
@message[:p3] = "1 + 1 = <%= 1 + 1 %>"
|
38
|
+
@message[:p4] = "1 + 1 = <%= two %>"
|
39
|
+
@message.read_property(:p3, binding).must_equal "1 + 1 = 2"
|
40
|
+
@message[:p3].must_equal "1 + 1 = <%= 1 + 1 %>"
|
41
|
+
two = 2
|
42
|
+
@message[:p4, binding].must_equal "1 + 1 = 2"
|
43
|
+
@message[:p4].must_equal "1 + 1 = <%= two %>"
|
77
44
|
end
|
78
45
|
|
79
46
|
it "must be able to pretty print an app_event message" do
|
80
|
-
Message.inform
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
end
|
89
|
-
|
90
|
-
describe "when asked to parse a XML element into Message object" do
|
91
|
-
it "must create the message object correctly " do
|
92
|
-
xml = Message.create do |m|
|
93
|
-
m.property('type', 'vm')
|
94
|
-
m.property('os', 'debian')
|
95
|
-
m.property('memory', { value: 1024, unit: 'mb', precision: 0 })
|
96
|
-
m.property('devices', [{ name: 'w0', driver: 'mod_bob'}, { name: 'w1', driver: ['mod1', 'mod2']} ])
|
97
|
-
m.property('true', true)
|
98
|
-
m.property('false', false)
|
99
|
-
m.property('boolean_array', [false, true])
|
100
|
-
end.canonicalize
|
101
|
-
|
102
|
-
message = Message.parse(xml)
|
103
|
-
|
104
|
-
message.must_be_kind_of Message
|
105
|
-
message.operation.must_equal :create
|
106
|
-
message.read_element("property").size.must_equal 7
|
107
|
-
message.read_content("property[@key='memory']/unit").must_equal 'mb'
|
108
|
-
message.read_element("property").size.must_equal 7
|
109
|
-
message.read_property("type").must_equal 'vm'
|
110
|
-
message.read_property(:type).must_equal 'vm'
|
111
|
-
|
112
|
-
memory = message.read_property(:memory)
|
113
|
-
memory.must_be_kind_of Hashie::Mash
|
114
|
-
memory.value.must_equal 1024
|
115
|
-
memory.unit.must_equal 'mb'
|
116
|
-
memory.precision.must_equal 0
|
117
|
-
|
118
|
-
devices = message.read_property(:devices)
|
119
|
-
devices.must_be_kind_of Array
|
120
|
-
devices.size.must_equal 2
|
121
|
-
devices.find { |v| v.name == 'w1'}.driver.size.must_equal 2
|
122
|
-
# Each property iterator
|
123
|
-
message.each_property do |v|
|
124
|
-
%w(type os memory devices true false boolean_array).must_include v.attr('key')
|
125
|
-
end
|
126
|
-
|
127
|
-
message.read_property(:true).must_equal true
|
128
|
-
message.read_property(:false).must_equal false
|
129
|
-
message.read_property('boolean_array').must_equal [false, true]
|
130
|
-
end
|
131
|
-
|
132
|
-
it "must fail if parse an empty xml" do
|
133
|
-
lambda { Message.parse("") }.must_raise ArgumentError
|
134
|
-
lambda { Message.parse(nil) }.must_raise ArgumentError
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
describe "when query the message object" do
|
139
|
-
it "must return nil if content of a property is empty string" do
|
140
|
-
xml = Message.request do |m|
|
141
|
-
m.property('type', 'vm')
|
142
|
-
m.property('empty')
|
143
|
-
m.element('empty')
|
144
|
-
end
|
145
|
-
|
146
|
-
xml.read_property('type').must_equal 'vm'
|
147
|
-
xml.read_property('empty').must_equal nil
|
148
|
-
xml.read_content('empty').must_equal nil
|
47
|
+
@message = OmfCommon::Message.create(:inform,
|
48
|
+
{ status_type: 'APP_EVENT',
|
49
|
+
event: 'DONE.OK',
|
50
|
+
app: 'app100',
|
51
|
+
msg: 'Everything will be OK',
|
52
|
+
seq: 1 },
|
53
|
+
{ itype: 'STATUS' })
|
54
|
+
@message.print_app_event.must_equal "APP_EVENT (app100, #1, DONE.OK): Everything will be OK"
|
149
55
|
end
|
150
56
|
end
|
151
57
|
end
|
data/test/test_helper.rb
CHANGED
@@ -4,9 +4,12 @@ SimpleCov.start { add_filter "/test" }
|
|
4
4
|
gem 'minitest'
|
5
5
|
require 'minitest/autorun'
|
6
6
|
require 'minitest/pride'
|
7
|
+
require 'minitest/spec'
|
8
|
+
require 'minitest/mock'
|
7
9
|
|
8
10
|
require 'omf_common'
|
9
11
|
|
12
|
+
OmfCommon::Message.init(type: :xml)
|
13
|
+
|
10
14
|
# Shut up all the loggers
|
11
15
|
Logging.logger.root.clear_appenders
|
12
|
-
|