omf_common 6.0.0.pre.6 → 6.0.0.pre.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,11 +4,17 @@ require 'omf_common/command'
4
4
  describe OmfCommon::Command do
5
5
  describe "when use util file to execute a system command" do
6
6
  it "must not print anything to stdout if executed successfully" do
7
- OmfCommon::Command.execute("date").must_match /^.+/
7
+ OmfCommon::Command.execute("ruby -e 'puts 100'").must_match /100/
8
8
  end
9
9
 
10
10
  it "must capture and log errors if command not found" do
11
- OmfCommon::Command.execute("dte -z").must_be_nil
11
+ OmfCommon::Command.execute("blahblah -z").must_be_nil
12
+ end
13
+
14
+ it "must log error when exit status is not 0" do
15
+ OmfCommon::Command.execute("ruby -e 'exit 1'").must_be_nil
16
+ OmfCommon::Command.execute("ruby -e 'exit 2'").must_be_nil
17
+ OmfCommon::Command.execute("ruby -e 'exit 3'").must_be_nil
12
18
  end
13
19
  end
14
20
  end
@@ -0,0 +1,309 @@
1
+ require 'test_helper'
2
+ require 'fixture/pubsub'
3
+ require 'em/minitest/spec'
4
+
5
+ describe OmfCommon::DSL::Xmpp do
6
+ before do
7
+ @client = Blather::Client.new
8
+ @stream = MiniTest::Mock.new
9
+ @stream.expect(:send, true, [Blather::Stanza])
10
+ @client.post_init @stream, Blather::JID.new('n@d/r')
11
+ @xmpp = Class.new { include OmfCommon::DSL::Xmpp }.new
12
+ end
13
+
14
+ describe "when communicating to xmpp server (via mocking)" do
15
+ include EM::MiniTest::Spec
16
+
17
+ it "must be able to connect" do
18
+ Blather::Stream::Client.stub(:start, @client) do
19
+ Blather::Client.stub :new, @client do
20
+ @xmpp.jid.inspect.must_equal "n@d/r"
21
+ @xmpp.connect('bob', 'pw', 'example.com')
22
+ @xmpp.jid.inspect.must_equal "bob@example.com"
23
+ end
24
+ end
25
+ end
26
+
27
+ it "must be able to disconnect" do
28
+ Blather::Stream::Client.stub(:start, @client) do
29
+ Blather::Client.stub :new, @client do
30
+ @stream.expect(:close_connection_after_writing, true)
31
+ @xmpp.disconnect
32
+ @stream.verify
33
+ end
34
+ end
35
+ end
36
+
37
+ it "must be able to subscribe & trigger callback when subscribed" do
38
+ Blather::Client.stub :new, @client do
39
+ subscription = Blather::XMPPNode.parse(subscription_xml)
40
+ write_callback = proc do |event|
41
+ event.must_be_kind_of Blather::Stanza::PubSub::Subscribe
42
+ subscription.id = event.id
43
+ @client.receive_data subscription
44
+ end
45
+ @client.stub :write, write_callback do
46
+ @xmpp.subscribe('xmpp_topic') { |e| e.must_equal subscription; done! }
47
+ end
48
+ end
49
+ wait!
50
+ end
51
+
52
+ it "must be able to create topic & trigger callback when created" do
53
+ Blather::Client.stub :new, @client do
54
+ created = Blather::XMPPNode.parse(created_xml)
55
+ write_callback = proc do |event|
56
+ event.must_be_kind_of Blather::Stanza::PubSub::Create
57
+ created.id = event.id
58
+ @client.receive_data created
59
+ end
60
+ @client.stub :write, write_callback do
61
+ @xmpp.create_topic('xmpp_topic') { |event| event.must_equal created; done! }
62
+ end
63
+ end
64
+ wait!
65
+ end
66
+
67
+ it "must be able to delete topic & trigger callback when topic deleted" do
68
+ Blather::Client.stub :new, @client do
69
+ deleted = Blather::XMPPNode.parse(fabulous_xmpp_empty_success_xml)
70
+ write_callback = proc do |event|
71
+ event.must_be_kind_of Blather::Stanza::PubSubOwner::Delete
72
+ deleted.id = event.id
73
+ @client.receive_data deleted
74
+ end
75
+ @client.stub :write, write_callback do
76
+ @xmpp.delete_topic('xmpp_topic') { |event| event.must_equal deleted; done! }
77
+ end
78
+ end
79
+ wait!
80
+ end
81
+
82
+ it "must be able to list affiliations (owned pubsub nodes) & react if received" do
83
+ Blather::Client.stub :new, @client do
84
+ affiliations = Blather::XMPPNode.parse(affiliations_xml)
85
+ write_callback = proc do |event|
86
+ event.must_be_kind_of Blather::Stanza::PubSub::Affiliations
87
+ affiliations.id = event.id
88
+ @client.receive_data affiliations
89
+ end
90
+ @client.stub :write, write_callback do
91
+ @xmpp.affiliations { |event| event[:owner].must_equal %w(node1 node2); done! }
92
+ end
93
+ end
94
+ wait!
95
+ end
96
+
97
+ it "must be able to publish if message is valid" do
98
+ Blather::Client.stub :new, @client do
99
+ @stream.expect(:send, true, [Blather::Stanza::PubSub::Publish])
100
+ @xmpp.publish 'xmpp_topic', Message.create {|v| v.property('type', 'test')}
101
+ proc { @xmpp.publish 'xmpp_topic', Message.inform {|v| v.element('blah', 'blah')} }.must_raise StandardError
102
+ @stream.verify
103
+ end
104
+ end
105
+
106
+ it "must trigger callback when item published" do
107
+ Blather::Client.stub :new, @client do
108
+ published = Blather::XMPPNode.parse(published_xml)
109
+ write_callback = proc do |event|
110
+ event.must_be_kind_of Blather::Stanza::PubSub::Publish
111
+ published.id = event.id
112
+ @client.receive_data published
113
+ end
114
+ @client.stub :write, write_callback do
115
+ @xmpp.publish 'xmpp_topic', Message.create {|v| v.property('type', 'test')} do |event|
116
+ event.must_equal published
117
+ done!
118
+ end
119
+ end
120
+ end
121
+ wait!
122
+ end
123
+
124
+ it "must be able to unsubscribe" do
125
+ Blather::Client.stub :new, @client do
126
+ @stream.expect(:send, true, [Blather::Stanza::PubSub::Subscriptions])
127
+ @xmpp.unsubscribe
128
+ @stream.verify
129
+ end
130
+ end
131
+
132
+ it "must trigger callback when unsubscribed (all topics)" do
133
+ Blather::Client.stub :new, @client do
134
+ 2.times do
135
+ @stream.expect(:send, true, [Blather::Stanza])
136
+ end
137
+
138
+ subscriptions = Blather::XMPPNode.parse(subscriptions_xml)
139
+ write_callback = proc do |event|
140
+ event.must_be_kind_of Blather::Stanza::PubSub::Subscriptions
141
+ subscriptions.id = event.id
142
+ @client.receive_data subscriptions
143
+ end
144
+ @client.stub :write, write_callback do
145
+ @xmpp.unsubscribe
146
+ end
147
+ @stream.verify
148
+ end
149
+ end
150
+
151
+ it "must be able to add a topic event handler" do
152
+ Blather::Client.stub :new, @client do
153
+ @xmpp.topic_event
154
+ @stream.verify
155
+ end
156
+ end
157
+ end
158
+
159
+ describe "when omf message related methods" do
160
+ it "must generate omf create xml fragment" do
161
+ m1 = @xmpp.create_message([type: 'engine'])
162
+ m2 = @xmpp.create_message do |v|
163
+ v.property('type', 'engine')
164
+ end
165
+ m1.must_be_kind_of OmfCommon::TopicMessage
166
+ m2.must_be_kind_of OmfCommon::TopicMessage
167
+ m1.body.name.must_equal 'create'
168
+ m1.body.to_xml.must_match /<property key="type" type="string">engine<\/property>/
169
+ m2.body.to_xml.must_match /<property key="type" type="string">engine<\/property>/
170
+ end
171
+
172
+ it "must generate omf configure xml fragment" do
173
+ m1 = @xmpp.configure_message([throttle: 50])
174
+ m2 = @xmpp.configure_message do |v|
175
+ v.property('throttle', 50)
176
+ end
177
+ m1.must_be_kind_of OmfCommon::TopicMessage
178
+ m2.must_be_kind_of OmfCommon::TopicMessage
179
+ m1.body.name.must_equal 'configure'
180
+ m1.body.to_xml.must_match /<property key="throttle" type="fixnum">50<\/property>/
181
+ m2.body.to_xml.must_match /<property key="throttle" type="fixnum">50<\/property>/
182
+ end
183
+
184
+ it "must generate omf inform xml fragment" do
185
+ m1 = @xmpp.inform_message([inform_type: 'CREATED'])
186
+ m2 = @xmpp.inform_message do |v|
187
+ v.property('inform_type', 'CREATED')
188
+ end
189
+ m1.must_be_kind_of OmfCommon::TopicMessage
190
+ m2.must_be_kind_of OmfCommon::TopicMessage
191
+ m1.body.name.must_equal 'inform'
192
+ m1.body.to_xml.must_match /<property key="inform_type" type="string">CREATED<\/property>/
193
+ m2.body.to_xml.must_match /<property key="inform_type" type="string">CREATED<\/property>/
194
+ end
195
+
196
+ it "must generate omf release xml fragment" do
197
+ m1 = @xmpp.release_message([resource_id: 100])
198
+ m2 = @xmpp.release_message do |v|
199
+ v.property('resource_id', 100)
200
+ end
201
+ m1.must_be_kind_of OmfCommon::TopicMessage
202
+ m2.must_be_kind_of OmfCommon::TopicMessage
203
+ m1.body.name.must_equal 'release'
204
+ m1.body.to_xml.must_match /<property key="resource_id" type="fixnum">100<\/property>/
205
+ m2.body.to_xml.must_match /<property key="resource_id" type="fixnum">100<\/property>/
206
+ end
207
+
208
+ it "must generate omf request xml fragment" do
209
+ m1 = @xmpp.request_message([:max_rpm, {:provider => {country: 'japan'}}, :max_power])
210
+ m2 = @xmpp.request_message do |v|
211
+ v.property('max_rpm')
212
+ v.property('provider', { country: 'japan' })
213
+ v.property('max_power')
214
+ end
215
+ m1.must_be_kind_of OmfCommon::TopicMessage
216
+ m2.must_be_kind_of OmfCommon::TopicMessage
217
+ m1.body.name.must_equal 'request'
218
+ m1.body.to_xml.must_match /<property key="max_rpm"\/>/
219
+ m1.body.to_xml.must_match /<property key="provider" type="hash">/
220
+ m2.body.to_xml.must_match /<property key="provider" type="hash">/
221
+ m1.body.to_xml.must_match /<country type="string">japan<\/country>/
222
+ m2.body.to_xml.must_match /<country type="string">japan<\/country>/
223
+ m1.body.to_xml.must_match /<property key="max_power"\/>/
224
+ end
225
+ end
226
+
227
+ describe "when informed message received" do
228
+ include EM::MiniTest::Spec
229
+
230
+ it "must react to omf created message" do
231
+ Blather::Client.stub :new, @client do
232
+ omf_create = OmfCommon::Message.create { |v| v.property('type', 'engine') }
233
+ omf_create.stub :context_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
234
+ omf_created = Blather::XMPPNode.parse(omf_created_xml)
235
+ @client.receive_data omf_created
236
+ @xmpp.on_created_message(omf_create) do |n|
237
+ n.must_equal Message.parse(omf_created.items.first.payload)
238
+ done!
239
+ end
240
+ end
241
+ end
242
+ wait!
243
+ end
244
+
245
+ it "must react to omf status message" do
246
+ Blather::Client.stub :new, @client do
247
+ omf_request = OmfCommon::Message.request { |v| v.property('bob') }
248
+ omf_request.stub :context_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
249
+ omf_status = Blather::XMPPNode.parse(omf_status_xml)
250
+ @client.receive_data omf_status
251
+ @xmpp.on_status_message(omf_request) do |n|
252
+ n.must_equal Message.parse(omf_status.items.first.payload)
253
+ done!
254
+ end
255
+ end
256
+ end
257
+ wait!
258
+ end
259
+
260
+ it "must react to omf release message" do
261
+ Blather::Client.stub :new, @client do
262
+ omf_release = OmfCommon::Message.release { |v| v.property('resource_id', '100') }
263
+ omf_release.stub :context_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
264
+ omf_released = Blather::XMPPNode.parse(omf_released_xml)
265
+ @client.receive_data omf_released
266
+ @xmpp.on_released_message(omf_release) do |n|
267
+ n.must_equal Message.parse(omf_released.items.first.payload)
268
+ done!
269
+ end
270
+ end
271
+ end
272
+ wait!
273
+ end
274
+
275
+ it "must react to omf failed message" do
276
+ Blather::Client.stub :new, @client do
277
+ omf_create = OmfCommon::Message.create { |v| v.property('type', 'engine') }
278
+ omf_create.stub :context_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
279
+ omf_failed = Blather::XMPPNode.parse(omf_failed_xml)
280
+ @client.receive_data omf_failed
281
+ @xmpp.on_failed_message(omf_create) do |n|
282
+ n.must_equal Message.parse(omf_failed.items.first.payload)
283
+ done!
284
+ end
285
+ end
286
+ end
287
+ wait!
288
+ end
289
+ end
290
+
291
+ describe "when use event machine style method" do
292
+ include EM::MiniTest::Spec
293
+
294
+ it "must accept these methods and forward to event machine" do
295
+ @xmpp.add_timer(0.05) { done! }
296
+ @xmpp.add_periodic_timer(0.05) { done! }
297
+ wait!
298
+ end
299
+ end
300
+
301
+ describe "when asked to get a topic object" do
302
+ it "must return a topic object (pubsub topic) or nil if not found" do
303
+ topic = @xmpp.get_topic('xmpp_topic')
304
+ topic.must_be_kind_of OmfCommon::Topic
305
+ topic.comm.must_equal @xmpp
306
+ end
307
+ end
308
+ end
309
+
@@ -8,7 +8,7 @@ describe OmfCommon::Message do
8
8
  describe "when constructing valid messages" do
9
9
  it "must return a create or configure XML element without failing" do
10
10
  %w(create configure).each do |msg_name|
11
- message = Message.send(msg_name) do |m|
11
+ message = Message.__send__(msg_name) do |m|
12
12
  PROP_ELEMENTS.each_with_index do |prop_element, index|
13
13
  if index == 0
14
14
  m.property(prop_element, rand(100))
@@ -27,33 +27,45 @@ describe OmfCommon::Message do
27
27
  it "must return a request XML element without failing" do
28
28
  request = Message.request('foo@bar') do |m|
29
29
  PROP_ELEMENTS.each do |prop_element|
30
- m.property(prop_element) do |p|
31
- p.element('min_value', 'test')
32
- p.element('max_value', 'test')
33
- end
30
+ m.property(prop_element, {min_value: 'test', max_value: 'test'})
34
31
  end
35
32
  end
36
33
  request.valid?.must_equal true
37
34
  end
38
35
 
39
36
  it "must return a release XML element without failing" do
40
- release = Message.release
37
+ release = Message.release { |v| v.element('resource_id', 'test') }
41
38
  release.valid?.must_equal true
42
39
  end
43
40
 
44
41
  it "must return a inform XML element without failing" do
45
- inform = Message.inform('9012c3bc-68de-459a-ac9f-530cc7168e22', 'CREATED') do |m|
42
+ inform = Message.inform('CREATED', '9012c3bc-68de-459a-ac9f-530cc7168e22') do |m|
46
43
  m.element('resource_id', 'test')
47
44
  m.element('resource_address', 'test')
48
45
  PROP_ELEMENTS.each do |prop_element|
49
- m.property(prop_element) do |p|
50
- p.element('current', 'test')
51
- p.element('target', 'test')
52
- end
46
+ m.property(prop_element, { current: 'test', target: 'test'})
53
47
  end
54
48
  end
55
49
  inform.valid?.must_equal true
56
50
  end
51
+
52
+ it "context_id & resource_id shortcut must work too" do
53
+ m = Message.inform('CREATED', '9012c3bc-68de-459a-ac9f-530cc7168e22') do |m|
54
+ m.element('resource_id', 'test')
55
+ end
56
+ m.resource_id.must_equal 'test'
57
+ m.context_id.must_equal '9012c3bc-68de-459a-ac9f-530cc7168e22'
58
+ end
59
+
60
+ it "must be able to pretty print an app_event message" do
61
+ Message.inform('STATUS') do |m|
62
+ m.property('status_type', 'APP_EVENT')
63
+ m.property('event', 'DONE.OK')
64
+ m.property('app', 'app100')
65
+ m.property('msg', 'Everything will be OK')
66
+ m.property('seq', 1)
67
+ end.print_app_event.must_equal "APP_EVENT (app100, #1, DONE.OK): Everything will be OK"
68
+ end
57
69
  end
58
70
 
59
71
  describe "must be able to parse a XML element into Message object" do
@@ -61,25 +73,48 @@ describe OmfCommon::Message do
61
73
  xml = Message.create do |m|
62
74
  m.property('type', 'vm')
63
75
  m.property('os', 'debian')
64
- m.property('memory', 1024) do |p|
65
- p.element('unit', 'mb')
66
- p.element('precision', '0')
67
- end
68
- end.to_xml
76
+ m.property('memory', { value: 1024, unit: 'mb', precision: 0 })
77
+ m.property('devices', [{ name: 'w0', driver: 'mod_bob'}, { name: 'w1', driver: ['mod1', 'mod2']} ])
78
+ end.canonicalize
69
79
 
70
80
  message = Message.parse(xml)
71
81
 
72
82
  message.must_be_kind_of Message
73
83
  message.operation.must_equal :create
74
- message.read_element("//property").size.must_equal 3
84
+ message.read_element("//property").size.must_equal 4
75
85
  message.read_content("unit").must_equal 'mb'
76
- message.read_element("/create/property").size.must_equal 3
86
+ message.read_element("/create/property").size.must_equal 4
77
87
  message.read_property("type").must_equal 'vm'
78
88
  message.read_property(:type).must_equal 'vm'
89
+
79
90
  memory = message.read_property(:memory)
91
+ memory.must_be_kind_of Hashie::Mash
80
92
  memory.value.must_equal 1024
81
93
  memory.unit.must_equal 'mb'
82
94
  memory.precision.must_equal 0
95
+
96
+ devices = message.read_property(:devices)
97
+ devices.items.must_be_kind_of Array
98
+ devices.items.size.must_equal 2
99
+ devices.items.find { |v| v.name == 'w1'}.driver.items.size.must_equal 2
100
+ # Each property iterator
101
+ message.each_property do |v|
102
+ %w(type os memory devices).must_include v.attr('key')
103
+ end
104
+ end
105
+ end
106
+
107
+ describe "when query the message object" do
108
+ it "must return nil if content of a property is empty string" do
109
+ xml = Message.request do |m|
110
+ m.property('type', 'vm')
111
+ m.property('empty')
112
+ m.element('empty')
113
+ end
114
+
115
+ xml.read_property('type').must_equal 'vm'
116
+ xml.read_property('empty').must_equal nil
117
+ xml.read_content('empty').must_equal nil
83
118
  end
84
119
  end
85
120
  end
@@ -0,0 +1,114 @@
1
+ require 'test_helper'
2
+ require 'fixture/pubsub'
3
+ require 'em/minitest/spec'
4
+
5
+ include OmfCommon
6
+
7
+ describe OmfCommon::Topic do
8
+ before do
9
+ @client = Blather::Client.new
10
+ @stream = MiniTest::Mock.new
11
+ @stream.expect(:send, true, [Blather::Stanza])
12
+ @client.post_init @stream, Blather::JID.new('n@d/r')
13
+ @comm = Class.new { include OmfCommon::DSL::Xmpp }.new
14
+ @topic = @comm.get_topic('mclaren')
15
+ @message = @comm.request_message([:bob])
16
+ end
17
+
18
+ describe "when topic message object initialised" do
19
+ include EM::MiniTest::Spec
20
+
21
+ it "must be able to publish to a topic" do
22
+ Blather::Client.stub :new, @client do
23
+ published = Blather::XMPPNode.parse(published_xml)
24
+ write_callback = proc do |event|
25
+ event.must_be_kind_of Blather::Stanza::PubSub::Publish
26
+ event.node.must_equal @topic.id
27
+ published.id = event.id
28
+ @client.receive_data published
29
+ end
30
+ @client.stub :write, write_callback do
31
+ @message.publish(@topic.id) do |event|
32
+ event.must_equal published
33
+ end
34
+
35
+ # Can publish again
36
+ @message.publish(@topic.id) do |event|
37
+ event.must_equal published
38
+ done!
39
+ end
40
+ end
41
+ end
42
+ wait!
43
+ end
44
+
45
+ end
46
+
47
+ describe "when message with same context id arrived " do
48
+ include EM::MiniTest::Spec
49
+
50
+ it "must react to omf created message" do
51
+ Blather::Client.stub :new, @client do
52
+ omf_create = @comm.create_message { |v| v.property('type', 'engine') }
53
+ omf_create.body.stub :context_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
54
+ omf_created = Blather::XMPPNode.parse(omf_created_xml)
55
+ @client.receive_data omf_created
56
+ omf_create.on_inform_created do |n|
57
+ n.context_id.must_equal "bf840fe9-c176-4fae-b7de-6fc27f183f76"
58
+ n.must_equal Message.parse(omf_created.items.first.payload)
59
+ done!
60
+ end
61
+ end
62
+ end
63
+ wait!
64
+ end
65
+
66
+ it "must react to omf status message" do
67
+ Blather::Client.stub :new, @client do
68
+ omf_request = @comm.request_message { |v| v.property('bob') }
69
+ omf_request.body.stub :context_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
70
+ omf_status = Blather::XMPPNode.parse(omf_status_xml)
71
+ @client.receive_data omf_status
72
+ omf_request.on_inform_status do |n|
73
+ n.context_id.must_equal "bf840fe9-c176-4fae-b7de-6fc27f183f76"
74
+ n.must_equal Message.parse(omf_status.items.first.payload)
75
+ done!
76
+ end
77
+ end
78
+ end
79
+ wait!
80
+ end
81
+
82
+ it "must react to omf release message" do
83
+ Blather::Client.stub :new, @client do
84
+ omf_release = @comm.release_message { |v| v.property('resource_id', '100') }
85
+ omf_release.body.stub :context_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
86
+ omf_released = Blather::XMPPNode.parse(omf_released_xml)
87
+ @client.receive_data omf_released
88
+ omf_release.on_inform_released do |n|
89
+ n.context_id.must_equal "bf840fe9-c176-4fae-b7de-6fc27f183f76"
90
+ n.must_equal Message.parse(omf_released.items.first.payload)
91
+ done!
92
+ end
93
+ end
94
+ end
95
+ wait!
96
+ end
97
+
98
+ it "must react to omf failed message" do
99
+ Blather::Client.stub :new, @client do
100
+ omf_create = @comm.create_message { |v| v.property('type', 'engine') }
101
+ omf_create.body.stub :context_id, "bf840fe9-c176-4fae-b7de-6fc27f183f76" do
102
+ omf_failed = Blather::XMPPNode.parse(omf_failed_xml)
103
+ @client.receive_data omf_failed
104
+ omf_create.on_inform_failed do |n|
105
+ n.context_id.must_equal "bf840fe9-c176-4fae-b7de-6fc27f183f76"
106
+ n.must_equal Message.parse(omf_failed.items.first.payload)
107
+ done!
108
+ end
109
+ end
110
+ end
111
+ wait!
112
+ end
113
+ end
114
+ end