bp-fnordmetric 1.2.7
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +6 -0
- data/Rakefile +6 -0
- data/fnordmetric.gemspec +41 -0
- data/lib/fnordmetric.rb +149 -0
- data/lib/fnordmetric/acceptors/acceptor.rb +42 -0
- data/lib/fnordmetric/acceptors/amqp_acceptor.rb +56 -0
- data/lib/fnordmetric/acceptors/fyrehose_acceptor.rb +43 -0
- data/lib/fnordmetric/acceptors/stomp_acceptor.rb +71 -0
- data/lib/fnordmetric/acceptors/tcp_acceptor.rb +58 -0
- data/lib/fnordmetric/acceptors/udp_acceptor.rb +37 -0
- data/lib/fnordmetric/api.rb +46 -0
- data/lib/fnordmetric/cache.rb +20 -0
- data/lib/fnordmetric/context.rb +96 -0
- data/lib/fnordmetric/defaults.rb +22 -0
- data/lib/fnordmetric/enterprise/compatibility_handler.rb +42 -0
- data/lib/fnordmetric/ext.rb +75 -0
- data/lib/fnordmetric/gauge.rb +98 -0
- data/lib/fnordmetric/gauge_calculations.rb +106 -0
- data/lib/fnordmetric/gauge_modifiers.rb +144 -0
- data/lib/fnordmetric/gauge_rendering.rb +40 -0
- data/lib/fnordmetric/gauge_validations.rb +15 -0
- data/lib/fnordmetric/gauges/distribution_gauge.rb +87 -0
- data/lib/fnordmetric/gauges/server_health_gauge.rb +13 -0
- data/lib/fnordmetric/gauges/timeseries_gauge.rb +138 -0
- data/lib/fnordmetric/gauges/toplist_gauge.rb +44 -0
- data/lib/fnordmetric/histogram.rb +64 -0
- data/lib/fnordmetric/logger.rb +63 -0
- data/lib/fnordmetric/namespace.rb +208 -0
- data/lib/fnordmetric/session.rb +139 -0
- data/lib/fnordmetric/standalone.rb +20 -0
- data/lib/fnordmetric/timeseries.rb +79 -0
- data/lib/fnordmetric/toplist.rb +61 -0
- data/lib/fnordmetric/udp_client.rb +22 -0
- data/lib/fnordmetric/util.rb +25 -0
- data/lib/fnordmetric/version.rb +3 -0
- data/lib/fnordmetric/web/app.rb +63 -0
- data/lib/fnordmetric/web/app_helpers.rb +42 -0
- data/lib/fnordmetric/web/dashboard.rb +40 -0
- data/lib/fnordmetric/web/event.rb +99 -0
- data/lib/fnordmetric/web/reactor.rb +127 -0
- data/lib/fnordmetric/web/web.rb +59 -0
- data/lib/fnordmetric/web/websocket.rb +41 -0
- data/lib/fnordmetric/widget.rb +82 -0
- data/lib/fnordmetric/widgets/bars_widget.rb +44 -0
- data/lib/fnordmetric/widgets/html_widget.rb +28 -0
- data/lib/fnordmetric/widgets/numbers_widget.rb +80 -0
- data/lib/fnordmetric/widgets/pie_widget.rb +23 -0
- data/lib/fnordmetric/widgets/timeseries_widget.rb +65 -0
- data/lib/fnordmetric/widgets/toplist_widget.rb +68 -0
- data/lib/fnordmetric/worker.rb +89 -0
- data/lib/fnordmetric/zero_config_gauge.rb +138 -0
- data/run_specs.sh +11 -0
- data/spec/api_spec.rb +49 -0
- data/spec/context_spec.rb +42 -0
- data/spec/dashboard_spec.rb +38 -0
- data/spec/event_spec.rb +170 -0
- data/spec/ext_spec.rb +14 -0
- data/spec/fnordmetric_spec.rb +56 -0
- data/spec/gauge_like_shared.rb +56 -0
- data/spec/gauge_modifiers_spec.rb +583 -0
- data/spec/gauge_spec.rb +230 -0
- data/spec/namespace_spec.rb +114 -0
- data/spec/session_spec.rb +231 -0
- data/spec/spec_helper.rb +49 -0
- data/spec/tcp_acceptor_spec.rb +35 -0
- data/spec/timeseries_gauge_spec.rb +56 -0
- data/spec/udp_acceptor_spec.rb +35 -0
- data/spec/util_spec.rb +46 -0
- data/spec/widget_spec.rb +113 -0
- data/spec/worker_spec.rb +40 -0
- data/web/.gitignore +4 -0
- data/web/build.sh +34 -0
- data/web/css/fnordmetric.core.css +868 -0
- data/web/haml/app.haml +20 -0
- data/web/haml/distribution_gauge.haml +118 -0
- data/web/haml/timeseries_gauge.haml +80 -0
- data/web/haml/toplist_gauge.haml +194 -0
- data/web/img/head.png +0 -0
- data/web/img/list.png +0 -0
- data/web/img/list_active.png +0 -0
- data/web/img/list_hover.png +0 -0
- data/web/img/loader.gif +0 -0
- data/web/img/loader_white.gif +0 -0
- data/web/img/navbar.png +0 -0
- data/web/img/navbar_btn.png +0 -0
- data/web/img/picto_gauge.png +0 -0
- data/web/js/fnordmetric.bars_widget.js +178 -0
- data/web/js/fnordmetric.dashboard_view.js +99 -0
- data/web/js/fnordmetric.gauge_explorer.js +173 -0
- data/web/js/fnordmetric.gauge_view.js +260 -0
- data/web/js/fnordmetric.html_widget.js +21 -0
- data/web/js/fnordmetric.js +315 -0
- data/web/js/fnordmetric.numbers_widget.js +122 -0
- data/web/js/fnordmetric.overview_view.js +35 -0
- data/web/js/fnordmetric.pie_widget.js +118 -0
- data/web/js/fnordmetric.realtime_timeline_widget.js +175 -0
- data/web/js/fnordmetric.session_view.js +342 -0
- data/web/js/fnordmetric.timeline_widget.js +333 -0
- data/web/js/fnordmetric.timeseries_widget.js +405 -0
- data/web/js/fnordmetric.toplist_widget.js +119 -0
- data/web/js/fnordmetric.ui.js +91 -0
- data/web/js/fnordmetric.util.js +248 -0
- data/web/vendor/font-awesome/css/font-awesome-ie7.min.css +22 -0
- data/web/vendor/font-awesome/css/font-awesome.css +540 -0
- data/web/vendor/font-awesome/css/font-awesome.min.css +33 -0
- data/web/vendor/font-awesome/font/FontAwesome.otf +0 -0
- data/web/vendor/font-awesome/font/fontawesome-webfont.eot +0 -0
- data/web/vendor/font-awesome/font/fontawesome-webfont.svg +284 -0
- data/web/vendor/font-awesome/font/fontawesome-webfont.ttf +0 -0
- data/web/vendor/font-awesome/font/fontawesome-webfont.woff +0 -0
- data/web/vendor/jquery-1.6.2.min.js +18 -0
- data/web/vendor/jquery-ui.min.js +6 -0
- data/web/vendor/jquery.combobox.js +129 -0
- data/web/vendor/jquery.maskedinput.js +252 -0
- metadata +438 -0
data/spec/gauge_spec.rb
ADDED
@@ -0,0 +1,230 @@
|
|
1
|
+
require ::File.expand_path('../spec_helper.rb', __FILE__)
|
2
|
+
|
3
|
+
describe FnordMetric::Gauge do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
@now = Time.utc(1992,01,13,5,23,23).to_i
|
7
|
+
@redis = Redis.new
|
8
|
+
@redis_wrap = RedisWrap.new(@redis, false)
|
9
|
+
@gauge_klass = FnordMetric::Gauge
|
10
|
+
end
|
11
|
+
|
12
|
+
before(:each) do
|
13
|
+
@redis.keys("fnordmetric-myns*").each { |k| @redis.del(k) }
|
14
|
+
end
|
15
|
+
|
16
|
+
it_should_behave_like FnordMetric::GaugeLike
|
17
|
+
|
18
|
+
describe "ticks" do
|
19
|
+
|
20
|
+
it "should return the correct tick if configured" do
|
21
|
+
gauge = FnordMetric::Gauge.new({:tick => 23, :key_prefix => "fnordmetrics-myns", :key => "mygauge"})
|
22
|
+
gauge.tick.should == 23
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should return the correct tick if configured with flush_interval" do
|
26
|
+
gauge = FnordMetric::Gauge.new({:flush_interval => 42, :key_prefix => "fnordmetrics-myns", :key => "mygauge"})
|
27
|
+
gauge.tick.should == 42
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should return the default tick if none configured" do
|
31
|
+
gauge = FnordMetric::Gauge.new({:key_prefix => "fnordmetrics-myns", :key => "mygauge"})
|
32
|
+
gauge.tick.should == FnordMetric.options[:default_flush_interval]
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should return the correct tick_at" do
|
36
|
+
gauge = FnordMetric::Gauge.new({:tick => 10, :key_prefix => "fnordmetrics-myns", :key => "mygauge"})
|
37
|
+
gauge.tick_at(@now).should == 695280200
|
38
|
+
gauge.tick_at(@now+6).should == 695280200
|
39
|
+
gauge.tick_at(@now+8).should == 695280210
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "value retrival" do
|
45
|
+
|
46
|
+
before(:each) do
|
47
|
+
@gauge_key = "fnordmetric-myns-gauge-mygauge_966-10"
|
48
|
+
@redis.hset(@gauge_key, "695280200", "54")
|
49
|
+
@redis.hset(@gauge_key, "695280210", "123")
|
50
|
+
@gauge = FnordMetric::Gauge.new({
|
51
|
+
:tick => 10,
|
52
|
+
:key_prefix => "fnordmetric-myns",
|
53
|
+
:key => "mygauge_966",
|
54
|
+
:redis => @redis
|
55
|
+
})
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should retrieve a gauge value at a given time" do
|
59
|
+
@gauge.value_at(@now).should == "54"
|
60
|
+
@gauge.value_at(@now+6).should == "54"
|
61
|
+
@gauge.value_at(@now+8).should == "123"
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should retrieve a gauge value at the current tick"
|
65
|
+
|
66
|
+
it "should call the value calculation block and return the result" do
|
67
|
+
@gauge.value_at(@now){ |v, t| v.to_i + 123 }.should == 177
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should return the correct value_at per session" do
|
71
|
+
@redis.hset(@gauge_key, "695280200", "76")
|
72
|
+
@redis.set(@gauge_key+"-695280200-sessions-count", "23")
|
73
|
+
_gauge = FnordMetric::Gauge.new({
|
74
|
+
:tick => 10,
|
75
|
+
:key_prefix => "fnordmetric-myns",
|
76
|
+
:key => "mygauge_966",
|
77
|
+
:unique => true,
|
78
|
+
:redis => @redis
|
79
|
+
})
|
80
|
+
_gauge.value_at(@now).should == "76"
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should return the correct value_at per session with avg" do
|
84
|
+
@redis.hset(@gauge_key, "695280200", "76")
|
85
|
+
@redis.set(@gauge_key+"-695280200-sessions-count", "23")
|
86
|
+
_gauge = FnordMetric::Gauge.new({
|
87
|
+
:tick => 10,
|
88
|
+
:key_prefix => "fnordmetric-myns",
|
89
|
+
:key => "mygauge_966",
|
90
|
+
:unique => true,
|
91
|
+
:average => true,
|
92
|
+
:redis => @redis
|
93
|
+
})
|
94
|
+
_gauge.value_at(@now).should == (76.0/23.0)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should receive gauge values for multiple ticks" do
|
98
|
+
@gauge.values_at([@now, @now+8]).should == {
|
99
|
+
695280200 => "54",
|
100
|
+
695280210 => "123"
|
101
|
+
}
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should receive gauge values per session for multiple ticks" do
|
105
|
+
@redis.set(@gauge_key+"-695280200-sessions-count", "23")
|
106
|
+
@redis.set(@gauge_key+"-695280210-sessions-count", "8")
|
107
|
+
@redis.hset(@gauge_key, "695280200", "76")
|
108
|
+
@redis.hset(@gauge_key, "695280210", "56")
|
109
|
+
_gauge = FnordMetric::Gauge.new({
|
110
|
+
:tick => 10,
|
111
|
+
:key_prefix => "fnordmetric-myns",
|
112
|
+
:key => "mygauge_966",
|
113
|
+
:unique => true,
|
114
|
+
:redis => @redis
|
115
|
+
})
|
116
|
+
_gauge.values_at([@now, @now+8]).should == {
|
117
|
+
695280200 => "76",
|
118
|
+
695280210 => "56"
|
119
|
+
}
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should receive gauge values per session for multiple ticks with avg" do
|
123
|
+
@redis.set(@gauge_key+"-695280200-sessions-count", "23")
|
124
|
+
@redis.set(@gauge_key+"-695280210-sessions-count", "8")
|
125
|
+
_gauge = FnordMetric::Gauge.new({
|
126
|
+
:tick => 10,
|
127
|
+
:key_prefix => "fnordmetric-myns",
|
128
|
+
:key => "mygauge_966",
|
129
|
+
:unique => true,
|
130
|
+
:average => true,
|
131
|
+
:redis => @redis
|
132
|
+
})
|
133
|
+
_gauge.values_at([@now, @now+8]).should == {
|
134
|
+
695280200 => (54.0/23.0),
|
135
|
+
695280210 => (123.0/8.0)
|
136
|
+
}
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should receive gauge values with custom calculation for multiple ticks" do
|
140
|
+
@gauge.values_at([@now, @now+8]){ |val, time|
|
141
|
+
val.to_i + 30
|
142
|
+
}.should == {
|
143
|
+
695280200 => 84,
|
144
|
+
695280210 => 153
|
145
|
+
}
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should receive gauge values for all ticks in a given range" do
|
149
|
+
@gauge.values_in(@now+10..@now+18).should == {
|
150
|
+
695280200 => "54",
|
151
|
+
695280210 => "123"
|
152
|
+
}
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "three-dim value retrival" do
|
158
|
+
|
159
|
+
before(:each) do
|
160
|
+
@gauge = FnordMetric::Gauge.new({
|
161
|
+
:tick => 10,
|
162
|
+
:key_prefix => "fnordmetric-myns",
|
163
|
+
:three_dimensional => true,
|
164
|
+
:key => "mygauge_966",
|
165
|
+
:redis => @redis
|
166
|
+
})
|
167
|
+
@redis.keys("fnordmetric-myns*").each { |k| @redis.del(k) }
|
168
|
+
@gauge_key = "fnordmetric-myns-gauge-mygauge_966-10-1323691200"
|
169
|
+
@redis.zadd(@gauge_key, 18, "fnordyblubb")
|
170
|
+
@redis.zadd(@gauge_key, 23, "uberfoo")
|
171
|
+
@redis.set(@gauge_key+"-count", 41)
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should retrieve field_values at a given time" do
|
175
|
+
@gauge.field_values_at(1323691200).should be_a(Array)
|
176
|
+
@gauge.field_values_at(1323691200).length.should == 2
|
177
|
+
@gauge.field_values_at(1323691200)[0].should == ["uberfoo", "23"]
|
178
|
+
@gauge.field_values_at(1323691200)[1].should == ["fnordyblubb", "18"]
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should retrieve the correct total count" do
|
182
|
+
@gauge.field_values_total(1323691200).should == 41
|
183
|
+
end
|
184
|
+
|
185
|
+
it "should retrieve max 50 fields per default" do
|
186
|
+
70.times{ |n| @redis.zadd(@gauge_key, 23, "field#{n}") }
|
187
|
+
@gauge.field_values_at(1323691200).should be_a(Array)
|
188
|
+
@gauge.field_values_at(1323691200).length.should == 50
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should retrieve more than 50 fields if requested" do
|
192
|
+
70.times{ |n| @redis.zadd(@gauge_key, 23, "field#{n}") }
|
193
|
+
@gauge.field_values_at(1323691200, :max_fields => 60).should be_a(Array)
|
194
|
+
@gauge.field_values_at(1323691200, :max_fields => 60).length.should == 60
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should retrieve all fields if requested" do
|
198
|
+
70.times{ |n| @redis.zadd(@gauge_key, 23, "field#{n}") }
|
199
|
+
@gauge.field_values_at(1323691200, :max_fields => 0).should be_a(Array)
|
200
|
+
@gauge.field_values_at(1323691200, :max_fields => 0).length.should == 72
|
201
|
+
end
|
202
|
+
|
203
|
+
it "should call the value calculation block and return the result" do
|
204
|
+
vals = @gauge.field_values_at(1323691200){ |v, t| v.to_i + 123 }
|
205
|
+
vals.should be_a(Array)
|
206
|
+
vals.length.should == 2
|
207
|
+
vals[0].should == ["uberfoo", 146]
|
208
|
+
vals[1].should == ["fnordyblubb", 141]
|
209
|
+
end
|
210
|
+
|
211
|
+
it "should return the correct field_values per session with avg" do
|
212
|
+
@redis.set(@gauge_key+"-sessions-count", "3")
|
213
|
+
@gauge = FnordMetric::Gauge.new({
|
214
|
+
:tick => 10,
|
215
|
+
:key_prefix => "fnordmetric-myns",
|
216
|
+
:three_dimensional => true,
|
217
|
+
:unique => true,
|
218
|
+
:average => true,
|
219
|
+
:key => "mygauge_966",
|
220
|
+
:redis => @redis
|
221
|
+
})
|
222
|
+
vals = @gauge.field_values_at(1323691200)
|
223
|
+
vals.should be_a(Array)
|
224
|
+
vals.length.should == 2
|
225
|
+
vals[0].should == ["uberfoo", 23/3.0]
|
226
|
+
vals[1].should == ["fnordyblubb", 18/3.0]
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
230
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require ::File.expand_path('../spec_helper.rb', __FILE__)
|
2
|
+
|
3
|
+
describe FnordMetric::Namespace do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
@redis = Redis.new
|
7
|
+
@redis_wrap = RedisWrap.new(@redis)
|
8
|
+
end
|
9
|
+
|
10
|
+
before(:each) do
|
11
|
+
@redis.keys("fnordmetric-myns*").each { |k| @redis.del(k) }
|
12
|
+
@namespace = FnordMetric::Namespace.new(:myns_213, :redis_prefix => "fnordmetric")
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should generate the correct redis prefix"
|
16
|
+
|
17
|
+
describe "instance methods" do
|
18
|
+
|
19
|
+
it "should create a new dashboard if a widget is added" do
|
20
|
+
@namespace.widget("MyFooDash", nil)
|
21
|
+
@namespace.dashboards.keys.should == ["MyFooDash"]
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should create a new dashboard if the dashboard-title contains whitespaces" do
|
25
|
+
@namespace.widget("My Dash", nil)
|
26
|
+
@namespace.dashboards.keys.should == ["MyDash"]
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should create a new dashboard if a widget is added and add the widget"
|
30
|
+
it "should add widget to an existing dashboard"
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "registering gauges" do
|
35
|
+
|
36
|
+
it "should register a simple gauge" do
|
37
|
+
@namespace.gauge(:fugauge, {:fnord => 23})
|
38
|
+
@namespace.gauges[:fugauge].should be_a(FnordMetric::Gauge)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should register a simple gauge and pass options" do
|
42
|
+
@namespace.gauge(:fugauge2, {:fnord => 23})
|
43
|
+
@namespace.gauges[:fugauge2].instance_variable_get(:@opts).should include({:fnord => 23})
|
44
|
+
@namespace.gauges[:fugauge2].instance_variable_get(:@opts).should include({:key => :fugauge2})
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should register a multi gauge" do
|
48
|
+
pending "fixme"
|
49
|
+
@namespace.numeric_gauge(:multigauge, {:fnord => 23, :ticks => [1.hour], :series => ["fnord"]})
|
50
|
+
@namespace.gauges[:multigauge].should be_a(FnordMetric::NumericGauge)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should register a multi gauge and pass options" do
|
54
|
+
pending "fixme"
|
55
|
+
@namespace.numeric_gauge(:multigauge2, {:fnord => 42, :ticks => [1.hour], :series => ["fnord"]})
|
56
|
+
@namespace.gauges[:multigauge2].instance_variable_get(:@opts).should include({:fnord => 42})
|
57
|
+
@namespace.gauges[:multigauge2].instance_variable_get(:@opts).should include({:key => :multigauge2})
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "registering event handlers" do
|
63
|
+
|
64
|
+
it "should register an event handler" do
|
65
|
+
@namespace.handlers.length.should == 0
|
66
|
+
@namespace.event(:foobar){}
|
67
|
+
@namespace.event(:fnordbar){}
|
68
|
+
@namespace.handlers["foobar"].length.should == 1
|
69
|
+
@namespace.handlers["fnordbar"].length.should == 1
|
70
|
+
@namespace.handlers.length.should == 2
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should register an event handler and create a context"
|
74
|
+
it "should register an event handler and pass options"
|
75
|
+
it "should register an event handler and pass gauges"
|
76
|
+
it "should announce an event to the correct handler"
|
77
|
+
it "should announce an event to multiple handlers"
|
78
|
+
it "should announce an event to the wildcard handler"
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should create a new session on announce if _session is set" do
|
82
|
+
FnordMetric::Session.should_receive(:create).and_return(SessionMock.new)
|
83
|
+
FnordMetric::Namespace.new(
|
84
|
+
:myns_213,
|
85
|
+
:redis_prefix => "fnordmetric"
|
86
|
+
).ready!(@redis_wrap, @redis).announce(
|
87
|
+
:_time => Time.now.to_i,
|
88
|
+
:_type => "foobar",
|
89
|
+
:_session => "sess213"
|
90
|
+
)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should add the event to the namespace-event-type-list" do
|
94
|
+
FnordMetric::Namespace.new(
|
95
|
+
:myns_215,
|
96
|
+
:redis_prefix => "fnordmetric"
|
97
|
+
).ready!(@redis_wrap, @redis).announce(
|
98
|
+
:_eid => "35r2423",
|
99
|
+
:_time => Time.now.to_i,
|
100
|
+
:_type => "fnordbar",
|
101
|
+
:_session => "sess213"
|
102
|
+
)
|
103
|
+
event_ids = @redis.lrange("fnordmetric-myns_215-type-fnordbar", 0, -1)
|
104
|
+
event_ids.length.should == 1
|
105
|
+
event_ids.first.should == "35r2423"
|
106
|
+
end
|
107
|
+
|
108
|
+
class SessionMock
|
109
|
+
def session_key
|
110
|
+
"asdasd"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
@@ -0,0 +1,231 @@
|
|
1
|
+
require ::File.expand_path('../spec_helper.rb', __FILE__)
|
2
|
+
|
3
|
+
describe FnordMetric::Session do
|
4
|
+
|
5
|
+
include FnordMetric
|
6
|
+
|
7
|
+
before(:all) do
|
8
|
+
@now = Time.utc(1992,01,13,5,23,23).to_i
|
9
|
+
@redis = Redis.new
|
10
|
+
@redis_wrap = RedisWrap.new(@redis)
|
11
|
+
|
12
|
+
@namespace = "fnordmetric-ns123"
|
13
|
+
@sessions = "#{@namespace}-session"
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "creating sessions" do
|
17
|
+
|
18
|
+
before(:all) do
|
19
|
+
@event = { :_session => "sess123", :_time => @now, :_eid => "34089749" }
|
20
|
+
@md5_key = Digest::MD5.hexdigest("sess123")
|
21
|
+
|
22
|
+
@redis.del("#{@namespace}-session")
|
23
|
+
@redis.del("#{@namespace}-session-#{@md5_key}-events")
|
24
|
+
@redis.del("#{@namespace}-session-#{@md5_key}-data")
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should add a new session on intialize" do
|
28
|
+
FnordMetric::Session.create(
|
29
|
+
:namespace_prefix => @namespace,
|
30
|
+
:event => @event,
|
31
|
+
:session_data_ttl => 10,
|
32
|
+
:redis => @redis_wrap
|
33
|
+
)
|
34
|
+
@redis.zcard(@sessions).should == 1
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should add a new session on intialize and hash the session token" do
|
38
|
+
FnordMetric::Session.create(
|
39
|
+
:namespace_prefix => @namespace,
|
40
|
+
:event => @event,
|
41
|
+
:session_data_ttl => 10,
|
42
|
+
:redis => @redis_wrap
|
43
|
+
)
|
44
|
+
@redis.zrange(@sessions, 0, -1).should == [ @md5_key]
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should add a new session on intialize and set the timestamp as score" do
|
48
|
+
FnordMetric::Session.create(
|
49
|
+
:namespace_prefix => @namespace,
|
50
|
+
:event => @event,
|
51
|
+
:session_data_ttl => 10,
|
52
|
+
:redis => @redis_wrap
|
53
|
+
)
|
54
|
+
@redis.zscore(@sessions, @md5_key).to_i.should == @now
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should update the timestamp on a existing session" do
|
58
|
+
@redis.zadd(@sessions, @now-10, @md5_key)
|
59
|
+
@redis.zscore(@sessions, @md5_key).to_i.should == @now-10
|
60
|
+
FnordMetric::Session.create(
|
61
|
+
:namespace_prefix => @namespace,
|
62
|
+
:event => @event,
|
63
|
+
:session_data_ttl => 10,
|
64
|
+
:redis => @redis_wrap
|
65
|
+
)
|
66
|
+
@redis.zscore(@sessions, @md5_key).to_i.should == @now
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should add the event_id to the session-event set on a new session" do
|
70
|
+
FnordMetric::Session.create(
|
71
|
+
:namespace_prefix => @namespace,
|
72
|
+
:event => @event,
|
73
|
+
:session_data_ttl => 10,
|
74
|
+
:redis => @redis_wrap
|
75
|
+
)
|
76
|
+
events_key = "#{@namespace}-session-#{@md5_key}-events"
|
77
|
+
@redis.zrange(events_key, 0, -1).first.should == @event[:_eid]
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should store a name in the session data" do
|
81
|
+
event_data = @event.merge(
|
82
|
+
:_type => "_set_name",
|
83
|
+
:name => "Horst Mayer"
|
84
|
+
)
|
85
|
+
FnordMetric::Session.create(
|
86
|
+
:namespace_prefix => @namespace,
|
87
|
+
:event => event_data,
|
88
|
+
:session_data_ttl => 10,
|
89
|
+
:redis => @redis_wrap
|
90
|
+
)
|
91
|
+
data_key = "#{@namespace}-session-#{@md5_key}-data"
|
92
|
+
@redis.hget(data_key, "_name").should == "Horst Mayer"
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should store a picture in the session data" do
|
96
|
+
event_data = @event.merge(
|
97
|
+
:_type => "_set_picture",
|
98
|
+
:url => "http://myhost/mypic.jpg"
|
99
|
+
)
|
100
|
+
FnordMetric::Session.create(
|
101
|
+
:namespace_prefix => @namespace,
|
102
|
+
:event => event_data,
|
103
|
+
:session_data_ttl => 10,
|
104
|
+
:redis => @redis_wrap
|
105
|
+
)
|
106
|
+
data_key = "#{@namespace}-session-#{@md5_key}-data"
|
107
|
+
@redis.hget(data_key, "_picture").should == "http://myhost/mypic.jpg"
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should store arbitrary data in the session data" do
|
111
|
+
event_data = @event.merge(
|
112
|
+
:_type => "_set_data",
|
113
|
+
:fnord => "blubb",
|
114
|
+
:foobar => "123"
|
115
|
+
)
|
116
|
+
FnordMetric::Session.create(
|
117
|
+
:namespace_prefix => @namespace,
|
118
|
+
:event => event_data,
|
119
|
+
:session_data_ttl => 10,
|
120
|
+
:redis => @redis_wrap
|
121
|
+
)
|
122
|
+
data_key = "#{@namespace}-session-#{@md5_key}-data"
|
123
|
+
@redis.hget(data_key, "fnord").should == "blubb"
|
124
|
+
@redis.hget(data_key, "foobar").should == "123"
|
125
|
+
end
|
126
|
+
|
127
|
+
it "not store special attributes in the session" do
|
128
|
+
event_data = @event.merge(
|
129
|
+
:_type => "_set_data",
|
130
|
+
:fnord => "blubb",
|
131
|
+
:foobar => "123"
|
132
|
+
)
|
133
|
+
FnordMetric::Session.create(
|
134
|
+
:namespace_prefix => @namespace,
|
135
|
+
:event => event_data,
|
136
|
+
:session_data_ttl => 10,
|
137
|
+
:redis => @redis_wrap
|
138
|
+
)
|
139
|
+
data_key = "#{@namespace}-session-#{@md5_key}-data"
|
140
|
+
@redis.hget(data_key, "_time").should be_nil
|
141
|
+
@redis.hget(data_key, "_eid").should be_nil
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
describe "Finding Sessions" do
|
147
|
+
|
148
|
+
before(:each) do
|
149
|
+
@redis.del("#{@namespace}-session")
|
150
|
+
@redis.keys("#{@namespace}-session-*").each { |k| @redis.del(k) }
|
151
|
+
|
152
|
+
@opts = {
|
153
|
+
:redis_prefix => "#{@namespace}-session",
|
154
|
+
:namespace_prefix => "#{@namespace}",
|
155
|
+
:redis => @redis
|
156
|
+
}
|
157
|
+
end
|
158
|
+
|
159
|
+
it "should find all sessions" do
|
160
|
+
create_session("sess533", @now, {})
|
161
|
+
create_session("sess343", @now, {})
|
162
|
+
FnordMetric::Session.all(@opts).length.should == 2
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should find all sessions and return session objects" do
|
166
|
+
create_session("sess523", @now, {})
|
167
|
+
FnordMetric::Session.all(@opts).first.should be_a(FnordMetric::Session)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should find a session and return a session object" do
|
171
|
+
create_session("sess223", @now, {})
|
172
|
+
sess = FnordMetric::Session.find(Digest::MD5.hexdigest("sess223"), @opts)
|
173
|
+
sess.should be_a(FnordMetric::Session)
|
174
|
+
sess.session_key.should == Digest::MD5.hexdigest("sess223")
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should find a sessions and return a session object with data" do
|
178
|
+
create_session("sess123", @now, { :fnord => "blubb" })
|
179
|
+
sess = FnordMetric::Session.find(Digest::MD5.hexdigest("sess123"), @opts)
|
180
|
+
sess.fetch_data!
|
181
|
+
sess.data(:fnord).should == "blubb"
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should not include special attributes in data" do
|
185
|
+
event_data = { :_name => "Horst Mayer", :_picture => "http://myhost/mypic.jpg" }
|
186
|
+
create_session("sess173", @now, event_data)
|
187
|
+
sess = FnordMetric::Session.find(Digest::MD5.hexdigest("sess173"), @opts)
|
188
|
+
sess.fetch_data!
|
189
|
+
sess.data(:_name).should == nil
|
190
|
+
sess.data(:_picture).should == nil
|
191
|
+
end
|
192
|
+
|
193
|
+
it "should find a session and return a session object with picture" do
|
194
|
+
event_data = { :_name => "Horst Mayer", :_picture => "http://myhost/mypic.jpg" }
|
195
|
+
create_session("sess163", @now, event_data)
|
196
|
+
sess = FnordMetric::Session.find(Digest::MD5.hexdigest("sess163"), @opts)
|
197
|
+
sess.fetch_data!
|
198
|
+
sess.picture.should == "http://myhost/mypic.jpg"
|
199
|
+
end
|
200
|
+
|
201
|
+
it "should find a session and return a session object with name" do
|
202
|
+
event_data = { :_name => "Horst Mayer", :_picture => "http://myhost/mypic.jpg" }
|
203
|
+
create_session("sess143", @now, event_data)
|
204
|
+
sess = FnordMetric::Session.find(Digest::MD5.hexdigest("sess143"), @opts)
|
205
|
+
sess.fetch_data!
|
206
|
+
sess.name.should == "Horst Mayer"
|
207
|
+
end
|
208
|
+
|
209
|
+
it "should find a session and return a session object with event_ids" do
|
210
|
+
sesshash = create_session("sess923", @now, {})
|
211
|
+
@redis_wrap.zadd("#{@namespace}-session-#{sesshash}-events", @now, "shmoo")
|
212
|
+
@redis_wrap.zadd("#{@namespace}-session-#{sesshash}-events", @now, "fnord")
|
213
|
+
sess = FnordMetric::Session.find(sesshash, @opts)
|
214
|
+
sess.fetch_event_ids!
|
215
|
+
sess.event_ids.should include("shmoo")
|
216
|
+
sess.event_ids.should include("fnord")
|
217
|
+
end
|
218
|
+
|
219
|
+
def create_session(sesskey, sesstime, sessdata)
|
220
|
+
Digest::MD5.hexdigest(sesskey).tap do |sesshash|
|
221
|
+
@redis_wrap.zadd("#{@namespace}-session", sesstime, sesshash)
|
222
|
+
sessdata.each do |k,v|
|
223
|
+
@redis_wrap.hset("#{@namespace}-session-#{sesshash}-data", k, v)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
end
|
229
|
+
|
230
|
+
|
231
|
+
end
|