File: monitoring_spec.rb

package info (click to toggle)
ruby-fog-openstack 1.1.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,784 kB
  • sloc: ruby: 47,937; makefile: 5; sh: 4
file content (387 lines) | stat: -rw-r--r-- 15,927 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
require 'spec_helper'
require_relative './shared_context'
require 'fog/openstack/monitoring/models/metric'
require 'time'

describe Fog::OpenStack::Monitoring do
  spec_data_folder = 'spec/fixtures/openstack/monitoring'

  before :all do
    openstack_vcr = OpenStackVCR.new(
      :vcr_directory => spec_data_folder,
      :service_class => Fog::OpenStack::Monitoring
    )
    @service      = openstack_vcr.service
    @timestamp    = 146_375_736_714_3
  end

  it 'metric crud tests' do
    VCR.use_cassette('metric_crud') do
      # create single metric
      metric_0 = @service.metrics.create(:name       => 'sample_metric_0',
                                         :timestamp  => @timestamp,
                                         :dimensions => {"key1" => "value1"},
                                         :value      => 42,
                                         :value_meta => {"meta_key1" => "meta_value1"})

      metric_0.wont_be_nil

      # create multiple metrics

      metric_1 = Fog::OpenStack::Monitoring::Metric.new(:name       => 'sample_metric_1',
                                                        :timestamp  => @timestamp,
                                                        :dimensions => {"key1" => "value1"},
                                                        :value      => 42,
                                                        :value_meta => {"meta_key1" => "meta_value1"})

      metric_2 = Fog::OpenStack::Monitoring::Metric.new(:name       => 'sample_metric_2',
                                                        :timestamp  => @timestamp,
                                                        :dimensions => {"key1" => "value1"},
                                                        :value      => 42,
                                                        :value_meta => {"meta_key1" => "meta_value1"})

      @service.metrics.create_metric_array([metric_1, metric_2])

      metric_0_identity = {:name       => 'sample_metric_0',
                           :dimensions => {"key1" => "value1"}}

      metric_1_identity = {:name       => 'sample_metric_1',
                           :dimensions => {"key1" => "value1"}}

      metric_2_identity = {:name       => 'sample_metric_2',
                           :dimensions => {"key1" => "value1"}}

      # list metrics filtered by name and search for previuosly created metrics by unique identifier of name,dimensions
      [metric_0_identity, metric_1_identity, metric_2_identity].each do |metric_identity|
        metrics_all = @service.metrics.all(:name => metric_identity[:name])
        metrics_all.wont_be_nil
        metrics_all.wont_be_empty
        metrics_all_identities = metrics_all.collect do |_metric|
          {:name       => metric_identity[:name],
           :dimensions => metric_identity[:dimensions]}
        end

        metrics_all_identities.must_include(metric_identity)
      end

      # list all metric names
      metrics_name_list = @service.metrics.list_metric_names

      metrics_name_list.wont_be_nil
      metrics_name_list.wont_be_empty

      # failure cases
      proc do
        @service.metrics.create(:name => "this won't be created due to insufficient args")
      end.must_raise ArgumentError

      proc do
        @service.metrics.create(:name => "this wont't be created due to invalid timestamp", :timestamp => 1234)
      end.must_raise ArgumentError
    end
  end

  it 'list measurements by name and start_time' do
    VCR.use_cassette('metric_measurement_list') do
      measurement_list = @service.measurements.find(:name          => 'cpu.user_perc',
                                                    :start_time    => '2016-04-01T14:43:00Z',
                                                    :merge_metrics => true)

      measurement_list.wont_be_nil
      measurement_list.wont_be_empty

      # should return an empty list
      measurement_list_empty = @service.measurements.find(:name       => 'non.existing.metric_name',
                                                          :start_time => '2016-04-01T14:43:00Z')

      measurement_list_empty.must_be_empty
    end
  end

  it 'find statistics specified by name, start_time and statistics' do
    VCR.use_cassette('statistics_list') do
      statistics_list = @service.statistics.all(:name          => 'cpu.system_perc',
                                                :start_time    => '2016-04-01T14:43:00Z',
                                                :statistics    => 'avg,min,max,sum,count',
                                                :merge_metrics => true)

      statistics_list.wont_be_nil
      statistics_list.wont_be_empty
    end
  end

  it 'notification methods crud test' do
    VCR.use_cassette('notification-methods_crud') do
      begin
        # create notification method
        notification_method      = @service.notification_methods.create(:name    => 'important notification',
                                                                        :type    => 'EMAIL',
                                                                        :address => 'admin@example.com',
                                                                        :period  => 0)

        # list all notification methods
        notification_methods_all = @service.notification_methods.all

        notification_methods_all.wont_be_nil
        notification_methods_all.wont_be_empty

        # find a notification method by id
        notification_method_by_id = @service.notification_methods.find_by_id(notification_method.id)

        notification_method.must_equal notification_method_by_id

        # update specific an existing notification
        notification_method.update(:name    => notification_method.name,
                                   :address => 'notification_methods@example.com',
                                   :type    => notification_method.type,
                                   :period  => 0)

        notification_method.address.must_equal 'notification_methods@example.com'
        notification_method.period.must_equal 0

        # Delete the notification method and make sure it is no longer found in the list
        notification_method.destroy
        (@service.notification_methods.all.include? notification_method).must_equal false
        notification_method = nil

        # failure cases
        proc do
          @service.notification_methods.create(:name => "this won't be created due to insufficient args")
        end.must_raise ArgumentError

        proc do
          @service.notification_methods.find_by_id('bogus_id')
        end.must_raise Fog::OpenStack::Monitoring::NotFound
      ensure
        notification_method.destroy if notification_method
      end
    end
  end

  it 'alarm definitions crud test' do
    VCR.use_cassette('alarm_definition_crud') do
      begin
        # create an alarm defintion
        alarm_definition = @service.alarm_definitions.create(
          :name        => 'average cpu usage in perc',
          :match_by    => ['hostname'],
          :expression  => '(avg(cpu.user_perc{hostname=devstack}) > 10)',
          :description => 'Definition for an important alarm'
        )

        # list all alarm definitions
        alarm_definitions_all = @service.alarm_definitions.all

        alarm_definitions_all.wont_be_nil
        alarm_definitions_all.wont_be_empty

        # find an alarm-definition by id
        alarm_definition_by_id = @service.alarm_definitions.find_by_id(alarm_definition.id)

        alarm_definition.id.must_equal alarm_definition_by_id.id
        alarm_definition.name.must_equal alarm_definition_by_id.name
        alarm_definition.expression.must_equal alarm_definition_by_id.expression
        alarm_definition.deterministic.must_equal false

        # create a notification method for the following test
        notification_method       = @service.notification_methods.create(:name    => 'important notification',
                                                                         :type    => 'EMAIL',
                                                                         :address => 'admin@example.com')

        # replace an alarm_definition
        alarm_definition_replaced = alarm_definition.update(
          :name                 => 'CPU percent greater than 15',
          :match_by             => ['hostname'],
          :description          => 'Replaced alarm-definition expression',
          :expression           => '(avg(cpu.user_perc{hostname=devstack}) > 15)',
          :severity             => 'LOW',
          :alarm_actions        => [notification_method.id],
          :ok_actions           => [notification_method.id],
          :undetermined_actions => [notification_method.id],
          :actions_enabled      => true
        )

        alarm_definition_replaced.id.must_equal alarm_definition.id
        alarm_definition_replaced.name.must_equal 'CPU percent greater than 15'
        alarm_definition_replaced.description.must_equal 'Replaced alarm-definition expression'
        alarm_definition_replaced.expression.must_equal '(avg(cpu.user_perc{hostname=devstack}) > 15)'
        #
        # patch specific attributes of alarm_definition
        alarm_definition_updated = alarm_definition.patch(:description => 'An updated alarm-definition.')

        alarm_definition.id.must_equal alarm_definition_updated.id
        alarm_definition_updated.description.must_equal 'An updated alarm-definition.'

        # delete alarm definition
        alarm_definition.destroy

        # ensure the alarm definition does not exist any more
        (@service.alarm_definitions.all.include? alarm_definition).must_equal false
        alarm_definition = nil

        # delete the notification method
        notification_method.destroy
        notification_method = nil

        # failure cases
        proc do
          @service.alarm_definitions.create(:name => "this won't be created due to insufficient args")
        end.must_raise ArgumentError
      ensure
        alarm_definition.destroy if alarm_definition
        notification_method.destroy if notification_method
      end
    end
  end

  it 'alarm crud test' do
    VCR.use_cassette('alarm_crud') do
      begin
        # create notification method
        notification_method = @service.notification_methods.create(:name    => 'another notification',
                                                                   :type    => 'EMAIL',
                                                                   :address => 'admin@example.com')

        # create an alarm definition which ensures an alarm is thrown
        alarm_definition = @service.alarm_definitions.create(:name        => 'avg cpu.user_per ge 0',
                                                             :expression  => '(avg(cpu.user_perc) >= 0)',
                                                             :description => 'ensure an alarm is thrown in crud test.')

        # list all alarms
        alarms_all = @service.alarms.all

        alarms_all.wont_be_nil
        alarms_all.wont_be_empty

        # list all alarms in ALARM state
        alarms_all_state_filter = @service.alarms.all(:state => 'OK')

        alarms_all_state_filter.wont_be_nil
        alarms_all_state_filter.wont_be_empty

        # get an alarm by name using list all alarms with filter
        alarm_list_by_name_filter = @service.alarms.all(:metric_name => 'cpu.idle_perc')
        alarm_by_name             = alarm_list_by_name_filter.first

        alarm_by_name.wont_be_nil

        # get the id of this alarm
        alarm_id    = alarm_by_name.id

        # find alarm by id
        alarm_by_id = @service.alarms.find_by_id(alarm_id)

        alarm_by_name.id.must_equal alarm_by_id.id
        alarm_by_name.state.must_equal alarm_by_id.state
        alarm_by_name.lifecycle_state.must_equal alarm_by_id.lifecycle_state

        # replace the entire state of the specified alarm
        alarm_by_id.update(:state           => 'ALARM',
                           :lifecycle_state => 'OPEN',
                           :link            => 'http://pagerduty.com/')

        alarm_by_id.state.must_equal 'ALARM'
        alarm_by_id.lifecycle_state.must_equal 'OPEN'
        alarm_by_id.link.must_equal 'http://pagerduty.com/'

        # check the link of an alarm before patching
        alarm_by_id.link.wont_equal 'http://somesite.com/this-alarm-info'

        # patch specific attributes of an existing alarm
        alarm_by_id.patch(:link => 'http://somesite.com/this-alarm-info')

        # check the link afterwards
        alarm_by_id.link.must_equal 'http://somesite.com/this-alarm-info'

        # list alarm state history for all alarms but limit history to 5
        alarm_state_history_all = @service.alarm_states.all(:limit => 5)

        alarm_state_history_all.wont_be_nil
        alarm_state_history_all.length.must_equal 5

        # list alarm state history
        alarm_state_history_for_alarm = @service.alarm_states.list_alarm_state_history(alarm_id)

        alarm_state_history_for_alarm.wont_be_nil
        alarm_state_history_for_alarm.wont_be_empty

        # delete an existing alarm
        alarm_by_id.destroy

        (@service.alarms.all.include? alarm_by_id).must_equal false

        alarm_definition    = nil
        notification_method = nil
      ensure
        # cleanup
        alarm_definition.destroy if alarm_definition
        notification_method.destroy if notification_method
      end
    end
  end

  it 'list alarm state history for all alarms' do
    VCR.use_cassette('alarm_state_history_all') do
      # get the alarm state history for all alarms
      alarm_state_history_all = @service.alarm_states.all

      alarm_state_history_all.wont_be_nil
      alarm_state_history_all.wont_be_empty

      # get an alarm by name using list all alarms with filter
      alarm_by_name = @service.alarms.all(:name => 'cpu.user_perc')

      # get the id of this alarm
      alarm_id      = alarm_by_name.first.id

      # find alarm by id
      @service.alarms.find_by_id(alarm_id)

      # get alarm state history for specific alarm
      alarm_state_history_for_alarm = @service.alarm_states.list_alarm_state_history(alarm_id)

      alarm_state_history_for_alarm.wont_be_nil
      alarm_state_history_for_alarm.wont_be_empty
    end
  end

  it 'list dimension values' do
    VCR.use_cassette('list_dimension_values') do
      # list dimension values
      dimension_values_by_key = @service.metrics.list_dimension_values('hostname').first

      dimension_values_by_key.wont_be_nil
      dimension_values_by_key.dimension_name.must_equal 'hostname'
      dimension_values_by_key.id.wont_be_nil
      dimension_values_by_key.values.wont_be_empty
    end
  end

  it 'list notification method types' do
    VCR.use_cassette('list_notification_method_types') do
      notification_method_types = @service.notification_methods.list_types

      notification_method_types.wont_be_nil
      notification_method_types.wont_be_empty

      notification_method_types.must_include :EMAIL
      notification_method_types.must_include :PAGERDUTY
      notification_method_types.must_include :WEBHOOK
    end
  end

  # FIXME: According to the API (https://github.com/openstack/monasca-api/blob/master/docs/monasca-api-spec.md)
  # the response body should not contain a 'id'-element, but actually it does contain "id": "null".
  # it 'alarm count test' do
  #   VCR.use_cassette('alarm_crud') do
  #     # get alarm counts
  #     alarm_count = @service.alarm_counts.get(:metric_name => 'cpu.system_perc',
  #                                             :group_by    => 'state')
  #
  #     alarm_count.columns.wont_be_nil
  #     alarm_count.columns.wont_be_empty
  #     alarm_count.counts.wont_be_nil
  #     alarm_count.counts.wont_be_empty
  #   end
  # end
end