rearview 1.1.2-jruby → 1.2.0-jruby
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +11 -3
- data/app/controllers/rearview/application_controller.rb +11 -0
- data/app/controllers/rearview/dashboard_children_controller.rb +1 -1
- data/app/controllers/rearview/dashboards_controller.rb +1 -1
- data/app/controllers/rearview/home_controller.rb +1 -1
- data/app/controllers/rearview/jobs_controller.rb +33 -29
- data/app/controllers/rearview/monitor_controller.rb +16 -2
- data/app/controllers/rearview/user_controller.rb +2 -2
- data/app/helpers/rearview/application_helper.rb +3 -3
- data/app/mailers/rearview/alert_mailer.rb +0 -2
- data/app/mailers/rearview/metrics_validation_mailer.rb +12 -0
- data/app/models/rearview/job.rb +17 -13
- data/app/views/rearview/home/show.html.erb +2 -0
- data/app/views/rearview/jobs/_job.json.jbuilder +1 -0
- data/app/views/rearview/metrics_validation_mailer/validation_failed_email.text.erb +13 -0
- data/app/views/rearview/monitor/create.json.jbuilder +1 -0
- data/db/migrate/20131106162900_base_schema.rb +2 -2
- data/lib/generators/templates/rearview.rb +24 -7
- data/lib/graphite.rb +13 -0
- data/lib/graphite/cacerts.pem +2184 -0
- data/lib/graphite/client.rb +44 -0
- data/lib/graphite/graph.rb +35 -0
- data/lib/{rearview/graphite_parser.rb → graphite/raw_parser.rb} +2 -3
- data/lib/graphite/target.rb +9 -0
- data/lib/graphite/target_grammer.rb +114 -0
- data/lib/graphite/target_grammer.treetop +53 -0
- data/lib/graphite/target_parser.rb +50 -0
- data/lib/graphite/treetop_ext.rb +14 -0
- data/lib/rearview.rb +11 -3
- data/lib/rearview/alerts_handler.rb +2 -6
- data/lib/rearview/configuration.rb +44 -19
- data/lib/rearview/cron_expression_validator.rb +11 -0
- data/lib/rearview/metrics_validator.rb +52 -0
- data/lib/rearview/metrics_validator_service.rb +24 -0
- data/lib/rearview/metrics_validator_task.rb +56 -0
- data/lib/rearview/monitor_runner.rb +9 -7
- data/lib/rearview/monitor_service.rb +2 -0
- data/lib/rearview/stats_service.rb +4 -2
- data/lib/rearview/version.rb +1 -1
- data/lib/tasks/rearview_tasks.rake +7 -1
- data/public/{help → rearview-src/help}/alert.html +0 -0
- data/public/{help → rearview-src/help}/quick.html +0 -0
- data/public/rearview-src/js/app.js +9 -0
- data/public/rearview-src/js/model/user.js +6 -2
- data/public/rearview-src/js/view/addmonitor.js +13 -8
- data/public/rearview-src/js/view/alert.js +11 -4
- data/public/rearview-src/js/view/dashboard.js +4 -2
- data/public/rearview-src/js/view/expandedmonitor.js +22 -9
- data/public/rearview-src/js/view/settings.js +84 -0
- data/public/rearview-src/less/login.less +4 -4
- data/public/rearview-src/less/rearview.less +17 -10
- data/public/{monitors → rearview-src/monitors}/index.json +1 -1
- data/public/{monitors → rearview-src/monitors}/outage.rb +0 -0
- data/public/rearview-src/templates/alert.hbs +10 -2
- data/public/rearview-src/templates/primarynav.hbs +6 -6
- data/public/rearview-src/templates/schedulemonitor.hbs +2 -1
- data/public/rearview-src/templates/settings.hbs +23 -0
- data/public/rearview/build.txt +1 -0
- data/public/rearview/help/alert.html +20 -0
- data/public/rearview/help/quick.html +34 -0
- data/public/rearview/js/app.js +1 -1
- data/public/rearview/js/main.js +21 -21
- data/public/rearview/js/model/user.js +1 -1
- data/public/rearview/js/view/addmonitor.js +1 -1
- data/public/rearview/js/view/alert.js +1 -1
- data/public/rearview/js/view/dashboard.js +1 -1
- data/public/rearview/js/view/expandedmonitor.js +1 -1
- data/public/rearview/js/view/settings.js +1 -0
- data/public/rearview/less/login.less +4 -4
- data/public/rearview/less/rearview.less +17 -10
- data/public/rearview/monitors/index.json +3 -0
- data/public/rearview/monitors/outage.rb +2 -0
- data/public/rearview/templates/alert.hbs +10 -2
- data/public/rearview/templates/primarynav.hbs +6 -6
- data/public/rearview/templates/schedulemonitor.hbs +2 -1
- data/public/rearview/templates/settings.hbs +23 -0
- data/spec/controllers/jobs_controller_spec.rb +1 -0
- data/spec/controllers/monitor_controller_spec.rb +3 -0
- data/spec/controllers/user_controller_spec.rb +5 -2
- data/spec/data/metrics.yml +598 -0
- data/spec/dummy/log/development.log +1044 -0
- data/spec/dummy/log/test.log +171716 -0
- data/spec/helpers/application_helper_spec.rb +33 -0
- data/spec/lib/graphite/client_spec.rb +126 -0
- data/spec/lib/graphite/graph_spec.rb +17 -0
- data/spec/lib/graphite/graphite_spec.rb +4 -0
- data/spec/lib/{rearview/graphite_parser_spec.rb → graphite/raw_parser.rb} +6 -5
- data/spec/lib/graphite/target_grammer_spec.rb +106 -0
- data/spec/lib/graphite/target_parser_spec.rb +124 -0
- data/spec/lib/graphite/target_spec.rb +5 -0
- data/spec/lib/rearview/configuration_spec.rb +69 -48
- data/spec/lib/rearview/metrics_validator_service_spec.rb +43 -0
- data/spec/lib/rearview/metrics_validator_spec.rb +84 -0
- data/spec/lib/rearview/metrics_validator_task_spec.rb +62 -0
- data/spec/lib/rearview/monitor_runner_spec.rb +3 -3
- data/spec/lib/rearview/stats_task_spec.rb +21 -0
- data/spec/mailers/metrics_validation_mailer_spec.rb +46 -0
- data/spec/models/job_spec.rb +82 -9
- data/spec/spec_helper.rb +15 -4
- data/spec/support/json_factory.rb +1 -1
- data/spec/views/dashboards/show.json.jbuilder_spec.rb +3 -1
- data/spec/views/jobs/show.json.jbuilder_spec.rb +2 -1
- metadata +98 -11
- data/public/rearview-src/templates/test.txt +0 -1
- data/public/rearview/templates/test.txt +0 -1
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rearview::ApplicationHelper do
|
4
|
+
context '#rearview_static_path' do
|
5
|
+
context 'development' do
|
6
|
+
it 'returns the non-compiled path' do
|
7
|
+
Rails.env.stubs(:development?).returns(true)
|
8
|
+
expect(helper.rearview_static_path).to eq('/rearview-src')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
context 'non-development' do
|
12
|
+
it 'returns the compiled path' do
|
13
|
+
Rails.env.stubs(:development?).returns(false)
|
14
|
+
expect(helper.rearview_static_path).to eq('/rearview')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
context 'segment' do
|
18
|
+
it 'prepends if present' do
|
19
|
+
expect(helper.rearview_static_path('/foo')).to eq('/rearview/foo')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
context '#rearview_link_tag' do
|
24
|
+
it 'creates a link tag prepended with rearview_static_path' do
|
25
|
+
expect(helper.rearview_link_tag('/foo/bar.css')).to eq(%q{<link href="/rearview/foo/bar.css" />})
|
26
|
+
end
|
27
|
+
end
|
28
|
+
context '#rearview_img_tag' do
|
29
|
+
it 'creates a img tag prepended with rearview_static_path and img' do
|
30
|
+
expect(helper.rearview_img_tag('/foo/bar.gif')).to eq(%q{<img src="/rearview/img/foo/bar.gif" />})
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Graphite::Client do
|
4
|
+
context '.initialize' do
|
5
|
+
let(:default_client) { Graphite::Client.new }
|
6
|
+
context 'ca_file' do
|
7
|
+
it 'uses the cacerts in graphite lib by default' do
|
8
|
+
cacerts = File.expand_path("../../../../lib/graphite/cacerts.pem",__FILE__)
|
9
|
+
expect(default_client.connection.ssl.ca_file).to eq(cacerts)
|
10
|
+
end
|
11
|
+
it 'can be specified' do
|
12
|
+
expect(Graphite::Client.new({ssl: {ca_file: "cacerts.pem" }}).connection.ssl.ca_file).to eq("cacerts.pem")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
context 'ssl_verify' do
|
16
|
+
it 'is true by default' do
|
17
|
+
expect(default_client.connection.ssl.verify).to be_true
|
18
|
+
end
|
19
|
+
it 'can be specified' do
|
20
|
+
expect(Graphite::Client.new({ssl: {verify: false}}).connection.ssl.verify).to be_false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
context 'basic_auth' do
|
24
|
+
it 'is not enabled by default' do
|
25
|
+
expect(default_client.connection.headers['Authorization']).to be_nil
|
26
|
+
end
|
27
|
+
it 'can be specified' do
|
28
|
+
expect(Graphite::Client.new({basic_auth: {user: "foo", password: "bar"}}).connection.headers['Authorization']).not_to be_nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
context '#find_metric' do
|
33
|
+
before do
|
34
|
+
@client = Graphite::Client.new(url: 'http://graphite1.graphitehosting.com')
|
35
|
+
@connection = mock
|
36
|
+
@client.stubs(:connection).returns(@connection)
|
37
|
+
end
|
38
|
+
it 'makes the correct graphite API query' do
|
39
|
+
@connection.expects(:get).with('/metrics/find',{ query: 'stats.my_count' })
|
40
|
+
@client.find_metric('stats.my_count')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
context '#render' do
|
44
|
+
before do
|
45
|
+
@client = Graphite::Client.new(url: 'http://graphite1.graphitehosting.com')
|
46
|
+
@connection = mock
|
47
|
+
@client.stubs(:connection).returns(@connection)
|
48
|
+
end
|
49
|
+
it 'makes the correct graphite API query' do
|
50
|
+
@connection.expects(:get).with('/render',{ foo: 'bar' })
|
51
|
+
@client.render({ foo: 'bar' })
|
52
|
+
end
|
53
|
+
end
|
54
|
+
context '#metric_exists?' do
|
55
|
+
before do
|
56
|
+
@client = Graphite::Client.new(url: 'http://graphite1.graphitehosting.com')
|
57
|
+
@request_stubs = Faraday::Adapter::Test::Stubs.new
|
58
|
+
@connection_stub = Faraday.new do |builder|
|
59
|
+
builder.adapter :test, @request_stubs
|
60
|
+
end
|
61
|
+
@client.stubs(:connection).returns(@connection_stub)
|
62
|
+
end
|
63
|
+
context 'true' do
|
64
|
+
it 'when response is 200, content-type is application/json, and json is a non-empty array' do
|
65
|
+
@request_stubs.get('/metrics/find?query=stats.my_count') {[ 200, { 'content-type' => 'application/json' }, '[ {"leaf": 1, "context": {}, "text": "my_count", "expandable": 0, "id": "stats.my_count", "allowChildren": 0} ]' ]}
|
66
|
+
expect(@client.metric_exists?('stats.my_count')).to be_true
|
67
|
+
end
|
68
|
+
end
|
69
|
+
context 'false' do
|
70
|
+
it 'when response is not 200' do
|
71
|
+
@request_stubs.get('/metrics/find?query=stats.my_count') {[ 406, { 'content-type' => 'application/json' }, '[ {"leaf": 1, "context": {}, "text": "my_count", "expandable": 0, "id": "stats.my_count", "allowChildren": 0} ]' ]}
|
72
|
+
expect(@client.metric_exists?('stats.my_count')).to be_false
|
73
|
+
end
|
74
|
+
it 'when content-type is not application/json' do
|
75
|
+
@request_stubs.get('/metrics/find?query=stats.my_count') {[ 200, { 'content-type' => 'image/png' }, '[ {"leaf": 1, "context": {}, "text": "my_count", "expandable": 0, "id": "stats.my_count", "allowChildren": 0} ]' ]}
|
76
|
+
expect(@client.metric_exists?('stats.my_count')).to be_false
|
77
|
+
end
|
78
|
+
it 'when json is an empty array' do
|
79
|
+
@request_stubs.get('/metrics/find?query=stats.my_count') {[ 200, { 'content-type' => 'application/json' }, '[ ]' ]}
|
80
|
+
expect(@client.metric_exists?('stats.my_count')).to be_false
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
context '#reachable?' do
|
85
|
+
before do
|
86
|
+
@client = Graphite::Client.new(url: 'http://graphite1.graphitehosting.com')
|
87
|
+
@request_stubs = Faraday::Adapter::Test::Stubs.new
|
88
|
+
@connection_stub = Faraday.new do |builder|
|
89
|
+
builder.adapter :test, @request_stubs
|
90
|
+
end
|
91
|
+
@client.stubs(:connection).returns(@connection_stub)
|
92
|
+
end
|
93
|
+
it 'is true when response is 200, content is image/png, and content-length > 0' do
|
94
|
+
@request_stubs.get('/render') {[ 200, { 'content-type' => 'image/png', 'content-length' => '123' }, '' ]}
|
95
|
+
expect(@client.reachable?).to be_true
|
96
|
+
end
|
97
|
+
it 'is false when response is not 200' do
|
98
|
+
@request_stubs.get('/render') {[ 500, { }, '' ]}
|
99
|
+
expect(@client.reachable?).to be_false
|
100
|
+
end
|
101
|
+
it 'is false when content-type is not image/png' do
|
102
|
+
@request_stubs.get('/render') {[ 200, { 'content-type' => 'text/html', 'content-length' => '123' }, '' ]}
|
103
|
+
expect(@client.reachable?).to be_false
|
104
|
+
end
|
105
|
+
it 'is false when content-length is 0' do
|
106
|
+
@request_stubs.get('/render') {[ 200, { 'content-type' => 'image/png', 'content-length' => '0' }, '' ]}
|
107
|
+
expect(@client.reachable?).to be_false
|
108
|
+
end
|
109
|
+
end
|
110
|
+
context 'forwardable' do
|
111
|
+
before do
|
112
|
+
@connection_stub = mock
|
113
|
+
Faraday.stubs(:new).returns(@connection_stub)
|
114
|
+
@client = Graphite::Client.new(url: 'http://graphite1.graphitehosting.com')
|
115
|
+
end
|
116
|
+
it 'to connection.get' do
|
117
|
+
@connection_stub.expects(:get).with('/render')
|
118
|
+
@client.get('/render')
|
119
|
+
end
|
120
|
+
it 'to connection.post' do
|
121
|
+
@connection_stub.expects(:post).with('/render')
|
122
|
+
@client.post('/render')
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Graphite::Graph do
|
4
|
+
|
5
|
+
context '.with_url' do
|
6
|
+
it 'should create a graph from the url' do
|
7
|
+
url = '/render?width=600&from=-1days&until=now&height=400&target=alias(summarize(stats_counts.deals.payment.sale.sent%2C%221min%22)%2C%22Sent%22)&target=alias(summarize(stats_counts.deals.payment.sale.notification_received%2C%221min%22)%2C%22Received%22)&target=alias(diffSeries(summarize(stats_counts.deals.payment.sale.notification_received%2C%221min%22)%2Csummarize(stats_counts.deals.payment.sale.sent%2C%221min%22))%2C%22Difference%22)&title=Payment_Sale_Per_Minute&yMin=&yMax=&_uniq=0.8545389957472919'
|
8
|
+
graph = Graphite::Graph.from_url(url)
|
9
|
+
expect(graph.targets.size).to eq(3)
|
10
|
+
expect(graph.from).to eq('-1days')
|
11
|
+
expect(graph.until).to eq('now')
|
12
|
+
expect(graph.title).to eq('Payment_Sale_Per_Minute')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
@@ -1,24 +1,25 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe Graphite::RawParser do
|
4
4
|
|
5
5
|
artifact = open("spec/data/test.dat").read
|
6
6
|
nanPayload = open("spec/data/nan.dat").read
|
7
7
|
|
8
|
-
describe '
|
8
|
+
describe '.parse' do
|
9
9
|
it "handles graphite data" do
|
10
|
-
data =
|
10
|
+
data = Graphite::RawParser.parse(artifact)
|
11
11
|
data.length.should == 3
|
12
12
|
end
|
13
13
|
|
14
14
|
it "handles NaN in graphite data" do
|
15
|
-
data =
|
15
|
+
data = Graphite::RawParser.parse(nanPayload)
|
16
16
|
data.length.should === 3
|
17
17
|
end
|
18
18
|
|
19
19
|
it "handles no data" do
|
20
|
-
data =
|
20
|
+
data = Graphite::RawParser.parse("")
|
21
21
|
data.length.should === 0
|
22
22
|
end
|
23
23
|
end
|
24
|
+
|
24
25
|
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Graphite::TargetGrammer do
|
4
|
+
|
5
|
+
example_targets = {
|
6
|
+
simple_method: %q[alias(stats.x.y,"processed")],
|
7
|
+
nested_method: %q[color(alias(stats.x.y,"processed"),"red")],
|
8
|
+
color_only: %q[color(stats.x.y,"blue")],
|
9
|
+
very_nested: %q[alias(color(summarize(sumSeries(stats.*.y),"1min"),"orange"),"processed")]
|
10
|
+
}
|
11
|
+
|
12
|
+
describe Graphite::TargetGrammer::Target do
|
13
|
+
context '#expressions' do
|
14
|
+
it 'should contain all the expressions' do
|
15
|
+
p = Graphite::TargetParser.parse(example_targets[:nested_method])
|
16
|
+
expect(p.tree.expressions.count).to eq(2)
|
17
|
+
end
|
18
|
+
it 'should be empty if there are no expressions' do
|
19
|
+
p = Graphite::TargetParser.parse("seg1_seg2.seg3")
|
20
|
+
expect(p.tree.expressions).to eq([])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
context '#color' do
|
24
|
+
it 'should return the color when its present' do
|
25
|
+
p = Graphite::TargetParser.parse(example_targets[:nested_method])
|
26
|
+
expect(p.tree.color).to eq("red")
|
27
|
+
end
|
28
|
+
it 'should return nil if there is no color' do
|
29
|
+
p = Graphite::TargetParser.parse(example_targets[:simple_method])
|
30
|
+
expect(p.tree.color).to be_nil
|
31
|
+
p = Graphite::TargetParser.parse("seg1_seg2.seg3")
|
32
|
+
expect(p.tree.color).to be_nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
context '#alias' do
|
36
|
+
it 'should return the alias when its present' do
|
37
|
+
p = Graphite::TargetParser.parse(example_targets[:nested_method])
|
38
|
+
expect(p.tree.alias).to eq("processed")
|
39
|
+
end
|
40
|
+
it 'should return nil if there is no alias' do
|
41
|
+
p = Graphite::TargetParser.parse(example_targets[:color_only])
|
42
|
+
expect(p.tree.alias).to be_nil
|
43
|
+
p = Graphite::TargetParser.parse("seg1_seg2.seg3")
|
44
|
+
expect(p.tree.alias).to be_nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
context '#metric' do
|
48
|
+
it 'should return the metric for nested expressions' do
|
49
|
+
p = Graphite::TargetParser.parse(example_targets[:nested_method])
|
50
|
+
expect(p.tree.metric).to eq("stats.x.y")
|
51
|
+
end
|
52
|
+
it 'should return the metric for a path only target' do
|
53
|
+
p = Graphite::TargetParser.parse("seg1_seg2.seg3")
|
54
|
+
expect(p.tree.metric).to eq("seg1_seg2.seg3")
|
55
|
+
end
|
56
|
+
it 'should return the metric for very nested expressions' do
|
57
|
+
p = Graphite::TargetParser.parse(example_targets[:very_nested])
|
58
|
+
expect(p.tree.metric).to eq("stats.*.y")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
context '#functions' do
|
62
|
+
it 'should return all functions when present' do
|
63
|
+
p = Graphite::TargetParser.parse(example_targets[:nested_method])
|
64
|
+
expect(p.tree.functions).to include("color")
|
65
|
+
expect(p.tree.functions).to include("alias")
|
66
|
+
end
|
67
|
+
it 'should be empty if there are no functions' do
|
68
|
+
p = Graphite::TargetParser.parse("seg1_seg2.seg3")
|
69
|
+
expect(p.tree.functions).to eq([])
|
70
|
+
end
|
71
|
+
end
|
72
|
+
context '#path?' do
|
73
|
+
it 'should be true if the target is a path' do
|
74
|
+
p = Graphite::TargetParser.parse("seg1_seg2.seg3")
|
75
|
+
expect(p.tree.path?).to be_true
|
76
|
+
end
|
77
|
+
it 'should be false if the target is not a path' do
|
78
|
+
p = Graphite::TargetParser.parse(example_targets[:nested_method])
|
79
|
+
expect(p.tree.path?).to be_false
|
80
|
+
end
|
81
|
+
end
|
82
|
+
context '#expression?' do
|
83
|
+
it 'should be true if the target is an expression' do
|
84
|
+
p = Graphite::TargetParser.parse(example_targets[:nested_method])
|
85
|
+
expect(p.tree.expression?).to be_true
|
86
|
+
end
|
87
|
+
it 'should be false if the target is not an expression' do
|
88
|
+
p = Graphite::TargetParser.parse("seg1_seg2.seg3")
|
89
|
+
expect(p.tree.expression?).to be_false
|
90
|
+
end
|
91
|
+
end
|
92
|
+
context '#to_model' do
|
93
|
+
it 'should create a model from a target' do
|
94
|
+
p = Graphite::TargetParser.parse(example_targets[:nested_method])
|
95
|
+
model = p.tree.to_model
|
96
|
+
expect(model.color).to eq("red")
|
97
|
+
expect(model.alias).to eq("processed")
|
98
|
+
expect(model.metric).to eq("stats.x.y")
|
99
|
+
expect(model.functions).to include("color")
|
100
|
+
expect(model.functions).to include("alias")
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec::Matchers.define :be_parsed do |expected|
|
4
|
+
|
5
|
+
match do |actual|
|
6
|
+
!actual.error?
|
7
|
+
end
|
8
|
+
|
9
|
+
failure_message_for_should do |actual|
|
10
|
+
"expected that #{actual.data} would be parseable (#{actual.error})"
|
11
|
+
end
|
12
|
+
|
13
|
+
failure_message_for_should_not do |actual|
|
14
|
+
"expected that #{actual.data} would not be parseable"
|
15
|
+
end
|
16
|
+
|
17
|
+
description do
|
18
|
+
"be parseable"
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
describe Graphite::TargetParser do
|
24
|
+
|
25
|
+
context '.error?' do
|
26
|
+
let(:invalid_target) { %q[alias@(stats.x.y,"processed")] }
|
27
|
+
let(:valid_target) { %q[alias(stats.x.y,"processed")] }
|
28
|
+
it 'should be true if there is an error' do
|
29
|
+
p = Graphite::TargetParser.parse(invalid_target)
|
30
|
+
expect(p.error?).to be_true
|
31
|
+
end
|
32
|
+
it 'should be false if there is no error' do
|
33
|
+
p = Graphite::TargetParser.parse(valid_target)
|
34
|
+
expect(p.error?).to be_false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context '.error' do
|
39
|
+
let(:invalid_target) { %q[alias@(stats.x.y,"processed")] }
|
40
|
+
it 'should return the parsing failure message, line, and column' do
|
41
|
+
p = Graphite::TargetParser.parse(invalid_target)
|
42
|
+
expect(p.error[:message].present?).to be_true
|
43
|
+
expect(p.error[:line].present?).to be_true
|
44
|
+
expect(p.error[:column].present?).to be_true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context '.grammer' do
|
49
|
+
it 'should return a valid grammer file' do
|
50
|
+
grammer = Graphite::TargetParser.grammer
|
51
|
+
expect(grammer).not_to be_nil
|
52
|
+
expect(File.exists?(grammer)).to be_true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context '.parse!' do
|
57
|
+
let(:invalid_target) { %q[alias@(stats.x.y,"processed")] }
|
58
|
+
it 'should raise a typed exception when the text is unparseable' do
|
59
|
+
p = Graphite::TargetParser.new
|
60
|
+
expect { p.parse!(invalid_target) }.to raise_error(Graphite::TargetParser::TargetParserError)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'expression' do
|
65
|
+
context 'is parseable' do
|
66
|
+
it 'for all values in metrics.yml' do
|
67
|
+
metrics = YAML.load_file("spec/data/metrics.yml")
|
68
|
+
parser = Graphite::TargetParser.new
|
69
|
+
metrics.each do |m|
|
70
|
+
parser.parse(m)
|
71
|
+
expect(parser).to be_parsed
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'string' do
|
78
|
+
context 'is valid' do
|
79
|
+
it 'with single quoted strings' do
|
80
|
+
p = Graphite::TargetParser.parse(%q[alias(summarize(stats_counts.message_center.consumer_replies.created, '12h'), 'Consumer replies')])
|
81
|
+
expect(p).to be_parsed
|
82
|
+
end
|
83
|
+
it 'with double quoted strings' do
|
84
|
+
p = Graphite::TargetParser.parse(%q[alias(summarize(stats_counts.message_center.consumer_replies.created, "12h"), "Consumer replies")])
|
85
|
+
expect(p).to be_parsed
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'path' do
|
91
|
+
context 'is valid' do
|
92
|
+
it 'with seg1' do
|
93
|
+
p = Graphite::TargetParser.parse("seg1")
|
94
|
+
expect(p).to be_parsed
|
95
|
+
end
|
96
|
+
it 'with seg1.*' do
|
97
|
+
p = Graphite::TargetParser.parse("seg1.*")
|
98
|
+
expect(p).to be_parsed
|
99
|
+
end
|
100
|
+
it 'with seg1.seg2' do
|
101
|
+
p = Graphite::TargetParser.parse("seg1.seg2")
|
102
|
+
expect(p).to be_parsed
|
103
|
+
end
|
104
|
+
it 'with seg1_seg2' do
|
105
|
+
p = Graphite::TargetParser.parse("seg1_seg2")
|
106
|
+
expect(p).to be_parsed
|
107
|
+
end
|
108
|
+
it 'with seg1_seg2.seg3' do
|
109
|
+
p = Graphite::TargetParser.parse("seg1_seg2.seg3")
|
110
|
+
expect(p).to be_parsed
|
111
|
+
end
|
112
|
+
it 'with *.seg3' do
|
113
|
+
p = Graphite::TargetParser.parse("*.seg3")
|
114
|
+
expect(p).to be_parsed
|
115
|
+
end
|
116
|
+
it 'with *' do
|
117
|
+
p = Graphite::TargetParser.parse("*")
|
118
|
+
expect(p).to be_parsed
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|