copperegg-revealmetrics 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (23) hide show
  1. checksums.yaml +7 -0
  2. data/Users/reto/Projects/copperegg-revealmetrics/CHANGELOG.md +60 -0
  3. data/Users/reto/Projects/copperegg-revealmetrics/Gemfile +3 -0
  4. data/Users/reto/Projects/copperegg-revealmetrics/Gemfile.lock +28 -0
  5. data/Users/reto/Projects/copperegg-revealmetrics/LICENSE +19 -0
  6. data/Users/reto/Projects/copperegg-revealmetrics/README.md +161 -0
  7. data/Users/reto/Projects/copperegg-revealmetrics/Rakefile +3 -0
  8. data/Users/reto/Projects/copperegg-revealmetrics/copperegg.gemspec +24 -0
  9. data/Users/reto/Projects/copperegg-revealmetrics/lib/copperegg.rb +12 -0
  10. data/Users/reto/Projects/copperegg-revealmetrics/lib/copperegg/api.rb +24 -0
  11. data/Users/reto/Projects/copperegg-revealmetrics/lib/copperegg/custom_dashboard.rb +138 -0
  12. data/Users/reto/Projects/copperegg-revealmetrics/lib/copperegg/metric_group.rb +123 -0
  13. data/Users/reto/Projects/copperegg-revealmetrics/lib/copperegg/metric_sample.rb +22 -0
  14. data/Users/reto/Projects/copperegg-revealmetrics/lib/copperegg/mixins/persistence.rb +108 -0
  15. data/Users/reto/Projects/copperegg-revealmetrics/lib/copperegg/ver.rb +3 -0
  16. data/Users/reto/Projects/copperegg-revealmetrics/pkg/copperegg-revealmetrics-0.6.1.gem +0 -0
  17. data/Users/reto/Projects/copperegg-revealmetrics/test/custom_dashboard_test.rb +118 -0
  18. data/Users/reto/Projects/copperegg-revealmetrics/test/metric_group_test.rb +61 -0
  19. data/Users/reto/Projects/copperegg-revealmetrics/test/metric_sample_test.rb +6 -0
  20. data/test/custom_dashboard_test.rb +118 -0
  21. data/test/metric_group_test.rb +61 -0
  22. data/test/metric_sample_test.rb +6 -0
  23. metadata +116 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9b7bb1be69dca77240c15db94a5eebc10f30b005
4
+ data.tar.gz: b1d20e84a42d1885a62b2b484421bfa384e8c748
5
+ SHA512:
6
+ metadata.gz: e725f928629913a3c9e6ce970c2ffa7b4a77e5f64c891699e24b73a5812aaa4ea5d30e6f908e67fe528c2293904414202c21e21cdbd87cec253658972ced6708
7
+ data.tar.gz: 826f07d4c1bb2fb4f49d103e6018a743faee47aa511fc0c412680342862e95f4716238d0e2da26a45c55dc70c9d3912ae0ced630d43baeff9aac6aedd68acbce
@@ -0,0 +1,60 @@
1
+ ## 0.6.2
2
+ - Fork from `CopperEgg/copperegg-ruby` to `cargomedia/copperegg-revealmetrics`
3
+
4
+
5
+ ## 0.6.1 (January 17, 2013)
6
+
7
+ Changes:
8
+
9
+ - Existing metric groups are used rather than automatically versioning metric group name upon creation.
10
+
11
+
12
+ ## 0.6.0 (January 3, 2013)
13
+
14
+ Changes:
15
+
16
+ - Substantial changes to syntax. API resources now represented by Ruby classes. See README for details.
17
+ - Replaced multi_json requirement with json_pure.
18
+
19
+ Features:
20
+
21
+ - Automatic dashboard creation for metric groups.
22
+ - Metric groups and custom dashboards can be updated and deleted.
23
+ - Client-side validation added.
24
+ - Added automated test suite.
25
+
26
+ Bugfixes:
27
+
28
+ - Metric group versioning is encorporated and recognized.
29
+
30
+
31
+ ## 0.5.3 (Dec 21, 2012)
32
+
33
+ Changes:
34
+
35
+ - Remove Gemfile.lock from git tracking
36
+
37
+ Bugfixes:
38
+
39
+ - format to match changes in CopperEgg API
40
+
41
+
42
+ ## 0.5.2 (Dec 3, 2012)
43
+
44
+ Bugfixes:
45
+
46
+ - add explicit requires to make 1.8.7 work
47
+
48
+
49
+ ## 0.5.1 (Nov 5, 2012)
50
+
51
+ Changes:
52
+
53
+ - Use SSL
54
+ - updated gemspec and variable names
55
+
56
+
57
+ ## 0.5.0 (Nov 5, 2012)
58
+
59
+ Initial commit
60
+
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,28 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ copperegg-revealmetrics (0.6.1)
5
+ json_pure (~> 1.7.6)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ diff-lcs (1.2.5)
11
+ json_pure (1.7.7)
12
+ rake (10.4.2)
13
+ rspec (2.99.0)
14
+ rspec-core (~> 2.99.0)
15
+ rspec-expectations (~> 2.99.0)
16
+ rspec-mocks (~> 2.99.0)
17
+ rspec-core (2.99.2)
18
+ rspec-expectations (2.99.2)
19
+ diff-lcs (>= 1.1.3, < 2.0)
20
+ rspec-mocks (2.99.3)
21
+
22
+ PLATFORMS
23
+ ruby
24
+
25
+ DEPENDENCIES
26
+ copperegg-revealmetrics!
27
+ rake
28
+ rspec (~> 2.0)
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2013 CopperEgg Corporation, 2015 Cargo Media.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,161 @@
1
+ # CopperEgg Revealmetrics
2
+
3
+ This gem allows programmatic access to the CopperEgg Revealmetrics API.
4
+
5
+ This is a fork of the [official client](https://github.com/CopperEgg/copperegg-ruby), adding additional functionality.
6
+
7
+ ## Install
8
+
9
+ ```
10
+ gem install copperegg-revealmetrics
11
+ ```
12
+
13
+ ## Getting Started
14
+
15
+ ### Setup
16
+
17
+ ``` ruby
18
+ require 'copperegg-revealmetrics'
19
+ CopperEgg::Api.apikey = "sdf87xxxxxxxxxxxxxxxxxxxxx" # from the web UI
20
+ ```
21
+
22
+ ### Get a metric group:
23
+
24
+ ``` ruby
25
+ metric_group = CopperEgg::MetricGroup.find("my_metric_group")
26
+ metric_group.name
27
+ # => "my_metric_group"
28
+ metric_group.label
29
+ # => "My Metric Group"
30
+ metric_group.metrics
31
+ # => [#<CopperEgg::MetricGroup::Metric:0x007fb43aab2570 @position=0, @type="ce_gauge", @name="metric1", @label="Metric 1", @unit="b">]
32
+ ```
33
+
34
+ ### Create a metric group:
35
+
36
+ ``` ruby
37
+ metric_group = CopperEgg::MetricGroup.new(:name => "my_new_metric_group", :label => "Cool New Group Visible Name", :frequency => 60) # data is sent every 60 seconds
38
+ metric_group.metrics << {"type"=>"ce_gauge", "name"=>"active_connections", "unit"=>"Connections"}
39
+ metric_group.metrics << {"type"=>"ce_gauge", "name"=>"connections_accepts", "unit"=>"Connections"}
40
+ metric_group.metrics << {"type"=>"ce_gauge", "name"=>"connections_handled", "unit"=>"Connections"}
41
+ metric_group.metrics << {"type"=>"ce_gauge", "name"=>"connections_requested", "unit"=>"Connections"}
42
+ metric_group.metrics << {"type"=>"ce_gauge", "name"=>"reading", "unit"=>"Connections"}
43
+ metric_group.metrics << {"type"=>"ce_gauge", "name"=>"writing", "unit"=>"Connections"}
44
+ metric_group.metrics << {"type"=>"ce_gauge", "name"=>"waiting", "unit"=>"Connections"}
45
+ metric_group.save
46
+ ```
47
+
48
+ If a metric group by the same name already exists, that one will rather than creating a new one. In addition, if the metric group was previously removed it will be restored.
49
+
50
+ ```ruby
51
+ metric_group2 = CopperEgg::MetricGroup.new(:name => "my_new_metric_group", :label => "New Group Version 2", :frequency => 60)
52
+ metric_group2.metrics << {"type"=>"ce_counter", "name"=>"active_connections", "unit"=>"Connections"}
53
+ metric_group2.save # this will perform an update to change the type of the metric 'active_connections' from 'ce_gauge' to 'ce_counter'
54
+
55
+ metric_group2.name
56
+ # => "my_metric_group"
57
+ ```
58
+
59
+ ### Updating a metric group:
60
+
61
+ Labels, frequency, metric types and metric units can be updated and additional metrics can be added. Changes to the metric group name or names of metrics within will be ignored.
62
+
63
+ ```ruby
64
+ metric_group.name = "this_will_be_ignored"
65
+ metric_group.label = "My New Metric Group"
66
+ metric_group.frequency = 5
67
+ metric_group.metrics << {"type"=>"ce_counter_f", "name"=>"new_metric"}
68
+ metric_group.save
69
+
70
+ metric_group.name
71
+ # => "my_metric_group"
72
+ metric_group.label
73
+ # => "My New Metric Group"
74
+ metric_group.frequency
75
+ # => 5
76
+ ```
77
+
78
+ ### Delete a metric group
79
+
80
+ ```ruby
81
+ metric_group.delete
82
+ ```
83
+
84
+
85
+ ### Post samples for a metric group
86
+
87
+ ```ruby
88
+ CopperEgg::MetricSample.save(metric_group.name, "custom_identifier1", Time.now.to_i, "active_connections" => 2601, "connections_accepts" => 154, "connections_handled" => 128, "connections_requested" => 1342, ...)
89
+ ```
90
+
91
+ ### Get samples
92
+
93
+ ```ruby
94
+ # Get the most recent samples for a single metric
95
+ CopperEgg::MetricSample.samples(metric_group.name, "connections_accepts")
96
+
97
+ # Get the most recent samples for multiple metrics
98
+ CopperEgg::MetricSample.samples(metric_group.name, ["connections_accepts", "connections_handled", "reading", "writing"])
99
+
100
+ # Specify a start time and duration
101
+ CopperEgg::MetricSample.samples(metric_group.name, ["connections_accepts", "connections_handled", "reading", "writing"], :starttime => 4.hours.ago, :duration => 15.minutes)
102
+ ```
103
+
104
+ The raw JSON response is returned as specified in the [API docs][sample_docs].
105
+
106
+ ### Create a dashboard from a metric group
107
+
108
+ By default, the dashboard created will be named "_MetricGroupLabel_ Dashboard" and will have one timeline widget per metric matching all sources.
109
+
110
+ ```ruby
111
+ # Creates a dashboard named "My Metric Group Dashboard"
112
+ dashboard = CopperEgg::CustomDashboard.create(metric_group)
113
+ ```
114
+
115
+ You can pass an option to specify the name of the dashboard.
116
+
117
+ ```ruby
118
+ dashboard = CopperEgg::CustomDashboard.create(metric_group, :name => "Cloud Servers")
119
+ ```
120
+
121
+ If a single identifier is specified, the dashboard will be created having one value widget per metric matching the single identifier.
122
+
123
+ ```ruby
124
+ dashboard = CopperEgg::CustomDashboard.create(metric_group, :name => "Cloud Servers", :identifiers => "custom_identifier1")
125
+ ```
126
+
127
+ If an array of identifiers is specified, the dashboard will be created having one timeline widget per metric matching each identifier.
128
+
129
+ ```ruby
130
+ dashboard = CopperEgg::CustomDashboard.create(metric_group, :name => "Cloud Servers", :identifiers => ["custom_identifier1", "custom_identifier2"])
131
+ ```
132
+
133
+ You can limit the widgets created by metric.
134
+
135
+ ```ruby
136
+ dashboard = CopperEgg::CustomDashboard.create(metric_group, :name => "Cloud Servers", :identifiers => ["custom_identifier1", "custom_identifier2"], :metrics => ["reading", "writing", "waiting"])
137
+ ```
138
+
139
+ ### Get a dashboard
140
+
141
+ ```ruby
142
+ dashboard = CopperEgg::CustomDashboard.find_by_name("My Metric Group Dashboard")
143
+ ```
144
+
145
+ ### Delete a dashboard
146
+
147
+ Dashboards can be deleted like metric groups:
148
+
149
+ ```ruby
150
+ dashboard.delete
151
+ ```
152
+
153
+ ## Questions / Problems?
154
+
155
+ There are more detailed examples in the [test classes][test_classes].
156
+
157
+ Full [API docs][docs] are available.
158
+
159
+ [sample_docs]:http://dev.copperegg.com/revealmetrics/samples.html
160
+ [test_classes]:/test
161
+ [docs]:http://dev.copperegg.com
@@ -0,0 +1,3 @@
1
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
2
+
3
+ require 'bundler/gem_tasks'
@@ -0,0 +1,24 @@
1
+ require File.expand_path('../lib/copperegg/ver', __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'copperegg-revealmetrics'
5
+ s.version = CopperEgg::GEM_VERSION
6
+ s.summary = 'API client for CopperEgg Revealmetrics'
7
+ s.description = 'API client for CopperEgg Revealmetrics'
8
+ s.authors = ['Eric Anderson', 'Cargo Media']
9
+ s.email = 'hello@cargomedia.ch'
10
+ s.homepage = 'https://github.com/cargomedia/copperegg-revealmetrics'
11
+ s.license = 'MIT'
12
+
13
+ s.platform = Gem::Platform::RUBY
14
+ s.require_paths = %w[lib]
15
+ s.files = Dir["#{File.dirname(__FILE__)}/**/*"]
16
+ s.test_files = Dir.glob("{test,spec,features}/*")
17
+
18
+ s.add_dependency('json_pure', '~> 1.7.6')
19
+
20
+ s.add_development_dependency 'rake'
21
+ s.add_development_dependency 'rspec', '~> 2.0'
22
+
23
+ s.rdoc_options = ['--line-numbers', '--inline-source', '--title', 'copperegg-revealmetrics', '--main', 'README.md']
24
+ end
@@ -0,0 +1,12 @@
1
+ require "net/http"
2
+ require "net/https"
3
+ require "uri"
4
+ require "json/pure"
5
+ require File.dirname(__FILE__) + "/copperegg/mixins/persistence"
6
+ require File.dirname(__FILE__) + "/copperegg/metric_group"
7
+ require File.dirname(__FILE__) + "/copperegg/custom_dashboard"
8
+ require File.dirname(__FILE__) + "/copperegg/metric_sample"
9
+ require File.dirname(__FILE__) + "/copperegg/api"
10
+
11
+ module CopperEgg
12
+ end
@@ -0,0 +1,24 @@
1
+ module CopperEgg
2
+ class Api
3
+ class << self
4
+ attr_accessor :apikey
5
+ attr_reader :ssl_verify_peer, :timeout
6
+
7
+ def host=(host)
8
+ @uri = URI.join(host, "/v2/revealmetrics/").to_s
9
+ end
10
+
11
+ def uri
12
+ @uri || "https://api.copperegg.com/v2/revealmetrics/"
13
+ end
14
+
15
+ def ssl_verify_peer=(boolean)
16
+ @ssl_verify_peer = boolean ? true : false
17
+ end
18
+
19
+ def timeout=(seconds)
20
+ @timeout = seconds.to_i
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,138 @@
1
+ module CopperEgg
2
+ class CustomDashboard
3
+ include CopperEgg::Mixins::Persistence
4
+
5
+ WIDGET_TYPES = %w(metric metric_list timeline)
6
+ WIDGET_STYLES = %w(value timeline both list values)
7
+ WIDGET_MATCHES = %w(select multi tag all)
8
+
9
+ resource "dashboards"
10
+
11
+ attr_accessor :name, :label, :data
12
+
13
+ def load_attributes(attributes)
14
+ @data = {"widgets" => {}, "order" => []}
15
+ attributes.each do |name, value|
16
+ if name.to_s == "id"
17
+ @id = value
18
+ elsif name.to_s == "data"
19
+ attributes[name].each do |data_name, data_value|
20
+ if data_name.to_s == "order"
21
+ data["order"] = data_value
22
+ else
23
+ data["widgets"] = data_value
24
+ end
25
+ end
26
+ elsif !respond_to?("#{name}=")
27
+ next
28
+ else
29
+ send "#{name}=", value
30
+ end
31
+ end
32
+ end
33
+
34
+ def valid?
35
+ @error = nil
36
+ if self.name.nil? || self.name.to_s.strip.empty?
37
+ @error = "Name can't be blank."
38
+ else
39
+ self.data["widgets"].values.each do |widget|
40
+ widget.each do |key, value|
41
+ if key.to_s == "type" && !WIDGET_TYPES.include?(value)
42
+ @error = "Invalid widget type #{value}."
43
+ elsif key.to_s == "style" && !WIDGET_STYLES.include?(value)
44
+ @error = "Invalid widget style #{value}."
45
+ elsif key.to_s == "match" && !WIDGET_MATCHES.include?(value)
46
+ @error = "Invalid widget match #{value}."
47
+ elsif key.to_s == "metric" && (!value.is_a?(Hash) || value.keys.size == 0)
48
+ @error = "Invalid widget metric. #{value}"
49
+ else
50
+ (widget["metric"] || widget[:metric]).each do |metric_group_name, metric_group_value|
51
+ if !metric_group_value.is_a?(Array)
52
+ @error = "Invalid widget metric. #{metric_group_value}"
53
+ elsif metric_group_value.length == 0
54
+ @error = "Invalid widget metric. #{metric_group_value}"
55
+ else
56
+ metric_group_value.each do |metric_data|
57
+ if !metric_data.is_a?(Array)
58
+ @error = "Invalid widget metric. #{metric_group_value}"
59
+ elsif metric_data.length < 2
60
+ @error = "Invalid widget metric. #{metric_group_value}"
61
+ elsif (/^\d+$/ =~ metric_data.first.to_s).nil?
62
+ @error = "Invalid widget metric. #{metric_group_value}"
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ match_param = widget["match_param"] || widget[:match_param]
70
+ if (widget["match"] || widget[:match]) != "all" && (match_param.nil? || match_param.to_s.strip.empty?)
71
+ @error = "Missing match parameter."
72
+ end
73
+ break if !@error.nil?
74
+ end
75
+ end
76
+ @error.nil?
77
+ end
78
+
79
+ def to_hash
80
+ set_data_order
81
+ self.instance_variables.reduce({}) do |memo, variable|
82
+ unless variable.to_s == "@error"
83
+ value = instance_variable_get(variable)
84
+ memo[variable.to_s.sub("@","")] = value
85
+ end
86
+ memo
87
+ end
88
+ end
89
+
90
+ class <<self
91
+ def create(*args)
92
+ options = args.last.class == Hash ? args.pop : {}
93
+
94
+ return super(args.first) if args.first.is_a?(Hash)
95
+
96
+ metric_group = args.first
97
+ raise ArgumentError.new("CopperEgg::MetricGroup object expected") if !metric_group.is_a?(MetricGroup)
98
+ raise ArgumentError.new("Invalid metric group") if !metric_group.valid?
99
+
100
+ metrics = filter_metrics(metric_group, options[:metrics]).map { |name| metric_group.metrics.find {|metric| metric.name == name} }
101
+ identifiers = options[:identifiers].is_a?(Array) ? (options[:identifiers].empty? ? nil : options[:identifiers]) : (options[:identifier] ? [options[:identifiers]] : nil)
102
+ widget_match = identifiers.nil? ? "all" : (identifiers.size == 1 ? "select" : "multi")
103
+ widget_type = widget_match == "select" ? "metric" : "timeline"
104
+ widget_style = widget_type == "metric" ? "both" : "values"
105
+ name = options[:name] || "#{metric_group.label} Dashboard"
106
+
107
+ dashboard = new(:name => name)
108
+ metrics.each.with_index do |metric, i|
109
+ metric_data = [metric.position, metric.name]
110
+ metric_data.push("rate") if metric.type == "ce_counter" || metric.type == "ce_counter_f"
111
+ widget = {:type => widget_type, :style => widget_style, :match => widget_match, :metric => {metric_group.name => [metric_data]}}
112
+ widget[:match_param] = identifiers if identifiers
113
+ dashboard.data["widgets"][i.to_s] = widget
114
+ end
115
+ dashboard.save
116
+ dashboard
117
+ end
118
+
119
+ def find_by_name(name)
120
+ find.detect {|dashboard| dashboard.name == name}
121
+ end
122
+
123
+ private
124
+
125
+ def filter_metrics(metric_group, specified_metrics)
126
+ metrics = metric_group.metrics.map(&:name)
127
+ specified_metrics = specified_metrics.is_a?(Array) ? specified_metrics & metrics : (specified_metrics ? [specified_metrics] & metrics : [])
128
+ specified_metrics.empty? ? metrics : specified_metrics
129
+ end
130
+ end
131
+
132
+ private
133
+
134
+ def set_data_order
135
+ @data["order"] = @data["widgets"].keys if @data["order"].empty?
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,123 @@
1
+ module CopperEgg
2
+ class MetricGroup
3
+ include CopperEgg::Mixins::Persistence
4
+
5
+ resource "metric_groups"
6
+
7
+ attr_accessor :name, :label, :frequency, :metrics
8
+
9
+ def load_attributes(attributes)
10
+ @metrics = []
11
+ attributes.each do |name, value|
12
+ if name.to_s == "id"
13
+ @id = value
14
+ elsif !respond_to?("#{name}=")
15
+ next
16
+ elsif value.to_s == "metrics"
17
+ @metrics = value.map {|v| Metric.new(v)}
18
+ else
19
+ send "#{name}=", value
20
+ end
21
+ end
22
+ end
23
+
24
+ def to_hash
25
+ self.instance_variables.reduce({}) do |memo, variable|
26
+ value = instance_variable_get(variable)
27
+ if variable.to_s == "@metrics"
28
+ memo[variable.to_s.sub("@","")] = value.map(&:to_hash)
29
+ elsif variable.to_s != "@error"
30
+ memo[variable.to_s.sub("@","")] = value
31
+ end
32
+ memo
33
+ end
34
+ end
35
+
36
+ def valid?
37
+ @error = nil
38
+ if self.name.nil? || self.name.to_s.strip.empty?
39
+ @error = "Name can't be blank."
40
+ elsif self.metrics.nil? || self.metrics.empty?
41
+ @error = "You must define at least one metric."
42
+ else
43
+ self.metrics = self.metrics.map {|metric| metric.is_a?(Hash) ? Metric.new(metric) : metric}
44
+ self.metrics.each do |metric|
45
+ if !metric.is_a?(Metric)
46
+ @error = "Metric expected."
47
+ break
48
+ elsif !metric.valid?
49
+ @error = metric.error
50
+ break
51
+ else
52
+ metric.send(:remove_instance_variable, :@position) if (metric.instance_variables.include?(:@position) || metric.instance_variables.include?("@position")) && !self.persisted?
53
+ end
54
+ end
55
+ end
56
+ @error.nil?
57
+ end
58
+
59
+ private
60
+
61
+ def create
62
+ response = self.class.request(:request_type => "get", :id => self.name, :show_hidden => true)
63
+ if response.code == "200"
64
+ json = JSON.parse(response.body)
65
+ metric_group = self.class.new(json)
66
+ @id = self.name
67
+ # needs_update = self.label != metric_group.label || self.frequency != metric_group.frequency || self.metrics.length != metric_group.metrics.length || self.metrics.map(&:name).sort != metric_group.metrics.map {|m| m["name"]}.sort
68
+ if true #needs_update
69
+ self.class.request(self.to_hash.merge(:id => @id, :is_hidden => 0, :request_type => "put", :show_hidden => true))
70
+ else
71
+ response
72
+ end
73
+ else
74
+ self.class.request(self.to_hash.merge(:request_type => "post"))
75
+ end
76
+ end
77
+
78
+ class Metric
79
+ TYPES = %w(ce_gauge ce_gauge_f ce_counter ce_counter_f)
80
+
81
+ attr_accessor :name, :label, :type, :unit
82
+ attr_reader :error, :position
83
+
84
+ def initialize(attributes={})
85
+ attributes.each do |name, value|
86
+ if name.to_s == "position"
87
+ @position = value
88
+ elsif !respond_to?("#{name}=")
89
+ next
90
+ else
91
+ send "#{name}=", value
92
+ end
93
+ end
94
+ end
95
+
96
+ def to_hash
97
+ self.instance_variables.reduce({}) do |memo, variable|
98
+ if variable.to_s != "@error"
99
+ value = instance_variable_get(variable)
100
+ memo[variable.to_s.sub("@","")] = value
101
+ end
102
+ memo
103
+ end
104
+ end
105
+
106
+ def valid?
107
+ valid = false
108
+ @error = nil
109
+ if self.name.nil? || self.name.to_s.strip.empty?
110
+ @error = "Metric name cannot be blank."
111
+ elsif self.type.nil? || self.type.to_s.strip.empty?
112
+ @error = "Metric type must be defined."
113
+ elsif !TYPES.include?(self.type)
114
+ @error = "Invalid metric type #{self.type}."
115
+ else
116
+ valid = true
117
+ remove_instance_variable(:@error)
118
+ end
119
+ valid
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,22 @@
1
+ module CopperEgg
2
+ class MetricSample
3
+ include CopperEgg::Mixins::Persistence
4
+
5
+ resource "samples"
6
+
7
+ def self.save(group_name, identifier, timestamp, metric_values)
8
+ request(:id => group_name, :identifier => identifier, :timestamp => timestamp, :values => metric_values, :request_type => "post")
9
+ end
10
+
11
+ def self.samples(group_name, metrics, starttime=nil, duration=nil, sample_size=nil)
12
+ metrics = [metrics] unless metrics.is_a?(Array)
13
+ params = {}
14
+ params[:starttime] = starttime if starttime
15
+ params[:duration] = duration if duration
16
+ params[:sample_size] = sample_size if sample_size
17
+ params[:queries] = {group_name => [{:metrics => metrics}]}
18
+
19
+ request(params.merge(:request_type => "get"))
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,108 @@
1
+ module CopperEgg
2
+ class ValidationError < Exception; end
3
+
4
+ module Mixins
5
+ module Persistence
6
+ def self.included(klass)
7
+ klass.class_eval do
8
+ class << self
9
+ attr_reader :resource_name
10
+
11
+ def find(*args)
12
+ params = args.last.class == Hash ? args.pop : {}
13
+ id = args.first
14
+ response = request(params.merge(:request_type => "get", :id => id))
15
+ if response.code == "200"
16
+ json = JSON.parse(response.body)
17
+ if json.is_a?(Array)
18
+ json.map {|attributes| new(attributes)}
19
+ else
20
+ new(json)
21
+ end
22
+ end
23
+ end
24
+
25
+ def create(params)
26
+ params.delete(:id)
27
+ params.delete("id")
28
+ new(params).save
29
+ end
30
+
31
+ def delete(id)
32
+ request(:id => id, :request_type => "delete")
33
+ end
34
+
35
+ def request(params={})
36
+ request_type = params.delete(:request_type)
37
+ raise "invalid type" if !%w(get post put delete).include?(request_type)
38
+ id = params.delete(:id)
39
+
40
+ uri = id ? URI.parse("#{Api.uri}/#{self.resource_name}/#{id}.json") : URI.parse("#{Api.uri}/#{self.resource_name}.json")
41
+
42
+ http = Net::HTTP.new(uri.host, uri.port)
43
+ http.use_ssl = uri.scheme == 'https'
44
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE if !Api.ssl_verify_peer
45
+
46
+ request = Net::HTTP.const_get(request_type.capitalize).new(uri.request_uri)
47
+ request.body = JSON.generate(params) unless params.empty?
48
+ request.basic_auth(Api.apikey, "U")
49
+ request["Content-Type"] = "application/json"
50
+
51
+ begin
52
+ response = http.request(request)
53
+ rescue Exception => e
54
+ raise e
55
+ end
56
+
57
+ response
58
+ end
59
+
60
+ private
61
+
62
+ def resource(value)
63
+ @resource_name = value
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ attr_reader :id, :error
70
+
71
+ def initialize(attributes={})
72
+ load_attributes(attributes)
73
+ end
74
+
75
+ def save
76
+ if valid?
77
+ response = persisted? ? update : create
78
+ attributes = JSON.parse(response.body)
79
+ if response.code != "200"
80
+ @error = attributes.merge("code" => response.code)
81
+ else
82
+ load_attributes(attributes)
83
+ end
84
+ else
85
+ raise ValidationError.new(@error)
86
+ end
87
+ end
88
+
89
+ def delete
90
+ self.class.request(:id => @id, :request_type => "delete")
91
+ end
92
+
93
+ def persisted?
94
+ !@id.nil?
95
+ end
96
+
97
+ private
98
+
99
+ def create
100
+ self.class.request(to_hash.merge(:request_type => "post"))
101
+ end
102
+
103
+ def update
104
+ self.class.request(to_hash.merge(:id => @id, :request_type => "put"))
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,3 @@
1
+ module CopperEgg
2
+ GEM_VERSION = "0.6.2"
3
+ end
@@ -0,0 +1,118 @@
1
+ require "test/unit"
2
+ require "copperegg"
3
+
4
+ class CustomDashboardTest < Test::Unit::TestCase
5
+
6
+ def test_name_accessor_and_setter
7
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
8
+
9
+ assert_equal "My Dashboard", dashboard.name
10
+ end
11
+
12
+ def test_save_should_fail_if_name_is_not_set
13
+ dashboard = CopperEgg::CustomDashboard.new
14
+
15
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
16
+ assert_equal "Name can't be blank.", error.message
17
+ end
18
+
19
+ def test_save_should_fail_for_an_invalid_widget_type
20
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
21
+ dashboard.data["widgets"]["0"] = {:type => "foo", :style => "value", :match => "tag", :match_param => ["test"],
22
+ :metric => {"my_metric_group" => [[0, "metric1"]]}}
23
+
24
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
25
+ assert_equal "Invalid widget type foo.", error.message
26
+ end
27
+
28
+ def test_save_should_fail_for_an_invalid_widget_style
29
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
30
+ dashboard.data["widgets"]["0"] = {:type => "metric", :style => "foo", :match => "tag", :match_param => ["test"],
31
+ :metric => {"my_metric_group" => [[0, "metric1"]]}}
32
+
33
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
34
+ assert_equal "Invalid widget style foo.", error.message
35
+ end
36
+
37
+ def test_save_should_ail_for_an_invalidvwidget_match
38
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
39
+ dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "foo", :match_param => ["test"],
40
+ :metric => {"my_metric_group" => [[0, "metric1"]]}}
41
+
42
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
43
+ assert_equal "Invalid widget match foo.", error.message
44
+ end
45
+
46
+ def test_save_should_fail_for_a_missing_match_parameter
47
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
48
+ dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "select", :metric => {"my_metric_group" => [[0, "metric1"]]}}
49
+
50
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
51
+ assert_equal "Missing match parameter.", error.message
52
+ end
53
+
54
+ def test_save_should_fail_if_metric_is_not_a_hash
55
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
56
+ dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => ["my_metric_group", 0, "metric1"]}
57
+
58
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
59
+ assert_match /invalid widget metric/i, error.message
60
+ end
61
+
62
+ def test_save_should_fail_if_metric_does_not_contain_an_array
63
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
64
+ dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => "metric1"}}
65
+
66
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
67
+ assert_match /invalid widget metric/i, error.message
68
+ end
69
+
70
+ def test_save_should_fail_if_metric_contains_an_empty_array
71
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
72
+ dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => []}}
73
+
74
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
75
+ assert_match /invalid widget metric/i, error.message
76
+ end
77
+
78
+ def test_save_should_fail_if_metric_contains_an_array_with_invalid_values
79
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
80
+ dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => ["metric1"]}}
81
+
82
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
83
+ assert_match /invalid widget metric/i, error.message
84
+ end
85
+
86
+ def test_save_should_fail_if_metric_contains_an_array_with_an_invalid_position
87
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
88
+ dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => [["four", "metric1"]]}}
89
+
90
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
91
+ assert_match /invalid widget metric/i, error.message
92
+ end
93
+
94
+ def test_save_should_fail_if_metric_contains_an_array_with_no_metric_name
95
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
96
+ dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => [[0]]}}
97
+
98
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
99
+ assert_match /invalid widget metric/i, error.message
100
+ end
101
+
102
+ def test_to_hash
103
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
104
+ dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => [[1, "metric1"]]}}
105
+
106
+ assert dashboard.valid?
107
+
108
+ hash = dashboard.to_hash
109
+
110
+ assert_equal "My Dashboard", hash["name"]
111
+ assert_equal "metric", hash["data"]["widgets"]["0"][:type]
112
+ assert_equal "value", hash["data"]["widgets"]["0"][:style]
113
+ assert_equal "tag", hash["data"]["widgets"]["0"][:match]
114
+ assert_equal ["test"], hash["data"]["widgets"]["0"][:match_param]
115
+ assert_equal [[1, "metric1"]], hash["data"]["widgets"]["0"][:metric]["my_metric_group"]
116
+ end
117
+
118
+ end
@@ -0,0 +1,61 @@
1
+ require "test/unit"
2
+ require "copperegg"
3
+
4
+ class MetricGroupTest < Test::Unit::TestCase
5
+
6
+ def test_name_accessor_and_setter
7
+ metric_group = CopperEgg::MetricGroup.new(:name => "my_metric_group")
8
+
9
+ assert_equal "my_metric_group", metric_group.name
10
+ end
11
+
12
+ def test_save_should_fail_if_name_is_blank
13
+ metric_group = CopperEgg::MetricGroup.new
14
+
15
+ error = assert_raise(CopperEgg::ValidationError) { metric_group.save }
16
+ assert_equal "Name can't be blank.", error.message
17
+ end
18
+
19
+ def test_save_should_fail_if_no_metrics_are_declared
20
+ metric_group = CopperEgg::MetricGroup.new(:name => "my_metric_group")
21
+
22
+ error = assert_raise(CopperEgg::ValidationError) { metric_group.save }
23
+ assert_equal "You must define at least one metric.", error.message
24
+ end
25
+
26
+ def test_save_should_fail_if_metrics_include_non_metric
27
+ metric_group = CopperEgg::MetricGroup.new(:name => "my_metric_group", :metrics => ["metric"])
28
+
29
+ error = assert_raise(CopperEgg::ValidationError) { metric_group.save }
30
+ assert_equal "Metric expected.", error.message
31
+ end
32
+
33
+ def test_save_should_fail_for_invalid_metric
34
+ metric_group = CopperEgg::MetricGroup.new(:name => "my_metric_group", :metrics => [{:name => "test", :type => "invalid"}])
35
+
36
+ error = assert_raise(CopperEgg::ValidationError) { metric_group.save }
37
+ assert_equal "Invalid metric type invalid.", error.message
38
+ end
39
+
40
+ def test_to_hash
41
+ metric_group = CopperEgg::MetricGroup.new(:name => "test", :label => "Test Metric", :frequency => 5)
42
+ metric_group.metrics << {:type => "ce_counter", :name => "metric1", :label => "Metric 1", :unit => "ticks"}
43
+ metric_group.metrics << {:type => "ce_counter_f", :name => "metric2", :label => "Metric 2"}
44
+
45
+ assert metric_group.valid?
46
+ hash = metric_group.to_hash
47
+
48
+ assert_nil hash["id"]
49
+ assert_equal "test", hash["name"]
50
+ assert_equal "Test Metric", hash["label"]
51
+ assert_equal 5, hash["frequency"]
52
+ assert_equal "ce_counter", hash["metrics"].first["type"]
53
+ assert_equal "metric1", hash["metrics"].first["name"]
54
+ assert_equal "Metric 1", hash["metrics"].first["label"]
55
+ assert_equal "ticks", hash["metrics"].first["unit"]
56
+ assert_equal "ce_counter_f", hash["metrics"].last["type"]
57
+ assert_equal "metric2", hash["metrics"].last["name"]
58
+ assert_equal "Metric 2", hash["metrics"].last["label"]
59
+ end
60
+
61
+ end
@@ -0,0 +1,6 @@
1
+ require "test/unit"
2
+ require "copperegg"
3
+
4
+ class MetricSampleTest < Test::Unit::TestCase
5
+
6
+ end
@@ -0,0 +1,118 @@
1
+ require "test/unit"
2
+ require "copperegg"
3
+
4
+ class CustomDashboardTest < Test::Unit::TestCase
5
+
6
+ def test_name_accessor_and_setter
7
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
8
+
9
+ assert_equal "My Dashboard", dashboard.name
10
+ end
11
+
12
+ def test_save_should_fail_if_name_is_not_set
13
+ dashboard = CopperEgg::CustomDashboard.new
14
+
15
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
16
+ assert_equal "Name can't be blank.", error.message
17
+ end
18
+
19
+ def test_save_should_fail_for_an_invalid_widget_type
20
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
21
+ dashboard.data["widgets"]["0"] = {:type => "foo", :style => "value", :match => "tag", :match_param => ["test"],
22
+ :metric => {"my_metric_group" => [[0, "metric1"]]}}
23
+
24
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
25
+ assert_equal "Invalid widget type foo.", error.message
26
+ end
27
+
28
+ def test_save_should_fail_for_an_invalid_widget_style
29
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
30
+ dashboard.data["widgets"]["0"] = {:type => "metric", :style => "foo", :match => "tag", :match_param => ["test"],
31
+ :metric => {"my_metric_group" => [[0, "metric1"]]}}
32
+
33
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
34
+ assert_equal "Invalid widget style foo.", error.message
35
+ end
36
+
37
+ def test_save_should_ail_for_an_invalidvwidget_match
38
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
39
+ dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "foo", :match_param => ["test"],
40
+ :metric => {"my_metric_group" => [[0, "metric1"]]}}
41
+
42
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
43
+ assert_equal "Invalid widget match foo.", error.message
44
+ end
45
+
46
+ def test_save_should_fail_for_a_missing_match_parameter
47
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
48
+ dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "select", :metric => {"my_metric_group" => [[0, "metric1"]]}}
49
+
50
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
51
+ assert_equal "Missing match parameter.", error.message
52
+ end
53
+
54
+ def test_save_should_fail_if_metric_is_not_a_hash
55
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
56
+ dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => ["my_metric_group", 0, "metric1"]}
57
+
58
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
59
+ assert_match /invalid widget metric/i, error.message
60
+ end
61
+
62
+ def test_save_should_fail_if_metric_does_not_contain_an_array
63
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
64
+ dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => "metric1"}}
65
+
66
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
67
+ assert_match /invalid widget metric/i, error.message
68
+ end
69
+
70
+ def test_save_should_fail_if_metric_contains_an_empty_array
71
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
72
+ dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => []}}
73
+
74
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
75
+ assert_match /invalid widget metric/i, error.message
76
+ end
77
+
78
+ def test_save_should_fail_if_metric_contains_an_array_with_invalid_values
79
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
80
+ dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => ["metric1"]}}
81
+
82
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
83
+ assert_match /invalid widget metric/i, error.message
84
+ end
85
+
86
+ def test_save_should_fail_if_metric_contains_an_array_with_an_invalid_position
87
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
88
+ dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => [["four", "metric1"]]}}
89
+
90
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
91
+ assert_match /invalid widget metric/i, error.message
92
+ end
93
+
94
+ def test_save_should_fail_if_metric_contains_an_array_with_no_metric_name
95
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
96
+ dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => [[0]]}}
97
+
98
+ error = assert_raise(CopperEgg::ValidationError) { dashboard.save }
99
+ assert_match /invalid widget metric/i, error.message
100
+ end
101
+
102
+ def test_to_hash
103
+ dashboard = CopperEgg::CustomDashboard.new(:name => "My Dashboard")
104
+ dashboard.data["widgets"]["0"] = {:type => "metric", :style => "value", :match => "tag", :match_param => ["test"], :metric => {"my_metric_group" => [[1, "metric1"]]}}
105
+
106
+ assert dashboard.valid?
107
+
108
+ hash = dashboard.to_hash
109
+
110
+ assert_equal "My Dashboard", hash["name"]
111
+ assert_equal "metric", hash["data"]["widgets"]["0"][:type]
112
+ assert_equal "value", hash["data"]["widgets"]["0"][:style]
113
+ assert_equal "tag", hash["data"]["widgets"]["0"][:match]
114
+ assert_equal ["test"], hash["data"]["widgets"]["0"][:match_param]
115
+ assert_equal [[1, "metric1"]], hash["data"]["widgets"]["0"][:metric]["my_metric_group"]
116
+ end
117
+
118
+ end
@@ -0,0 +1,61 @@
1
+ require "test/unit"
2
+ require "copperegg"
3
+
4
+ class MetricGroupTest < Test::Unit::TestCase
5
+
6
+ def test_name_accessor_and_setter
7
+ metric_group = CopperEgg::MetricGroup.new(:name => "my_metric_group")
8
+
9
+ assert_equal "my_metric_group", metric_group.name
10
+ end
11
+
12
+ def test_save_should_fail_if_name_is_blank
13
+ metric_group = CopperEgg::MetricGroup.new
14
+
15
+ error = assert_raise(CopperEgg::ValidationError) { metric_group.save }
16
+ assert_equal "Name can't be blank.", error.message
17
+ end
18
+
19
+ def test_save_should_fail_if_no_metrics_are_declared
20
+ metric_group = CopperEgg::MetricGroup.new(:name => "my_metric_group")
21
+
22
+ error = assert_raise(CopperEgg::ValidationError) { metric_group.save }
23
+ assert_equal "You must define at least one metric.", error.message
24
+ end
25
+
26
+ def test_save_should_fail_if_metrics_include_non_metric
27
+ metric_group = CopperEgg::MetricGroup.new(:name => "my_metric_group", :metrics => ["metric"])
28
+
29
+ error = assert_raise(CopperEgg::ValidationError) { metric_group.save }
30
+ assert_equal "Metric expected.", error.message
31
+ end
32
+
33
+ def test_save_should_fail_for_invalid_metric
34
+ metric_group = CopperEgg::MetricGroup.new(:name => "my_metric_group", :metrics => [{:name => "test", :type => "invalid"}])
35
+
36
+ error = assert_raise(CopperEgg::ValidationError) { metric_group.save }
37
+ assert_equal "Invalid metric type invalid.", error.message
38
+ end
39
+
40
+ def test_to_hash
41
+ metric_group = CopperEgg::MetricGroup.new(:name => "test", :label => "Test Metric", :frequency => 5)
42
+ metric_group.metrics << {:type => "ce_counter", :name => "metric1", :label => "Metric 1", :unit => "ticks"}
43
+ metric_group.metrics << {:type => "ce_counter_f", :name => "metric2", :label => "Metric 2"}
44
+
45
+ assert metric_group.valid?
46
+ hash = metric_group.to_hash
47
+
48
+ assert_nil hash["id"]
49
+ assert_equal "test", hash["name"]
50
+ assert_equal "Test Metric", hash["label"]
51
+ assert_equal 5, hash["frequency"]
52
+ assert_equal "ce_counter", hash["metrics"].first["type"]
53
+ assert_equal "metric1", hash["metrics"].first["name"]
54
+ assert_equal "Metric 1", hash["metrics"].first["label"]
55
+ assert_equal "ticks", hash["metrics"].first["unit"]
56
+ assert_equal "ce_counter_f", hash["metrics"].last["type"]
57
+ assert_equal "metric2", hash["metrics"].last["name"]
58
+ assert_equal "Metric 2", hash["metrics"].last["label"]
59
+ end
60
+
61
+ end
@@ -0,0 +1,6 @@
1
+ require "test/unit"
2
+ require "copperegg"
3
+
4
+ class MetricSampleTest < Test::Unit::TestCase
5
+
6
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: copperegg-revealmetrics
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.2
5
+ platform: ruby
6
+ authors:
7
+ - Eric Anderson
8
+ - Cargo Media
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-03-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: json_pure
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: 1.7.6
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: 1.7.6
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '2.0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '2.0'
56
+ description: API client for CopperEgg Revealmetrics
57
+ email: hello@cargomedia.ch
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - "/Users/reto/Projects/copperegg-revealmetrics/CHANGELOG.md"
63
+ - "/Users/reto/Projects/copperegg-revealmetrics/Gemfile"
64
+ - "/Users/reto/Projects/copperegg-revealmetrics/Gemfile.lock"
65
+ - "/Users/reto/Projects/copperegg-revealmetrics/LICENSE"
66
+ - "/Users/reto/Projects/copperegg-revealmetrics/README.md"
67
+ - "/Users/reto/Projects/copperegg-revealmetrics/Rakefile"
68
+ - "/Users/reto/Projects/copperegg-revealmetrics/copperegg.gemspec"
69
+ - "/Users/reto/Projects/copperegg-revealmetrics/lib/copperegg.rb"
70
+ - "/Users/reto/Projects/copperegg-revealmetrics/lib/copperegg/api.rb"
71
+ - "/Users/reto/Projects/copperegg-revealmetrics/lib/copperegg/custom_dashboard.rb"
72
+ - "/Users/reto/Projects/copperegg-revealmetrics/lib/copperegg/metric_group.rb"
73
+ - "/Users/reto/Projects/copperegg-revealmetrics/lib/copperegg/metric_sample.rb"
74
+ - "/Users/reto/Projects/copperegg-revealmetrics/lib/copperegg/mixins/persistence.rb"
75
+ - "/Users/reto/Projects/copperegg-revealmetrics/lib/copperegg/ver.rb"
76
+ - "/Users/reto/Projects/copperegg-revealmetrics/pkg/copperegg-revealmetrics-0.6.1.gem"
77
+ - "/Users/reto/Projects/copperegg-revealmetrics/test/custom_dashboard_test.rb"
78
+ - "/Users/reto/Projects/copperegg-revealmetrics/test/metric_group_test.rb"
79
+ - "/Users/reto/Projects/copperegg-revealmetrics/test/metric_sample_test.rb"
80
+ - test/custom_dashboard_test.rb
81
+ - test/metric_group_test.rb
82
+ - test/metric_sample_test.rb
83
+ homepage: https://github.com/cargomedia/copperegg-revealmetrics
84
+ licenses:
85
+ - MIT
86
+ metadata: {}
87
+ post_install_message:
88
+ rdoc_options:
89
+ - "--line-numbers"
90
+ - "--inline-source"
91
+ - "--title"
92
+ - copperegg-revealmetrics
93
+ - "--main"
94
+ - README.md
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.4.5
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: API client for CopperEgg Revealmetrics
113
+ test_files:
114
+ - test/custom_dashboard_test.rb
115
+ - test/metric_group_test.rb
116
+ - test/metric_sample_test.rb