riemann-client 0.2.5 → 0.2.6
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.
- data/.gitignore +6 -0
- data/Gemfile +3 -0
- data/README.markdown +2 -2
- data/Rakefile.rb +46 -0
- data/lib/riemann/client.rb +7 -0
- data/lib/riemann/client/tcp_socket.rb +4 -3
- data/lib/riemann/version.rb +1 -1
- data/riemann-client.gemspec +31 -0
- data/spec/client.rb +288 -0
- metadata +53 -8
data/Gemfile
ADDED
data/README.markdown
CHANGED
@@ -48,8 +48,8 @@ faster than TCP, but you will not know if the server is down or encountered an
|
|
48
48
|
error. You can specify what transport to use by selecting a subclient:
|
49
49
|
|
50
50
|
``` ruby
|
51
|
-
c.udp << { :state "ok" } # => nil
|
52
|
-
c.tcp << { :state "ok" } # => #<Message ...>
|
51
|
+
c.udp << { :state => "ok" } # => nil
|
52
|
+
c.tcp << { :state => "ok" } # => #<Message ...>
|
53
53
|
c.tcp["true"] # => [#<Event ... >, ...]
|
54
54
|
c.udp["true"] # => raise Riemann::Client::Unsupported
|
55
55
|
```
|
data/Rakefile.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), 'lib'))
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rubygems/package_task'
|
5
|
+
require 'rdoc/task'
|
6
|
+
require 'riemann/version'
|
7
|
+
require 'find'
|
8
|
+
|
9
|
+
# Don't include resource forks in tarballs on Mac OS X.
|
10
|
+
ENV['COPY_EXTENDED_ATTRIBUTES_DISABLE'] = 'true'
|
11
|
+
ENV['COPYFILE_DISABLE'] = 'true'
|
12
|
+
|
13
|
+
# Gemspec
|
14
|
+
gemspec = Gem::Specification.new do |s|
|
15
|
+
s.rubyforge_project = 'riemann-client'
|
16
|
+
|
17
|
+
s.name = 'riemann-client'
|
18
|
+
s.version = Riemann::VERSION
|
19
|
+
s.author = 'Kyle Kingsbury'
|
20
|
+
s.email = 'aphyr@aphyr.com'
|
21
|
+
s.homepage = 'https://github.com/aphyr/riemann-ruby-client'
|
22
|
+
s.platform = Gem::Platform::RUBY
|
23
|
+
s.summary = 'Client for the distributed event system Riemann.'
|
24
|
+
|
25
|
+
s.add_dependency 'beefcake', '>= 0.3.5'
|
26
|
+
s.add_dependency 'trollop', '>= 1.16.2'
|
27
|
+
s.add_dependency 'mtrc', '>= 0.0.4'
|
28
|
+
|
29
|
+
s.files = FileList['{lib}/**/*', 'LICENSE', 'README.markdown'].to_a
|
30
|
+
s.executables = []
|
31
|
+
s.require_path = 'lib'
|
32
|
+
s.has_rdoc = true
|
33
|
+
|
34
|
+
s.required_ruby_version = '>= 1.8.7'
|
35
|
+
end
|
36
|
+
|
37
|
+
Gem::PackageTask.new gemspec do |p|
|
38
|
+
end
|
39
|
+
|
40
|
+
RDoc::Task.new do |rd|
|
41
|
+
rd.main = 'Riemann'
|
42
|
+
rd.title = 'Riemann'
|
43
|
+
rd.rdoc_dir = 'doc'
|
44
|
+
|
45
|
+
rd.rdoc_files.include('lib/**/*.rb')
|
46
|
+
end
|
data/lib/riemann/client.rb
CHANGED
@@ -115,8 +115,9 @@ module Riemann
|
|
115
115
|
sock = ::Socket.new(::Socket::AF_INET, ::Socket::SOCK_STREAM, 0)
|
116
116
|
|
117
117
|
# close file descriptors if we exec
|
118
|
-
|
119
|
-
|
118
|
+
if Fcntl.constants.include?(:F_SETFD) && Fcntl.constants.include?(:FD_CLOEXEC)
|
119
|
+
sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
120
|
+
end
|
120
121
|
# Disable Nagle's algorithm
|
121
122
|
sock.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1)
|
122
123
|
|
@@ -331,4 +332,4 @@ module Riemann
|
|
331
332
|
end
|
332
333
|
end
|
333
334
|
end
|
334
|
-
end
|
335
|
+
end
|
data/lib/riemann/version.rb
CHANGED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'riemann/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'riemann-client'
|
8
|
+
spec.version = Riemann::VERSION
|
9
|
+
spec.author = 'Kyle Kingsbury'
|
10
|
+
spec.email = 'aphyr@aphyr.com'
|
11
|
+
spec.summary = 'Client for the distributed event system Riemann.'
|
12
|
+
spec.description = 'Client for the distributed event system Riemann.'
|
13
|
+
spec.homepage = 'https://github.com/aphyr/riemann-ruby-client'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
spec.platform = Gem::Platform::RUBY
|
16
|
+
|
17
|
+
spec.files = `git ls-files`.split($/)
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
spec.has_rdoc = true
|
22
|
+
|
23
|
+
spec.required_ruby_version = '>= 1.8.7'
|
24
|
+
|
25
|
+
spec.add_development_dependency 'bundler', '>= 1.3'
|
26
|
+
spec.add_development_dependency 'bacon'
|
27
|
+
|
28
|
+
spec.add_dependency 'beefcake', ['>= 0.3.5','<= 1.0.0 ']
|
29
|
+
spec.add_dependency 'trollop', '>= 1.16.2'
|
30
|
+
spec.add_dependency 'mtrc', '>= 0.0.4'
|
31
|
+
end
|
data/spec/client.rb
ADDED
@@ -0,0 +1,288 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# How to run the bacon tests:
|
4
|
+
# 1. Start Riemann on default location 127.0.0.1:5555
|
5
|
+
# 2. $ bundle exec bacon spec/client.rb
|
6
|
+
|
7
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'riemann'))
|
8
|
+
require 'riemann/client'
|
9
|
+
require 'bacon'
|
10
|
+
require 'set'
|
11
|
+
|
12
|
+
Bacon.summary_on_exit
|
13
|
+
|
14
|
+
include Riemann
|
15
|
+
|
16
|
+
INACTIVITY_TIME = 5
|
17
|
+
RIEMANN_IP = ENV["RIEMANN_IP"] || "127.0.0.1"
|
18
|
+
RIEMANN_PORT = ENV["RIEMANN_PORT"] || 5555
|
19
|
+
|
20
|
+
def roundtrip_metric(m)
|
21
|
+
@client_with_transport << {
|
22
|
+
:service => 'metric-test',
|
23
|
+
:metric => m
|
24
|
+
}
|
25
|
+
@client["service = \"metric-test\" and metric = #{m}"].
|
26
|
+
first.metric.should.equal m
|
27
|
+
end
|
28
|
+
|
29
|
+
def truthy
|
30
|
+
lambda { |obj| !(obj.nil? || obj == false) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def falsey
|
34
|
+
lambda { |obj| obj.nil? || obj == false }
|
35
|
+
end
|
36
|
+
|
37
|
+
shared "a riemann client" do
|
38
|
+
|
39
|
+
should 'yield itself to given block' do
|
40
|
+
client = nil
|
41
|
+
Client.new(:host => RIEMANN_IP, :port => RIEMANN_PORT) do |c|
|
42
|
+
client = c
|
43
|
+
end
|
44
|
+
client.should.be.kind_of?(Client)
|
45
|
+
client.should.not.be.connected
|
46
|
+
end
|
47
|
+
|
48
|
+
should 'close sockets if given a block that raises' do
|
49
|
+
client = nil
|
50
|
+
begin
|
51
|
+
Client.new(:host => RIEMANN_IP, :port => RIEMANN_PORT) do |c|
|
52
|
+
client = c
|
53
|
+
raise "The Boom"
|
54
|
+
end
|
55
|
+
rescue
|
56
|
+
# swallow the exception
|
57
|
+
end
|
58
|
+
client.should.be.kind_of?(Client)
|
59
|
+
client.should.not.be.connected
|
60
|
+
end
|
61
|
+
|
62
|
+
should 'be connected after sending' do
|
63
|
+
@client_with_transport.connected?.should.be falsey
|
64
|
+
@client.connected?.should.be falsey
|
65
|
+
@client_with_transport << {:state => 'ok', :service => 'connected check' }
|
66
|
+
@client_with_transport.connected?.should.be truthy
|
67
|
+
# NOTE: only single transport connected at this point, @client.connected? is still false until all transports used
|
68
|
+
end
|
69
|
+
|
70
|
+
should 'send longs' do
|
71
|
+
roundtrip_metric(0)
|
72
|
+
roundtrip_metric(-3)
|
73
|
+
roundtrip_metric(5)
|
74
|
+
roundtrip_metric(-(2**63))
|
75
|
+
roundtrip_metric(2**63 - 1)
|
76
|
+
end
|
77
|
+
|
78
|
+
should 'send doubles' do
|
79
|
+
roundtrip_metric 0.0
|
80
|
+
roundtrip_metric 12.0
|
81
|
+
roundtrip_metric 1.2300000190734863
|
82
|
+
end
|
83
|
+
|
84
|
+
should 'send custom attributes' do
|
85
|
+
event = Event.new(
|
86
|
+
:service => 'custom',
|
87
|
+
:state => 'ok',
|
88
|
+
:cats => 'meow',
|
89
|
+
:env => 'prod'
|
90
|
+
)
|
91
|
+
event[:sneak] = 'attack'
|
92
|
+
@client_with_transport << event
|
93
|
+
event2 = @client['service = "custom"'].first
|
94
|
+
event2.service.should.equal 'custom'
|
95
|
+
event2.state.should.equal 'ok'
|
96
|
+
event2[:cats].should.equal 'meow'
|
97
|
+
event2[:env].should.equal 'prod'
|
98
|
+
event2[:sneak].should.equal 'attack'
|
99
|
+
end
|
100
|
+
|
101
|
+
should 'send a state with a time' do
|
102
|
+
t = Time.now.to_i - 10
|
103
|
+
@client_with_transport << {
|
104
|
+
:state => 'ok',
|
105
|
+
:service => 'test',
|
106
|
+
:time => t
|
107
|
+
}
|
108
|
+
@client.query('service = "test"').events.first.time.should.equal t
|
109
|
+
end
|
110
|
+
|
111
|
+
should 'send a state without time' do
|
112
|
+
@client_with_transport << {
|
113
|
+
:state => 'ok',
|
114
|
+
:service => 'timeless test'
|
115
|
+
}
|
116
|
+
@client.query('service = "timeless test"').events.first.time.should.equal Time.now.to_i
|
117
|
+
end
|
118
|
+
|
119
|
+
should "query states" do
|
120
|
+
@client_with_transport << { :state => 'critical', :service => '1' }
|
121
|
+
@client_with_transport << { :state => 'warning', :service => '2' }
|
122
|
+
@client_with_transport << { :state => 'critical', :service => '3' }
|
123
|
+
@client.query.events.
|
124
|
+
map(&:service).to_set.should.superset ['1', '2', '3'].to_set
|
125
|
+
@client.query('state = "critical" and (service = "1" or service = "2" or service = "3")').events.
|
126
|
+
map(&:service).to_set.should.equal ['1', '3'].to_set
|
127
|
+
end
|
128
|
+
|
129
|
+
it '[]' do
|
130
|
+
# @client['state = "critical"'].should == []
|
131
|
+
@client_with_transport << {:state => 'critical'}
|
132
|
+
@client['state = "critical"'].first.state.should.equal 'critical'
|
133
|
+
end
|
134
|
+
|
135
|
+
should 'query quickly' do
|
136
|
+
t1 = Time.now
|
137
|
+
total = 1000
|
138
|
+
total.times do |i|
|
139
|
+
@client.query('state = "critical"')
|
140
|
+
end
|
141
|
+
t2 = Time.now
|
142
|
+
|
143
|
+
rate = total / (t2 - t1)
|
144
|
+
puts "\n #{"%.2f" % rate} queries/sec (#{"%.2f" % (1000/rate)}ms per query)"
|
145
|
+
rate.should > 100
|
146
|
+
end
|
147
|
+
|
148
|
+
should 'be threadsafe' do
|
149
|
+
concurrency = 10
|
150
|
+
per_thread = 200
|
151
|
+
total = concurrency * per_thread
|
152
|
+
|
153
|
+
t1 = Time.now
|
154
|
+
(0...concurrency).map do |i|
|
155
|
+
Thread.new do
|
156
|
+
per_thread.times do
|
157
|
+
@client_with_transport.<<({
|
158
|
+
:state => 'ok',
|
159
|
+
:service => 'test',
|
160
|
+
:description => 'desc',
|
161
|
+
:metric_f => 1.0
|
162
|
+
})
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end.each do |t|
|
166
|
+
t.join
|
167
|
+
end
|
168
|
+
t2 = Time.now
|
169
|
+
|
170
|
+
rate = total / (t2 - t1)
|
171
|
+
puts "\n #{"%.2f" % rate} inserts/sec (#{"%.2f" % (1000/rate)}ms per insert)"
|
172
|
+
rate.should > @expected_rate
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
describe "Riemann::Client (TCP transport)" do
|
179
|
+
before do
|
180
|
+
@client = Client.new(:host => RIEMANN_IP, :port => RIEMANN_PORT)
|
181
|
+
@client_with_transport = @client.tcp
|
182
|
+
@expected_rate = 100
|
183
|
+
end
|
184
|
+
behaves_like "a riemann client"
|
185
|
+
|
186
|
+
should 'send a state' do
|
187
|
+
res = @client_with_transport << {
|
188
|
+
:state => 'ok',
|
189
|
+
:service => 'test',
|
190
|
+
:description => 'desc',
|
191
|
+
:metric_f => 1.0
|
192
|
+
}
|
193
|
+
|
194
|
+
res.ok.should.be truthy
|
195
|
+
@client['service = "test"'].first.state.should.equal 'ok'
|
196
|
+
end
|
197
|
+
|
198
|
+
should 'survive inactivity' do
|
199
|
+
@client_with_transport.<<({
|
200
|
+
:state => 'warning',
|
201
|
+
:service => 'survive TCP inactivity',
|
202
|
+
})
|
203
|
+
@client['service = "survive TCP inactivity"'].first.state.should.equal 'warning'
|
204
|
+
|
205
|
+
sleep INACTIVITY_TIME
|
206
|
+
|
207
|
+
@client_with_transport.<<({
|
208
|
+
:state => 'ok',
|
209
|
+
:service => 'survive TCP inactivity',
|
210
|
+
}).ok.should.be truthy
|
211
|
+
@client['service = "survive TCP inactivity"'].first.state.should.equal 'ok'
|
212
|
+
end
|
213
|
+
|
214
|
+
should 'survive local close' do
|
215
|
+
@client_with_transport.<<({
|
216
|
+
:state => 'warning',
|
217
|
+
:service => 'survive TCP local close',
|
218
|
+
}).ok.should.be truthy
|
219
|
+
@client['service = "survive TCP local close"'].first.state.should.equal 'warning'
|
220
|
+
|
221
|
+
@client.close
|
222
|
+
|
223
|
+
@client_with_transport.<<({
|
224
|
+
:state => 'ok',
|
225
|
+
:service => 'survive TCP local close',
|
226
|
+
}).ok.should.be truthy
|
227
|
+
@client['service = "survive TCP local close"'].first.state.should.equal 'ok'
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
describe "Riemann::Client (UDP transport)" do
|
232
|
+
before do
|
233
|
+
@client = Client.new(:host => RIEMANN_IP, :port => RIEMANN_PORT)
|
234
|
+
@client_with_transport = @client.udp
|
235
|
+
@expected_rate = 1000
|
236
|
+
end
|
237
|
+
behaves_like "a riemann client"
|
238
|
+
|
239
|
+
should 'send a state' do
|
240
|
+
res = @client_with_transport << {
|
241
|
+
:state => 'ok',
|
242
|
+
:service => 'test',
|
243
|
+
:description => 'desc',
|
244
|
+
:metric_f => 1.0
|
245
|
+
}
|
246
|
+
|
247
|
+
res.should.be.nil
|
248
|
+
@client['service = "test"'].first.state.should.equal 'ok'
|
249
|
+
end
|
250
|
+
|
251
|
+
should 'survive inactivity' do
|
252
|
+
@client_with_transport.<<({
|
253
|
+
:state => 'warning',
|
254
|
+
:service => 'survive UDP inactivity',
|
255
|
+
})
|
256
|
+
@client['service = "survive UDP inactivity"'].first.state.should.equal 'warning'
|
257
|
+
|
258
|
+
sleep INACTIVITY_TIME
|
259
|
+
|
260
|
+
@client_with_transport.<<({
|
261
|
+
:state => 'ok',
|
262
|
+
:service => 'survive UDP inactivity',
|
263
|
+
})
|
264
|
+
@client['service = "survive UDP inactivity"'].first.state.should.equal 'ok'
|
265
|
+
end
|
266
|
+
|
267
|
+
should 'survive local close' do
|
268
|
+
@client_with_transport.<<({
|
269
|
+
:state => 'warning',
|
270
|
+
:service => 'survive UDP local close',
|
271
|
+
})
|
272
|
+
@client['service = "survive UDP local close"'].first.state.should.equal 'warning'
|
273
|
+
|
274
|
+
@client.close
|
275
|
+
|
276
|
+
@client_with_transport.<<({
|
277
|
+
:state => 'ok',
|
278
|
+
:service => 'survive UDP local close',
|
279
|
+
})
|
280
|
+
@client['service = "survive UDP local close"'].first.state.should.equal 'ok'
|
281
|
+
end
|
282
|
+
|
283
|
+
should "raise Riemann::Client::Unsupported exception on query" do
|
284
|
+
should.raise(Riemann::Client::Unsupported) { @client_with_transport['service = "test"'] }
|
285
|
+
should.raise(Riemann::Client::Unsupported) { @client_with_transport.query('service = "test"') }
|
286
|
+
end
|
287
|
+
|
288
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: riemann-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,40 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-11-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.3'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: bacon
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
14
46
|
- !ruby/object:Gem::Dependency
|
15
47
|
name: beefcake
|
16
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -19,6 +51,9 @@ dependencies:
|
|
19
51
|
- - ! '>='
|
20
52
|
- !ruby/object:Gem::Version
|
21
53
|
version: 0.3.5
|
54
|
+
- - <=
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 1.0.0
|
22
57
|
type: :runtime
|
23
58
|
prerelease: false
|
24
59
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -27,6 +62,9 @@ dependencies:
|
|
27
62
|
- - ! '>='
|
28
63
|
- !ruby/object:Gem::Version
|
29
64
|
version: 0.3.5
|
65
|
+
- - <=
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 1.0.0
|
30
68
|
- !ruby/object:Gem::Dependency
|
31
69
|
name: trollop
|
32
70
|
requirement: !ruby/object:Gem::Requirement
|
@@ -59,12 +97,17 @@ dependencies:
|
|
59
97
|
- - ! '>='
|
60
98
|
- !ruby/object:Gem::Version
|
61
99
|
version: 0.0.4
|
62
|
-
description:
|
100
|
+
description: Client for the distributed event system Riemann.
|
63
101
|
email: aphyr@aphyr.com
|
64
102
|
executables: []
|
65
103
|
extensions: []
|
66
104
|
extra_rdoc_files: []
|
67
105
|
files:
|
106
|
+
- .gitignore
|
107
|
+
- Gemfile
|
108
|
+
- LICENSE
|
109
|
+
- README.markdown
|
110
|
+
- Rakefile.rb
|
68
111
|
- lib/riemann.rb
|
69
112
|
- lib/riemann/attribute.rb
|
70
113
|
- lib/riemann/auto_state.rb
|
@@ -78,10 +121,11 @@ files:
|
|
78
121
|
- lib/riemann/query.rb
|
79
122
|
- lib/riemann/state.rb
|
80
123
|
- lib/riemann/version.rb
|
81
|
-
-
|
82
|
-
-
|
124
|
+
- riemann-client.gemspec
|
125
|
+
- spec/client.rb
|
83
126
|
homepage: https://github.com/aphyr/riemann-ruby-client
|
84
|
-
licenses:
|
127
|
+
licenses:
|
128
|
+
- MIT
|
85
129
|
post_install_message:
|
86
130
|
rdoc_options: []
|
87
131
|
require_paths:
|
@@ -99,9 +143,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
143
|
- !ruby/object:Gem::Version
|
100
144
|
version: '0'
|
101
145
|
requirements: []
|
102
|
-
rubyforge_project:
|
146
|
+
rubyforge_project:
|
103
147
|
rubygems_version: 1.8.25
|
104
148
|
signing_key:
|
105
149
|
specification_version: 3
|
106
150
|
summary: Client for the distributed event system Riemann.
|
107
|
-
test_files:
|
151
|
+
test_files:
|
152
|
+
- spec/client.rb
|