omf_common 6.0.0.pre.10 → 6.0.0.pre.11
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/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
|
-
|