servolux 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,8 @@
1
+ module Servolux
2
+ VERSION = "0.11.0".freeze
3
+
4
+ # Returns the version string for the library.
5
+ def self.version
6
+ VERSION
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env sh
2
+
3
+ gem list -i bones >/dev/null 2>&1
4
+ rc=$?
5
+ if [[ $rc != 0 ]]; then
6
+ gem install bones
7
+ fi
8
+
9
+ rake gem:install_dependencies
@@ -2,7 +2,6 @@
2
2
  require File.expand_path('../spec_helper', __FILE__)
3
3
 
4
4
  describe Servolux::Child do
5
-
6
5
  before :all do
7
6
  @child = Servolux::Child.new
8
7
  end
@@ -12,22 +11,22 @@ describe Servolux::Child do
12
11
  end
13
12
 
14
13
  it 'has some sensible defaults' do
15
- @child.command.should be_nil
16
- @child.timeout.should be_nil
17
- @child.signals.should be == %w[TERM QUIT KILL]
18
- @child.suspend.should be == 4
19
- @child.pid.should be_nil
20
- @child.io.should be_nil
14
+ expect(@child.command).to be_nil
15
+ expect(@child.timeout).to be_nil
16
+ expect(@child.signals).to eq(%w[TERM QUIT KILL])
17
+ expect(@child.suspend).to eq(4)
18
+ expect(@child.pid).to be_nil
19
+ expect(@child.io).to be_nil
21
20
  end
22
21
 
23
22
  it 'starts a child process' do
24
23
  @child.command = 'echo `pwd`'
25
24
  @child.start
26
25
 
27
- @child.pid.should_not be_nil
26
+ expect(@child.pid).to_not be_nil
28
27
  @child.wait
29
- @child.io.read.strip.should be == Dir.pwd
30
- @child.success?.should be_true
28
+ expect(@child.io.read.strip).to eq(Dir.pwd)
29
+ expect(@child.success?).to be true
31
30
  end
32
31
 
33
32
  it 'kills a child process after some timeout' do
@@ -35,16 +34,14 @@ describe Servolux::Child do
35
34
  @child.timeout = 0.25
36
35
  @child.start
37
36
 
38
- @child.pid.should_not be_nil
37
+ expect(@child.pid).to_not be_nil
39
38
  @child.wait
40
39
 
41
- @child.io.read.strip.should be_empty
40
+ expect(@child.io.read.strip).to be_empty
42
41
 
43
- @child.signaled?.should be_true
44
- @child.exited?.should be_false
45
- @child.exitstatus.should be_nil
46
- @child.success?.should be_nil
42
+ expect(@child.signaled?).to be true
43
+ expect(@child.exited?).to be false
44
+ expect(@child.exitstatus).to be_nil
45
+ expect(@child.success?).to be_nil
47
46
  end
48
-
49
47
  end
50
-
@@ -1,12 +1,9 @@
1
-
2
1
  require File.expand_path('../spec_helper', __FILE__)
3
2
  require 'logger'
4
3
  require 'fileutils'
5
4
 
6
5
  if Servolux.fork?
7
-
8
6
  describe Servolux::Daemon do
9
-
10
7
  TestServer = Module.new {
11
8
  def before_starting() @counter = 0; end
12
9
  def after_stopping() exit!(0); end
@@ -35,7 +32,7 @@ describe Servolux::Daemon do
35
32
  @daemon = Servolux::Daemon.new(:server => server, :log_file => log_fn, :timeout => 8)
36
33
 
37
34
  @daemon.startup false
38
- @daemon.should be_alive
35
+ expect(@daemon).to be_alive
39
36
  end
40
37
 
41
38
  it 'waits for a particular line to appear in the log file' do
@@ -44,7 +41,7 @@ describe Servolux::Daemon do
44
41
  @daemon = Servolux::Daemon.new(:server => server, :log_file => log_fn, :look_for => 'executing run loop [2]', :timeout => 8)
45
42
 
46
43
  @daemon.startup false
47
- @daemon.should be_alive
44
+ expect(@daemon).to be_alive
48
45
  end
49
46
 
50
47
  it 'raises an error if the startup timeout is exceeded' do
@@ -52,10 +49,7 @@ describe Servolux::Daemon do
52
49
  server.extend TestServer
53
50
  @daemon = Servolux::Daemon.new(:server => server, :log_file => log_fn, :look_for => 'executing run loop [42]', :timeout => 4)
54
51
 
55
- lambda { @daemon.startup }.should raise_error(Servolux::Daemon::Timeout)
52
+ expect { @daemon.startup }.to raise_error(Servolux::Daemon::Timeout)
56
53
  end
57
-
58
54
  end
59
-
60
55
  end # if Servolux.fork?
61
-
@@ -1,10 +1,7 @@
1
-
2
1
  require File.expand_path('../spec_helper', __FILE__)
3
2
 
4
3
  if Servolux.fork?
5
-
6
4
  describe Servolux::Piper do
7
-
8
5
  before :each do
9
6
  @piper = nil
10
7
  end
@@ -18,15 +15,16 @@ describe Servolux::Piper do
18
15
 
19
16
  it 'only understands three file modes' do
20
17
  %w[r w rw].each do |mode|
21
- lambda {
18
+ expect {
22
19
  piper = Servolux::Piper.new(mode)
23
20
  piper.child { piper.close; exit! }
24
21
  piper.parent { piper.close }
25
- }.should_not raise_error
22
+ }.not_to raise_error
26
23
  end
27
24
 
28
- lambda { Servolux::Piper.new('f') }.should raise_error(
29
- ArgumentError, 'Unsupported mode "f"')
25
+ expect {
26
+ Servolux::Piper.new('f')
27
+ }.to raise_error(ArgumentError, 'Unsupported mode "f"')
30
28
  end
31
29
 
32
30
  it 'enables communication between parents and children' do
@@ -45,23 +43,23 @@ describe Servolux::Piper do
45
43
 
46
44
  @piper.parent {
47
45
  @piper.puts 'foo bar baz'
48
- @piper.gets.should be == 'foo bar baz'
46
+ expect(@piper.gets).to eq('foo bar baz')
49
47
 
50
48
  @piper.puts %w[one two three]
51
- @piper.gets.should be == %w[one two three]
49
+ expect(@piper.gets).to eq(%w[one two three])
52
50
 
53
- @piper.puts('Returns # of bytes written').should be > 0
54
- @piper.gets.should be == 'Returns # of bytes written'
51
+ expect(@piper.puts('Returns # of bytes written')).to be > 0
52
+ expect(@piper.gets).to eq('Returns # of bytes written')
55
53
 
56
54
  @piper.puts 1
57
55
  @piper.puts 2
58
56
  @piper.puts 3
59
- @piper.gets.should be == 1
60
- @piper.gets.should be == 2
61
- @piper.gets.should be == 3
57
+ expect(@piper.gets).to eq(1)
58
+ expect(@piper.gets).to eq(2)
59
+ expect(@piper.gets).to eq(3)
62
60
 
63
61
  @piper.timeout = 0.1
64
- @piper.readable?.should be_false
62
+ expect(@piper).not_to be_readable
65
63
  }
66
64
  end
67
65
 
@@ -82,13 +80,13 @@ describe Servolux::Piper do
82
80
  }
83
81
 
84
82
  @piper.parent {
85
- @piper.gets.should be == :ready
83
+ expect(@piper.gets).to eq(:ready)
86
84
 
87
85
  @piper.signal 'USR2'
88
- @piper.gets.should be == "'USR2' was received"
86
+ expect(@piper.gets).to eq("'USR2' was received")
89
87
 
90
88
  @piper.signal 'INT'
91
- @piper.gets.should be == "'INT' was received"
89
+ expect(@piper.gets).to eq("'INT' was received")
92
90
  }
93
91
  end
94
92
 
@@ -102,10 +100,9 @@ describe Servolux::Piper do
102
100
  }
103
101
 
104
102
  @piper.parent {
105
- @piper.gets.should_not == Process.pid
103
+ expect(@piper.gets).not_to eq(Process.pid)
106
104
  }
107
105
  end
108
-
109
106
  end
110
107
  end # if Servolux.fork?
111
108
 
@@ -1,13 +1,10 @@
1
-
2
1
  require File.expand_path('../spec_helper', __FILE__)
3
2
  require 'tempfile'
4
3
  require 'fileutils'
5
4
  require 'enumerator'
6
5
 
7
6
  if Servolux.fork?
8
-
9
7
  describe Servolux::Prefork do
10
-
11
8
  def pids
12
9
  workers.map! { |w| w.pid }
13
10
  end
@@ -34,17 +31,17 @@ describe Servolux::Prefork do
34
31
 
35
32
  before :all do
36
33
  tmp = Tempfile.new 'servolux-prefork'
37
- @path = path = tmp.path; tmp.unlink
34
+ @path = tmp.path; tmp.unlink
38
35
  @glob = @path + '/*.txt'
39
36
  FileUtils.mkdir @path
40
37
 
41
- @worker = Module.new {
42
- define_method(:before_executing) { @fd = File.open(path + "/#$$.txt", 'w') }
38
+ @worker = Module.new do
39
+ def before_executing() @fd = File.open("#{config[:path]}/#$$.txt", 'w'); end
43
40
  def after_executing() @fd.close; FileUtils.rm_f @fd.path; end
44
41
  def execute() @fd.puts Time.now; sleep 2; end
45
42
  def hup() @thread.wakeup; end
46
43
  alias :term :hup
47
- }
44
+ end
48
45
  end
49
46
 
50
47
  after :all do
@@ -65,51 +62,51 @@ describe Servolux::Prefork do
65
62
  end
66
63
 
67
64
  it "starts up a single worker" do
68
- @prefork = Servolux::Prefork.new :module => @worker
65
+ @prefork = Servolux::Prefork.new :module => @worker, :config => {:path => @path}
69
66
  @prefork.start 1
70
67
  ary = workers
71
68
  sleep 0.1 until ary.all? { |w| w.alive? }
72
69
  sleep 0.1 until worker_count >= 1
73
70
 
74
71
  ary = Dir.glob(@glob)
75
- ary.length.should be == 1
76
- File.basename(ary.first).to_i.should be == pids.first
72
+ expect(ary.length).to eq(1)
73
+ expect(File.basename(ary.first).to_i).to eq(pids.first)
77
74
  end
78
75
 
79
76
  it "starts up a number of workers" do
80
- @prefork = Servolux::Prefork.new :module => @worker
77
+ @prefork = Servolux::Prefork.new :module => @worker, :config => {:path => @path}
81
78
  @prefork.start 8
82
79
  ary = workers
83
80
  sleep 0.250 until ary.all? { |w| w.alive? }
84
81
  sleep 0.250 until worker_count >= 8
85
82
 
86
83
  ary = Dir.glob(@glob)
87
- ary.length.should be == 8
84
+ expect(ary.length).to eq(8)
88
85
 
89
86
  ary.map! { |fn| File.basename(fn).to_i }.sort!
90
- ary.should be == pids.sort
87
+ expect(ary).to eq(pids.sort)
91
88
  end
92
89
 
93
90
  it "stops workers gracefullly" do
94
- @prefork = Servolux::Prefork.new :module => @worker
91
+ @prefork = Servolux::Prefork.new :module => @worker, :config => {:path => @path}
95
92
  @prefork.start 3
96
93
  ary = workers
97
94
  sleep 0.250 until ary.all? { |w| w.alive? }
98
95
  sleep 0.250 until worker_count >= 3
99
96
 
100
97
  ary = Dir.glob(@glob)
101
- ary.length.should be == 3
98
+ expect(ary.length).to eq(3)
102
99
 
103
100
  @prefork.stop
104
101
  sleep 0.250 until Dir.glob(@glob).length == 0
105
102
  workers.each { |w| w.wait rescue nil }
106
103
 
107
104
  rv = workers.all? { |w| !w.alive? }
108
- rv.should be == true
105
+ expect(rv).to be true
109
106
  end
110
107
 
111
108
  it "restarts a worker via SIGHUP" do
112
- @prefork = Servolux::Prefork.new :module => @worker
109
+ @prefork = Servolux::Prefork.new :module => @worker, :config => {:path => @path}
113
110
  @prefork.start 2
114
111
  ary = workers
115
112
  sleep 0.250 until ary.all? { |w| w.alive? }
@@ -120,11 +117,11 @@ describe Servolux::Prefork do
120
117
  @prefork.reap until !alive? pid
121
118
  sleep 0.250 until ary.all? { |w| w.alive? }
122
119
 
123
- pid.should_not == pids.last
120
+ expect(pid).not_to eq(pids.last)
124
121
  end
125
122
 
126
123
  it "starts up a stopped worker" do
127
- @prefork = Servolux::Prefork.new :module => @worker
124
+ @prefork = Servolux::Prefork.new :module => @worker, :config => {:path => @path}
128
125
  @prefork.start 2
129
126
  ary = workers
130
127
  sleep 0.250 until ary.all? { |w| w.alive? }
@@ -138,11 +135,11 @@ describe Servolux::Prefork do
138
135
  worker.start unless worker.alive?
139
136
  end
140
137
  sleep 0.250 until ary.all? { |w| w.alive? }
141
- pid.should_not == pids.last
138
+ expect(pid).not_to eq(pids.last)
142
139
  end
143
140
 
144
141
  it "adds a new worker to the worker pool" do
145
- @prefork = Servolux::Prefork.new :module => @worker
142
+ @prefork = Servolux::Prefork.new :module => @worker, :config => {:path => @path}
146
143
  @prefork.start 2
147
144
  ary = workers
148
145
  sleep 0.250 until ary.all? { |w| w.alive? }
@@ -151,11 +148,11 @@ describe Servolux::Prefork do
151
148
 
152
149
  @prefork.add_workers( 2 )
153
150
  sleep 0.250 until worker_count >= 4
154
- workers.size.should == 4
151
+ expect(workers.size).to eq(4)
155
152
  end
156
153
 
157
154
  it "only adds workers up to the max_workers value" do
158
- @prefork = Servolux::Prefork.new :module => @worker, :max_workers => 3
155
+ @prefork = Servolux::Prefork.new :module => @worker, :max_workers => 3, :config => {:path => @path}
159
156
  @prefork.start 2
160
157
  ary = workers
161
158
  sleep 0.250 until ary.all? { |w| w.alive? }
@@ -163,11 +160,11 @@ describe Servolux::Prefork do
163
160
 
164
161
  @prefork.add_workers( 2 )
165
162
  sleep 0.250 until worker_count >= 3
166
- workers.size.should == 3
163
+ expect(workers.size).to eq(3)
167
164
  end
168
165
 
169
166
  it "prunes workers that are no longer running" do
170
- @prefork = Servolux::Prefork.new :module => @worker
167
+ @prefork = Servolux::Prefork.new :module => @worker, :config => {:path => @path}
171
168
  @prefork.start 2
172
169
  ary = workers
173
170
  sleep 0.250 until ary.all? { |w| w.alive? }
@@ -175,17 +172,17 @@ describe Servolux::Prefork do
175
172
 
176
173
  @prefork.add_workers( 2 )
177
174
  sleep 0.250 until worker_count >= 3
178
- workers.size.should be == 4
175
+ expect(workers.size).to eq(4)
179
176
 
180
177
  workers[0].stop
181
178
  sleep 0.250 while workers[0].alive?
182
179
 
183
180
  @prefork.prune_workers
184
- workers.size.should be == 3
181
+ expect(workers.size).to eq(3)
185
182
  end
186
183
 
187
184
  it "ensures that there are minimum number of workers" do
188
- @prefork = Servolux::Prefork.new :module => @worker, :min_workers => 3
185
+ @prefork = Servolux::Prefork.new :module => @worker, :min_workers => 3, :config => {:path => @path}
189
186
  @prefork.start 1
190
187
  ary = workers
191
188
  sleep 0.250 until ary.all? { |w| w.alive? }
@@ -193,8 +190,7 @@ describe Servolux::Prefork do
193
190
 
194
191
  @prefork.ensure_worker_pool_size
195
192
  sleep 0.250 until worker_count >= 3
196
- workers.size.should be == 3
193
+ expect(workers.size).to eq(3)
197
194
  end
198
195
  end
199
196
  end # Servolux.fork?
200
-
@@ -26,54 +26,54 @@ describe Servolux::Server do
26
26
  end
27
27
 
28
28
  it 'generates a PID file' do
29
- test(?e, @server.pid_file).should be_false
29
+ expect(test(?e, @server.pid_file)).to be false
30
30
 
31
31
  t = Thread.new {@server.startup}
32
32
  wait_until { @server.running? and t.status == 'sleep' }
33
- test(?e, @server.pid_file).should be_true
33
+ expect(test(?e, @server.pid_file)).to be true
34
34
 
35
35
  @server.shutdown
36
36
  wait_until { t.status == false }
37
- test(?e, @server.pid_file).should be_false
37
+ expect(test(?e, @server.pid_file)).to be false
38
38
  end
39
39
 
40
40
  it 'generates a PID file with mode rw-r----- by default' do
41
41
  t = Thread.new {@server.startup}
42
42
  wait_until { @server.running? and t.status == 'sleep' }
43
- test(?e, @server.pid_file).should be_true
43
+ expect(test(?e, @server.pid_file)).to be true
44
44
 
45
- @log_output.readline.chomp.should be == %q(DEBUG Servolux : Server "Test Server" creating pid file "test_server.pid")
46
- @log_output.readline.chomp.should be == %q(DEBUG Servolux : Starting)
47
- (File.stat(@server.pid_file).mode & 0777).should be == 0640
45
+ expect(@log_output.readline.chomp).to eq(%q(DEBUG Servolux : Server "Test Server" creating pid file "test_server.pid"))
46
+ expect(@log_output.readline.chomp).to eq(%q(DEBUG Servolux : Starting))
47
+ expect(File.stat(@server.pid_file).mode & 0777).to eq(0640)
48
48
 
49
49
  @server.shutdown
50
50
  wait_until { t.status == false }
51
- test(?e, @server.pid_file).should be_false
51
+ expect(test(?e, @server.pid_file)).to be false
52
52
  end
53
53
 
54
54
  it 'generates PID file with the specified permissions' do
55
55
  @server.pid_file_mode = 0400
56
56
  t = Thread.new {@server.startup}
57
57
  wait_until { @server.running? and t.status == 'sleep' }
58
- test(?e, @server.pid_file).should be_true
58
+ expect(test(?e, @server.pid_file)).to be true
59
59
 
60
- @log_output.readline.chomp.should be == %q(DEBUG Servolux : Server "Test Server" creating pid file "test_server.pid")
61
- @log_output.readline.chomp.should be == %q(DEBUG Servolux : Starting)
62
- (File.stat(@server.pid_file).mode & 0777).should be == 0400
60
+ expect(@log_output.readline.chomp).to eq(%q(DEBUG Servolux : Server "Test Server" creating pid file "test_server.pid"))
61
+ expect(@log_output.readline.chomp).to eq(%q(DEBUG Servolux : Starting))
62
+ expect(File.stat(@server.pid_file).mode & 0777).to eq(0400)
63
63
 
64
64
  @server.shutdown
65
65
  wait_until { t.status == false }
66
- test(?e, @server.pid_file).should be_false
66
+ expect(test(?e, @server.pid_file)).to be false
67
67
  end
68
68
 
69
69
  it 'shuts down gracefully when signaled' do
70
70
  t = Thread.new {@server.startup}
71
71
  wait_until { @server.running? and t.status == 'sleep' }
72
- @server.should be_running
72
+ expect(@server).to be_running
73
73
 
74
74
  `kill -SIGINT #{$$}`
75
75
  wait_until { t.status == false }
76
- @server.should_not be_running
76
+ expect(@server).to_not be_running
77
77
  end
78
78
 
79
79
  it 'responds to signals that have defined handlers' do
@@ -86,29 +86,50 @@ describe Servolux::Server do
86
86
  t = Thread.new {@server.startup}
87
87
  wait_until { @server.running? and t.status == 'sleep' }
88
88
  @log_output.readline
89
- @log_output.readline.strip.should be == 'DEBUG Servolux : Starting'
89
+ expect(@log_output.readline.strip).to eq('DEBUG Servolux : Starting')
90
90
 
91
91
  line = nil
92
92
  Process.kill 'SIGUSR1', $$
93
93
  wait_until { line = @log_output.readline }
94
- line.should_not be_nil
95
- line.strip.should be == 'INFO Servolux : usr1 was called'
94
+ expect(line).to_not be_nil
95
+ expect(line.strip).to eq('INFO Servolux : usr1 was called')
96
96
 
97
97
  line = nil
98
98
  Process.kill 'SIGHUP', $$
99
99
  wait_until { line = @log_output.readline }
100
- line.should_not be_nil
101
- line.strip.should be == 'INFO Servolux : hup was called'
100
+ expect(line).to_not be_nil
101
+ expect(line.strip).to eq('INFO Servolux : hup was called')
102
102
 
103
103
  line = nil
104
104
  Process.kill 'SIGUSR2', $$
105
105
  wait_until { line = @log_output.readline }
106
- line.should_not be_nil
107
- line.strip.should be == 'INFO Servolux : usr2 was called'
106
+ expect(line).to_not be_nil
107
+ expect(line.strip).to eq('INFO Servolux : usr2 was called')
108
108
 
109
109
  Process.kill 'SIGTERM', $$
110
110
  wait_until { t.status == false }
111
- @server.should_not be_running
111
+ expect(@server).to_not be_running
112
112
  end
113
- end
114
113
 
114
+ it 'captures exceptions raised by the signal handlers' do
115
+ class << @server
116
+ def usr2() raise 'Ooops!'; end
117
+ end
118
+
119
+ t = Thread.new {@server.startup}
120
+ wait_until { @server.running? and t.status == 'sleep' }
121
+ @log_output.readline
122
+ expect(@log_output.readline.strip).to eq('DEBUG Servolux : Starting')
123
+
124
+ line = nil
125
+ Process.kill 'SIGUSR2', $$
126
+ wait_until { line = @log_output.readline }
127
+ expect(line).to_not be_nil
128
+ expect(line.strip).to eq('ERROR Servolux : Exception in signal handler: usr2')
129
+
130
+ line = nil
131
+ wait_until { line = @log_output.readline }
132
+ expect(line).to_not be_nil
133
+ expect(line.strip).to eq('ERROR Servolux : <RuntimeError> Ooops!')
134
+ end
135
+ end