dynport_tools 0.2.19 → 0.2.20

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.
@@ -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