oneacct-export 0.1.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 (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,146 @@
1
+ require 'spec_helper'
2
+
3
+ describe OneWriter do
4
+ subject { one_writer }
5
+ before :example do
6
+ Settings.output['output_type'] = 'one_writer_test_output_type'
7
+ end
8
+
9
+ let(:data) { { 'aaa' => 111, 'bbb' => 222 } }
10
+ let(:testfile) { "#{GEM_DIR}/mock/one_writer_testfile" }
11
+ let(:dev_null) { '/dev/null' }
12
+ let(:output) { "#{GEM_DIR}/mock/one_writer_output" }
13
+
14
+ describe '#new' do
15
+ context 'with correct arguments' do
16
+ before :example do
17
+ allow(OneWriter).to receive(:template_filename) { testfile }
18
+ end
19
+
20
+ let(:one_writer) do
21
+ OneWriter.new(data, output, dev_null)
22
+ end
23
+
24
+ it 'takes three parameters and returns OneWriter object' do
25
+ is_expected.to be_an_instance_of OneWriter
26
+ end
27
+
28
+ it 'correctly assigns three parameters' do
29
+ expect(subject.data).to eq(data)
30
+ expect(subject.output).to eq(output)
31
+ expect(subject.log).to eq(dev_null)
32
+ end
33
+ end
34
+
35
+ context 'with incorrect arguments' do
36
+ before :example do
37
+ allow(OneWriter).to receive(:template_filename) { testfile }
38
+ end
39
+
40
+ it 'fails with ArgumentError if output is nil' do
41
+ expect { OneWriter.new(data, nil, dev_null) }.to\
42
+ raise_error(ArgumentError)
43
+ end
44
+
45
+ it 'fails with ArgumentError if data is nil' do
46
+ expect { OneWriter.new(nil, output, dev_null) }.to raise_error(ArgumentError)
47
+ end
48
+ end
49
+
50
+ context 'with non existing template file' do
51
+ before :example do
52
+ allow(OneWriter).to receive(:template_filename) { 'non_existing' }
53
+ end
54
+
55
+ it 'fails with ArgumentError' do
56
+ expect { OneWriter.new(data, output, dev_null) }.to\
57
+ raise_error(ArgumentError)
58
+ end
59
+ end
60
+ end
61
+
62
+ describe '#template_filename' do
63
+ it 'returns template name in form of filename within template directory' do
64
+ expect(OneWriter.template_filename('test')).to eq("#{GEM_DIR}/lib/templates/test.erb")
65
+ end
66
+ end
67
+
68
+ describe '.fill_template' do
69
+ before :example do
70
+ allow(OneWriter).to receive(:template_filename) { testfile }
71
+ end
72
+
73
+ let(:one_writer) do
74
+ OneWriter.new(data, output, Logger.new(dev_null))
75
+ end
76
+
77
+ it 'returns result version of a template with data' do
78
+ expect(subject.fill_template).to eq("aaa: 111\nbbb: 222")
79
+ end
80
+ end
81
+
82
+ describe '.write_to_tmp' do
83
+ before :example do
84
+ allow(OneWriter).to receive(:template_filename) { testfile }
85
+ end
86
+
87
+ after :example do
88
+ File.delete(tmp) if File.exist?(tmp)
89
+ end
90
+
91
+ let(:tmp) { File.open("#{GEM_DIR}/mock/one_writer_tmp", 'w') }
92
+ let(:one_writer) do
93
+ OneWriter.new(data, output, Logger.new(dev_null))
94
+ end
95
+
96
+ it 'writes data into temporary file' do
97
+ subject.write_to_tmp(tmp, data)
98
+ expect(File.read(tmp)).to eq(data.to_s)
99
+ end
100
+ end
101
+
102
+ describe '.copy_to_output' do
103
+ before :example do
104
+ allow(OneWriter).to receive(:template_filename) { testfile }
105
+ end
106
+
107
+ after :example do
108
+ File.delete(to) if File.exist?(to)
109
+ end
110
+
111
+ let(:from) { testfile }
112
+ let(:to) { "#{GEM_DIR}/mock/one_writer_copy" }
113
+ let(:one_writer) do
114
+ OneWriter.new(data, output, Logger.new(dev_null))
115
+ end
116
+
117
+ it 'copies temporary file to output file' do
118
+ subject.copy_to_output(from, to)
119
+ expect(File.read(from)).to eq(File.read(to))
120
+ end
121
+ end
122
+
123
+ describe '.write' do
124
+ before :example do
125
+ allow(OneWriter).to receive(:template_filename) { testfile }
126
+ allow(subject).to receive(:fill_template) { data }
127
+ allow(Tempfile).to receive(:new) { tmp }
128
+ end
129
+
130
+ let(:one_writer) do
131
+ OneWriter.new(data, output, Logger.new(dev_null))
132
+ end
133
+ let(:tmp) do
134
+ tmp = double('tmp')
135
+ allow(tmp).to receive(:path) { "#{GEM_DIR}/mock/one_writer_tmp" }
136
+ tmp
137
+ end
138
+
139
+ it 'writes result version of a template into output file' do
140
+ expect(subject).to receive(:write_to_tmp).with(tmp, data)
141
+ expect(subject).to receive(:copy_to_output).with("#{GEM_DIR}/mock/one_writer_tmp", output)
142
+ expect(tmp).to receive(:close)
143
+ subject.write
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,262 @@
1
+ require 'spec_helper'
2
+ require 'ostruct'
3
+
4
+ Sidekiq::Testing.fake!
5
+
6
+ describe OneacctExporter do
7
+ subject { oneacct_exporter }
8
+
9
+ let(:oneacct_exporter) { OneacctExporter.new({}, Logger.new('/dev/null')) }
10
+
11
+ describe '#new' do
12
+ it 'returns an instance of OneacctExporter' do
13
+ expect(OneacctExporter.new({}, 'fake_logger')).to be_instance_of(OneacctExporter)
14
+ end
15
+
16
+ context 'with arguments' do
17
+ let(:range) { { 1 => 2, 3 => 4 } }
18
+ let(:groups) { { 5 => 6, 7 => 8 } }
19
+ let(:timeout) { 42 }
20
+ let(:blocking) { true }
21
+ let(:logger) { 'fake_logger' }
22
+ let(:opts) { { range: range, groups: groups, timeout: timeout, blocking: blocking } }
23
+
24
+ it 'correctly assignes the arguments' do
25
+ oe = OneacctExporter.new(opts, logger)
26
+ expect(oe.log).to eq(logger)
27
+ expect(oe.groups).to eq(groups)
28
+ expect(oe.range).to eq(range)
29
+ expect(oe.blocking).to eq(blocking)
30
+ expect(oe.timeout).to eq(timeout)
31
+ end
32
+ end
33
+ end
34
+
35
+ describe '.export' do
36
+ before :example do
37
+ allow(subject).to receive(:clean_output_dir)
38
+ allow(OneDataAccessor).to receive(:new) { oda }
39
+ end
40
+
41
+ let(:oda) { double('oda') }
42
+
43
+ context 'with increasing batch number' do
44
+ before :example do
45
+ expect(oda).to receive(:vms).with(0, nil, nil).ordered { [1, 2, 3] }
46
+ expect(oda).to receive(:vms).with(1, nil, nil).ordered { [4, 5, 6] }
47
+ expect(oda).to receive(:vms).with(2, nil, nil).ordered { [7, 8, 9] }
48
+ expect(oda).to receive(:vms).with(3, nil, nil).ordered { nil }
49
+ end
50
+
51
+ it 'will always finish when there are no more vms to process' do
52
+ subject.export
53
+ end
54
+ end
55
+
56
+ context 'with non-empty batches of vms' do
57
+ before :example do
58
+ Sidekiq::Worker.clear_all
59
+ allow(oda).to receive(:vms).with(0, nil, nil).ordered { [1, 2, 3] }
60
+ allow(oda).to receive(:vms).with(1, nil, nil).ordered { [4, 5, 6] }
61
+ allow(oda).to receive(:vms).with(2, nil, nil).ordered { [7, 8, 9] }
62
+ allow(oda).to receive(:vms).with(3, nil, nil).ordered { nil }
63
+ end
64
+
65
+ after :example do
66
+ Sidekiq::Worker.clear_all
67
+ end
68
+
69
+ it 'starts worker for every vm batch' do
70
+ subject.export
71
+ expect(OneWorker.jobs.size).to eq(3)
72
+ end
73
+
74
+ it 'starts worker with right vms' do
75
+ subject.export
76
+ expect(OneWorker.jobs[0]['args'][0]).to eq('1|2|3')
77
+ expect(OneWorker.jobs[1]['args'][0]).to eq('4|5|6')
78
+ expect(OneWorker.jobs[2]['args'][0]).to eq('7|8|9')
79
+ end
80
+ end
81
+
82
+ context 'with some empty batches of vms' do
83
+ before :example do
84
+ Sidekiq::Worker.clear_all
85
+ allow(oda).to receive(:vms).with(0, nil, nil).ordered { [1, 2, 3] }
86
+ allow(oda).to receive(:vms).with(1, nil, nil).ordered { [] }
87
+ allow(oda).to receive(:vms).with(2, nil, nil).ordered { [7, 8, 9] }
88
+ allow(oda).to receive(:vms).with(3, nil, nil).ordered { [] }
89
+ allow(oda).to receive(:vms).with(4, nil, nil).ordered { nil }
90
+ end
91
+
92
+ after :example do
93
+ Sidekiq::Worker.clear_all
94
+ end
95
+
96
+ it 'starts worker for every non-empty vm batch' do
97
+ subject.export
98
+ expect(OneWorker.jobs.size).to eq(2)
99
+ end
100
+ end
101
+ end
102
+
103
+ describe '.clean_output_dir' do
104
+ let(:testdir_path) { "#{GEM_DIR}/mock/oneacct_exporter_testdir" }
105
+
106
+ before :example do
107
+ Settings.output['output_dir'] = testdir_path
108
+ Dir.mkdir(testdir_path)
109
+ end
110
+
111
+ after :example do
112
+ FileUtils.remove_dir(testdir_path, true)
113
+ end
114
+
115
+ context 'with empty output directory' do
116
+ it 'remains empty' do
117
+ subject.clean_output_dir
118
+ expect(Dir.entries(testdir_path).count).to eq(2)
119
+ end
120
+ end
121
+
122
+ context 'with not related files' do
123
+ before :example do
124
+ FileUtils.touch("#{testdir_path}/aa")
125
+ FileUtils.touch("#{testdir_path}/11")
126
+ FileUtils.touch("#{testdir_path}/aa11")
127
+ FileUtils.touch("#{testdir_path}/11aa")
128
+ FileUtils.touch("#{testdir_path}/0")
129
+ FileUtils.touch("#{testdir_path}/01")
130
+ FileUtils.touch("#{testdir_path}/0000000000001")
131
+ end
132
+
133
+ it 'keeps non-related files in the directory' do
134
+ subject.clean_output_dir
135
+ expect(Dir.entries(testdir_path).count).to eq(9)
136
+ end
137
+ end
138
+
139
+ context 'with related files' do
140
+ before :example do
141
+ FileUtils.touch("#{testdir_path}/00000000000001")
142
+ FileUtils.touch("#{testdir_path}/00000000000002")
143
+ FileUtils.touch("#{testdir_path}/00000000000003")
144
+ FileUtils.touch("#{testdir_path}/00000000000004")
145
+ FileUtils.touch("#{testdir_path}/00000000000005")
146
+ FileUtils.touch("#{testdir_path}/00000000000006")
147
+ end
148
+
149
+ it 'removes all files and leaves directory empty' do
150
+ subject.clean_output_dir
151
+ expect(Dir.entries(testdir_path).count).to eq(2)
152
+ end
153
+ end
154
+
155
+ context 'with both related and on-related files' do
156
+ before :example do
157
+ FileUtils.touch("#{testdir_path}/00000000000001")
158
+ FileUtils.touch("#{testdir_path}/00000000000002")
159
+ FileUtils.touch("#{testdir_path}/00000000000003")
160
+ FileUtils.touch("#{testdir_path}/00000000000004")
161
+ FileUtils.touch("#{testdir_path}/00000000000005")
162
+ FileUtils.touch("#{testdir_path}/00000000000006")
163
+ FileUtils.touch("#{testdir_path}/aa")
164
+ FileUtils.touch("#{testdir_path}/11")
165
+ FileUtils.touch("#{testdir_path}/aa11")
166
+ FileUtils.touch("#{testdir_path}/11aa")
167
+ FileUtils.touch("#{testdir_path}/0")
168
+ FileUtils.touch("#{testdir_path}/01")
169
+ FileUtils.touch("#{testdir_path}/0000000000001")
170
+ end
171
+
172
+ it 'removes all related files and keeps all non-related files' do
173
+ subject.clean_output_dir
174
+ expect(Dir.entries(testdir_path).count).to eq(9)
175
+ end
176
+ end
177
+ end
178
+
179
+ describe '.all_workers_done?' do
180
+ context 'with all workers done' do
181
+ before :example do
182
+ allow(Sidekiq::Workers).to receive(:new) { [] }
183
+ end
184
+
185
+ it 'returns true' do
186
+ expect(subject.all_workers_done?).to be true
187
+ end
188
+ end
189
+
190
+ context 'with some workers still processing' do
191
+ before :example do
192
+ allow(Sidekiq::Workers).to receive(:new) { [1, 2] }
193
+ end
194
+
195
+ it 'returns false' do
196
+ expect(subject.all_workers_done?).to be false
197
+ end
198
+ end
199
+ end
200
+
201
+ describe '.queue_empty?' do
202
+ before :example do
203
+ Settings.sidekiq['queue'] = 'oneacct_export_test'
204
+ stats = double('stats')
205
+ allow(Sidekiq::Stats).to receive(:new) { stats }
206
+ allow(stats).to receive(:queues) { queues }
207
+ end
208
+
209
+ let(:queues) { { 'queue1' => 5, 'queue2' => 0, 'oneacct_export_test' => 0, 'queue3' => 7 } }
210
+
211
+ context 'with empty queue' do
212
+ it 'returns true' do
213
+ expect(subject.queue_empty?).to be true
214
+ end
215
+ end
216
+
217
+ context 'with empty queue' do
218
+ before :example do
219
+ queues['oneacct_export_test'] = 10
220
+ end
221
+
222
+ it 'returns false' do
223
+ expect(subject.queue_empty?).to be false
224
+ end
225
+ end
226
+
227
+ context 'with empty queue' do
228
+ before :example do
229
+ queues.delete 'oneacct_export_test'
230
+ end
231
+
232
+ it 'returns true' do
233
+ expect(subject.queue_empty?).to be true
234
+ end
235
+ end
236
+ end
237
+
238
+ describe '.wait_for_processing' do
239
+ let(:oneacct_exporter) { OneacctExporter.new({ timeout: 120 }, Logger.new('/dev/null')) }
240
+
241
+ context 'without timeout' do
242
+ it 'ends naturally' do
243
+ expect(subject).to receive(:queue_empty?).and_return(false, false, true, true, true)
244
+ expect(subject).to receive(:all_workers_done?).and_return(false, false, true)
245
+
246
+ subject.wait_for_processing
247
+ end
248
+ end
249
+
250
+ context 'with unfinished processing and exceeded timeout' do
251
+ let(:oneacct_exporter) { OneacctExporter.new({ timeout: 20 }, Logger.new('/dev/null')) }
252
+
253
+ it 'ends program' do
254
+ allow(subject).to receive(:queue_empty?) { false }
255
+ allow(subject).to receive(:all_workers_done?) { false }
256
+ expect(subject.log).to receive(:error)
257
+
258
+ subject.wait_for_processing
259
+ end
260
+ end
261
+ end
262
+ end
@@ -0,0 +1,229 @@
1
+ require 'spec_helper'
2
+
3
+ describe OneacctOpts do
4
+ before :example do
5
+ allow(OneWriter).to receive(:template_filename) { "#{GEM_DIR}/mock/one_writer_testfile" }
6
+ end
7
+
8
+ let(:options) { OpenStruct.new }
9
+
10
+ describe '#set_defaults' do
11
+ context 'with empty options' do
12
+ it 'sets the default values' do
13
+ OneacctOpts.set_defaults(options)
14
+ expect(options.blocking).to eq(OneacctOpts::BLOCKING_DEFAULT)
15
+ expect(options.timeout).to be_nil
16
+ expect(options.compatibility).to eq(OneacctOpts::COMPATIBILITY_DEFAULT)
17
+ end
18
+ end
19
+
20
+ context 'with blocking set' do
21
+ before :example do
22
+ options.blocking = true
23
+ end
24
+
25
+ it 'keeps the blocking option' do
26
+ OneacctOpts.set_defaults(options)
27
+ expect(options.blocking).to eq(true)
28
+ expect(options.timeout).to eq(OneacctOpts::TIMEOUT_DEFAULT)
29
+ expect(options.compatibility).to eq(OneacctOpts::COMPATIBILITY_DEFAULT)
30
+ end
31
+ end
32
+
33
+ context 'with timeout set' do
34
+ before :example do
35
+ options.timeout = 42
36
+ end
37
+
38
+ it 'keeps the blocking option' do
39
+ OneacctOpts.set_defaults(options)
40
+ expect(options.blocking).to eq(OneacctOpts::BLOCKING_DEFAULT)
41
+ expect(options.timeout).to eq(42)
42
+ expect(options.compatibility).to eq(OneacctOpts::COMPATIBILITY_DEFAULT)
43
+ end
44
+ end
45
+
46
+ context 'with compatibility set' do
47
+ before :example do
48
+ options.compatibility = true
49
+ end
50
+
51
+ it 'keeps the blocking option' do
52
+ OneacctOpts.set_defaults(options)
53
+ expect(options.blocking).to eq(OneacctOpts::BLOCKING_DEFAULT)
54
+ expect(options.timeout).to be_nil
55
+ expect(options.compatibility).to eq(true)
56
+ end
57
+ end
58
+ end
59
+
60
+ describe '#check_options_restrictions' do
61
+ context 'with wrong time range' do
62
+ before :example do
63
+ options.records_from = (Time.new + 1000)
64
+ options.records_to = (Time.new - 1000)
65
+ end
66
+
67
+ it 'fails with ArgumentError' do
68
+ expect { OneacctOpts.check_options_restrictions(options) }.to raise_error(ArgumentError)
69
+ end
70
+ end
71
+
72
+ context 'with mixed groups' do
73
+ before :example do
74
+ options.include_groups = ['group']
75
+ options.exclude_groups = ['group']
76
+ end
77
+
78
+ it 'fails with ArgumentError' do
79
+ expect { OneacctOpts.check_options_restrictions(options) }.to raise_error(ArgumentError)
80
+ end
81
+ end
82
+
83
+ context 'with group file set without group restriction type' do
84
+ before :example do
85
+ options.groups_file = 'file'
86
+ end
87
+
88
+ it 'fails with ArgumentError' do
89
+ expect { OneacctOpts.check_options_restrictions(options) }.to raise_error(ArgumentError)
90
+ end
91
+ end
92
+
93
+ context 'with timout set without blocking option' do
94
+ before :example do
95
+ options.timeout = 50
96
+ end
97
+
98
+ it 'fails with ArgumentError' do
99
+ expect { OneacctOpts.check_options_restrictions(options) }.to raise_error(ArgumentError)
100
+ end
101
+ end
102
+
103
+ context 'with correct set of options' do
104
+ before :example do
105
+ options.records_from = (Time.new - 1000)
106
+ options.records_to = (Time.new + 1000)
107
+ options.include_groups = []
108
+ options.groups_file = 'file'
109
+ options.blocking = true
110
+ options.timeout = 50
111
+ end
112
+
113
+ it 'finishes without any failure' do
114
+ OneacctOpts.check_options_restrictions(options)
115
+ end
116
+ end
117
+ end
118
+
119
+ describe '#check_settings_restrictions' do
120
+ before :example do
121
+ Settings['site_name'] = 'Hogwarts'
122
+ Settings['cloud_type'] = 'OpenNebula'
123
+ Settings['endpoint'] = 'machine.hogwarts.co.uk'
124
+ Settings.output['output_dir'] = '/some/output/dir'
125
+ Settings.output['output_type'] = 'apel-v0.2'
126
+ Settings.logging['log_type'] = 'file'
127
+ Settings.logging['log_file'] = '/var/log/oneacct.log'
128
+ end
129
+
130
+ context 'with missing mandatory paramter' do
131
+ context 'site_name' do
132
+ before :example do
133
+ Settings['site_name'] = nil
134
+ end
135
+
136
+ it 'falis with ArgumentError' do
137
+ expect { OneacctOpts.check_settings_restrictions }.to raise_error(ArgumentError)
138
+ end
139
+ end
140
+
141
+ context 'cloud_type' do
142
+ before :example do
143
+ Settings['cloud_type'] = nil
144
+ end
145
+
146
+ it 'falis with ArgumentError' do
147
+ expect { OneacctOpts.check_settings_restrictions }.to raise_error(ArgumentError)
148
+ end
149
+ end
150
+
151
+ context 'endpoint' do
152
+ before :example do
153
+ Settings['endpoint'] = nil
154
+ end
155
+
156
+ it 'falis with ArgumentError' do
157
+ expect { OneacctOpts.check_settings_restrictions }.to raise_error(ArgumentError)
158
+ end
159
+ end
160
+
161
+ context 'output_dir' do
162
+ before :example do
163
+ Settings.output['output_dir'] = nil
164
+ end
165
+
166
+ it 'falis with ArgumentError' do
167
+ expect { OneacctOpts.check_settings_restrictions }.to raise_error(ArgumentError)
168
+ end
169
+ end
170
+
171
+ context 'output_type' do
172
+ before :example do
173
+ Settings.output['output_type'] = nil
174
+ end
175
+
176
+ it 'falis with ArgumentError' do
177
+ expect { OneacctOpts.check_settings_restrictions }.to raise_error(ArgumentError)
178
+ end
179
+ end
180
+ end
181
+
182
+ context 'with logging set to file without file specified' do
183
+ before :example do
184
+ Settings.logging['log_type'] = 'file'
185
+ Settings.logging['log_file'] = nil
186
+ end
187
+
188
+ it 'falis with ArgumentError' do
189
+ expect { OneacctOpts.check_settings_restrictions }.to raise_error(ArgumentError)
190
+ end
191
+ end
192
+
193
+ context 'with non existing template' do
194
+ before :example do
195
+ allow(OneWriter).to receive(:template_filename) { 'nonexisting_file' }
196
+ end
197
+
198
+ it 'falis with ArgumentError' do
199
+ expect { OneacctOpts.check_settings_restrictions }.to raise_error(ArgumentError)
200
+ end
201
+ end
202
+
203
+ context 'with all settings correct' do
204
+ it 'finishes without any failure' do
205
+ OneacctOpts.check_settings_restrictions
206
+ end
207
+ end
208
+ end
209
+
210
+ describe '#parse' do
211
+ let(:args) { ['--records-from', '01.01.2014', '--records-to', '01.07.2014', '--include-groups', 'aaa,bbb,ccc', '-b', '-t', '50', '-c'] }
212
+
213
+ it 'returns correctly parsed options' do
214
+ options = OneacctOpts.parse(args)
215
+ expect(options.records_from).to be_instance_of(Time)
216
+ expect(options.records_from).to eq(Time.new(2014, 1, 1))
217
+ expect(options.records_to).to be_instance_of(Time)
218
+ expect(options.records_to).to eq(Time.new(2014, 7, 1))
219
+ expect(options.include_groups).to be_instance_of(Array)
220
+ expect(options.include_groups).to eq(%w(aaa bbb ccc))
221
+ expect(options.blocking).to be_instance_of(TrueClass)
222
+ expect(options.blocking).to be true
223
+ expect(options.timeout).to be_instance_of(Fixnum)
224
+ expect(options.timeout).to eq(50)
225
+ expect(options.compatibility).to be_instance_of(TrueClass)
226
+ expect(options.compatibility).to be true
227
+ end
228
+ end
229
+ end