klarlack 0.0.2
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/LICENSE +20 -0
- data/README.rdoc +43 -0
- data/Rakefile +48 -0
- data/VERSION.yml +4 -0
- data/lib/klarlack.rb +8 -0
- data/lib/varnish/client.rb +258 -0
- data/lib/varnish/socket_factory.rb +57 -0
- data/spec/klarlack_spec.rb +154 -0
- data/spec/spec_helper.rb +5 -0
- metadata +65 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Max Schöfmann
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
= klarlack
|
2
|
+
|
3
|
+
Klarlack is a ruby client library for the varnish administration interface.
|
4
|
+
|
5
|
+
See also: http://www.varnish-cache.org
|
6
|
+
|
7
|
+
Please note: You need at least version 2.0.3 of varnish for purging to work.
|
8
|
+
|
9
|
+
=== Installation
|
10
|
+
|
11
|
+
sudo gem install schoefmax-klarlack --source=http://gems.github.com
|
12
|
+
|
13
|
+
=== Example
|
14
|
+
|
15
|
+
Lets purge all blog posts from the cache...
|
16
|
+
|
17
|
+
require 'rubygems'
|
18
|
+
require 'klarlack'
|
19
|
+
|
20
|
+
varnish = Varnish::Client.new '127.0.0.1:6082'
|
21
|
+
# the regexp is not a ruby regexp, just a plain string varnishd understands
|
22
|
+
varnish.purge :url, "^/posts/.*"
|
23
|
+
|
24
|
+
In a Rails app, you might want to use use this in a cache sweeper.
|
25
|
+
|
26
|
+
=== Specs
|
27
|
+
|
28
|
+
Start up a local varnishd with <tt>-T 127.0.0.1:6082</tt>. Then run
|
29
|
+
|
30
|
+
spec spec
|
31
|
+
|
32
|
+
=== TODO
|
33
|
+
|
34
|
+
* Support authentication when varnishd is started with <tt>-S</tt>
|
35
|
+
* Make parameter manipulation/display more friendly
|
36
|
+
|
37
|
+
=== WTF?
|
38
|
+
|
39
|
+
http://dict.leo.org/?search=klarlack
|
40
|
+
|
41
|
+
=== Copyright
|
42
|
+
|
43
|
+
Copyright (c) 2009 Max Schöfmann. Distributed under the MIT-License
|
data/Rakefile
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "klarlack"
|
8
|
+
gem.summary = %Q{ruby client for varnishd's admin interface}
|
9
|
+
gem.email = "max@pragmatic-it.de"
|
10
|
+
gem.homepage = "http://github.com/schoefmax/klarlack"
|
11
|
+
gem.authors = ["Max Schöfmann"]
|
12
|
+
|
13
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
14
|
+
end
|
15
|
+
rescue LoadError
|
16
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'spec/rake/spectask'
|
20
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
21
|
+
spec.libs << 'lib' << 'spec'
|
22
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
23
|
+
end
|
24
|
+
|
25
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
26
|
+
spec.libs << 'lib' << 'spec'
|
27
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
28
|
+
spec.rcov = true
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
task :default => :spec
|
33
|
+
|
34
|
+
require 'rake/rdoctask'
|
35
|
+
Rake::RDocTask.new do |rdoc|
|
36
|
+
if File.exist?('VERSION.yml')
|
37
|
+
config = YAML.load(File.read('VERSION.yml'))
|
38
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
39
|
+
else
|
40
|
+
version = ""
|
41
|
+
end
|
42
|
+
|
43
|
+
rdoc.rdoc_dir = 'rdoc'
|
44
|
+
rdoc.title = "klarlack #{version}"
|
45
|
+
rdoc.rdoc_files.include('README*')
|
46
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
47
|
+
end
|
48
|
+
|
data/VERSION.yml
ADDED
data/lib/klarlack.rb
ADDED
@@ -0,0 +1,258 @@
|
|
1
|
+
module Varnish
|
2
|
+
class Client
|
3
|
+
# Default management port of varnishd
|
4
|
+
DEFAULT_PORT = 6082
|
5
|
+
|
6
|
+
# We assume varnishd on localhost
|
7
|
+
DEFAULT_HOST = 'localhost'
|
8
|
+
|
9
|
+
DEFAULT_OPTS = {
|
10
|
+
:keep_alive => false,
|
11
|
+
:timeout => 1
|
12
|
+
}
|
13
|
+
|
14
|
+
# timeout in seconds when connecting to varnishd. Default is 1
|
15
|
+
attr_accessor :timeout
|
16
|
+
|
17
|
+
# set to true, to keep the connection alive. Default is false
|
18
|
+
attr_accessor :keep_alive
|
19
|
+
|
20
|
+
# hostname or IP-address of varnishd. Default is "localhost"
|
21
|
+
attr_accessor :host
|
22
|
+
|
23
|
+
# port number of varnishd. Default is 6082
|
24
|
+
attr_accessor :port
|
25
|
+
|
26
|
+
# Examples:
|
27
|
+
#
|
28
|
+
# Varnish::Client.new "127.0.0.1"
|
29
|
+
# Varnish::Client.new "mydomain.com:6082"
|
30
|
+
# Varnish::Client.new :timeout => 5
|
31
|
+
# Varnish::Client.new "10.0.0.3:6060", :timeout => nil, :keep_alive => true
|
32
|
+
#
|
33
|
+
# === Configuration options
|
34
|
+
#
|
35
|
+
# +timeout+:: if specified (seconds), calls to varnish
|
36
|
+
# will be wrapped in a timeout, default is 1 second.
|
37
|
+
# Disable with <tt>:timeout => nil</tt>
|
38
|
+
# +keep_alive+:: if true, the connection is kept alive by sending
|
39
|
+
# ping commands to varnishd every few seconds
|
40
|
+
def initialize(*args)
|
41
|
+
opts = {}
|
42
|
+
|
43
|
+
case args.length
|
44
|
+
when 0
|
45
|
+
self.server = DEFAULT_HOST
|
46
|
+
when 1
|
47
|
+
arg = args[0]
|
48
|
+
case arg
|
49
|
+
when String
|
50
|
+
self.server = arg
|
51
|
+
when Hash
|
52
|
+
self.server = DEFAULT_HOST
|
53
|
+
opts = arg
|
54
|
+
end
|
55
|
+
when 2
|
56
|
+
self.server = args[0]
|
57
|
+
opts = args[1]
|
58
|
+
else
|
59
|
+
raise ArgumentError, "wrong number of arguments (#{args.length} for 2)"
|
60
|
+
end
|
61
|
+
|
62
|
+
opts = DEFAULT_OPTS.merge(opts)
|
63
|
+
@timeout = opts[:timeout]
|
64
|
+
@keep_alive = opts[:keep_alive]
|
65
|
+
|
66
|
+
@mutex = Mutex.new
|
67
|
+
end
|
68
|
+
|
69
|
+
# Set the varnishd management host and port.
|
70
|
+
# Expects a string as "hostname" or "hostname:port"
|
71
|
+
def server=(server)
|
72
|
+
@host, @port = server.split(':')
|
73
|
+
@port = (@port || DEFAULT_PORT).to_i
|
74
|
+
server
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns the varnishd management host and port as "hostname:port"
|
78
|
+
def server
|
79
|
+
"#{@host}:#{@port}"
|
80
|
+
end
|
81
|
+
|
82
|
+
# Manipulate the VCL configuration
|
83
|
+
#
|
84
|
+
# .vcl :load, <configname>, <filename>
|
85
|
+
# .vcl :inline, <configname>, <quoted_VCLstring>
|
86
|
+
# .vcl :use, <configname>
|
87
|
+
# .vcl :discard, <configname>
|
88
|
+
# .vcl :list
|
89
|
+
# .vcl :show, <configname>
|
90
|
+
#
|
91
|
+
# Returns an array of VCL configurations for :list, and the servers
|
92
|
+
# response as string otherwise
|
93
|
+
#
|
94
|
+
# Ex.:
|
95
|
+
# v = Varnish::Client.new
|
96
|
+
# v.vcl :list
|
97
|
+
# #=> [["active", 0, "boot"]]
|
98
|
+
#
|
99
|
+
# v.vcl :load, "newconf", "/etc/varnish/myconf.vcl"
|
100
|
+
#
|
101
|
+
#
|
102
|
+
def vcl(op, *params)
|
103
|
+
response = cmd("vcl.#{op}", *params)
|
104
|
+
case op
|
105
|
+
when :list
|
106
|
+
response.split("\n").map do |line|
|
107
|
+
a = line.split(/\s+/, 3)
|
108
|
+
[a[0], a[1].to_i, a[2]]
|
109
|
+
end
|
110
|
+
else
|
111
|
+
response
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Purge objects from the cache or show the purge queue.
|
116
|
+
#
|
117
|
+
# .purge :url, <regexp>
|
118
|
+
# .purge :hash, <regexp>
|
119
|
+
# .purge :list
|
120
|
+
# .purge <costum-field> <args>
|
121
|
+
#
|
122
|
+
# +op+:: :url, :hash, :list or a custom field
|
123
|
+
# +regexp+:: a string containing a varnish compatible regexp
|
124
|
+
#
|
125
|
+
# Returns true for purging, returns an array containing the purge queue
|
126
|
+
# for :list
|
127
|
+
#
|
128
|
+
# Ex.:
|
129
|
+
# v = Varnish::Client.new
|
130
|
+
# v.purge :url, '.*'
|
131
|
+
#
|
132
|
+
# v.purge :list
|
133
|
+
# #=> [[1, "req.url ~ .*"]]
|
134
|
+
#
|
135
|
+
def purge(op, *regexp_or_args)
|
136
|
+
c = [:url, :hash, :list].include?(op) ? "purge.#{op}" : "purge #{op}"
|
137
|
+
response = cmd(c, *regexp_or_args)
|
138
|
+
case op
|
139
|
+
when :list
|
140
|
+
response.split("\n").map do |line|
|
141
|
+
a = line.split("\t")
|
142
|
+
[a[0].to_i, a[1]]
|
143
|
+
end
|
144
|
+
else
|
145
|
+
bool response
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# Ping the server to keep the connection alive
|
150
|
+
def ping(timestamp = nil)
|
151
|
+
cmd("ping", timestamp)
|
152
|
+
end
|
153
|
+
|
154
|
+
# Returns a hash of status information
|
155
|
+
#
|
156
|
+
# Ex.:
|
157
|
+
# v = Varnish::Client.new
|
158
|
+
# v.stats
|
159
|
+
# => {"Total header bytes"=>0, "Cache misses"=>0 ...}
|
160
|
+
def stats
|
161
|
+
result = cmd("stats")
|
162
|
+
Hash[*result.split("\n").map { |line|
|
163
|
+
stat = line.strip!.split(/\s+/, 2)
|
164
|
+
[stat[1], stat[0].to_i]
|
165
|
+
}.flatten
|
166
|
+
]
|
167
|
+
end
|
168
|
+
|
169
|
+
# Set and show parameters
|
170
|
+
#
|
171
|
+
# .param :show, [-l], [<param>]
|
172
|
+
# .param :set, <param>, <value>
|
173
|
+
def param(op, *args)
|
174
|
+
cmd("param.#{op}", *args)
|
175
|
+
end
|
176
|
+
|
177
|
+
# Returns the status string from varnish.
|
178
|
+
# See also #running? and #stopped?
|
179
|
+
def status
|
180
|
+
cmd("status")
|
181
|
+
end
|
182
|
+
|
183
|
+
def start
|
184
|
+
bool cmd("start")
|
185
|
+
end
|
186
|
+
|
187
|
+
def stop
|
188
|
+
bool cmd("stop")
|
189
|
+
end
|
190
|
+
|
191
|
+
def running?
|
192
|
+
bool status =~ /running/
|
193
|
+
end
|
194
|
+
|
195
|
+
def stopped?
|
196
|
+
bool status =~ /stopped/
|
197
|
+
end
|
198
|
+
|
199
|
+
# close the connection to varnishd.
|
200
|
+
# Note that the connection will automatically be re-established
|
201
|
+
# when another command is issued.
|
202
|
+
def disconnect
|
203
|
+
if connected?
|
204
|
+
@conn.write "quit\n"
|
205
|
+
@conn.gets
|
206
|
+
@conn.close unless @conn.closed?
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def connected?
|
211
|
+
bool @conn && !@conn.closed?
|
212
|
+
end
|
213
|
+
|
214
|
+
private
|
215
|
+
|
216
|
+
# Sends a command to varnishd.
|
217
|
+
# Raises an Varnish::Error when a non-200 status is returned
|
218
|
+
# Returns the response text
|
219
|
+
def cmd(name, *params)
|
220
|
+
@mutex.synchronize do
|
221
|
+
connect unless connected?
|
222
|
+
@conn.write "#{name} #{params.join(' ')}\n"
|
223
|
+
status, length = @conn.gets.split # <status> <content_length>\n
|
224
|
+
content = @conn.read(length.to_i + 1) # +1 = \n
|
225
|
+
content.chomp!
|
226
|
+
raise Error, "Command #{name} returned with status #{status}: #{content}" if status.to_i != 200
|
227
|
+
content
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def connect
|
232
|
+
@conn = SocketFactory.tcp_socket(@host, @port, @timeout)
|
233
|
+
|
234
|
+
# If keep alive, we ping the server every few seconds.
|
235
|
+
if @keep_alive
|
236
|
+
varnish = self
|
237
|
+
Thread.new do
|
238
|
+
while(true) do
|
239
|
+
if varnish.connected?
|
240
|
+
varnish.ping
|
241
|
+
sleep 5
|
242
|
+
else
|
243
|
+
break
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
@conn
|
250
|
+
end
|
251
|
+
|
252
|
+
# converts +value+ into a boolean
|
253
|
+
def bool(value)
|
254
|
+
!!value
|
255
|
+
end
|
256
|
+
|
257
|
+
end
|
258
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Varnish
|
2
|
+
# Wrapper around Ruby's Socket.
|
3
|
+
#
|
4
|
+
# Uses Mike Perhams superior (in both reliability and
|
5
|
+
# performance) connection technique with proper timeouts:
|
6
|
+
# See: http://github.com/mperham/memcache-client
|
7
|
+
class SocketFactory
|
8
|
+
|
9
|
+
begin
|
10
|
+
# Try to use the SystemTimer gem instead of Ruby's timeout library
|
11
|
+
# when running on something that looks like Ruby 1.8.x. See:
|
12
|
+
# http://ph7spot.com/articles/system_timer
|
13
|
+
# We don't want to bother trying to load SystemTimer on jruby and
|
14
|
+
# ruby 1.9+.
|
15
|
+
if !defined?(RUBY_ENGINE)
|
16
|
+
require 'system_timer'
|
17
|
+
Timer = SystemTimer
|
18
|
+
else
|
19
|
+
require 'timeout'
|
20
|
+
Timer = Timeout
|
21
|
+
end
|
22
|
+
rescue LoadError => e
|
23
|
+
$stderr.puts "[klarlack] Could not load SystemTimer gem, falling back to Ruby's slower/unsafe timeout library: #{e.message}"
|
24
|
+
require 'timeout'
|
25
|
+
Timer = Timeout
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.tcp_socket(host, port, timeout = nil)
|
29
|
+
addr = Socket.getaddrinfo(host, nil)
|
30
|
+
sock = Socket.new(Socket.const_get(addr[0][0]), Socket::SOCK_STREAM, 0)
|
31
|
+
|
32
|
+
if timeout
|
33
|
+
secs = Integer(timeout)
|
34
|
+
usecs = Integer((timeout - secs) * 1_000_000)
|
35
|
+
optval = [secs, usecs].pack("l_2")
|
36
|
+
sock.setsockopt Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, optval
|
37
|
+
sock.setsockopt Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, optval
|
38
|
+
|
39
|
+
# Socket timeouts don't work for more complex IO operations
|
40
|
+
# like gets which lay on top of read. We need to fall back to
|
41
|
+
# the standard Timeout mechanism.
|
42
|
+
sock.instance_eval <<-EOR
|
43
|
+
alias :blocking_gets :gets
|
44
|
+
def gets
|
45
|
+
Timer.timeout(#{timeout}) do
|
46
|
+
self.blocking_gets
|
47
|
+
end
|
48
|
+
end
|
49
|
+
EOR
|
50
|
+
end
|
51
|
+
sock.connect(Socket.pack_sockaddr_in(port, addr[0][3]))
|
52
|
+
sock.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
53
|
+
sock
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe Varnish::Client do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@varnish = Varnish::Client.new "127.0.0.1:6082"
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '(connection handling)' do
|
10
|
+
|
11
|
+
it 'should not be connected on object instantiation' do
|
12
|
+
@varnish.connected?.should be_false
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should not raise an error when trying to disconnect a non-connected client' do
|
16
|
+
lambda { @varnish.disconnect }.should_not raise_error
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should automatically connect when a command is issued' do
|
20
|
+
@varnish.ping
|
21
|
+
@varnish.connected?.should be_true
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should use timeouts when sending commands' do
|
25
|
+
Varnish::SocketFactory::Timer.should_receive(:timeout).and_return("200 0")
|
26
|
+
@varnish.timeout = 10
|
27
|
+
@varnish.ping
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should be possible to disable timeouts' do
|
31
|
+
Varnish::SocketFactory::Timer.should_not_receive(:timeout)
|
32
|
+
@varnish.timeout = nil
|
33
|
+
@varnish.ping
|
34
|
+
end
|
35
|
+
|
36
|
+
it '#disconnect should close the connection' do
|
37
|
+
@varnish.ping
|
38
|
+
@varnish.connected?.should be_true
|
39
|
+
@varnish.disconnect
|
40
|
+
@varnish.connected?.should be_false
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'given keep_alive is set, the connection should be kept alive with pings' do
|
44
|
+
@varnish.keep_alive = true
|
45
|
+
@varnish.should_receive :ping
|
46
|
+
@varnish.send :connect
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'given keep_alive is not set, no pings should be sent to varnishd' do
|
50
|
+
@varnish.keep_alive = false
|
51
|
+
@varnish.should_not_receive :ping
|
52
|
+
@varnish.send :connect
|
53
|
+
end
|
54
|
+
|
55
|
+
it '#server should return the host and port for the connection' do
|
56
|
+
@varnish.host = "foohost"
|
57
|
+
@varnish.port = 1234
|
58
|
+
@varnish.server.should == "foohost:1234"
|
59
|
+
end
|
60
|
+
|
61
|
+
it '#server= should set the host and port for the connection' do
|
62
|
+
@varnish.server = "blahost:9876"
|
63
|
+
@varnish.host.should == "blahost"
|
64
|
+
@varnish.port.should == 9876
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
describe '(commands)' do
|
70
|
+
|
71
|
+
before(:each) do
|
72
|
+
ensure_started
|
73
|
+
end
|
74
|
+
|
75
|
+
# ... the specs for #param, #purge and #vcl could be better ...
|
76
|
+
|
77
|
+
it '#param should send the param command to varnishd' do
|
78
|
+
@varnish.param(:show).should_not be_empty
|
79
|
+
end
|
80
|
+
|
81
|
+
it '#purge should allow purging by url, hash and custom fields' do
|
82
|
+
@varnish.purge(:url, '^/articles/.*').should be_true
|
83
|
+
@varnish.purge(:hash, 12345).should be_true
|
84
|
+
@varnish.purge("req.http.host", "~", "www.example.com").should be_true
|
85
|
+
end
|
86
|
+
|
87
|
+
it '#purge with :list should return an array with queued purges' do
|
88
|
+
@varnish.purge(:url, '^/posts/.*')
|
89
|
+
list = @varnish.purge(:list)
|
90
|
+
list.last[0].should be_kind_of(Integer)
|
91
|
+
list.last[1].should == "req.url ~ ^/posts/.*"
|
92
|
+
end
|
93
|
+
|
94
|
+
it '#vcl with :list should return an array of VCL configurations' do
|
95
|
+
list = @varnish.vcl(:list)
|
96
|
+
list.should_not be_empty
|
97
|
+
list.should be_kind_of(Array)
|
98
|
+
list.first[0].should be_kind_of(String)
|
99
|
+
list.first[1].should be_kind_of(Integer)
|
100
|
+
list.first[2].should be_kind_of(String)
|
101
|
+
end
|
102
|
+
|
103
|
+
it '#ping should send a ping to the server and return a string containing the response' do
|
104
|
+
@varnish.ping.should =~ /^PONG \d+/
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
it '#status should return a string explaining the daemons status' do
|
109
|
+
@varnish.status.should =~ /running|stopped|stopping|starting/
|
110
|
+
end
|
111
|
+
|
112
|
+
it "#stats should return a hash containing status information" do
|
113
|
+
stats = @varnish.stats
|
114
|
+
stats.should_not be_empty
|
115
|
+
stats.values.each {|v| v.should be_kind_of(Integer) }
|
116
|
+
stats.keys.each {|k| k.should_not be_empty }
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
describe '(daemon lifecycle)' do
|
122
|
+
|
123
|
+
it '#start, #stop, #running?, #stopped? should bahave as advertised' do
|
124
|
+
ensure_stopped # issues #stop
|
125
|
+
@varnish.stopped?.should be_true
|
126
|
+
@varnish.running?.should be_false
|
127
|
+
ensure_started # issues #start
|
128
|
+
@varnish.stopped?.should be_false
|
129
|
+
@varnish.running?.should be_true
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'starting an already started daemon should raise an error' do
|
133
|
+
ensure_started
|
134
|
+
lambda { @varnish.start }.should raise_error(Varnish::Error)
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'stopping an already stopped daemon should raise an error' do
|
138
|
+
ensure_stopped
|
139
|
+
lambda { @varnish.stop }.should raise_error(Varnish::Error)
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
def ensure_started
|
145
|
+
@varnish.start if @varnish.stopped?
|
146
|
+
while(!@varnish.running?) do sleep 0.1 end
|
147
|
+
end
|
148
|
+
|
149
|
+
def ensure_stopped
|
150
|
+
@varnish.stop if @varnish.running?
|
151
|
+
while(!@varnish.stopped?) do sleep 0.1 end
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: klarlack
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- "Max Sch\xC3\xB6fmann"
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-04-24 00:00:00 +02:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: max@pragmatic-it.de
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- LICENSE
|
24
|
+
- README.rdoc
|
25
|
+
files:
|
26
|
+
- LICENSE
|
27
|
+
- README.rdoc
|
28
|
+
- Rakefile
|
29
|
+
- VERSION.yml
|
30
|
+
- lib/klarlack.rb
|
31
|
+
- lib/varnish/client.rb
|
32
|
+
- lib/varnish/socket_factory.rb
|
33
|
+
- spec/klarlack_spec.rb
|
34
|
+
- spec/spec_helper.rb
|
35
|
+
has_rdoc: true
|
36
|
+
homepage: http://github.com/schoefmax/klarlack
|
37
|
+
licenses: []
|
38
|
+
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options:
|
41
|
+
- --charset=UTF-8
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: "0"
|
49
|
+
version:
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
version:
|
56
|
+
requirements: []
|
57
|
+
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 1.3.5
|
60
|
+
signing_key:
|
61
|
+
specification_version: 2
|
62
|
+
summary: ruby client for varnishd's admin interface
|
63
|
+
test_files:
|
64
|
+
- spec/klarlack_spec.rb
|
65
|
+
- spec/spec_helper.rb
|