dynport_tools 0.2.19 → 0.2.20

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,102 @@
1
+ require 'spec_helper'
2
+
3
+ describe DynportTools::Features do
4
+ let(:redis) { Redis.new }
5
+
6
+ before(:each) do
7
+ DynportTools::Features.features = nil
8
+ keys = redis.keys("features*")
9
+ redis.multi do
10
+ keys.each do |key|
11
+ redis.del(key)
12
+ end
13
+ end
14
+ DynportTools::Features.redis = redis
15
+ end
16
+
17
+ describe "defining features" do
18
+ it "adds the features to an array" do
19
+ DynportTools::Features.feature :solr
20
+ DynportTools::Features.feature :sphinx
21
+ DynportTools::Features.features.should == [:solr, :sphinx]
22
+ end
23
+
24
+ it "adds the *_enabled_for? method" do
25
+ DynportTools::Features.feature :solr
26
+ DynportTools::Features.should respond_to(:solr_enabled_for?)
27
+ end
28
+
29
+ it "returns true when user included in users set" do
30
+ user = double("user", :id => 2)
31
+ DynportTools::Features.feature :solr
32
+ DynportTools::Features.add_user(:solr, user)
33
+ DynportTools::Features.solr_enabled_for?(user).should == true
34
+ end
35
+
36
+ it "returns false when user not included in user set" do
37
+ user = double("user", :id => 2)
38
+ DynportTools::Features.feature :solr
39
+ DynportTools::Features.solr_enabled_for?(user).should == false
40
+ end
41
+
42
+ it "returns false when user is nil" do
43
+ DynportTools::Features.feature :solr
44
+ DynportTools::Features.solr_enabled_for?(nil).should == false
45
+ end
46
+
47
+ it "executes the block given when enabled" do
48
+ user = double("user", :id => 2)
49
+ DynportTools::Features.feature :solr
50
+ DynportTools::Features.add_user(:solr, user)
51
+ called = false
52
+ DynportTools::Features.solr_enabled_for?(user) do
53
+ called = true
54
+ end.should == true
55
+ called.should == true
56
+ end
57
+
58
+ it "does not execute the block given when not enabled" do
59
+ DynportTools::Features.feature :solr
60
+ called = false
61
+ DynportTools::Features.solr_enabled_for?(nil) do
62
+ called = true
63
+ end.should == false
64
+ called.should == false
65
+ end
66
+ end
67
+
68
+ it "allows setting a redis instance" do
69
+ r = double("my r")
70
+ DynportTools::Features.redis = r
71
+ DynportTools::Features.redis.should == r
72
+ end
73
+
74
+ describe "add_user" do
75
+ before(:each) do
76
+ DynportTools::Features.feature :solr
77
+ end
78
+
79
+ it "raises an error when feature not defined" do
80
+ lambda {
81
+ DynportTools::Features.add_user(:some_other, double("user", :id => 2))
82
+ }.should raise_error
83
+ end
84
+
85
+ it "adds the user id to the specific group" do
86
+ DynportTools::Features.add_user(:solr, double("user", :id => 2))
87
+ DynportTools::Features.add_user(:solr, double("user", :id => 2))
88
+ DynportTools::Features.add_user(:solr, double("user", :id => 4))
89
+ redis.smembers("features/solr/users").should == %w(2 4)
90
+ end
91
+ end
92
+
93
+ describe "remove_user" do
94
+ it "correctly removes users" do
95
+ DynportTools::Features.feature :solr
96
+ DynportTools::Features.add_user(:solr, double("user", :id => 2))
97
+ redis.smembers("features/solr/users").should == %w(2)
98
+ DynportTools::Features.remove_user(:solr, double("user", :id => 2))
99
+ redis.smembers("features/solr/users").should == %w()
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,303 @@
1
+ $:<<File.expand_path("../../../", __FILE__)
2
+ require "dynport_tools"
3
+ require "dynport_tools/services"
4
+
5
+ describe "Services" do
6
+ let(:services) { DynportTools::Services.new }
7
+ before(:each) do
8
+ services.stub(:system_call).and_raise("stub me")
9
+ end
10
+
11
+ it "can be initialized" do
12
+ DynportTools::Services.new.should be_kind_of(DynportTools::Services)
13
+ end
14
+
15
+ describe "solr_root" do
16
+ it "allows setting the solr root" do
17
+ services.solr_data_root = "/tmp/solr_path"
18
+ services.solr_data_root.should == "/tmp/solr_path"
19
+ end
20
+
21
+ it "returns /opt/solr by default" do
22
+ services.solr_data_root.should == "/opt/solr"
23
+ end
24
+ end
25
+
26
+ describe "solr" do
27
+ let(:tmp_path) { "/tmp/solr_#{Time.now.to_f.to_s.gsub(".", "")}" }
28
+ let(:solr_xml) { "#{tmp_path}/solr.xml"}
29
+
30
+ after do(:each)
31
+ FileUtils.rm_rf(tmp_path)
32
+ end
33
+
34
+ describe "#solr_bootstrapped?" do
35
+ before(:each) do
36
+ services.solr_data_root = tmp_path
37
+ end
38
+
39
+ it "returns false by default" do
40
+ services.should_not be_solr_bootstrapped
41
+ end
42
+
43
+ it "returns true when solr.xml exists" do
44
+ FileUtils.mkdir_p(tmp_path)
45
+ FileUtils.touch(solr_xml)
46
+ services.should be_solr_bootstrapped
47
+ end
48
+ end
49
+
50
+ describe "bootstrap_solr" do
51
+ before(:each) do
52
+ services.solr_data_root = tmp_path
53
+ end
54
+
55
+ it "raises an error when dir not exists" do
56
+ lambda {
57
+ services.bootstrap_solr
58
+ }.should raise_error("please create #{tmp_path} first")
59
+ end
60
+
61
+ it "creates a new solr.xml when not exists" do
62
+ FileUtils.mkdir_p(tmp_path)
63
+ services.bootstrap_solr
64
+ File.should be_exists(solr_xml)
65
+ end
66
+
67
+ it "sets the correct content" do
68
+ FileUtils.mkdir_p(tmp_path)
69
+ services.bootstrap_solr
70
+ expected = %(
71
+ <?xml version="1.0" encoding="UTF-8" ?>
72
+ <solr sharedLib="lib" persistent="true">
73
+ <cores adminPath="/admin/cores">
74
+ </cores>
75
+ </solr>
76
+ ).gsub(/^\s+/, "")
77
+ File.read(solr_xml).should == expected
78
+ end
79
+
80
+ it "raises an error when solr.xml already exists" do
81
+ FileUtils.mkdir_p(tmp_path)
82
+ FileUtils.touch(solr_xml)
83
+ lambda {
84
+ services.bootstrap_solr
85
+ }.should raise_error("#{solr_xml} already exists")
86
+ end
87
+ end
88
+
89
+ describe "#solr_running?" do
90
+ it "calls head with the correct url" do
91
+ services.should_receive(:head).with("http://localhost:8983/solr/").and_return 200
92
+ services.should be_solr_running
93
+ end
94
+
95
+ it "returns false when head != 200" do
96
+ services.should_receive(:head).with("http://localhost:8983/solr/").and_return 404
97
+ services.should_not be_solr_running
98
+ end
99
+
100
+ it "uses a custom solr_url when set" do
101
+ services.solr_url = "http://some.host:8080/solr/"
102
+ services.should_receive(:head).with("http://some.host:8080/solr/").and_return 200
103
+ services.should be_solr_running
104
+ end
105
+ end
106
+
107
+ describe "#solr_core_exists?" do
108
+ it "calls head with the correct url" do
109
+ services.solr_url = "http://some.host:8080/solr/"
110
+ services.should_receive(:head).with("http://some.host:8080/solr/custom_core_name/admin/").and_return 200
111
+ services.should be_solr_core_exists("custom_core_name")
112
+ end
113
+
114
+ it "returns false when status code != 200" do
115
+ services.solr_url = "http://some.host:8080/solr/"
116
+ services.should_receive(:head).with("http://some.host:8080/solr/custom_core_name_2/admin/").and_return 404
117
+ services.should_not be_solr_core_exists("custom_core_name_2")
118
+ end
119
+ end
120
+
121
+ describe "#create_solr_core" do
122
+ before(:each) do
123
+ services.solr_url = "http://some.host:8080/solr/"
124
+ services.solr_instance_path = "/path/to/solr/instance"
125
+ services.solr_data_root = "/solr/data"
126
+ end
127
+
128
+ it "calls post with the correct url" do
129
+ url = "http://some.host:8080/solr/admin/cores?action=CREATE&name=new_core_name&instanceDir=/path/to/solr/instance&dataDir=/solr/data/new_core_name"
130
+ services.should_receive(:post).with(url)
131
+ services.create_solr_core("new_core_name")
132
+ end
133
+
134
+ it "raises an error when solr_instance_path is not set" do
135
+ services.should_not_receive(:post)
136
+ services.solr_instance_path = nil
137
+ lambda {
138
+ services.create_solr_core("new_core_name")
139
+ }.should raise_error("please set solr_instance_path first!")
140
+ end
141
+ end
142
+
143
+ describe "#unload_solr_core" do
144
+ it "calls the correct post method (haha, post)" do
145
+ services.solr_url = "http://some.host:8080/solr/"
146
+ url = "http://some.host:8080/solr/admin/cores?action=UNLOAD&core=core_to_unload"
147
+ services.should_receive(:post).with(url)
148
+ services.unload_solr_core("core_to_unload")
149
+ end
150
+ end
151
+ end
152
+
153
+ describe "redis" do
154
+ before(:each) do
155
+ services.redis_path_prefix = "/tmp/path/to/redis"
156
+ end
157
+
158
+ describe "#redis_path_prefix" do
159
+ it "raises an error when not set" do
160
+ services.redis_path_prefix = nil
161
+ lambda {
162
+ services.redis_path_prefix
163
+ }.should raise_error("redis_path_prefix not set!")
164
+ end
165
+ end
166
+
167
+ it "returns the correct redis_socket_path when redis_path_prefix is set" do
168
+ services.redis_socket_path.should == "/tmp/path/to/redis.socket"
169
+ end
170
+
171
+ it "returns the correct redis_config_path when redis_path_prefix is set" do
172
+ services.redis_config_path.should == "/tmp/path/to/redis.conf"
173
+ end
174
+
175
+ describe "#redis_running?" do
176
+ before(:each) do
177
+ services.unstub(:system_call)
178
+ services.stub(:redis_socket_path).and_return("/path/to/redis.socket")
179
+ end
180
+
181
+ it "executes the correct command" do
182
+ services.should_receive(:system_call).with(%(echo "info" | redis-cli -s /path/to/redis.socket 2> /dev/null | grep uptime_in_seconds)).and_return "uptime_in_seconds:1787353"
183
+ services.should be_redis_running
184
+ end
185
+
186
+ it "returns false when system_call returns a blank string" do
187
+ services.should_receive(:system_call).with(%(echo "info" | redis-cli -s /path/to/redis.socket 2> /dev/null | grep uptime_in_seconds)).and_return ""
188
+ services.should_not be_redis_running
189
+ end
190
+ end
191
+
192
+ describe "#start_redis" do
193
+ before(:each) do
194
+ services.stub!(:write_redis_config)
195
+ services.stub!(:system_call)
196
+ end
197
+
198
+ it "calls write_redis_config" do
199
+ services.should_receive(:write_redis_config)
200
+ services.start_redis
201
+ end
202
+
203
+ it "starts redis with the correct command" do
204
+ services.redis_path_prefix = "/path/to/redis"
205
+ services.should_receive(:system_call).with("redis-server /path/to/redis.conf")
206
+ services.start_redis
207
+ end
208
+ end
209
+
210
+ describe "#write_redis_config" do
211
+ it "writes redis_config to the correct path" do
212
+ services.stub!(:redis_config).and_return("some config")
213
+ services.redis_path_prefix = "/path/to/redis"
214
+ file = double("file")
215
+ File.should_receive(:open).with("/path/to/redis.conf", "w").and_yield(file)
216
+ file.should_receive(:puts).with("some config")
217
+ services.write_redis_config
218
+ end
219
+ end
220
+
221
+ describe "#redis_config_hash" do
222
+ it "returns the default hash by default" do
223
+ services.redis_path_prefix = "/path/to/redis"
224
+ services.redis_config_hash.should == {
225
+ :unixsocket => "/path/to/redis.socket",
226
+ :logfile => "/path/to/redis.log",
227
+ :daemonize => "yes",
228
+ :port => 0
229
+ }
230
+ end
231
+
232
+ it "merges the custom set redis_config_path" do
233
+ services.redis_path_prefix = "/path/to/redis"
234
+ services.redis_config_hash = { :port => 1234 }
235
+ services.redis_config_hash.should == {
236
+ :unixsocket => "/path/to/redis.socket",
237
+ :port => 1234,
238
+ :logfile => "/path/to/redis.log",
239
+ :daemonize => "yes"
240
+ }
241
+ end
242
+ end
243
+
244
+ describe "#redis_config" do
245
+ it "returns a string" do
246
+ services.redis_config.should be_kind_of(String)
247
+ end
248
+
249
+ it "returns the correct string" do
250
+ services.stub(:redis_config_hash).and_return(
251
+ :port => 0,
252
+ :unixsocket => "/path/to/socket"
253
+ )
254
+ services.redis_config.split("\n").sort.should == ["port 0", "unixsocket /path/to/socket"].sort
255
+ end
256
+
257
+ it "does not include empty values" do
258
+ services.stub(:redis_config_hash).and_return(
259
+ :port => nil,
260
+ :unixsocket => "/path/to/socket"
261
+ )
262
+ services.redis_config.should == "unixsocket /path/to/socket"
263
+ end
264
+ end
265
+ end
266
+
267
+ it "forwards the system call" do
268
+ services.unstub(:system_call)
269
+ services.stub(:puts)
270
+ Kernel.should_receive(:`).with("ls -l").and_return("the result")
271
+ services.system_call("ls -l").should == "the result"
272
+ end
273
+
274
+ describe "http methods" do
275
+ let(:url) { "http://www.some.host:1234/path" }
276
+ describe "#head" do
277
+ before(:each) do
278
+ services.unstub(:system_call)
279
+ end
280
+
281
+ it "executes the correct system call" do
282
+ services.should_receive(:system_call).with(%(curl -s -I "#{url}" | head -n 1)).and_return("HTTP/1.1 200 OK")
283
+ services.head(url).should == 200
284
+ end
285
+
286
+ it "returns nil when result is empty" do
287
+ services.stub(:system_call).and_return("")
288
+ services.head("/some/path").should be_nil
289
+ end
290
+ end
291
+
292
+ describe "#post" do
293
+ before(:each) do
294
+ services.unstub(:system_call)
295
+ end
296
+
297
+ it "executes the correct system call" do
298
+ services.should_receive(:system_call).with(%(curl -s -I -XPOST "#{url}"))
299
+ services.post(url)
300
+ end
301
+ end
302
+ end
303
+ end
@@ -0,0 +1,177 @@
1
+ require 'spec_helper'
2
+
3
+ describe DynportTools::Settings do
4
+ let(:redis) { Redis.new }
5
+ let(:time) { Time.parse("2011-02-03 04:05:06") }
6
+
7
+ before(:each) do
8
+ DynportTools::Settings.defaults = nil
9
+ DynportTools::Settings.redis = redis
10
+ redis.del("settings")
11
+ redis.del("settings/updated_at")
12
+ DynportTools::Settings.instance_variable_set("@all", nil)
13
+ DynportTools::Settings.instance_variable_set("@cached_at", nil)
14
+ end
15
+
16
+ it "allows setting a redis connection" do
17
+ r = double("redis2")
18
+ DynportTools::Settings.redis = r
19
+ DynportTools::Settings.redis.should == r
20
+ end
21
+
22
+ it "allows addings new settings" do
23
+ DynportTools::Settings.set(:refresh, 11)
24
+ DynportTools::Settings.defaults[:refresh].should == 11
25
+ end
26
+
27
+ it "returns the correct defaults" do
28
+ DynportTools::Settings.set(:refresh, 12)
29
+ DynportTools::Settings.refresh.should == 12
30
+ end
31
+
32
+ it "allows setting of multiple settings at once" do
33
+ DynportTools::Settings.set(:a => 1, :b => 2)
34
+ DynportTools::Settings.a.should == 1
35
+ DynportTools::Settings.b.should == 2
36
+ end
37
+
38
+ describe "#all" do
39
+ it "fetches the correct values" do
40
+ redis.hset("settings", "a", "1")
41
+ redis.hset("settings", "b", "2")
42
+ DynportTools::Settings.all.should == { "a" => "1", "b" => "2" }
43
+ end
44
+
45
+ it "caches the fetched records" do
46
+ Timecop.freeze(time) do
47
+ redis.hset("settings", "a", "1")
48
+ redis.hset("settings", "b", "2")
49
+ DynportTools::Settings.all
50
+ DynportTools::Settings.instance_variable_get("@all").should == { "a" => "1", "b" => "2" }
51
+ DynportTools::Settings.instance_variable_get("@cached_at").should == time
52
+ end
53
+ end
54
+
55
+ it "returns the cached settings when not expired" do
56
+ DynportTools::Settings.stub(:expired?).and_return false
57
+ DynportTools::Settings.instance_variable_set("@all", { "c" => "3" })
58
+ DynportTools::Settings.all.should == { "c" => "3" }
59
+ end
60
+ end
61
+
62
+ describe "#expired?" do
63
+ it "returns false when @cached_at is nil" do
64
+ DynportTools::Settings.should_not be_expired
65
+ end
66
+
67
+ it "returns false when cached_at exactly 60 seconds ago" do
68
+ Timecop.freeze(time) do
69
+ DynportTools::Settings.instance_variable_set("@cached_at", time - 60)
70
+ DynportTools::Settings.should_not be_expired
71
+ end
72
+ end
73
+
74
+ it "returns true when exactly 61 seconds ago" do
75
+ Timecop.freeze(time) do
76
+ DynportTools::Settings.instance_variable_set("@cached_at", time - 61)
77
+ DynportTools::Settings.should be_expired
78
+ end
79
+ end
80
+ end
81
+
82
+ describe "#changed?" do
83
+ it "returns true when redis value != cached_at" do
84
+ Timecop.freeze(time) do
85
+ redis.set("settings/updated_at", time.to_i + 1)
86
+ DynportTools::Settings.should be_changed
87
+ end
88
+ end
89
+
90
+ it "returns true when both nil" do
91
+ DynportTools::Settings.instance_variable_set("@cached_at", nil)
92
+ DynportTools::Settings.should be_changed
93
+ end
94
+
95
+ it "false when redis value == cached_at" do
96
+ Timecop.freeze(time) do
97
+ DynportTools::Settings.instance_variable_set("@cached_at", time)
98
+ redis.set("settings/updated_at", time.to_i)
99
+ DynportTools::Settings.should_not be_changed
100
+ end
101
+ end
102
+ end
103
+
104
+ describe "#set_value" do
105
+ it "resets the @all variable" do
106
+ DynportTools::Settings.set :refresh, 11
107
+ DynportTools::Settings.instance_variable_set("@all", { "b" => "2" })
108
+ DynportTools::Settings.set_value(:refresh, 12)
109
+ DynportTools::Settings.instance_variable_get("@all").should == { "refresh" => "12" }
110
+ end
111
+
112
+ it "sets the updated_at field" do
113
+ Timecop.freeze(Time.at(11)) do
114
+ DynportTools::Settings.set :refresh, 11
115
+ DynportTools::Settings.set_value(:refresh, 12)
116
+ redis.get("settings/updated_at").should == "11"
117
+ end
118
+ end
119
+ end
120
+
121
+ describe "dsl" do
122
+ before(:each) do
123
+ DynportTools::Settings.redis = redis
124
+ redis.del("settings")
125
+ end
126
+
127
+ it "sets the defaults array" do
128
+ DynportTools::Settings.set :refresh, 11
129
+ DynportTools::Settings.defaults[:refresh].should == 11
130
+ end
131
+
132
+ it "allows addings settings" do
133
+ DynportTools::Settings.set :refresh, 10
134
+ DynportTools::Settings.refresh.should == 10
135
+ end
136
+
137
+ it "uses settings stored in redis" do
138
+ redis.hset("settings", "refresh", 20)
139
+ DynportTools::Settings.set(:refresh, 10)
140
+ DynportTools::Settings.refresh.should == 20
141
+ end
142
+
143
+ it "returns the correct types for integers" do
144
+ redis.hset("settings", "enabled", true)
145
+ DynportTools::Settings.set(:enabled, false)
146
+ DynportTools::Settings.enabled.should == true
147
+ end
148
+
149
+ describe "with boolean methods" do
150
+ it "adds the enable_<key>! method" do
151
+ DynportTools::Settings.set(:new_feature, true)
152
+ DynportTools::Settings.disable_new_feature!
153
+ DynportTools::Settings.new_feature.should == false
154
+ end
155
+
156
+ it "adds the enable_<key>! method" do
157
+ DynportTools::Settings.set(:new_feature, false)
158
+ DynportTools::Settings.enable_new_feature!
159
+ DynportTools::Settings.new_feature.should == true
160
+ end
161
+
162
+ it "adds the new_feature?`method" do
163
+ DynportTools::Settings.set(:new_feature, false)
164
+ DynportTools::Settings.new_feature?.should == false
165
+ DynportTools::Settings.enable_new_feature!
166
+ DynportTools::Settings.new_feature?.should == true
167
+ end
168
+ end
169
+
170
+ it "allows setting of settings" do
171
+ DynportTools::Settings.set(:refresh, 12)
172
+ DynportTools::Settings.set_refresh(13)
173
+ DynportTools::Settings.refresh.should == 13
174
+ redis.hgetall("settings")["refresh"].should == "13"
175
+ end
176
+ end
177
+ end