oneacct-export 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +11 -0
  6. data/Rakefile +18 -0
  7. data/bin/oneacct-export +72 -0
  8. data/config/conf.yml +53 -0
  9. data/config/sidekiq.yml +6 -0
  10. data/lib/errors.rb +7 -0
  11. data/lib/errors/authentication_error.rb +3 -0
  12. data/lib/errors/resource_not_found_error.rb +3 -0
  13. data/lib/errors/resource_retrieval_error.rb +3 -0
  14. data/lib/errors/resource_state_error.rb +3 -0
  15. data/lib/errors/user_not_authorized_error.rb +3 -0
  16. data/lib/input_validator.rb +18 -0
  17. data/lib/one_data_accessor.rb +147 -0
  18. data/lib/one_worker.rb +181 -0
  19. data/lib/one_writer.rb +51 -0
  20. data/lib/oneacct_exporter.rb +88 -0
  21. data/lib/oneacct_exporter/log.rb +15 -0
  22. data/lib/oneacct_exporter/version.rb +3 -0
  23. data/lib/oneacct_opts.rb +131 -0
  24. data/lib/redis_conf.rb +29 -0
  25. data/lib/settings.rb +13 -0
  26. data/lib/sidekiq_conf.rb +11 -0
  27. data/lib/templates/apel-0.2.erb +30 -0
  28. data/mock/one_worker_DEPLOY_ID_missing.xml +136 -0
  29. data/mock/one_worker_DISK_missing.xml +119 -0
  30. data/mock/one_worker_ETIME_0.xml +137 -0
  31. data/mock/one_worker_ETIME_missing.xml +136 -0
  32. data/mock/one_worker_ETIME_nan.xml +137 -0
  33. data/mock/one_worker_GID_missing.xml +136 -0
  34. data/mock/one_worker_GNAME_missing.xml +136 -0
  35. data/mock/one_worker_HISTORY_RECORDS_missing.xml +91 -0
  36. data/mock/one_worker_HISTORY_many.xml +137 -0
  37. data/mock/one_worker_HISTORY_missing.xml +93 -0
  38. data/mock/one_worker_HISTORY_one.xml +115 -0
  39. data/mock/one_worker_IMAGE_ID_missing.xml +136 -0
  40. data/mock/one_worker_MEMORY_0.xml +137 -0
  41. data/mock/one_worker_MEMORY_missing.xml +136 -0
  42. data/mock/one_worker_MEMORY_nan.xml +137 -0
  43. data/mock/one_worker_NET_RX_0.xml +137 -0
  44. data/mock/one_worker_NET_RX_missing.xml +136 -0
  45. data/mock/one_worker_NET_RX_nan.xml +137 -0
  46. data/mock/one_worker_NET_TX_0.xml +137 -0
  47. data/mock/one_worker_NET_TX_missing.xml +136 -0
  48. data/mock/one_worker_NET_TX_nan.xml +137 -0
  49. data/mock/one_worker_RETIME_0.xml +115 -0
  50. data/mock/one_worker_RETIME_missing.xml +114 -0
  51. data/mock/one_worker_RSTIME_0.xml +115 -0
  52. data/mock/one_worker_RSTIME_>_RETIME.xml +115 -0
  53. data/mock/one_worker_RSTIME_missing.xml +114 -0
  54. data/mock/one_worker_STATE_missing.xml +136 -0
  55. data/mock/one_worker_STATE_out_of_range.xml +137 -0
  56. data/mock/one_worker_STIME_>_ETIME.xml +137 -0
  57. data/mock/one_worker_STIME_missing.xml +136 -0
  58. data/mock/one_worker_STIME_nan.xml +137 -0
  59. data/mock/one_worker_TEMPLATE_missing.xml +79 -0
  60. data/mock/one_worker_UID_missing.xml +136 -0
  61. data/mock/one_worker_VCPU_0.xml +137 -0
  62. data/mock/one_worker_VCPU_missing.xml +136 -0
  63. data/mock/one_worker_VCPU_nan.xml +137 -0
  64. data/mock/one_worker_malformed_vm.xml +136 -0
  65. data/mock/one_worker_valid_machine.xml +137 -0
  66. data/mock/one_worker_vm1.xml +137 -0
  67. data/mock/one_worker_vm2.xml +137 -0
  68. data/mock/one_worker_vm3.xml +137 -0
  69. data/mock/one_writer_testfile +2 -0
  70. data/oneacct-export.gemspec +31 -0
  71. data/spec/one_data_accessor_spec.rb +441 -0
  72. data/spec/one_worker_spec.rb +684 -0
  73. data/spec/one_writer_spec.rb +146 -0
  74. data/spec/oneacct_exporter_spec.rb +262 -0
  75. data/spec/oneacct_opts_spec.rb +229 -0
  76. data/spec/redis_conf_spec.rb +94 -0
  77. data/spec/spec_helper.rb +11 -0
  78. metadata +254 -0
@@ -0,0 +1,684 @@
1
+ require 'spec_helper'
2
+
3
+ describe OneWorker do
4
+ subject { one_worker }
5
+
6
+ let(:one_worker) { OneWorker.new }
7
+ let(:oda) { double('oda') }
8
+
9
+ describe '.common_data' do
10
+ before :example do
11
+ Settings['endpoint'] = 'machine.hogwarts.co.uk'
12
+ Settings['site_name'] = 'Hogwarts'
13
+ Settings['cloud_type'] = 'OpenNebula'
14
+ end
15
+
16
+ let(:common_data) { { 'endpoint' => 'machine.hogwarts.co.uk', 'site_name' => 'Hogwarts', 'cloud_type' => 'OpenNebula' } }
17
+
18
+ it 'returns data common for every vm in form of hash' do
19
+ expect(subject.common_data).to eq(common_data)
20
+ end
21
+ end
22
+
23
+ describe '.create_user_map' do
24
+ it 'returns user map' do
25
+ expect(subject).to receive(:create_map).with(OpenNebula::UserPool, anything, anything) { 'map' }
26
+ expect(subject.create_user_map(oda)).to eq('map')
27
+ end
28
+ end
29
+
30
+ describe '.create_image_map' do
31
+ it 'returns image map' do
32
+ expect(subject).to receive(:create_map).with(OpenNebula::ImagePool, anything, anything) { 'map' }
33
+ expect(subject.create_image_map(oda)).to eq('map')
34
+ end
35
+ end
36
+
37
+ describe '.create_map' do
38
+ let(:pool_type) { double('pool_type') }
39
+ let(:mapping) { double('mapping') }
40
+
41
+ context 'without any error during data retrieval' do
42
+ before :example do
43
+ expect(oda).to receive(:mapping).with(pool_type, mapping)
44
+ end
45
+
46
+ it 'returns requested map' do
47
+ subject.create_map(pool_type, mapping, oda)
48
+ end
49
+ end
50
+
51
+ context 'with error during data retrieval' do
52
+ before :example do
53
+ expect(oda).to receive(:mapping).and_raise(Errors::ResourceRetrievalError)
54
+ end
55
+
56
+ it 'raises an error' do
57
+ expect { subject.create_map(pool_type, mapping, oda) }.to raise_error(RuntimeError)
58
+ end
59
+ end
60
+ end
61
+
62
+ describe '.load_vm' do
63
+ context 'without error' do
64
+ before :example do
65
+ expect(oda).to receive(:vm).with(5) { vm }
66
+ end
67
+
68
+ let(:vm) { double('vm') }
69
+
70
+ it 'returns vm with given ID' do
71
+ expect(subject.load_vm(5, oda)).to eq(vm)
72
+ end
73
+ end
74
+
75
+ context 'with error' do
76
+ before :example do
77
+ expect(oda).to receive(:vm).and_raise(Errors::ResourceRetrievalError)
78
+ end
79
+
80
+ it 'returns nil' do
81
+ expect(subject.load_vm(5, oda)).to be_nil
82
+ end
83
+ end
84
+ end
85
+
86
+ describe '.parse' do
87
+ let(:regex) { /[[:digit:]]+/ }
88
+
89
+ context 'with three parameters' do
90
+ context 'if regex matches the value' do
91
+ it 'returns the value' do
92
+ expect(subject.parse('42', regex, '0')).to eq('42')
93
+ end
94
+ end
95
+
96
+ context 'if regex does not match the value' do
97
+ it 'it returns substitute' do
98
+ expect(subject.parse('abc', regex, '0')).to eq('0')
99
+ end
100
+ end
101
+ end
102
+
103
+ context 'with two parameters' do
104
+ context 'if regex matches the value' do
105
+ it 'returns the value' do
106
+ expect(subject.parse('42', regex)).to eq('42')
107
+ end
108
+ end
109
+
110
+ context 'if regex does not match the value' do
111
+ it 'returns "NULL"' do
112
+ expect(subject.parse('abc', regex)).to eq('NULL')
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ describe 'write_data' do
119
+ before :example do
120
+ expect(OneWriter).to receive(:new).with(data, output, anything) { ow }
121
+ end
122
+
123
+ let(:data) { double('data') }
124
+ let(:output) { double('output') }
125
+ let(:ow) { double('one_writer') }
126
+
127
+ context 'without error' do
128
+ before :example do
129
+ expect(ow).to receive(:write)
130
+ end
131
+
132
+ it 'calls OneWriter.write with specified data and output directory' do
133
+ subject.write_data(data, output)
134
+ end
135
+ end
136
+
137
+ context 'with error' do
138
+ before :example do
139
+ expect(ow).to receive(:write).and_raise(Errors::ResourceRetrievalError)
140
+ end
141
+
142
+ it 'raises a RuntimeError' do
143
+ expect { subject.write_data(data, output) }.to raise_error(RuntimeError)
144
+ end
145
+ end
146
+ end
147
+
148
+ describe '.process_vm' do
149
+ before :example do
150
+ Settings['endpoint'] = 'machine.hogwarts.co.uk'
151
+ Settings['site_name'] = 'Hogwarts'
152
+ Settings['cloud_type'] = 'OpenNebula'
153
+ end
154
+
155
+ let(:vm) do
156
+ xml = File.read("#{GEM_DIR}/mock/#{filename}")
157
+ OpenNebula::XMLElement.new(OpenNebula::XMLElement.build_xml(xml, 'VM'))
158
+ end
159
+
160
+ let(:data) do
161
+ data = {}
162
+ data['endpoint'] = 'machine.hogwarts.co.uk'
163
+ data['site_name'] = 'Hogwarts'
164
+ data['cloud_type'] = 'OpenNebula'
165
+ data['vm_uuid'] = '36551'
166
+ data['start_time'] = '1383741160'
167
+ data['start_time_readable'] = '2013-11-06 13:32:40+01:00'
168
+ data['end_time'] = '1383742270'
169
+ data['machine_name'] = 'one-36551'
170
+ data['user_id'] = '120'
171
+ data['group_id'] = '0'
172
+ data['user_name'] = 'user_name'
173
+ data['fqan'] = 'gname'
174
+ data['status'] = 'completed'
175
+ data['duration'] = '596'
176
+ data['suspend'] = '514'
177
+ data['cpu_count'] = '1'
178
+ data['network_inbound'] = 0
179
+ data['network_outbound'] = 0
180
+ data['memory'] = '1736960'
181
+ data['image_name'] = 'image_name'
182
+
183
+ data
184
+ end
185
+
186
+ let(:user_map) { { '120' => 'user_name' } }
187
+ let(:image_map) { { '31' => 'image_name' } }
188
+
189
+ context 'with valid vm' do
190
+ let(:filename) { 'one_worker_valid_machine.xml' }
191
+
192
+ it 'returns correct vm data' do
193
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
194
+ end
195
+ end
196
+
197
+ context 'vm without STIME' do
198
+ let(:filename) { 'one_worker_STIME_missing.xml' }
199
+
200
+ it 'returns nil' do
201
+ expect(subject.process_vm(vm, user_map, image_map)).to be_nil
202
+ end
203
+ end
204
+
205
+ context 'vm with STIME that is not a number' do
206
+ let(:filename) { 'one_worker_STIME_nan.xml' }
207
+
208
+ it 'returns nil' do
209
+ expect(subject.process_vm(vm, user_map, image_map)).to be_nil
210
+ end
211
+ end
212
+
213
+ context 'vm without ETIME' do
214
+ before :example do
215
+ data['end_time'] = 'NULL'
216
+ data['suspend'] = 'NULL'
217
+ end
218
+
219
+ let(:filename) { 'one_worker_ETIME_missing.xml' }
220
+
221
+ it 'replaces ETIME with "NULL"' do
222
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
223
+ end
224
+ end
225
+
226
+ context 'vm with ETIME that is not a number' do
227
+ before :example do
228
+ data['end_time'] = 'NULL'
229
+ data['suspend'] = 'NULL'
230
+ end
231
+
232
+ let(:filename) { 'one_worker_ETIME_nan.xml' }
233
+
234
+ it 'replaces ETIME with "NULL"' do
235
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
236
+ end
237
+ end
238
+
239
+ context 'vm ETIME that is 0' do
240
+ before :example do
241
+ data['end_time'] = 'NULL'
242
+ data['suspend'] = 'NULL'
243
+ end
244
+
245
+ let(:filename) { 'one_worker_ETIME_0.xml' }
246
+
247
+ it 'replaces ETIME with "NULL"' do
248
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
249
+ end
250
+ end
251
+
252
+ context 'vm with STIME bigger than ETIME' do
253
+ let(:filename) { 'one_worker_STIME_>_ETIME.xml' }
254
+
255
+ it 'returns nil' do
256
+ expect(subject.process_vm(vm, user_map, image_map)).to be_nil
257
+ end
258
+ end
259
+
260
+ context 'vm without DEPLOY_ID' do
261
+ let(:filename) { 'one_worker_DEPLOY_ID_missing.xml' }
262
+
263
+ it 'replaces machine name with string created from id and prefix "one-"' do
264
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
265
+ end
266
+ end
267
+
268
+ context 'vm without UID' do
269
+ before :example do
270
+ data['user_id'] = 'NULL'
271
+ data['user_name'] = 'NULL'
272
+ end
273
+
274
+ let(:filename) { 'one_worker_UID_missing.xml' }
275
+
276
+ it 'replaces user id with "NULL"' do
277
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
278
+ end
279
+ end
280
+
281
+ context 'vm without GID' do
282
+ before :example do
283
+ data['group_id'] = 'NULL'
284
+ end
285
+
286
+ let(:filename) { 'one_worker_GID_missing.xml' }
287
+
288
+ it 'replaces group id with "NULL"' do
289
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
290
+ end
291
+ end
292
+
293
+ context 'vm without GNAME' do
294
+ before :example do
295
+ data['fqan'] = nil
296
+ end
297
+
298
+ let(:filename) { 'one_worker_GNAME_missing.xml' }
299
+
300
+ it 'sets fqan to nil' do
301
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
302
+ end
303
+ end
304
+
305
+ context 'vm without STATE' do
306
+ before :example do
307
+ data['status'] = 'NULL'
308
+ end
309
+
310
+ let(:filename) { 'one_worker_STATE_missing.xml' }
311
+
312
+ it 'replaces status with "NULL"' do
313
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
314
+ end
315
+ end
316
+
317
+ context 'vm with STATE with value out of range' do
318
+ before :example do
319
+ data['status'] = 'NULL'
320
+ end
321
+
322
+ let(:filename) { 'one_worker_STATE_out_of_range.xml' }
323
+
324
+ it 'replaces status with "NULL"' do
325
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
326
+ end
327
+ end
328
+
329
+ context 'vm without HISTORY_RECORDS' do
330
+ let(:filename) { 'one_worker_HISTORY_RECORDS_missing.xml' }
331
+
332
+ it 'returns nil' do
333
+ expect(subject.process_vm(vm, user_map, image_map)).to be_nil
334
+ end
335
+ end
336
+
337
+ context 'vm one HISTORY record' do
338
+ let(:filename) { 'one_worker_HISTORY_one.xml' }
339
+
340
+ it 'returns correct vm data' do
341
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
342
+ end
343
+ end
344
+
345
+ context 'vm many HISTORY records' do
346
+ before :example do
347
+ data['duration'] = '831'
348
+ data['suspend'] = '279'
349
+ end
350
+
351
+ let(:filename) { 'one_worker_HISTORY_many.xml' }
352
+
353
+ it 'returns correct vm data' do
354
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
355
+ end
356
+ end
357
+
358
+ context 'vm without TEMPLATE' do
359
+ before :example do
360
+ data['cpu_count'] = '1'
361
+ data['image_name'] = 'NULL'
362
+ end
363
+
364
+ let(:filename) { 'one_worker_TEMPLATE_missing.xml' }
365
+
366
+ it 'replaces items in TEMPLATE section with "NULL"' do
367
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
368
+ end
369
+ end
370
+
371
+ context 'vm without VCPU' do
372
+ before :example do
373
+ data['cpu_count'] = '1'
374
+ end
375
+
376
+ let(:filename) { 'one_worker_VCPU_missing.xml' }
377
+
378
+ it 'replaces cpu count with value 1' do
379
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
380
+ end
381
+ end
382
+
383
+ context 'vm with VCPU that is 0' do
384
+ before :example do
385
+ data['cpu_count'] = '1'
386
+ end
387
+
388
+ let(:filename) { 'one_worker_VCPU_0.xml' }
389
+
390
+ it 'replaces cpu count with value 1' do
391
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
392
+ end
393
+ end
394
+
395
+ context 'vm with VCPU that is not a number' do
396
+ before :example do
397
+ data['cpu_count'] = '1'
398
+ end
399
+
400
+ let(:filename) { 'one_worker_VCPU_nan.xml' }
401
+
402
+ it 'replaces cpu count with value 1' do
403
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
404
+ end
405
+ end
406
+
407
+ context 'vm without NET_TX' do
408
+ before :example do
409
+ data['network_inbound'] = 0
410
+ end
411
+
412
+ let(:filename) { 'one_worker_NET_TX_missing.xml' }
413
+
414
+ it 'replaces network outbound with value 0' do
415
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
416
+ end
417
+ end
418
+
419
+ context 'vm with NET_TX that is 0' do
420
+ before :example do
421
+ data['network_inbound'] = 0
422
+ end
423
+
424
+ let(:filename) { 'one_worker_NET_TX_0.xml' }
425
+
426
+ it 'replaces network outbound with value 0' do
427
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
428
+ end
429
+ end
430
+
431
+ context 'vm with NET_TX that is not a number' do
432
+ before :example do
433
+ data['network_inbound'] = 0
434
+ end
435
+
436
+ let(:filename) { 'one_worker_NET_TX_nan.xml' }
437
+
438
+ it 'replaces network outbound with value 0' do
439
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
440
+ end
441
+ end
442
+
443
+ context 'vm without NET_RX' do
444
+ before :example do
445
+ data['network_outbound'] = 0
446
+ end
447
+
448
+ let(:filename) { 'one_worker_NET_RX_missing.xml' }
449
+
450
+ it 'replaces network outbound with value 0' do
451
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
452
+ end
453
+ end
454
+
455
+ context 'vm with NET_RX that is 0' do
456
+ before :example do
457
+ data['network_outbound'] = 0
458
+ end
459
+
460
+ let(:filename) { 'one_worker_NET_RX_0.xml' }
461
+
462
+ it 'replaces network outbound with value 0' do
463
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
464
+ end
465
+ end
466
+
467
+ context 'vm with NET_RX that is not a number' do
468
+ before :example do
469
+ data['network_outbound'] = 0
470
+ end
471
+
472
+ let(:filename) { 'one_worker_NET_RX_nan.xml' }
473
+
474
+ it 'replaces network outbound with value 0' do
475
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
476
+ end
477
+ end
478
+
479
+ context 'vm without MEMORY' do
480
+ before :example do
481
+ data['memory'] = '0'
482
+ end
483
+
484
+ let(:filename) { 'one_worker_MEMORY_missing.xml' }
485
+
486
+ it 'replaces memory with value 0' do
487
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
488
+ end
489
+ end
490
+
491
+ context 'vm with MEMORY that is 0' do
492
+ before :example do
493
+ data['memory'] = '0'
494
+ end
495
+
496
+ let(:filename) { 'one_worker_MEMORY_0.xml' }
497
+
498
+ it 'replaces memory with value 0' do
499
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
500
+ end
501
+ end
502
+
503
+ context 'vm with MEMORY that is not a number' do
504
+ before :example do
505
+ data['memory'] = '0'
506
+ end
507
+
508
+ let(:filename) { 'one_worker_MEMORY_nan.xml' }
509
+
510
+ it 'replaces memory with value 0' do
511
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
512
+ end
513
+ end
514
+
515
+ context 'vm without DISK' do
516
+ before :example do
517
+ data['image_name'] = 'NULL'
518
+ end
519
+
520
+ let(:filename) { 'one_worker_DISK_missing.xml' }
521
+
522
+ it 'replaces image name with "NULL"' do
523
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
524
+ end
525
+ end
526
+
527
+ context 'vm without IMAGE_ID' do
528
+ before :example do
529
+ data['image_name'] = 'NULL'
530
+ end
531
+
532
+ let(:filename) { 'one_worker_IMAGE_ID_missing.xml' }
533
+
534
+ it 'replaces image name with "NULL"' do
535
+ expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
536
+ end
537
+ end
538
+ end
539
+
540
+ describe '.sum_rstime' do
541
+ let(:vm) do
542
+ xml = File.read("#{GEM_DIR}/mock/#{filename}")
543
+ OpenNebula::XMLElement.new(OpenNebula::XMLElement.build_xml(xml, 'VM'))
544
+ end
545
+
546
+ context 'vm without RSTIME' do
547
+ let(:filename) { 'one_worker_RSTIME_missing.xml' }
548
+
549
+ it 'returns 0' do
550
+ expect(subject.sum_rstime(vm)).to eq(0)
551
+ end
552
+ end
553
+
554
+ context 'vm with RSTIME that is 0' do
555
+ let(:filename) { 'one_worker_RSTIME_0.xml' }
556
+
557
+ it 'returns 0' do
558
+ expect(subject.sum_rstime(vm)).to eq(0)
559
+ end
560
+ end
561
+
562
+ context 'vm without RETIME' do
563
+ let(:filename) { 'one_worker_RETIME_missing.xml' }
564
+
565
+ it 'returns 0' do
566
+ expect(subject.sum_rstime(vm)).to eq(0)
567
+ end
568
+ end
569
+
570
+ context 'vm with RETIME that is 0' do
571
+ let(:filename) { 'one_worker_RETIME_0.xml' }
572
+
573
+ it 'returns 0' do
574
+ expect(subject.sum_rstime(vm)).to eq(0)
575
+ end
576
+ end
577
+
578
+ context 'vm with RSTIME bigger than RETIME' do
579
+ let(:filename) { 'one_worker_RSTIME_>_RETIME.xml' }
580
+
581
+ it 'returns nil' do
582
+ expect(subject.sum_rstime(vm)).to be_nil
583
+ end
584
+ end
585
+ end
586
+
587
+ describe '.perform' do
588
+ before :example do
589
+ allow(OneDataAccessor).to receive(:new) { oda }
590
+ allow(subject).to receive(:create_user_map) { user_map }
591
+ allow(subject).to receive(:create_image_map) { image_map }
592
+ allow(subject).to receive(:load_vm).and_return(:default)
593
+ allow(subject).to receive(:load_vm).with('10', oda).and_return(vm1)
594
+ allow(subject).to receive(:load_vm).with('20', oda).and_return(vm2)
595
+ allow(subject).to receive(:load_vm).with('30', oda).and_return(vm3)
596
+ end
597
+
598
+ let(:vms) { '10|20|30' }
599
+ let(:user_map) { { '120' => 'user_name' } }
600
+ let(:image_map) { { '31' => 'image_name' } }
601
+ let(:vm1) do
602
+ xml = File.read("#{GEM_DIR}/mock/one_worker_vm1.xml")
603
+ OpenNebula::XMLElement.new(OpenNebula::XMLElement.build_xml(xml, 'VM'))
604
+ end
605
+ let(:vm2) do
606
+ xml = File.read("#{GEM_DIR}/mock/one_worker_vm2.xml")
607
+ OpenNebula::XMLElement.new(OpenNebula::XMLElement.build_xml(xml, 'VM'))
608
+ end
609
+ let(:vm3) do
610
+ xml = File.read("#{GEM_DIR}/mock/one_worker_vm3.xml")
611
+ OpenNebula::XMLElement.new(OpenNebula::XMLElement.build_xml(xml, 'VM'))
612
+ end
613
+
614
+ let(:data) do
615
+ data = {}
616
+ data['endpoint'] = 'machine.hogwarts.co.uk'
617
+ data['site_name'] = 'Hogwarts'
618
+ data['cloud_type'] = 'OpenNebula'
619
+ data['vm_uuid'] = '36551'
620
+ data['start_time'] = '1383741160'
621
+ data['start_time_readable'] = '2013-11-06 13:32:40+01:00'
622
+ data['end_time'] = '1383742270'
623
+ data['machine_name'] = 'one-36551'
624
+ data['user_id'] = '120'
625
+ data['group_id'] = '0'
626
+ data['user_name'] = 'user_name'
627
+ data['fqan'] = 'gname'
628
+ data['status'] = 'completed'
629
+ data['duration'] = '596'
630
+ data['suspend'] = '514'
631
+ data['cpu_count'] = '1'
632
+ data['network_inbound'] = 0
633
+ data['network_outbound'] = 0
634
+ data['memory'] = '1736960'
635
+ data['image_name'] = 'image_name'
636
+
637
+ data
638
+ end
639
+
640
+ let(:vm1_data) { data }
641
+ let(:vm2_data) do
642
+ vm2_data = data.clone
643
+ vm2_data['vm_uuid'] = '36552'
644
+
645
+ vm2_data
646
+ end
647
+ let(:vm3_data) do
648
+ vm3_data = data.clone
649
+ vm3_data['vm_uuid'] = '36553'
650
+
651
+ vm3_data
652
+ end
653
+
654
+ context 'with valid vms' do
655
+ it 'writes vm data' do
656
+ expect(subject).to receive(:write_data).with([vm1_data, vm2_data, vm3_data], anything)
657
+ subject.perform(vms, 'output_dir')
658
+ end
659
+ end
660
+
661
+ context 'with one vm not loaded correclty' do
662
+ before :example do
663
+ allow(subject).to receive(:load_vm).with('20', oda).and_return(nil)
664
+ end
665
+
666
+ it 'writes data of the correct vms' do
667
+ expect(subject).to receive(:write_data).with([vm1_data, vm3_data], anything)
668
+ subject.perform(vms, 'output_dir')
669
+ end
670
+ end
671
+
672
+ context 'with one vm that has malformed data' do
673
+ let(:vm2) do
674
+ xml = File.read("#{GEM_DIR}/mock/one_worker_malformed_vm.xml")
675
+ OpenNebula::XMLElement.new(OpenNebula::XMLElement.build_xml(xml, 'VM'))
676
+ end
677
+
678
+ it 'writes data of the correct vms' do
679
+ expect(subject).to receive(:write_data).with([vm1_data, vm3_data], anything)
680
+ subject.perform(vms, 'output_dir')
681
+ end
682
+ end
683
+ end
684
+ end