observed 0.1.1
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.
- checksums.yaml +15 -0
- data/.gitignore +20 -0
- data/.travis.yml +11 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +204 -0
- data/Rakefile +4 -0
- data/examples/00readme/Gemfile +5 -0
- data/examples/00readme/clockwork.rb +16 -0
- data/examples/00readme/observed.rb +17 -0
- data/examples/observed.rb +10 -0
- data/exe/observed-oneshot +11 -0
- data/features/oneshot.feature +24 -0
- data/features/support/env.rb +8 -0
- data/features/test_in_single_ruby_source.feature +32 -0
- data/integrations/observed-clockwork/.gitignore +17 -0
- data/integrations/observed-clockwork/Gemfile +4 -0
- data/integrations/observed-clockwork/LICENSE.txt +22 -0
- data/integrations/observed-clockwork/README.md +53 -0
- data/integrations/observed-clockwork/Rakefile +1 -0
- data/integrations/observed-clockwork/bin/clockwork +16 -0
- data/integrations/observed-clockwork/bin/clockworkd +16 -0
- data/integrations/observed-clockwork/bin/observed-clockwork +16 -0
- data/integrations/observed-clockwork/bin/rake +16 -0
- data/integrations/observed-clockwork/examples/clockwork/clockwork.rb +9 -0
- data/integrations/observed-clockwork/examples/clockwork/foo_plugin.rb +19 -0
- data/integrations/observed-clockwork/examples/clockwork/observed.conf +6 -0
- data/integrations/observed-clockwork/features/run_observed_inside_clockwork.feature +59 -0
- data/integrations/observed-clockwork/features/support/env.rb +8 -0
- data/integrations/observed-clockwork/lib/observed/clockwork/version.rb +5 -0
- data/integrations/observed-clockwork/lib/observed/clockwork.rb +20 -0
- data/integrations/observed-clockwork/observed-clockwork.gemspec +29 -0
- data/lib/observed/application/oneshot.rb +114 -0
- data/lib/observed/application.rb +1 -0
- data/lib/observed/builtin_plugins/file.rb +49 -0
- data/lib/observed/builtin_plugins/stdout.rb +35 -0
- data/lib/observed/builtin_plugins.rb +2 -0
- data/lib/observed/config.rb +27 -0
- data/lib/observed/config_builder.rb +167 -0
- data/lib/observed/config_dsl.rb +77 -0
- data/lib/observed/configurable.rb +56 -0
- data/lib/observed/default/observer.rb +16 -0
- data/lib/observed/default/reporter.rb +17 -0
- data/lib/observed/default.rb +2 -0
- data/lib/observed/hash/builder.rb +24 -0
- data/lib/observed/hash/fetcher.rb +19 -0
- data/lib/observed/hash/key_path_encoding.rb +62 -0
- data/lib/observed/hash.rb +3 -0
- data/lib/observed/observer.rb +18 -0
- data/lib/observed/observer_helpers/timer.rb +37 -0
- data/lib/observed/pluggable.rb +34 -0
- data/lib/observed/reader.rb +14 -0
- data/lib/observed/reporter/regexp_matching.rb +11 -0
- data/lib/observed/reporter.rb +25 -0
- data/lib/observed/system.rb +109 -0
- data/lib/observed/version.rb +3 -0
- data/lib/observed/writer.rb +14 -0
- data/lib/observed.rb +77 -0
- data/observed.gemspec +30 -0
- data/plugins/observed-fluentd/.gitignore +20 -0
- data/plugins/observed-fluentd/Gemfile +12 -0
- data/plugins/observed-fluentd/LICENSE.txt +22 -0
- data/plugins/observed-fluentd/README.md +99 -0
- data/plugins/observed-fluentd/Rakefile +1 -0
- data/plugins/observed-fluentd/features/plugin.feature +61 -0
- data/plugins/observed-fluentd/features/support/env.rb +32 -0
- data/plugins/observed-fluentd/fluent.d/fluent.conf +93 -0
- data/plugins/observed-fluentd/fluentd.pid +1 -0
- data/plugins/observed-fluentd/lib/observed/fluentd/version.rb +5 -0
- data/plugins/observed-fluentd/lib/observed/fluentd.rb +30 -0
- data/plugins/observed-fluentd/observe.d/clockwork.rb +9 -0
- data/plugins/observed-fluentd/observe.d/observed.conf +17 -0
- data/plugins/observed-fluentd/observed-fluentd.gemspec +26 -0
- data/plugins/observed-gauge/.gitignore +18 -0
- data/plugins/observed-gauge/Gemfile +4 -0
- data/plugins/observed-gauge/LICENSE.txt +22 -0
- data/plugins/observed-gauge/README.md +29 -0
- data/plugins/observed-gauge/Rakefile +1 -0
- data/plugins/observed-gauge/lib/observed/gauge/version.rb +5 -0
- data/plugins/observed-gauge/lib/observed/gauge.rb +117 -0
- data/plugins/observed-gauge/observed-gauge.gemspec +30 -0
- data/plugins/observed-gauge/spec/gauge_spec.rb +195 -0
- data/plugins/observed-gauge/spec/spec_helper.rb +25 -0
- data/plugins/observed-http/.gitignore +17 -0
- data/plugins/observed-http/Gemfile +4 -0
- data/plugins/observed-http/LICENSE.txt +22 -0
- data/plugins/observed-http/README.md +37 -0
- data/plugins/observed-http/Rakefile +1 -0
- data/plugins/observed-http/features/observe_web_services_via_http.feature +32 -0
- data/plugins/observed-http/features/support/env.rb +8 -0
- data/plugins/observed-http/lib/observed/http/version.rb +5 -0
- data/plugins/observed-http/lib/observed/http.rb +60 -0
- data/plugins/observed-http/observed-http.gemspec +31 -0
- data/plugins/observed-http/spec/fixtures/observed.conf +10 -0
- data/plugins/observed-http/spec/http_spec.rb +14 -0
- data/plugins/observed-http/spec/spec_helper.rb +25 -0
- data/spec/builtin_plugins/file_spec.rb +145 -0
- data/spec/builtin_plugins/stdout_spec.rb +56 -0
- data/spec/config_builder_spec.rb +146 -0
- data/spec/config_dsl_spec.rb +50 -0
- data/spec/configurable_spec.rb +65 -0
- data/spec/fixtures/configure_by_conf/foo_plugin.rb +12 -0
- data/spec/fixtures/configure_by_conf/observed.conf +6 -0
- data/spec/fixtures/configure_by_conf_dot_d/foo_plugin.rb +18 -0
- data/spec/fixtures/configure_by_conf_dot_d/observed.conf.d/check_foo_1.rb +1 -0
- data/spec/fixtures/configure_by_conf_dot_d/observed.conf.d/plugins.rb +1 -0
- data/spec/fixtures/configure_by_require/observed_conf.rb +6 -0
- data/spec/hash/builder_spec.rb +36 -0
- data/spec/hash/fetcher_spec.rb +29 -0
- data/spec/input_helpers/timer_spec.rb +54 -0
- data/spec/observed_spec.rb +79 -0
- data/spec/observer_spec.rb +123 -0
- data/spec/oneshot_spec.rb +58 -0
- data/spec/reader_spec.rb +15 -0
- data/spec/reporter_spec.rb +19 -0
- data/spec/spec_helper.rb +65 -0
- data/spec/system_spec.rb +75 -0
- data/spec/writer_spec.rb +16 -0
- metadata +299 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
require 'observed/builtin_plugins/stdout'
|
|
4
|
+
|
|
5
|
+
describe Observed::BuiltinPlugins::Stdout do
|
|
6
|
+
|
|
7
|
+
subject {
|
|
8
|
+
reporter = Observed::BuiltinPlugins::Stdout.new
|
|
9
|
+
reporter.configure config
|
|
10
|
+
reporter
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let(:config) {
|
|
14
|
+
{ tag_pattern: /foo\..+/, format: formatter }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
context 'with a specific formatter' do
|
|
18
|
+
|
|
19
|
+
let(:formatter) {
|
|
20
|
+
-> tag, time, data, fetcher { "foo #{time.to_i} #{data[:foo]} #{fetcher['bar.baz']}" }
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
it 'reports the formatted data to the stdout' do
|
|
24
|
+
time = Time.now
|
|
25
|
+
STDOUT.expects(:puts).with("foo #{time.to_i} 1 2")
|
|
26
|
+
expect { subject.report('foo', time, {foo: 1, bar: {baz: 2}}) }.to_not raise_error
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context 'without a specific formatter' do
|
|
32
|
+
|
|
33
|
+
let(:formatter) {
|
|
34
|
+
nil
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
it 'reports the data formatted by the default formatter to the stdout' do
|
|
38
|
+
time = Time.now
|
|
39
|
+
STDOUT.expects(:puts).with("#{time.to_s} foo {:foo=>1}")
|
|
40
|
+
expect { subject.report('foo', time, {foo: 1}) }.to_not raise_error
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context 'with the formatter whose number of parameters is not 3 nor 4' do
|
|
46
|
+
|
|
47
|
+
let(:formatter) {
|
|
48
|
+
-> a, b {}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
it 'fails while reporting' do
|
|
52
|
+
pattern = /Number of parameters for the function for the key :format must be 3 or 4, but was 2/
|
|
53
|
+
expect { subject.report('foo', Time.now, {}) }.to raise_error(pattern)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'observed/config_builder'
|
|
3
|
+
|
|
4
|
+
describe Observed::ConfigBuilder do
|
|
5
|
+
|
|
6
|
+
include FakeFS::SpecHelpers
|
|
7
|
+
|
|
8
|
+
subject {
|
|
9
|
+
Observed::ConfigBuilder.new(
|
|
10
|
+
writer_plugins: writer_plugins,
|
|
11
|
+
reader_plugins: reader_plugins,
|
|
12
|
+
observer_plugins: observer_plugins,
|
|
13
|
+
reporter_plugins: reporter_plugins,
|
|
14
|
+
system: system
|
|
15
|
+
)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let(:system) {
|
|
19
|
+
mock('system')
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let(:observer_plugins) {
|
|
23
|
+
my_file = Class.new(Observed::Observer) do
|
|
24
|
+
attribute :path
|
|
25
|
+
attribute :key
|
|
26
|
+
def observe
|
|
27
|
+
content = File.open(path, 'r') do |f|
|
|
28
|
+
f.read
|
|
29
|
+
end
|
|
30
|
+
system.report(tag, { key => content })
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
{ 'my_file' => my_file }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let(:reporter_plugins) {
|
|
37
|
+
my_stdout = Class.new(Observed::Reporter) do
|
|
38
|
+
attribute :format
|
|
39
|
+
def match(tag)
|
|
40
|
+
true
|
|
41
|
+
end
|
|
42
|
+
def report(tag, time, data)
|
|
43
|
+
text = format.call tag, time, data, Observed::Hash::Fetcher.new(data)
|
|
44
|
+
STDOUT.puts text
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
{ 'my_stdout' => my_stdout }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let(:writer_plugins) {
|
|
51
|
+
stdout = Class.new(Observed::Writer) do
|
|
52
|
+
attribute :format
|
|
53
|
+
def write(tag, time, data)
|
|
54
|
+
text = format.call tag, time, data, Observed::Hash::Fetcher.new(data)
|
|
55
|
+
STDOUT.puts text
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
{ 'stdout' => stdout }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let(:reader_plugins) {
|
|
62
|
+
file = Class.new(Observed::Reader) do
|
|
63
|
+
attribute :path
|
|
64
|
+
attribute :key
|
|
65
|
+
def read
|
|
66
|
+
content = File.open(path, 'r') do |f|
|
|
67
|
+
f.read
|
|
68
|
+
end
|
|
69
|
+
{ key => content }
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
{
|
|
73
|
+
'file' => file
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
it 'creates writers' do
|
|
78
|
+
time = Time.now
|
|
79
|
+
subject.write to: 'stdout', with: {
|
|
80
|
+
format: -> tag, time, data, d { "value:#{d['foo.bar']}" }
|
|
81
|
+
}
|
|
82
|
+
STDOUT.expects(:puts).with('value:123')
|
|
83
|
+
expect { subject.build.writers.first.write('foo.bar', time, {foo:{bar:123}}) }.to_not raise_error
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it 'creates readers' do
|
|
87
|
+
subject.read from: 'file', with: {
|
|
88
|
+
path: 'foo.txt',
|
|
89
|
+
key: 'content'
|
|
90
|
+
}
|
|
91
|
+
File.open('foo.txt', 'w') do |f|
|
|
92
|
+
f.write('file content')
|
|
93
|
+
end
|
|
94
|
+
expect(subject.build.readers.first.read).to eq({ 'content' => 'file content' })
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it 'creates observers from reader plugins' do
|
|
98
|
+
subject.observe 'foo.bar', from: 'file', with: {
|
|
99
|
+
path: 'foo.txt',
|
|
100
|
+
key: 'content'
|
|
101
|
+
}
|
|
102
|
+
File.open('foo.txt', 'w') do |f|
|
|
103
|
+
f.write('file content')
|
|
104
|
+
end
|
|
105
|
+
system.expects(:report).with('foo.bar', { 'content' => 'file content' })
|
|
106
|
+
expect { subject.build.observers.first.observe }.to_not raise_error
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it 'creates observers from observer plugins' do
|
|
110
|
+
subject.observe 'foo.bar', via: 'my_file', which: {
|
|
111
|
+
path: 'foo.txt',
|
|
112
|
+
key: 'content'
|
|
113
|
+
}
|
|
114
|
+
File.open('foo.txt', 'w') do |f|
|
|
115
|
+
f.write('file content')
|
|
116
|
+
end
|
|
117
|
+
system.expects(:report).with('foo.bar', { 'content' => 'file content' })
|
|
118
|
+
expect { subject.build.observers.first.observe }.to_not raise_error
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it 'creates reporters from writer plugins' do
|
|
122
|
+
tag = 'foo.bar'
|
|
123
|
+
time = Time.now
|
|
124
|
+
|
|
125
|
+
subject.report /foo\.bar/, to: 'stdout', with: {
|
|
126
|
+
format: -> tag, time, data, d { "foo.bar #{time} #{d[tag]}" }
|
|
127
|
+
}
|
|
128
|
+
reporter = subject.reporters.first
|
|
129
|
+
STDOUT.expects(:puts).with("foo.bar #{time} 123").once
|
|
130
|
+
expect(reporter.match(tag)).to be_true
|
|
131
|
+
expect { reporter.report(tag, time, { foo: { bar: 123 }}) }.to_not raise_error
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it 'creates reporters from reporter plugins' do
|
|
135
|
+
tag = 'foo.bar'
|
|
136
|
+
time = Time.now
|
|
137
|
+
|
|
138
|
+
subject.report /foo\.bar/, via: 'my_stdout', with: {
|
|
139
|
+
format: -> tag, time, data, d { "foo.bar #{time} #{d[tag]}" }
|
|
140
|
+
}
|
|
141
|
+
reporter = subject.reporters.first
|
|
142
|
+
STDOUT.expects(:puts).with("foo.bar #{time} 123").once
|
|
143
|
+
expect(reporter.match(tag)).to be_true
|
|
144
|
+
expect { reporter.report(tag, time, { foo: { bar: 123 }}) }.to_not raise_error
|
|
145
|
+
end
|
|
146
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'observed/config_dsl'
|
|
3
|
+
require 'observed/observer'
|
|
4
|
+
require 'observed/reporter'
|
|
5
|
+
require 'observed/reporter/regexp_matching'
|
|
6
|
+
require 'observed/config_builder'
|
|
7
|
+
|
|
8
|
+
describe Observed::ConfigDSL do
|
|
9
|
+
subject {
|
|
10
|
+
Observed::ConfigDSL.new(builder: Observed::ConfigBuilder.new(
|
|
11
|
+
observer_plugins: observer_plugins,
|
|
12
|
+
reporter_plugins: reporter_plugins,
|
|
13
|
+
system: sys
|
|
14
|
+
))
|
|
15
|
+
}
|
|
16
|
+
let(:foo) {
|
|
17
|
+
Class.new(Observed::Observer) do
|
|
18
|
+
def observe
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
plugin_name 'foo'
|
|
22
|
+
end
|
|
23
|
+
}
|
|
24
|
+
let(:stdout) {
|
|
25
|
+
Class.new(Observed::Reporter) do
|
|
26
|
+
include Observed::Reporter::RegexpMatching
|
|
27
|
+
def report(tag, time, data)
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
plugin_name 'stdout'
|
|
31
|
+
end
|
|
32
|
+
}
|
|
33
|
+
let(:sys) {
|
|
34
|
+
mock('sys')
|
|
35
|
+
}
|
|
36
|
+
let(:observer_plugins) {
|
|
37
|
+
{ 'foo' => foo }
|
|
38
|
+
}
|
|
39
|
+
let(:reporter_plugins) {
|
|
40
|
+
{ 'stdout' => stdout }
|
|
41
|
+
}
|
|
42
|
+
it 'creates a config' do
|
|
43
|
+
subject.instance_eval do
|
|
44
|
+
observe 'foo', via: 'foo', with: { name: 'name' }
|
|
45
|
+
report /foo/, via: 'stdout'
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
#expect(subject.config).to eq({ observers: {'foo' => {plugin: 'foo', name: 'name'}}, reporters: {'foo' => {plugin: 'stdout'}}})
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'observed/configurable'
|
|
3
|
+
|
|
4
|
+
module ConfigurableSpec
|
|
5
|
+
class Foo
|
|
6
|
+
include Observed::Configurable
|
|
7
|
+
|
|
8
|
+
attribute :foo, default: 123
|
|
9
|
+
attribute :bar, default: 234
|
|
10
|
+
attribute :baz
|
|
11
|
+
|
|
12
|
+
default :bar => 345
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe Observed::Configurable do
|
|
17
|
+
|
|
18
|
+
context 'without parameters for the constructor' do
|
|
19
|
+
subject {
|
|
20
|
+
ConfigurableSpec::Foo.new
|
|
21
|
+
}
|
|
22
|
+
it 'uses default values for attributes' do
|
|
23
|
+
expect(subject.foo).to eq(123)
|
|
24
|
+
end
|
|
25
|
+
it 'overrides default values on `attribute name, :default => default_value`' do
|
|
26
|
+
expect(subject.bar).to eq(345)
|
|
27
|
+
end
|
|
28
|
+
it 'raises errors when attributes without values are read' do
|
|
29
|
+
expect { subject.baz }.to raise_error
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context 'with parameters for the constructor' do
|
|
34
|
+
subject {
|
|
35
|
+
ConfigurableSpec::Foo.new({foo: 1, bar: 2, baz: 3})
|
|
36
|
+
}
|
|
37
|
+
it 'prefers values from constructor parameters over defaults' do
|
|
38
|
+
expect(subject.foo).to eq(1)
|
|
39
|
+
expect(subject.bar).to eq(2)
|
|
40
|
+
expect(subject.baz).to eq(3)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context 'configured through `configure(args)` method' do
|
|
45
|
+
subject {
|
|
46
|
+
foo = ConfigurableSpec::Foo.new
|
|
47
|
+
foo.configure(args)
|
|
48
|
+
foo
|
|
49
|
+
}
|
|
50
|
+
shared_examples_for 'values are set' do
|
|
51
|
+
it 'prefers values from `configure(args)` over defaults' do
|
|
52
|
+
expect(subject.foo).to eq(1)
|
|
53
|
+
expect(subject.bar).to eq(2)
|
|
54
|
+
expect(subject.baz).to eq(3)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
context 'when args has symbol keys' do
|
|
58
|
+
let(:args) {
|
|
59
|
+
{foo: 1, bar: 2, baz: 3}
|
|
60
|
+
}
|
|
61
|
+
it_behaves_like 'values are set'
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module OneshotSpec
|
|
2
|
+
class FooPlugin < Observed::Observer
|
|
3
|
+
default :timeout_in_milliseconds => 5000
|
|
4
|
+
default :number_of_trials => 10
|
|
5
|
+
|
|
6
|
+
def sample
|
|
7
|
+
sleep_duration = rand / 20
|
|
8
|
+
sleep sleep_duration
|
|
9
|
+
"Foo #{sleep_duration}"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def logger
|
|
13
|
+
Logger.new(STDOUT)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
plugin_name 'foo'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
observe 'foo_1', via: 'foo'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require_relative '../foo_plugin'
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'observed/hash/builder'
|
|
3
|
+
|
|
4
|
+
describe Observed::Hash::Builder do
|
|
5
|
+
|
|
6
|
+
subject {
|
|
7
|
+
described_class.new(hash)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
context 'with a source hash' do
|
|
11
|
+
|
|
12
|
+
let(:hash) { {} }
|
|
13
|
+
|
|
14
|
+
context 'with a key path' do
|
|
15
|
+
it 'decodes the key path and recursively creates missing Hash object for each part in the key path' do
|
|
16
|
+
subject['foo.bar'] = 1
|
|
17
|
+
|
|
18
|
+
expect(subject.build).to eq({foo:{bar:1}})
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context 'with a regular string key' do
|
|
23
|
+
it 'updates the value for the key' do
|
|
24
|
+
subject['foo'] = 1
|
|
25
|
+
expect(subject.build).to eq({foo:1})
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context 'with a regular symbol key' do
|
|
30
|
+
it 'updates the value for the key' do
|
|
31
|
+
subject[:foo] = 1
|
|
32
|
+
expect(subject.build).to eq({foo:1})
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
require 'observed/hash/fetcher'
|
|
4
|
+
|
|
5
|
+
describe Observed::Hash::Fetcher do
|
|
6
|
+
|
|
7
|
+
subject {
|
|
8
|
+
described_class.new(hash)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
context 'when the source hash is nil' do
|
|
12
|
+
|
|
13
|
+
let(:hash) { nil }
|
|
14
|
+
|
|
15
|
+
it 'fails' do
|
|
16
|
+
expect { subject }.to raise_error
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context 'when the source hash is nested' do
|
|
21
|
+
|
|
22
|
+
let(:hash) { {foo:{bar:1},baz:2} }
|
|
23
|
+
|
|
24
|
+
it 'decodes the key path to recursively find the value' do
|
|
25
|
+
expect(subject['foo.bar']).to eq(1)
|
|
26
|
+
expect(subject['baz']).to eq(2)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'observed/observer_helpers/timer'
|
|
3
|
+
require 'observed/observer'
|
|
4
|
+
|
|
5
|
+
describe Observed::ObserverHelpers::Timer do
|
|
6
|
+
|
|
7
|
+
include Observed::SpecHelpers
|
|
8
|
+
|
|
9
|
+
before {
|
|
10
|
+
class ExampleTimerPlugin < Observed::Observer
|
|
11
|
+
include Observed::ObserverHelpers::Timer
|
|
12
|
+
|
|
13
|
+
attribute :timeout_in_milliseconds
|
|
14
|
+
attribute :time_to_sleep
|
|
15
|
+
|
|
16
|
+
def observe
|
|
17
|
+
time_and_report(timeout_in_seconds: self.timeout_in_milliseconds / 1000.0) do
|
|
18
|
+
sleep(time_to_sleep)
|
|
19
|
+
time_to_sleep
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.plugin_name
|
|
24
|
+
'timer'
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
subject {
|
|
30
|
+
input = ExampleTimerPlugin.new
|
|
31
|
+
input.configure system: system, tag: 'foo.timed', time_to_sleep: 0.001, timeout_in_milliseconds: 1000
|
|
32
|
+
input
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let(:system) {
|
|
36
|
+
m = mock('system')
|
|
37
|
+
m.stubs(:now).returns(1.0)
|
|
38
|
+
.then.returns(2.0)
|
|
39
|
+
.then.returns(3.0)
|
|
40
|
+
.then.returns(5.0)
|
|
41
|
+
.then.returns(6.0)
|
|
42
|
+
.then.returns(9.0)
|
|
43
|
+
m
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
it 'should report results with elapsed times' do
|
|
47
|
+
system.expects(:report).with('foo.timed.success', status: :success, elapsed_time: 1.0, result: 0.001)
|
|
48
|
+
system.expects(:report).with('foo.timed.success', status: :success, elapsed_time: 2.0, result: 0.001)
|
|
49
|
+
system.expects(:report).with('foo.timed.success', status: :success, elapsed_time: 3.0, result: 0.001)
|
|
50
|
+
subject.observe
|
|
51
|
+
subject.observe
|
|
52
|
+
subject.observe
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'observed'
|
|
3
|
+
require 'observed/builtin_plugins'
|
|
4
|
+
|
|
5
|
+
describe Observed do
|
|
6
|
+
include FakeFS::SpecHelpers
|
|
7
|
+
|
|
8
|
+
describe '#load!`' do
|
|
9
|
+
|
|
10
|
+
context 'with a relative file path under the current working directory' do
|
|
11
|
+
|
|
12
|
+
subject do
|
|
13
|
+
mod = Module.new do
|
|
14
|
+
extend Observed
|
|
15
|
+
end
|
|
16
|
+
mod.load! './observed.rb'
|
|
17
|
+
mod.config
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context 'with invalid file path' do
|
|
21
|
+
it 'should raise an error while loading' do
|
|
22
|
+
expect { subject }.to raise_error(%r|No such file or directory.+observed\.rb|)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
context 'with a valid relative file path' do
|
|
27
|
+
before do
|
|
28
|
+
File.open('./observed.rb', 'w') do |file|
|
|
29
|
+
file.write(
|
|
30
|
+
<<-EOS
|
|
31
|
+
report /foo/, via: 'stdout'
|
|
32
|
+
EOS
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'should load observed.rb' do
|
|
38
|
+
expect { subject }.to_not raise_error
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context 'with an absolute file path' do
|
|
44
|
+
|
|
45
|
+
subject {
|
|
46
|
+
mod = Module.new do
|
|
47
|
+
extend Observed
|
|
48
|
+
end
|
|
49
|
+
mod.load! '/tmp/foo/observed_conf.rb'
|
|
50
|
+
mod.config
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
context 'when the file does not exist' do
|
|
54
|
+
|
|
55
|
+
it 'fails to load it' do
|
|
56
|
+
expect { subject }.to raise_error(%r|No such file or directory - /tmp/foo/observed_conf.rb|)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
context 'when the file exists' do
|
|
61
|
+
|
|
62
|
+
before {
|
|
63
|
+
FileUtils.mkdir_p('/tmp/foo')
|
|
64
|
+
File.open('/tmp/foo/observed_conf.rb', 'w') do |f|
|
|
65
|
+
f.write(
|
|
66
|
+
<<-EOS
|
|
67
|
+
report /foo/, via: 'stdout'
|
|
68
|
+
EOS
|
|
69
|
+
)
|
|
70
|
+
end
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
it 'succeeds to load it' do
|
|
74
|
+
expect { subject }.to_not raise_error
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'observed/observer'
|
|
3
|
+
|
|
4
|
+
describe Observed::Observer do
|
|
5
|
+
|
|
6
|
+
subject {
|
|
7
|
+
described_class.new(tag: 'the_tag', system: sys)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let(:sys) { mock('system') }
|
|
11
|
+
|
|
12
|
+
it 'fails when the method `observe` is not overrode' do
|
|
13
|
+
expect { subject.observe }.to raise_error
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe 'attribute' do
|
|
17
|
+
|
|
18
|
+
it 'can be given by constructor parameters' do
|
|
19
|
+
klass = Class.new(Observed::Observer) do
|
|
20
|
+
attribute :timeout_in_milliseconds
|
|
21
|
+
attribute :number_of_trials
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
subject = klass.new(
|
|
25
|
+
timeout_in_milliseconds: 5000,
|
|
26
|
+
number_of_trials: 5000,
|
|
27
|
+
tag: 'tag'
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
expect(subject.timeout_in_milliseconds).to eq(5000)
|
|
31
|
+
expect(subject.number_of_trials).to eq(5000)
|
|
32
|
+
expect(subject.tag).to eq('tag')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'can have a default value' do
|
|
36
|
+
klass = Class.new(Observed::Observer) do
|
|
37
|
+
attribute :timeout_in_milliseconds
|
|
38
|
+
attribute :number_of_trials
|
|
39
|
+
default :timeout_in_milliseconds => 5000
|
|
40
|
+
default :number_of_trials => 5000
|
|
41
|
+
default :tag => 'tag'
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
subject = klass.new
|
|
45
|
+
|
|
46
|
+
expect(subject.timeout_in_milliseconds).to eq(5000)
|
|
47
|
+
expect(subject.number_of_trials).to eq(5000)
|
|
48
|
+
expect(subject.tag).to eq('tag')
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
context 'without a default value or a given value' do
|
|
52
|
+
it 'raises errors when accessed' do
|
|
53
|
+
klass = Class.new(Observed::Observer) do
|
|
54
|
+
attribute :timeout_in_milliseconds
|
|
55
|
+
attribute :number_of_trials
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
subject = klass.new
|
|
59
|
+
|
|
60
|
+
expect { subject.timeout_in_milliseconds }.to raise_error
|
|
61
|
+
expect { subject.number_of_trials }.to raise_error
|
|
62
|
+
expect { subject.tag }.to raise_error
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
describe '.find_plugin_named' do
|
|
69
|
+
|
|
70
|
+
it 'returns nil when no plugin with the specific name found' do
|
|
71
|
+
expect(Observed::Observer.find_plugin_named('an_invalid_name')).to be_nil
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
context 'with one named plugin' do
|
|
75
|
+
let(:klass) {
|
|
76
|
+
Class.new(Observed::Observer) do
|
|
77
|
+
attribute :timeout_in_milliseconds
|
|
78
|
+
attribute :number_of_trials
|
|
79
|
+
|
|
80
|
+
default :timeout_in_milliseconds => 5000
|
|
81
|
+
default :number_of_trials => 2
|
|
82
|
+
|
|
83
|
+
def sample
|
|
84
|
+
time_to_sleep = rand / 100
|
|
85
|
+
sleep rand
|
|
86
|
+
"Foo #{time_to_sleep}"
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
plugin_name 'observer_spec_foo'
|
|
90
|
+
end
|
|
91
|
+
}
|
|
92
|
+
before {
|
|
93
|
+
klass
|
|
94
|
+
}
|
|
95
|
+
it 'returns the plugin' do
|
|
96
|
+
expect(Observed::Observer.find_plugin_named('observer_spec_foo')).to eq(klass)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
context 'with two named plugins' do
|
|
101
|
+
let(:bar) {
|
|
102
|
+
Class.new(Observed::Observer) do
|
|
103
|
+
plugin_name 'observer_spec_bar'
|
|
104
|
+
end
|
|
105
|
+
}
|
|
106
|
+
let(:baz) {
|
|
107
|
+
Class.new(Observed::Observer) do
|
|
108
|
+
plugin_name 'observer_spec_baz'
|
|
109
|
+
end
|
|
110
|
+
}
|
|
111
|
+
before {
|
|
112
|
+
bar
|
|
113
|
+
baz
|
|
114
|
+
}
|
|
115
|
+
it 'returns each plugin' do
|
|
116
|
+
expect(Observed::Observer.find_plugin_named('observer_spec_bar')).to eq(bar)
|
|
117
|
+
expect(Observed::Observer.find_plugin_named('observer_spec_baz')).to eq(baz)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
end
|