overwatch-collection 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.
- data/.gitignore +4 -0
- data/.watchr +18 -0
- data/Gemfile +33 -0
- data/Gemfile.lock +104 -0
- data/README.md +26 -0
- data/Rakefile +57 -0
- data/bin/overwatch-collection +38 -0
- data/config.ru +9 -0
- data/config/overwatch.yml +6 -0
- data/lib/..rb +5 -0
- data/lib/overwatch/collection.rb +42 -0
- data/lib/overwatch/collection/application.rb +46 -0
- data/lib/overwatch/collection/attributes.rb +136 -0
- data/lib/overwatch/collection/models/resource.rb +50 -0
- data/lib/overwatch/collection/models/snapshot.rb +88 -0
- data/lib/overwatch/collection/routes/resource.rb +107 -0
- data/lib/overwatch/collection/routes/snapshot.rb +66 -0
- data/lib/overwatch/collection/version.rb +5 -0
- data/log/.gitkeep +0 -0
- data/overwatch-collection.gemspec +43 -0
- data/spec/overwatch/collection/application_spec.rb +0 -0
- data/spec/overwatch/collection/attributes_spec.rb +64 -0
- data/spec/overwatch/collection/helpers_spec.rb +0 -0
- data/spec/overwatch/collection/models/resource_spec.rb +60 -0
- data/spec/overwatch/collection/models/snapshot_spec.rb +32 -0
- data/spec/overwatch/collection/routes/resource_spec.rb +146 -0
- data/spec/overwatch/collection/routes/snapshot_spec.rb +161 -0
- data/spec/overwatch/collection_spec.rb +0 -0
- data/spec/overwatch_spec.rb +2 -0
- data/spec/spec_helper.rb +51 -0
- data/spec/support/json.rb +3 -0
- data/spec/support/respond_with_matchers.rb +33 -0
- data/spec/support/snapshot_data.rb +7 -0
- data/spec/support/time_travel.rb +3 -0
- metadata +304 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Overwatch
|
4
|
+
describe Snapshot do
|
5
|
+
let(:resource) { Overwatch::Resource.create(:name => "foo") }
|
6
|
+
|
7
|
+
describe "new record" do
|
8
|
+
it "should create a new snapshot" do
|
9
|
+
snapshot = resource.snapshots.create(:data => snapshot_data)
|
10
|
+
snapshot.should be_valid
|
11
|
+
snapshot.resource.should == resource
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#update_attribute_keys" do
|
16
|
+
it "should update the resource's available attribute keys" do
|
17
|
+
resource.snapshots.create(:data => snapshot_data)
|
18
|
+
resource.attribute_keys.should include("load_average.one_minute")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#parse_data" do
|
23
|
+
it "should add each snapshot attribute to a sorted set" do
|
24
|
+
10.times do
|
25
|
+
resource.snapshots.create(:data => snapshot_data)
|
26
|
+
time_travel!
|
27
|
+
end
|
28
|
+
$redis.zcard("overwatch::resource:#{resource.id}:load_average.one_minute").should == 10
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Overwatch
|
4
|
+
module Collection
|
5
|
+
|
6
|
+
describe Application do
|
7
|
+
|
8
|
+
describe "GET /resources" do
|
9
|
+
before do
|
10
|
+
Overwatch::Resource.create(:name => 'foo')
|
11
|
+
get '/resources'
|
12
|
+
end
|
13
|
+
|
14
|
+
subject { last_response }
|
15
|
+
|
16
|
+
it { should respond_with 200 }
|
17
|
+
it { should respond_with_content_type 'application/json' }
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "GET /resources/:id" do
|
22
|
+
let(:resource) { Overwatch::Resource.create(:name => 'foo') }
|
23
|
+
before do
|
24
|
+
get "/resources/#{resource.id}"
|
25
|
+
end
|
26
|
+
|
27
|
+
subject { last_response }
|
28
|
+
|
29
|
+
it { should respond_with 200 }
|
30
|
+
it { should respond_with_content_type 'application/json' }
|
31
|
+
|
32
|
+
it "should return one record" do
|
33
|
+
resource.id.should == Yajl.load(last_response.body)['id']
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "POST /resources" do
|
38
|
+
|
39
|
+
before do
|
40
|
+
post "/resources", Yajl.dump({:name => "foo" })
|
41
|
+
end
|
42
|
+
|
43
|
+
subject { last_response }
|
44
|
+
|
45
|
+
it { should respond_with 201 }
|
46
|
+
it { should respond_with_content_type 'application/json' }
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "PUT /resources/:id" do
|
50
|
+
let(:resource) { Overwatch::Resource.create(:name => 'foo') }
|
51
|
+
before do
|
52
|
+
put "/resources/#{resource.id}", Yajl.dump({:name => "bar" })
|
53
|
+
end
|
54
|
+
|
55
|
+
subject { last_response }
|
56
|
+
|
57
|
+
it { should respond_with 200 }
|
58
|
+
it { should respond_with_content_type 'application/json' }
|
59
|
+
|
60
|
+
it "should update the record" do
|
61
|
+
Resource.get(resource.id).name.should == "bar"
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "DELETE /resources/:id" do
|
67
|
+
let(:resource) { Overwatch::Resource.create(:name => 'foo') }
|
68
|
+
before do
|
69
|
+
delete "/resources/#{resource.id}"
|
70
|
+
end
|
71
|
+
|
72
|
+
subject { last_response }
|
73
|
+
|
74
|
+
it { should respond_with 200 }
|
75
|
+
it { should respond_with_content_type 'application/json' }
|
76
|
+
|
77
|
+
it "should delete record" do
|
78
|
+
Resource.get(resource.id).should be_nil
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "GET /resources/:id/attributes" do
|
83
|
+
let(:resource) { Overwatch::Resource.create(:name => 'foo') }
|
84
|
+
before do
|
85
|
+
resource.snapshots.create(:data => snapshot_data)
|
86
|
+
get "/resources/#{resource.id}/attributes"
|
87
|
+
end
|
88
|
+
|
89
|
+
subject { last_response }
|
90
|
+
|
91
|
+
it { should respond_with 200 }
|
92
|
+
it { should respond_with_content_type 'application/json' }
|
93
|
+
|
94
|
+
it "should return an array of available attributes" do
|
95
|
+
attributes = last_json
|
96
|
+
attributes.should include("load_average.one_minute")
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "GET /resources/:id/attributes/:attribute" do
|
101
|
+
let(:resource) { Overwatch::Resource.create(:name => 'foo') }
|
102
|
+
before do
|
103
|
+
resource.snapshots.create(:data => snapshot_data)
|
104
|
+
time_travel!
|
105
|
+
resource.snapshots.create(:data => snapshot_data)
|
106
|
+
get "/resources/#{resource.id}/attributes/load_average.one_minute"
|
107
|
+
end
|
108
|
+
|
109
|
+
subject { last_response }
|
110
|
+
|
111
|
+
it { should respond_with 200 }
|
112
|
+
it { should respond_with_content_type 'application/json' }
|
113
|
+
|
114
|
+
it "should return a hash of the attribute name and values" do
|
115
|
+
values = last_json
|
116
|
+
values.should include('data')
|
117
|
+
values.should include('name')
|
118
|
+
values['name'].should eq "load_average.one_minute"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe "GET /resources/:id/attributes/:attribute" do
|
123
|
+
let(:resource) { Overwatch::Resource.create(:name => 'foo') }
|
124
|
+
before do
|
125
|
+
resource.snapshots.create(:data => snapshot_data)
|
126
|
+
time_travel!
|
127
|
+
resource.snapshots.create(:data => snapshot_data)
|
128
|
+
get "/resources/#{resource.id}/attributes/load_average.one_minute?start_at=#{(Time.now - 1.hour).to_i * 1000}&end=#{(Time.now ).to_i * 1000}"
|
129
|
+
end
|
130
|
+
|
131
|
+
subject { last_response }
|
132
|
+
|
133
|
+
it { should respond_with 200 }
|
134
|
+
it { should respond_with_content_type 'application/json' }
|
135
|
+
|
136
|
+
it "should return a hash of the attribute name and values" do
|
137
|
+
values = last_json
|
138
|
+
values.should include('data')
|
139
|
+
values.should include('name')
|
140
|
+
values['name'].should eq "load_average.one_minute"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Overwatch
|
4
|
+
module Collection
|
5
|
+
|
6
|
+
describe Application do
|
7
|
+
let(:resource) { Overwatch::Resource.create(:name => 'foo') }
|
8
|
+
|
9
|
+
describe "GET /resources/:resource_id/snapshots" do
|
10
|
+
before do
|
11
|
+
5.times do
|
12
|
+
resource.snapshots.create(:data => snapshot_data)
|
13
|
+
end
|
14
|
+
get "/resources/#{resource.id}/snapshots"
|
15
|
+
end
|
16
|
+
|
17
|
+
subject { last_response }
|
18
|
+
|
19
|
+
it { should respond_with 200 }
|
20
|
+
it { should respond_with_content_type 'application/json' }
|
21
|
+
it "should return an array of snapshots" do
|
22
|
+
last_json.should have(5).items
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "GET /resources/:resource_id/snapshots/:id" do
|
27
|
+
let(:snapshot) { resource.snapshots.create(:data => snapshot_data) }
|
28
|
+
before do
|
29
|
+
get "/resources/#{resource.id}/snapshots/#{snapshot.id}"
|
30
|
+
end
|
31
|
+
|
32
|
+
subject { last_response }
|
33
|
+
|
34
|
+
it { should respond_with 200 }
|
35
|
+
it { should respond_with_content_type 'application/json' }
|
36
|
+
|
37
|
+
it "should return one record" do
|
38
|
+
resource.id.should == Yajl.load(last_response.body)['id']
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "POST /snapshots" do
|
43
|
+
before do
|
44
|
+
post "/snapshots?key=#{resource.api_key}", Yajl.dump(snapshot_data)
|
45
|
+
end
|
46
|
+
|
47
|
+
subject { last_response }
|
48
|
+
|
49
|
+
it { should respond_with 201 }
|
50
|
+
it { should respond_with_content_type 'application/json' }
|
51
|
+
|
52
|
+
it "should create one snapshot" do
|
53
|
+
resource.snapshots.should have(1).item
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "GET /resources/:resource_id/snapshots/:id/data" do
|
58
|
+
let(:snapshot) { resource.snapshots.create(:data => snapshot_data) }
|
59
|
+
|
60
|
+
before do
|
61
|
+
get "/resources/#{resource.id}/snapshots/#{snapshot.id}/data"
|
62
|
+
end
|
63
|
+
|
64
|
+
subject { last_response }
|
65
|
+
|
66
|
+
it { should respond_with 200 }
|
67
|
+
it { should respond_with_content_type 'application/json' }
|
68
|
+
|
69
|
+
it "should return full JSON of a given snapshot" do
|
70
|
+
puts last_json
|
71
|
+
end
|
72
|
+
end
|
73
|
+
#
|
74
|
+
# describe "POST /resources" do
|
75
|
+
#
|
76
|
+
# before do
|
77
|
+
# post "/resources", Yajl.dump({:name => "foo" })
|
78
|
+
# end
|
79
|
+
#
|
80
|
+
# subject { last_response }
|
81
|
+
#
|
82
|
+
# it { should respond_with 201 }
|
83
|
+
# it { should respond_with_content_type 'application/json' }
|
84
|
+
# end
|
85
|
+
#
|
86
|
+
# describe "PUT /resources/:id" do
|
87
|
+
# let(:resource) { Overwatch::Resource.create(:name => 'foo') }
|
88
|
+
# before do
|
89
|
+
# put "/resources/#{resource.id}", Yajl.dump({:name => "bar" })
|
90
|
+
# end
|
91
|
+
#
|
92
|
+
# subject { last_response }
|
93
|
+
#
|
94
|
+
# it { should respond_with 200 }
|
95
|
+
# it { should respond_with_content_type 'application/json' }
|
96
|
+
#
|
97
|
+
# it "should update the record" do
|
98
|
+
# Resource.get(resource.id).name.should == "bar"
|
99
|
+
# end
|
100
|
+
#
|
101
|
+
# end
|
102
|
+
#
|
103
|
+
# describe "DELETE /resources/:id" do
|
104
|
+
# let(:resource) { Overwatch::Resource.create(:name => 'foo') }
|
105
|
+
# before do
|
106
|
+
# delete "/resources/#{resource.id}"
|
107
|
+
# end
|
108
|
+
#
|
109
|
+
# subject { last_response }
|
110
|
+
#
|
111
|
+
# it { should respond_with 200 }
|
112
|
+
# it { should respond_with_content_type 'application/json' }
|
113
|
+
#
|
114
|
+
# it "should delete record" do
|
115
|
+
# Resource.get(resource.id).should be_nil
|
116
|
+
# end
|
117
|
+
# end
|
118
|
+
#
|
119
|
+
# describe "GET /resources/:id/attributes" do
|
120
|
+
# let(:resource) { Overwatch::Resource.create(:name => 'foo') }
|
121
|
+
# before do
|
122
|
+
# resource.snapshots.create(:raw_data => { :one => 1, :two => 2 })
|
123
|
+
# get "/resources/#{resource.id}/attributes"
|
124
|
+
# end
|
125
|
+
#
|
126
|
+
# subject { last_response }
|
127
|
+
#
|
128
|
+
# it { should respond_with 200 }
|
129
|
+
# it { should respond_with_content_type 'application/json' }
|
130
|
+
#
|
131
|
+
# it "should return an array of available attributes" do
|
132
|
+
# attributes = Yajl.load(last_response.body)
|
133
|
+
# attributes.should == ["one", "two"]
|
134
|
+
# end
|
135
|
+
# end
|
136
|
+
#
|
137
|
+
# describe "GET /resources/:id/attributes/:attribute" do
|
138
|
+
# let(:resource) { Overwatch::Resource.create(:name => 'foo') }
|
139
|
+
# before do
|
140
|
+
# Timecop.travel(Time.local(2011, 7, 20, 12, 1, 0))
|
141
|
+
# resource.snapshots.create(:raw_data => { :one => 1, :two => 2 })
|
142
|
+
# Timecop.travel(Time.local(2011, 7, 20, 12, 2, 0))
|
143
|
+
# resource.snapshots.create(:raw_data => { :one => 1, :two => 2 })
|
144
|
+
# get "/resources/#{resource.id}/attributes/one"
|
145
|
+
# end
|
146
|
+
#
|
147
|
+
# subject { last_response }
|
148
|
+
#
|
149
|
+
# it { should respond_with 200 }
|
150
|
+
# it { should respond_with_content_type 'application/json' }
|
151
|
+
#
|
152
|
+
# it "should return a hash of the attribute name and values" do
|
153
|
+
# values = Yajl.load(last_response.body)
|
154
|
+
# values['name'].should eq "one"
|
155
|
+
# puts resource.snapshots.inspect
|
156
|
+
# end
|
157
|
+
# end
|
158
|
+
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
File without changes
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spork'
|
3
|
+
|
4
|
+
Spork.prefork do
|
5
|
+
require 'bundler'
|
6
|
+
Bundler.require(:default, :test)
|
7
|
+
|
8
|
+
ENV["RACK_ENV"] ||= 'test'
|
9
|
+
|
10
|
+
$: << File.join(File.dirname(__FILE__), "lib")
|
11
|
+
|
12
|
+
require 'overwatch/collection'
|
13
|
+
|
14
|
+
support_files = File.join(File.expand_path(File.dirname(__FILE__)), "/support/**/*.rb")
|
15
|
+
Dir[support_files].each {|f| require f}
|
16
|
+
|
17
|
+
ENV['REDIS_URL'] = 'redis://localhost:6379/3'
|
18
|
+
|
19
|
+
RSpec.configure do |config|
|
20
|
+
config.color_enabled = true
|
21
|
+
config.formatter = "documentation"
|
22
|
+
config.mock_with :rspec
|
23
|
+
|
24
|
+
config.before :suite do
|
25
|
+
end
|
26
|
+
|
27
|
+
config.before :each do
|
28
|
+
Timecop.freeze(Time.now) #(Time.local(2011, 1, 1, 0, 0, 0))
|
29
|
+
header 'Accept', 'application/json'
|
30
|
+
header 'Content-Type', 'application/json'
|
31
|
+
$redis.flushdb
|
32
|
+
end
|
33
|
+
|
34
|
+
config.after :each do
|
35
|
+
# $redis.flushdb
|
36
|
+
Timecop.return
|
37
|
+
end
|
38
|
+
|
39
|
+
config.after :suite do
|
40
|
+
end
|
41
|
+
|
42
|
+
config.include Rack::Test::Methods
|
43
|
+
end
|
44
|
+
|
45
|
+
def app
|
46
|
+
Overwatch::Collection::Application
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
Spork.each_run do
|
51
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
RSpec::Matchers.define :respond_with do |expected_status|
|
2
|
+
match do |last_response|
|
3
|
+
@actual_status = last_response.status
|
4
|
+
@expected_status = expected_status
|
5
|
+
@actual_status == @expected_status
|
6
|
+
end
|
7
|
+
|
8
|
+
failure_message_for_should do
|
9
|
+
"Expected #{@expected_status}, got: #{@actual_status}"
|
10
|
+
end
|
11
|
+
|
12
|
+
failure_message_for_should_not do
|
13
|
+
"Did not expect #{@expected_status}, got: #{@actual_status}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
RSpec::Matchers.define :respond_with_content_type do |expected_content_type|
|
18
|
+
match do |last_response|
|
19
|
+
response_content_type == expected_content_type
|
20
|
+
end
|
21
|
+
|
22
|
+
failure_message_for_should do
|
23
|
+
"Expected #{@expected_content_type}, got: #{@actual_content_type}"
|
24
|
+
end
|
25
|
+
|
26
|
+
failure_message_for_should_not do
|
27
|
+
"Did not expect #{@expected_content_type}, got: #{@actual_content_type}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def response_content_type
|
31
|
+
last_response.content_type.to_s
|
32
|
+
end
|
33
|
+
end
|