oneacct-export 0.2.7 → 0.3.0

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.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +1 -21
  5. data/bin/oneacct-export +7 -6
  6. data/config/conf.yml +25 -7
  7. data/lib/data_validators/apel_data_validator.rb +99 -0
  8. data/lib/data_validators/data_compute.rb +57 -0
  9. data/lib/data_validators/data_validator.rb +12 -0
  10. data/lib/data_validators/data_validator_helper.rb +15 -0
  11. data/lib/data_validators/logstash_data_validator.rb +82 -0
  12. data/lib/data_validators/pbs_data_validator.rb +86 -0
  13. data/lib/errors/not_implemented_error.rb +3 -0
  14. data/lib/errors/validation_error.rb +3 -0
  15. data/lib/errors.rb +2 -0
  16. data/lib/input_validator.rb +12 -2
  17. data/lib/one_data_accessor.rb +11 -10
  18. data/lib/one_worker.rb +109 -137
  19. data/lib/oneacct_exporter/version.rb +1 -1
  20. data/lib/oneacct_exporter.rb +9 -7
  21. data/lib/oneacct_opts.rb +36 -13
  22. data/lib/output_types.rb +5 -0
  23. data/lib/redis_conf.rb +2 -2
  24. data/lib/settings.rb +3 -3
  25. data/lib/templates/apel-0.2.erb +6 -6
  26. data/lib/templates/logstash-0.1.erb +3 -0
  27. data/lib/templates/pbs-0.1.erb +6 -0
  28. data/mock/{one_worker_vm8.xml → one_worker_vm_dn01.xml} +76 -74
  29. data/mock/one_worker_vm_dn02.xml +174 -0
  30. data/mock/{one_worker_DISK_missing.xml → one_worker_vm_empty_disk_records.xml} +10 -6
  31. data/mock/one_worker_vm_empty_history_records.xml +131 -0
  32. data/mock/one_worker_vm_image_name01.xml +175 -0
  33. data/mock/{one_worker_valid_machine.xml → one_worker_vm_image_name02.xml} +35 -7
  34. data/mock/one_worker_vm_image_name03.xml +167 -0
  35. data/mock/{one_worker_vm2.xml → one_worker_vm_image_name04.xml} +38 -9
  36. data/mock/{one_worker_vm1.xml → one_worker_vm_image_name05.xml} +36 -8
  37. data/mock/{one_worker_vm9.xml → one_worker_vm_image_name06.xml} +8 -5
  38. data/oneacct-export.gemspec +1 -0
  39. data/spec/data_validators/apel_data_validator_spec.rb +497 -0
  40. data/spec/data_validators/data_compute_spec.rb +193 -0
  41. data/spec/data_validators/data_validator_helper_spec.rb +66 -0
  42. data/spec/data_validators/data_validator_spec.rb +14 -0
  43. data/spec/data_validators/logstash_data_validator_spec.rb +469 -0
  44. data/spec/data_validators/pbs_data_validator_spec.rb +353 -0
  45. data/spec/one_worker_spec.rb +234 -542
  46. data/spec/oneacct_exporter_spec.rb +1 -41
  47. data/spec/oneacct_opts_spec.rb +135 -32
  48. data/spec/spec_helper.rb +18 -1
  49. metadata +51 -52
  50. data/mock/one_worker_DEPLOY_ID_missing.xml +0 -136
  51. data/mock/one_worker_DISK_SIZE_nan.xml +0 -147
  52. data/mock/one_worker_ETIME_0.xml +0 -137
  53. data/mock/one_worker_ETIME_missing.xml +0 -136
  54. data/mock/one_worker_ETIME_nan.xml +0 -137
  55. data/mock/one_worker_GID_missing.xml +0 -136
  56. data/mock/one_worker_GNAME_missing.xml +0 -136
  57. data/mock/one_worker_HISTORY_RECORDS_missing.xml +0 -91
  58. data/mock/one_worker_HISTORY_many.xml +0 -137
  59. data/mock/one_worker_HISTORY_missing.xml +0 -93
  60. data/mock/one_worker_HISTORY_one.xml +0 -115
  61. data/mock/one_worker_IMAGE_ID_missing.xml +0 -136
  62. data/mock/one_worker_MEMORY_0.xml +0 -137
  63. data/mock/one_worker_MEMORY_missing.xml +0 -135
  64. data/mock/one_worker_MEMORY_nan.xml +0 -137
  65. data/mock/one_worker_NET_RX_0.xml +0 -137
  66. data/mock/one_worker_NET_RX_missing.xml +0 -136
  67. data/mock/one_worker_NET_RX_nan.xml +0 -137
  68. data/mock/one_worker_NET_TX_0.xml +0 -137
  69. data/mock/one_worker_NET_TX_missing.xml +0 -136
  70. data/mock/one_worker_NET_TX_nan.xml +0 -137
  71. data/mock/one_worker_RETIME_0_RUNNING.xml +0 -115
  72. data/mock/one_worker_RETIME_0_STOPPED.xml +0 -115
  73. data/mock/one_worker_RETIME_missing.xml +0 -114
  74. data/mock/one_worker_RSTIME_0.xml +0 -115
  75. data/mock/one_worker_RSTIME_>_RETIME.xml +0 -115
  76. data/mock/one_worker_RSTIME_missing.xml +0 -114
  77. data/mock/one_worker_STATE_missing.xml +0 -136
  78. data/mock/one_worker_STATE_out_of_range.xml +0 -137
  79. data/mock/one_worker_STIME_>_ETIME.xml +0 -137
  80. data/mock/one_worker_STIME_missing.xml +0 -136
  81. data/mock/one_worker_STIME_nan.xml +0 -137
  82. data/mock/one_worker_TEMPLATE_missing.xml +0 -79
  83. data/mock/one_worker_UID_missing.xml +0 -136
  84. data/mock/one_worker_VCPU_0.xml +0 -137
  85. data/mock/one_worker_VCPU_missing.xml +0 -136
  86. data/mock/one_worker_VCPU_nan.xml +0 -137
  87. data/mock/one_worker_malformed_vm.xml +0 -136
  88. data/mock/one_worker_vm3.xml +0 -137
  89. data/mock/one_worker_vm4.xml +0 -106
  90. data/mock/one_worker_vm5.xml +0 -106
  91. data/mock/one_worker_vm6.xml +0 -107
  92. data/mock/one_worker_vm7.xml +0 -147
@@ -6,17 +6,36 @@ describe OneWorker do
6
6
  let(:one_worker) { OneWorker.new }
7
7
  let(:oda) { double('oda') }
8
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'
9
+ describe '.output_type_specific_data' do
10
+ context 'with output type apel' do
11
+ before :example do
12
+ Settings.output['output_type'] = 'apel-0.2'
13
+ Settings.output.apel['endpoint'] = 'machine.hogwarts.co.uk'
14
+ Settings.output.apel['site_name'] = 'Hogwarts'
15
+ Settings.output.apel['cloud_type'] = 'OpenNebula'
16
+ end
17
+
18
+ let(:output_type_specific_data) { {'endpoint' => 'machine.hogwarts.co.uk', 'site_name' => 'Hogwarts', 'cloud_type' => 'OpenNebula'} }
19
+
20
+ it 'returns data specific for apel output type in form of hash' do
21
+ expect(subject.output_type_specific_data).to eq(output_type_specific_data)
22
+ end
14
23
  end
15
24
 
16
- let(:common_data) { { 'endpoint' => 'machine.hogwarts.co.uk', 'site_name' => 'Hogwarts', 'cloud_type' => 'OpenNebula' } }
25
+ context 'with output type pbs' do
26
+ before :example do
27
+ Settings.output['output_type'] = 'pbs-0.1'
28
+ Settings.output.pbs['realm'] = 'REALM'
29
+ Settings.output.pbs['queue'] = 'cloud'
30
+ Settings.output.pbs['scratch_type'] = 'local'
31
+ Settings.output.pbs['host_identifier'] = 'on_localhost'
32
+ end
33
+
34
+ let(:output_type_specific_data) { {'realm' => 'REALM', 'pbs_queue' => 'cloud', 'scratch_type' => 'local', 'host' => 'on_localhost'} }
17
35
 
18
- it 'returns data common for every vm in form of hash' do
19
- expect(subject.common_data).to eq(common_data)
36
+ it 'returns data specific for pbs output type in form of hash' do
37
+ expect(subject.output_type_specific_data).to eq(output_type_specific_data)
38
+ end
20
39
  end
21
40
  end
22
41
 
@@ -83,38 +102,6 @@ describe OneWorker do
83
102
  end
84
103
  end
85
104
 
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
105
  describe 'write_data' do
119
106
  before :example do
120
107
  expect(OneWriter).to receive(:new).with(data, output, anything) { ow }
@@ -145,11 +132,14 @@ describe OneWorker do
145
132
  end
146
133
  end
147
134
 
148
- describe '.process_vm' do
135
+ describe 'process_vm' do
149
136
  before :example do
150
- Settings['endpoint'] = 'machine.hogwarts.co.uk'
151
- Settings['site_name'] = 'Hogwarts'
152
- Settings['cloud_type'] = 'OpenNebula'
137
+ Settings.output['output_type'] = 'apel-0.2'
138
+ Settings.output.apel['endpoint'] = 'machine.hogwarts.co.uk'
139
+ Settings.output.apel['site_name'] = 'Hogwarts'
140
+ Settings.output.apel['cloud_type'] = 'OpenNebula'
141
+
142
+ allow(vm).to receive(:state_str) { 'DONE' }
153
143
  end
154
144
 
155
145
  let(:vm) do
@@ -159,650 +149,352 @@ describe OneWorker do
159
149
 
160
150
  let(:data) do
161
151
  data = {}
152
+
162
153
  data['endpoint'] = 'machine.hogwarts.co.uk'
163
154
  data['site_name'] = 'Hogwarts'
164
155
  data['cloud_type'] = 'OpenNebula'
156
+
165
157
  data['vm_uuid'] = '36551'
166
- data['start_time'] = Time.at(1383741160)
167
- data['end_time'] = Time.at(1383742270)
158
+ data['start_time'] = '1383741160'
159
+ data['end_time'] = '1383742270'
168
160
  data['machine_name'] = 'one-36551'
169
161
  data['user_id'] = '120'
170
162
  data['group_id'] = '0'
171
- data['user_name'] = 'user_name'
172
- data['fqan'] = 'gname'
173
- data['status'] = 'completed'
174
- data['duration'] = '596'
175
- data['suspend'] = '514'
163
+ data['user_name'] = 'uname'
164
+ data['group_name'] = 'gname'
165
+ data['status_code'] = '6'
166
+ data['status'] = 'DONE'
176
167
  data['cpu_count'] = '1'
177
- data['network_inbound'] = 0
178
- data['network_outbound'] = 0
168
+ data['network_inbound'] = '43557888'
169
+ data['network_outbound'] = '376832'
179
170
  data['memory'] = '1736960'
180
- data['image_name'] = 'image_name'
181
- data['disk_size'] = 'NULL'
171
+ history = []
172
+ rec = {}
173
+ rec['start_time'] = '1383741169'
174
+ rec['end_time'] = '1383741259'
175
+ rec['rstart_time'] = '0'
176
+ rec['rend_time'] = '0'
177
+ rec['seq'] = '0'
178
+ rec['hostname'] = 'supermachine1.somewhere.com'
179
+ history << rec
180
+ rec = {}
181
+ rec['start_time'] = '1383741589'
182
+ rec['end_time'] = '1383742270'
183
+ rec['rstart_time'] = '1383741674'
184
+ rec['rend_time'] = '1383742270'
185
+ rec['seq'] = '1'
186
+ rec['hostname'] = 'supermachine2.somewhere.com'
187
+ history << rec
188
+ data['history'] = history
189
+ data['disks'] = [{'size' => '10240'}, {'size' => '42368'}]
190
+
191
+ data['user_dn'] = '/Dn=FrOm/CN=DN/CN=TeMpLaTe'
192
+ data['image_name'] = 'https://appdb.egi.eu/store/vo/image/image_name_from_VMCATCHER_EVENT_AD_MPURI_tag/'
182
193
 
183
194
  data
184
195
  end
185
196
 
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
- data['memory'] = '0'
363
- end
364
-
365
- let(:filename) { 'one_worker_TEMPLATE_missing.xml' }
366
-
367
- it 'replaces items in TEMPLATE section with "NULL"' do
368
- expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
369
- end
370
- end
371
-
372
- context 'vm without VCPU' do
373
- before :example do
374
- data['cpu_count'] = '1'
375
- end
197
+ let(:user_map) { {'120' => '/Dn=FrOm/CN=DN/CN=MaP'} }
198
+ let(:image_map) { {'31' => 'image_name_from_map'} }
376
199
 
377
- let(:filename) { 'one_worker_VCPU_missing.xml' }
200
+ context 'with apel specific data' do
201
+ let(:filename) { 'one_worker_vm_dn01.xml' }
378
202
 
379
- it 'replaces cpu count with value 1' do
203
+ it 'returns correct vm data with apel specific data' do
380
204
  expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
381
205
  end
382
206
  end
383
207
 
384
- context 'vm with VCPU that is 0' do
208
+ context 'with pbs specific data' do
385
209
  before :example do
386
- data['cpu_count'] = '1'
387
- end
210
+ Settings.output['output_type'] = 'pbs-0.1'
211
+ Settings.output.pbs['realm'] = 'REALM'
212
+ Settings.output.pbs['queue'] = 'cloud'
213
+ Settings.output.pbs['scratch_type'] = 'local'
214
+ Settings.output.pbs['host_identifier'] = 'on_localhost'
388
215
 
389
- let(:filename) { 'one_worker_VCPU_0.xml' }
390
-
391
- it 'replaces cpu count with value 1' do
392
- expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
393
- end
394
- end
216
+ data['realm'] = 'REALM'
217
+ data['pbs_queue'] = 'cloud'
218
+ data['scratch_type'] = 'local'
219
+ data['host'] = 'on_localhost'
395
220
 
396
- context 'vm with VCPU that is not a number' do
397
- before :example do
398
- data['cpu_count'] = '1'
221
+ data.delete 'endpoint'
222
+ data.delete 'site_name'
223
+ data.delete 'cloud_type'
399
224
  end
400
225
 
401
- let(:filename) { 'one_worker_VCPU_nan.xml' }
226
+ let(:filename) { 'one_worker_vm_dn01.xml' }
402
227
 
403
- it 'replaces cpu count with value 1' do
228
+ it 'returns correct vm data with pbs specific data' do
404
229
  expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
405
230
  end
406
231
  end
407
232
 
408
- context 'vm without NET_TX' do
409
- before :example do
410
- data['network_inbound'] = 0
411
- end
233
+ context 'with user\'s dn in template' do
234
+ let(:filename) { 'one_worker_vm_dn01.xml' }
412
235
 
413
- let(:filename) { 'one_worker_NET_TX_missing.xml' }
414
-
415
- it 'replaces network outbound with value 0' do
236
+ it 'returns correct vm data with user\'s dn from template' do
416
237
  expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
417
238
  end
418
239
  end
419
240
 
420
- context 'vm with NET_TX that is 0' do
421
- before :example do
422
- data['network_inbound'] = 0
423
- end
424
-
425
- let(:filename) { 'one_worker_NET_TX_0.xml' }
426
-
427
- it 'replaces network outbound with value 0' do
428
- expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
429
- end
430
- end
241
+ context 'with user\'s dn in map' do
242
+ let(:filename) { 'one_worker_vm_dn02.xml' }
431
243
 
432
- context 'vm with NET_TX that is not a number' do
433
244
  before :example do
434
- data['network_inbound'] = 0
245
+ data['user_dn'] = '/Dn=FrOm/CN=DN/CN=MaP'
435
246
  end
436
247
 
437
- let(:filename) { 'one_worker_NET_TX_nan.xml' }
438
-
439
- it 'replaces network outbound with value 0' do
248
+ it 'returns correct vm data with user\'s dn from map' do
440
249
  expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
441
250
  end
442
251
  end
443
252
 
444
- context 'vm without NET_RX' do
445
- before :example do
446
- data['network_outbound'] = 0
447
- end
253
+ context 'with image name in VMCATCHER_EVENT_AD_MPURI tag' do
254
+ let(:filename) { 'one_worker_vm_image_name01.xml' }
448
255
 
449
- let(:filename) { 'one_worker_NET_RX_missing.xml' }
450
-
451
- it 'replaces network outbound with value 0' do
256
+ it 'returns correct vm data with image name from VMCATCHER_EVENT_AD_MPURI tag' do
452
257
  expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
453
258
  end
454
259
  end
455
260
 
456
- context 'vm with NET_RX that is 0' do
457
- before :example do
458
- data['network_outbound'] = 0
459
- end
460
-
461
- let(:filename) { 'one_worker_NET_RX_0.xml' }
261
+ context 'with image name in map' do
262
+ let(:filename) { 'one_worker_vm_image_name02.xml' }
462
263
 
463
- it 'replaces network outbound with value 0' do
464
- expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
465
- end
466
- end
467
-
468
- context 'vm with NET_RX that is not a number' do
469
264
  before :example do
470
- data['network_outbound'] = 0
265
+ data['image_name'] = 'image_name_from_map'
471
266
  end
472
267
 
473
- let(:filename) { 'one_worker_NET_RX_nan.xml' }
474
-
475
- it 'replaces network outbound with value 0' do
268
+ it 'returns correct vm data with image name from map' do
476
269
  expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
477
270
  end
478
271
  end
479
272
 
480
- context 'vm without MEMORY' do
481
- before :example do
482
- data['memory'] = '0'
483
- end
484
-
485
- let(:filename) { 'one_worker_MEMORY_missing.xml' }
486
-
487
- it 'replaces memory with value 0' do
488
- expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
489
- end
490
- end
273
+ #TODO should be moved into tests for mixin method
274
+ context 'with image name in USER_TEMPLATE/OCCI_COMPUTE_MIXINS tag' do
275
+ let(:filename) { 'one_worker_vm_image_name03.xml' }
491
276
 
492
- context 'vm with MEMORY that is 0' do
493
277
  before :example do
494
- data['memory'] = '0'
278
+ data['image_name'] = 'http://occi.localhost/occi/infrastructure/os_tpl#image_name_from_USER_TEMPLATE_OCCI_COMPUTE_MIXINS'
495
279
  end
496
280
 
497
- let(:filename) { 'one_worker_MEMORY_0.xml' }
498
-
499
- it 'replaces memory with value 0' do
281
+ it 'returns correct vm data with image name from USER_TEMPLATE/OCCI_COMPUTE_MIXINS tag' do
500
282
  expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
501
283
  end
502
284
  end
503
285
 
504
- context 'vm with MEMORY that is not a number' do
505
- before :example do
506
- data['memory'] = '0'
507
- end
508
-
509
- let(:filename) { 'one_worker_MEMORY_nan.xml' }
510
-
511
- it 'replaces memory with value 0' do
512
- expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
513
- end
514
- end
286
+ #TODO should be moved into tests for mixin method
287
+ context 'with image name in USER_TEMPLATE/OCCI_MIXIN tag' do
288
+ let(:filename) { 'one_worker_vm_image_name04.xml' }
515
289
 
516
- context 'vm without DISK' do
517
290
  before :example do
518
- data['image_name'] = 'NULL'
291
+ data['image_name'] = 'http://occi.localhost/occi/infrastructure/os_tpl#image_name_from_USER_TEMPLATE_OCCI_MIXIN'
519
292
  end
520
293
 
521
- let(:filename) { 'one_worker_DISK_missing.xml' }
522
-
523
- it 'replaces image name with "NULL"' do
294
+ it 'returns correct vm data with image name from USER_TEMPLATE/OCCI_MIXIN tag' do
524
295
  expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
525
296
  end
526
297
  end
527
298
 
528
- context 'vm with TEMPLATE/DISK/VMCATCHER_EVENT_AD_MPURI' do
529
- let(:filename) { 'one_worker_vm7.xml'}
530
- let(:image_name) { 'https://appdb.egi.eu/store/vo/image/662b0e71-3e21-5f43-b6a1-cc2f51319fa7:156/' }
531
-
532
- it 'uses TEMPLATE/DISK/VMCATCHER_EVENT_AD_MPURI for image id mapping' do
533
- expect(subject.process_vm(vm, user_map, image_map)['image_name']).to eq(image_name)
534
- end
535
- end
536
-
537
- context 'vm without IMAGE_ID' do
538
- before :example do
539
- data['image_name'] = 'NULL'
540
- end
541
-
542
- let(:filename) { 'one_worker_IMAGE_ID_missing.xml' }
543
-
544
- it 'replaces image name with "NULL"' do
545
- expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
546
- end
547
- end
299
+ #TODO should be moved into tests for mixin method
300
+ context 'with image name in TEMPLATE/OCCI_MIXIN tag' do
301
+ let(:filename) { 'one_worker_vm_image_name05.xml' }
548
302
 
549
- context 'vm without IMAGE_ID mapping' do
550
303
  before :example do
551
- data['image_name'] = '31'
304
+ data['image_name'] = 'http://occi.localhost/occi/infrastructure/os_tpl#image_name_from_TEMPLATE_OCCI_MIXIN'
552
305
  end
553
306
 
554
- let(:image_map) { { 'non_existing_id' => 'name' } }
555
- let(:filename) { 'one_worker_valid_machine.xml' }
556
-
557
- it 'replaces image name with IMAGE_ID' do
307
+ it 'returns correct vm data with image name from TEMPLATE/OCCI_MIXIN tag' do
558
308
  expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
559
309
  end
560
310
  end
561
311
 
562
- context 'vm with USER_TEMPLATE/OCCI_COMPUTE_MIXINS' do
563
- let(:filename) { 'one_worker_vm4.xml' }
564
- let(:image_name) { 'http://occi.localhost/occi/infrastructure/os_tpl#uuid_monitoring_20' }
565
-
566
- it 'w/o map info uses os_tpl mixin' do
567
- expect(subject.process_vm(vm, user_map, {})['image_name']).to eq(image_name)
568
- end
569
-
570
- it 'w/ map info uses map info' do
571
- expect(subject.process_vm(vm, user_map, image_map)['image_name']).to eq(data['image_name'])
572
- end
573
- end
574
-
575
- context 'vm with USER_TEMPLATE/OCCI_MIXIN' do
576
- let(:filename) { 'one_worker_vm5.xml' }
577
- let(:image_name) { 'https://occi.localhost/occi/infrastructure/os_tpl#omr_worker_x86_64_ide_1_0' }
578
-
579
- it 'w/o map info uses os_tpl mixin' do
580
- expect(subject.process_vm(vm, user_map, {})['image_name']).to eq(image_name)
581
- end
582
-
583
- it 'w/ map info uses map info' do
584
- expect(subject.process_vm(vm, user_map, image_map)['image_name']).to eq(data['image_name'])
585
- end
586
- end
587
-
588
- context 'vm with USER_TEMPLATE/USER_X509_DN' do
589
- let(:filename) { 'one_worker_vm6.xml' }
590
- let(:user_name) { '/MY=STuPID/CN=DN/CN=HERE' }
312
+ context 'with image name as image id' do
313
+ let(:filename) { 'one_worker_vm_image_name06.xml' }
591
314
 
592
- it 'w/o map info uses USER_X509_DN' do
593
- expect(subject.process_vm(vm, user_map, {})['user_name']).to eq(user_name)
594
- end
595
-
596
- it 'w/ map info uses USER_X509_DN' do
597
- expect(subject.process_vm(vm, user_map, image_map)['user_name']).to eq(user_name)
598
- end
599
- end
600
-
601
- context 'vm with DISK SIZEs' do
602
315
  before :example do
603
- data['disk_size'] = 53
316
+ data['image_name'] = '42'
604
317
  end
605
318
 
606
- let(:filename) { 'one_worker_vm9.xml' }
607
-
608
- it 'correctly sums disk sizes' do
319
+ it 'returns correct vm data with image name as image id' do
609
320
  expect(subject.process_vm(vm, user_map, image_map)).to eq(data)
610
321
  end
611
322
  end
612
323
  end
613
324
 
614
- describe '.sum_disk_size' do
325
+ describe 'history_records' do
615
326
  let(:vm) do
616
327
  xml = File.read("#{GEM_DIR}/mock/#{filename}")
617
328
  OpenNebula::XMLElement.new(OpenNebula::XMLElement.build_xml(xml, 'VM'))
618
329
  end
619
330
 
620
- context 'vm with DISK without SIZE' do
621
- let(:filename) { 'one_worker_valid_machine.xml' }
622
-
623
- it 'returns NULL' do
624
- expect(subject.sum_disk_size(vm)).to eq('NULL')
625
- end
626
- end
627
-
628
- context 'vm with DISK with invalid SIZE' do
629
- let(:filename) { 'one_worker_DISK_SIZE_nan.xml' }
331
+ let(:history) do
332
+ history = []
333
+ rec = {}
334
+ rec['start_time'] = '1383741169'
335
+ rec['end_time'] = '1383741259'
336
+ rec['rstart_time'] = '0'
337
+ rec['rend_time'] = '0'
338
+ rec['seq'] = '0'
339
+ rec['hostname'] = 'supermachine1.somewhere.com'
340
+ history << rec
341
+ rec = {}
342
+ rec['start_time'] = '1383741589'
343
+ rec['end_time'] = '1383742270'
344
+ rec['rstart_time'] = '1383741674'
345
+ rec['rend_time'] = '1383742270'
346
+ rec['seq'] = '1'
347
+ rec['hostname'] = 'supermachine2.somewhere.com'
348
+ history << rec
630
349
 
631
- it 'returns NULL' do
632
- expect(subject.sum_disk_size(vm)).to eq('NULL')
633
- end
350
+ history
634
351
  end
635
352
 
636
- context 'vm with single DISK and valid SIZE' do
637
- let(:filename) { 'one_worker_vm7.xml' }
353
+ context 'with correct history records in vm' do
354
+ let(:filename) { 'one_worker_vm_dn01.xml' }
638
355
 
639
- it 'return correct disk size' do
640
- expect(subject.sum_disk_size(vm)).to eq(11)
356
+ it 'returns history records for vm' do
357
+ expect(subject.history_records(vm)).to eq(history)
641
358
  end
642
359
  end
643
360
 
644
- context 'vm with multiple DISKs and valid SIZE' do
645
- let(:filename) { 'one_worker_vm8.xml' }
361
+ context 'with no history records' do
362
+ let(:filename) { 'one_worker_vm_empty_history_records.xml' }
646
363
 
647
- it 'return correct disk size' do
648
- expect(subject.sum_disk_size(vm)).to eq(53)
364
+ it 'returns emtpy array' do
365
+ expect(subject.history_records(vm)).to be_empty
649
366
  end
650
367
  end
651
368
  end
652
369
 
653
- describe '.sum_rstime' do
370
+ describe 'disk_records' do
654
371
  let(:vm) do
655
372
  xml = File.read("#{GEM_DIR}/mock/#{filename}")
656
373
  OpenNebula::XMLElement.new(OpenNebula::XMLElement.build_xml(xml, 'VM'))
657
374
  end
658
375
 
659
- context 'vm without RSTIME' do
660
- let(:filename) { 'one_worker_RSTIME_missing.xml' }
661
-
662
- it 'returns 0' do
663
- expect(subject.sum_rstime(vm)).to eq(0)
664
- end
665
- end
666
-
667
- context 'vm with RSTIME that is 0' do
668
- let(:filename) { 'one_worker_RSTIME_0.xml' }
669
-
670
- it 'returns 0' do
671
- expect(subject.sum_rstime(vm)).to eq(0)
672
- end
673
- end
674
-
675
- context 'vm without RETIME' do
676
- let(:filename) { 'one_worker_RETIME_missing.xml' }
376
+ let(:disks) do
377
+ disks = []
378
+ disk = {}
379
+ disk['size'] = '10240'
380
+ disks << disk
381
+ disk = {}
382
+ disk['size'] = '42368'
383
+ disks << disk
677
384
 
678
- it 'returns 0' do
679
- expect(subject.sum_rstime(vm)).to eq(0)
680
- end
681
- end
682
-
683
- context 'vm with RETIME that is 0 and still running' do
684
- before :example do
685
- allow(Time).to receive(:now) { Time.at(1383741716) }
686
- end
687
-
688
- let(:filename) { 'one_worker_RETIME_0_RUNNING.xml' }
689
-
690
- it 'returns difference between current time and start of the virtual machine' do
691
- expect(subject.sum_rstime(vm)).to eq(42)
692
- end
385
+ disks
693
386
  end
694
387
 
695
- context 'vm with RETIME that is 0 and is stopped' do
696
- let(:filename) { 'one_worker_RETIME_0_STOPPED.xml' }
388
+ context 'with correct disk records in vm' do
389
+ let(:filename) { 'one_worker_vm_dn01.xml' }
697
390
 
698
- it 'returns nil' do
699
- expect(subject.sum_rstime(vm)).to be_nil
391
+ it 'returns history records for vm' do
392
+ expect(subject.disk_records(vm)).to eq(disks)
700
393
  end
701
394
  end
702
395
 
703
- context 'vm with RSTIME bigger than RETIME' do
704
- let(:filename) { 'one_worker_RSTIME_>_RETIME.xml' }
396
+ context 'with no disk records' do
397
+ let(:filename) { 'one_worker_vm_empty_disk_records.xml' }
705
398
 
706
- it 'returns nil' do
707
- expect(subject.sum_rstime(vm)).to be_nil
399
+ it 'returns emtpy array' do
400
+ expect(subject.disk_records(vm)).to be_empty
708
401
  end
709
402
  end
710
403
  end
711
404
 
712
405
  describe '.perform' do
713
406
  before :example do
407
+ Settings.output['output_type'] = 'unknown'
714
408
  allow(OneDataAccessor).to receive(:new) { oda }
715
- allow(subject).to receive(:create_user_map) { user_map }
716
- allow(subject).to receive(:create_image_map) { image_map }
409
+ allow(subject).to receive(:create_user_map) { 'user_map' }
410
+ allow(subject).to receive(:create_image_map) { 'image_map' }
717
411
  allow(subject).to receive(:load_vm).and_return(:default)
718
- allow(subject).to receive(:load_vm).with('10', oda).and_return(vm1)
719
- allow(subject).to receive(:load_vm).with('20', oda).and_return(vm2)
720
- allow(subject).to receive(:load_vm).with('30', oda).and_return(vm3)
412
+ allow(subject).to receive(:load_vm).with('10', oda).and_return('10')
413
+ allow(subject).to receive(:load_vm).with('20', oda).and_return('20')
414
+ allow(subject).to receive(:load_vm).with('30', oda).and_return('30')
415
+ allow(subject).to receive(:process_vm).with('10', anything, anything).and_return('data_vm1')
416
+ allow(subject).to receive(:process_vm).with('20', anything, anything).and_return('data_vm2')
417
+ allow(subject).to receive(:process_vm).with('30', anything, anything).and_return('data_vm3')
721
418
  end
722
419
 
723
420
  let(:vms) { '10|20|30' }
724
- let(:user_map) { { '120' => 'user_name' } }
725
- let(:image_map) { { '31' => 'image_name' } }
726
- let(:vm1) do
727
- xml = File.read("#{GEM_DIR}/mock/one_worker_vm1.xml")
728
- OpenNebula::XMLElement.new(OpenNebula::XMLElement.build_xml(xml, 'VM'))
729
- end
730
- let(:vm2) do
731
- xml = File.read("#{GEM_DIR}/mock/one_worker_vm2.xml")
732
- OpenNebula::XMLElement.new(OpenNebula::XMLElement.build_xml(xml, 'VM'))
733
- end
734
- let(:vm3) do
735
- xml = File.read("#{GEM_DIR}/mock/one_worker_vm3.xml")
736
- OpenNebula::XMLElement.new(OpenNebula::XMLElement.build_xml(xml, 'VM'))
421
+ let(:file_number) { 42 }
422
+
423
+ context 'with valid vms' do
424
+ it 'writes vm data' do
425
+ expect(subject).to receive(:write_data).with(['data_vm1', 'data_vm2', 'data_vm3'], file_number)
426
+ subject.perform(vms, file_number)
427
+ end
737
428
  end
738
429
 
739
- let(:data) do
740
- data = {}
741
- data['endpoint'] = 'machine.hogwarts.co.uk'
742
- data['site_name'] = 'Hogwarts'
743
- data['cloud_type'] = 'OpenNebula'
744
- data['vm_uuid'] = '36551'
745
- data['start_time'] = Time.at(1383741160)
746
- data['end_time'] = Time.at(1383742270)
747
- data['machine_name'] = 'one-36551'
748
- data['user_id'] = '120'
749
- data['group_id'] = '0'
750
- data['user_name'] = 'user_name'
751
- data['fqan'] = 'gname'
752
- data['status'] = 'completed'
753
- data['duration'] = '596'
754
- data['suspend'] = '514'
755
- data['cpu_count'] = '1'
756
- data['network_inbound'] = 0
757
- data['network_outbound'] = 0
758
- data['memory'] = '1736960'
759
- data['image_name'] = 'image_name'
760
- data['disk_size'] = 'NULL'
430
+ context 'with one vm not loaded correctly' do
431
+ before :example do
432
+ allow(subject).to receive(:load_vm).with('20', oda).and_return(nil)
433
+ end
761
434
 
762
- data
435
+ it 'writes data of the correct vms' do
436
+ expect(subject).to receive(:write_data).with(['data_vm1', 'data_vm3'], file_number)
437
+ subject.perform(vms, file_number)
438
+ end
763
439
  end
764
440
 
765
- let(:vm1_data) { data }
766
- let(:vm2_data) do
767
- vm2_data = data.clone
768
- vm2_data['vm_uuid'] = '36552'
441
+ context 'with apel data validator' do
442
+ before :example do
443
+ Settings.output['output_type'] = 'apel-0.2'
444
+ end
769
445
 
770
- vm2_data
771
- end
772
- let(:vm3_data) do
773
- vm3_data = data.clone
774
- vm3_data['vm_uuid'] = '36553'
446
+ let(:validator) { double('validator') }
775
447
 
776
- vm3_data
777
- end
448
+ context 'and all vm valid' do
449
+ it 'uses apel data validator to validate all vms and all passes' do
450
+ expect(DataValidators::ApelDataValidator).to receive(:new).and_return(validator).exactly(3).times
451
+ expect(validator).to receive(:validate_data).with('data_vm1').and_return('valid_data_vm1')
452
+ expect(validator).to receive(:validate_data).with('data_vm2').and_return('valid_data_vm2')
453
+ expect(validator).to receive(:validate_data).with('data_vm3').and_return('valid_data_vm3')
454
+ expect(subject).to receive(:write_data).with(['valid_data_vm1', 'valid_data_vm2', 'valid_data_vm3'], file_number)
455
+ subject.perform(vms, file_number)
456
+ end
457
+ end
778
458
 
779
- context 'with valid vms' do
780
- it 'writes vm data' do
781
- expect(subject).to receive(:write_data).with([vm1_data, vm2_data, vm3_data], anything)
782
- subject.perform(vms, 'output_dir')
459
+ context 'and all vm valid but one' do
460
+ it 'uses apel data validator to validate all vms and all but one passes' do
461
+ expect(DataValidators::ApelDataValidator).to receive(:new).and_return(validator).exactly(3).times
462
+ expect(validator).to receive(:validate_data).with('data_vm1').and_return('valid_data_vm1')
463
+ expect(validator).to receive(:validate_data).with('data_vm2').and_raise(Errors::ValidationError)
464
+ expect(validator).to receive(:validate_data).with('data_vm3').and_return('valid_data_vm3')
465
+ expect(subject).to receive(:write_data).with(['valid_data_vm1', 'valid_data_vm3'], file_number)
466
+ subject.perform(vms, file_number)
467
+ end
783
468
  end
784
469
  end
785
470
 
786
- context 'with one vm not loaded correclty' do
471
+ context 'with apel data validator' do
787
472
  before :example do
788
- allow(subject).to receive(:load_vm).with('20', oda).and_return(nil)
473
+ Settings.output['output_type'] = 'pbs-0.1'
789
474
  end
790
475
 
791
- it 'writes data of the correct vms' do
792
- expect(subject).to receive(:write_data).with([vm1_data, vm3_data], anything)
793
- subject.perform(vms, 'output_dir')
794
- end
795
- end
476
+ let(:validator) { double('validator') }
796
477
 
797
- context 'with one vm that has malformed data' do
798
- let(:vm2) do
799
- xml = File.read("#{GEM_DIR}/mock/one_worker_malformed_vm.xml")
800
- OpenNebula::XMLElement.new(OpenNebula::XMLElement.build_xml(xml, 'VM'))
478
+ context 'and all vm valid' do
479
+ it 'uses apel data validator to validate all vms and all passes' do
480
+ expect(DataValidators::PbsDataValidator).to receive(:new).and_return(validator).exactly(3).times
481
+ expect(validator).to receive(:validate_data).with('data_vm1').and_return('valid_data_vm1')
482
+ expect(validator).to receive(:validate_data).with('data_vm2').and_return('valid_data_vm2')
483
+ expect(validator).to receive(:validate_data).with('data_vm3').and_return('valid_data_vm3')
484
+ expect(subject).to receive(:write_data).with(['valid_data_vm1', 'valid_data_vm2', 'valid_data_vm3'], file_number)
485
+ subject.perform(vms, file_number)
486
+ end
801
487
  end
802
488
 
803
- it 'writes data of the correct vms' do
804
- expect(subject).to receive(:write_data).with([vm1_data, vm3_data], anything)
805
- subject.perform(vms, 'output_dir')
489
+ context 'and all vm valid but one' do
490
+ it 'uses apel data validator to validate all vms and all but one passes' do
491
+ expect(DataValidators::PbsDataValidator).to receive(:new).and_return(validator).exactly(3).times
492
+ expect(validator).to receive(:validate_data).with('data_vm1').and_return('valid_data_vm1')
493
+ expect(validator).to receive(:validate_data).with('data_vm2').and_raise(Errors::ValidationError)
494
+ expect(validator).to receive(:validate_data).with('data_vm3').and_return('valid_data_vm3')
495
+ expect(subject).to receive(:write_data).with(['valid_data_vm1', 'valid_data_vm3'], file_number)
496
+ subject.perform(vms, file_number)
497
+ end
806
498
  end
807
499
  end
808
500
  end