svdir 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.
Files changed (56) hide show
  1. data/CHANGELOG +29 -0
  2. data/LICENSE +19 -0
  3. data/README +67 -0
  4. data/Rakefile +66 -0
  5. data/example/svctl +117 -0
  6. data/lib/sys/sv/statusbytes.rb +53 -0
  7. data/lib/sys/sv/svdir.rb +224 -0
  8. data/lib/sys/sv/util.rb +36 -0
  9. data/test/fixtures/PrefabSvDir.rb +22 -0
  10. data/test/fixtures/TempSvDir.rb +62 -0
  11. data/test/services/corrupt-normd/down +0 -0
  12. data/test/services/corrupt-normd/supervise/ok +0 -0
  13. data/test/services/corrupt-normd/supervise/status +0 -0
  14. data/test/services/corrupt-normu/supervise/ok +0 -0
  15. data/test/services/corrupt-normu/supervise/status +0 -0
  16. data/test/services/corrupt-zero-normd/down +0 -0
  17. data/test/services/corrupt-zero-normd/supervise/ok +0 -0
  18. data/test/services/corrupt-zero-normd/supervise/status +0 -0
  19. data/test/services/corrupt-zero-normu/supervise/ok +0 -0
  20. data/test/services/corrupt-zero-normu/supervise/status +0 -0
  21. data/test/services/down-0-normd-nowant/down +0 -0
  22. data/test/services/down-0-normd-nowant/supervise/ok +0 -0
  23. data/test/services/down-0-normd-nowant/supervise/status +0 -0
  24. data/test/services/down-0-normu-nowant/supervise/ok +0 -0
  25. data/test/services/down-0-normu-nowant/supervise/status +0 -0
  26. data/test/services/up-12526-normu-wantd/supervise/ok +0 -0
  27. data/test/services/up-12526-normu-wantd/supervise/status +0 -0
  28. data/test/services/up-12581-normd-wantd-paused/down +0 -0
  29. data/test/services/up-12581-normd-wantd-paused/supervise/ok +0 -0
  30. data/test/services/up-12581-normd-wantd-paused/supervise/status +0 -0
  31. data/test/services/up-12581-normu-wantd-paused/supervise/ok +0 -0
  32. data/test/services/up-12581-normu-wantd-paused/supervise/status +0 -0
  33. data/test/services/up-12816-normd-nowant/down +0 -0
  34. data/test/services/up-12816-normd-nowant/supervise/ok +0 -0
  35. data/test/services/up-12816-normd-nowant/supervise/status +0 -0
  36. data/test/services/up-12816-normu-nowant/supervise/ok +0 -0
  37. data/test/services/up-12816-normu-nowant/supervise/status +0 -0
  38. data/test/services/up-12868-normd-wantu-paused/down +0 -0
  39. data/test/services/up-12868-normd-wantu-paused/supervise/ok +0 -0
  40. data/test/services/up-12868-normd-wantu-paused/supervise/status +0 -0
  41. data/test/services/up-12868-normd-wantu/down +0 -0
  42. data/test/services/up-12868-normd-wantu/supervise/ok +0 -0
  43. data/test/services/up-12868-normd-wantu/supervise/status +0 -0
  44. data/test/services/up-12868-normu-wantu-paused/supervise/ok +0 -0
  45. data/test/services/up-12868-normu-wantu-paused/supervise/status +0 -0
  46. data/test/services/up-12868-normu-wantu/supervise/ok +0 -0
  47. data/test/services/up-12868-normu-wantu/supervise/status +0 -0
  48. data/test/services/up-16464-normd-wantd/down +0 -0
  49. data/test/services/up-16464-normd-wantd/supervise/ok +0 -0
  50. data/test/services/up-16464-normd-wantd/supervise/status +0 -0
  51. data/test/testbase.rb +30 -0
  52. data/test/ts_corrupt.rb +133 -0
  53. data/test/ts_nosupervisor.rb +81 -0
  54. data/test/ts_signal.rb +128 -0
  55. data/test/ts_svstat.rb +548 -0
  56. metadata +117 -0
@@ -0,0 +1,36 @@
1
+ #
2
+ # Author:: Mike Pomraning
3
+ # Copyright:: Copyright (c) 2011 Qualys, Inc.
4
+ # License:: MIT (see the file LICENSE)
5
+ #
6
+
7
+ require 'fcntl' # O_RDONLY | O_NONBLOCK
8
+
9
+ module Sys # :nodoc:
10
+ module Sv # :nodoc:
11
+
12
+ module Util #:nodoc:
13
+ def self.open_read(fn, &p)
14
+ open_nonblock(fn, Fcntl::O_RDONLY, p)
15
+ end
16
+
17
+ def self.open_write(fn, &p)
18
+ open_nonblock(fn, Fcntl::O_WRONLY, p)
19
+ end
20
+
21
+ private
22
+ def self.open_nonblock(fn, mode, p)
23
+ mode |= Fcntl::O_NONBLOCK
24
+ return File.open(fn, mode) if p.nil?
25
+
26
+ begin
27
+ f = File.open(fn, mode)
28
+ return p.call(f)
29
+ ensure
30
+ f.close if f
31
+ end
32
+ end
33
+ end #-- module Util
34
+
35
+ end #-- module Sv
36
+ end #-- module Sys
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Author:: Mike Pomraning
4
+ # Copyright:: Copyright (c) 2011 Qualys, Inc.
5
+ # License:: MIT (see the file LICENSE)
6
+
7
+ require 'sys/sv/svdir'
8
+
9
+ module Fixtures
10
+ module PrefabSvDir
11
+ # Test::Unit::TestCase helper to recognize "static" supervisory
12
+ # directories.
13
+ def setup
14
+ dirname = self.class.name.gsub(/^TC_/, '').tr('_', '-')
15
+ dirname = File.join(File.dirname(__FILE__), '..', 'services', dirname)
16
+
17
+ raise RuntimeError.new("Expected static testing dir #{dirname} not found") unless File.directory? dirname
18
+ @svdir = Sys::Sv::SvDir.new dirname
19
+ super
20
+ end
21
+ end
22
+ end # -- module Fixtures
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Author:: Mike Pomraning
4
+ # Copyright:: Copyright (c) 2011 Qualys, Inc.
5
+ # License:: MIT (see the file LICENSE)
6
+
7
+ require 'tmpdir' # Dir.tmpdir
8
+ require 'fileutils' # FileUtils.rm_rf
9
+ require 'sys/sv/svdir'
10
+
11
+ module Fixtures
12
+ module TempSvDir
13
+ # Test::Unit::TestCase mixin to create one-off service directories
14
+
15
+ # Make a temp sv-style dir with supervise/ subdir and two FIFOs
16
+ def setup
17
+ i = 0
18
+
19
+ # make a temporary dir
20
+ begin
21
+ @svdirname = File.join(Dir::tmpdir, "TempSvDir.#{$$}.#{i}")
22
+ i += 1
23
+ Dir::mkdir(@svdirname)
24
+ rescue Errno::EEXIST
25
+ retry if i < 100
26
+ raise RuntimeError.new("Unable to create a mock svc dir. Check #{Dir::tmpdir}")
27
+ end
28
+
29
+ Dir::mkdir File.join(@svdirname, "supervise")
30
+
31
+ # Make and hold open our FIFOs
32
+ @fifos = {}
33
+ for fn in %w(control ok)
34
+ @fifos[ fn.to_sym ] = openfifo(File.join(@svdirname, "supervise", fn))
35
+ end
36
+
37
+ @svdir = Sys::Sv::SvDir.new(@svdirname)
38
+ super
39
+ end
40
+
41
+ def fifo_control
42
+ @fifos[:control]
43
+ end
44
+
45
+ def fifo_ok
46
+ @fifos[:ok]
47
+ end
48
+
49
+ def teardown
50
+ @fifos.each_value {|f| f.close rescue nil}
51
+ FileUtils.rm_rf( @svdirname )
52
+ super
53
+ end
54
+
55
+ private
56
+ def openfifo(fn)
57
+ system "mkfifo #{Regexp.quote(fn)}"
58
+ File.open(fn, Fcntl::O_NONBLOCK|Fcntl::O_RDONLY)
59
+ end
60
+ end
61
+
62
+ end # -- module Fixtures
File without changes
File without changes
File without changes
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Author:: Mike Pomraning
4
+ # Copyright:: Copyright (c) 2011 Qualys, Inc.
5
+ # License:: MIT (see the file LICENSE)
6
+
7
+ require 'test/unit'
8
+
9
+ class Test::Unit::TestCase
10
+ # Load the appropriate Fixtures::Blah
11
+ def self.include_fixtures(sym, *optional)
12
+ raise RuntimeError.new("Must subclass Test::Unit::TestCase") \
13
+ if self == Test::Unit::TestCase
14
+
15
+ for s in [sym, *optional]
16
+ load "fixtures/#{sym}.rb"
17
+ self.__send__(:include, Module.const_get(:Fixtures).const_get(sym))
18
+ end
19
+
20
+ end
21
+
22
+ def self.include_fixture(sym)
23
+ include_fixtures(sym)
24
+ end
25
+
26
+ def assert_elapsed_time(elapsed)
27
+ assert_kind_of(::Float, elapsed, "elapsed time measurement was wrong type")
28
+ assert(elapsed > 0.0, "elapsed time measurement was not > 0")
29
+ end
30
+ end
@@ -0,0 +1,133 @@
1
+ # Test the basics of service status interrogation
2
+ #
3
+ # Author:: Mike Pomraning
4
+ # Copyright:: Copyright (c) 2011 Qualys, Inc.
5
+ # License:: MIT (see the file LICENSE)
6
+ #
7
+
8
+ require 'testbase'
9
+ require 'sys/sv/svdir'
10
+
11
+ class TC_corrupt_normu < Test::Unit::TestCase
12
+ include_fixture :PrefabSvDir
13
+
14
+ def test_down?
15
+ assert_raise(::Errno::EPROTO) do
16
+ @svdir.down?
17
+ end
18
+ end
19
+
20
+ def test_want_up?
21
+ assert_raise(::Errno::EPROTO) do
22
+ @svdir.want_up?
23
+ end
24
+ end
25
+
26
+ def test_pid
27
+ assert_raise(::Errno::EPROTO) do
28
+ @svdir.pid
29
+ end
30
+ end
31
+
32
+ def test_want_down?
33
+ assert_raise(::Errno::EPROTO) do
34
+ @svdir.want_down?
35
+ end
36
+ end
37
+
38
+ def test_normally_up?
39
+ assert(@svdir.normally_up?, "normally_up? should still succeed even on corrupted SvDir")
40
+ end
41
+
42
+ def test_paused?
43
+ assert_raise(::Errno::EPROTO) do
44
+ @svdir.paused?
45
+ end
46
+ end
47
+
48
+ def test_normally_down?
49
+ assert(!@svdir.normally_down?, "normally_down? should still succeed even on corrupted SvDir")
50
+ end
51
+
52
+ def test_up?
53
+ assert_raise(::Errno::EPROTO) do
54
+ @svdir.up?
55
+ end
56
+ end
57
+
58
+ def test_downtime
59
+ assert_raise(::Errno::EPROTO) do
60
+ @svdir.downtime
61
+ end
62
+ end
63
+
64
+ def test_uptime
65
+ assert_raise(::Errno::EPROTO) do
66
+ @svdir.uptime
67
+ end
68
+ end
69
+ end
70
+
71
+ class TC_corrupt_normd < Test::Unit::TestCase
72
+ include_fixture :PrefabSvDir
73
+
74
+ def test_down?
75
+ assert_raise(::Errno::EPROTO) do
76
+ @svdir.down?
77
+ end
78
+ end
79
+
80
+ def test_want_up?
81
+ assert_raise(::Errno::EPROTO) do
82
+ @svdir.want_up?
83
+ end
84
+ end
85
+
86
+ def test_pid
87
+ assert_raise(::Errno::EPROTO) do
88
+ @svdir.pid
89
+ end
90
+ end
91
+
92
+ def test_want_down?
93
+ assert_raise(::Errno::EPROTO) do
94
+ @svdir.want_down?
95
+ end
96
+ end
97
+
98
+ def test_normally_up?
99
+ assert(!@svdir.normally_up?, "normally_up? should still succeed even on corrupted SvDir")
100
+ end
101
+
102
+ def test_paused?
103
+ assert_raise(::Errno::EPROTO) do
104
+ @svdir.paused?
105
+ end
106
+ end
107
+
108
+ def test_normally_down?
109
+ assert(@svdir.normally_down?, "normally_down? should still succeed even on corrupted SvDir")
110
+ end
111
+
112
+ def test_up?
113
+ assert_raise(::Errno::EPROTO) do
114
+ @svdir.up?
115
+ end
116
+ end
117
+
118
+ def test_downtime
119
+ assert_raise(::Errno::EPROTO) do
120
+ @svdir.downtime
121
+ end
122
+ end
123
+
124
+ def test_uptime
125
+ assert_raise(::Errno::EPROTO) do
126
+ @svdir.uptime
127
+ end
128
+ end
129
+ end
130
+
131
+ # Zero-byte status files take a slightly different code path to reach EPROTO
132
+ class TC_corrupt_zero_normd < TC_corrupt_normd; end
133
+ class TC_corrupt_zero_normu < TC_corrupt_normu; end
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Handle the case of no supervisor running
4
+ #
5
+ # Author:: Mike Pomraning
6
+ # Copyright:: Copyright (c) 2011 Qualys, Inc.
7
+ # License:: MIT (see the file LICENSE)
8
+ #
9
+
10
+ $:.unshift File.join(File.dirname(__FILE__), "lib")
11
+
12
+ require 'testbase'
13
+ require 'sys/sv/svdir'
14
+
15
+ class TestSvcNoSupervisor < Test::Unit::TestCase
16
+
17
+ include_fixture :TempSvDir
18
+
19
+ def setup
20
+ ret = super
21
+ # close .../control and .../ok
22
+ fifo_control.close
23
+ fifo_ok.close
24
+ ret
25
+ end
26
+
27
+ # Verify that unknown signal arguments still throw ArgumentError
28
+ def test_signal_unknown
29
+ [ :invalid, 'invalid' ].each do |bogus|
30
+ assert_raise ArgumentError do
31
+ @svdir.signal bogus
32
+ end
33
+ end
34
+ end
35
+
36
+ # Verify that a known signal generates ENXIO
37
+ def test_signal_up
38
+ [ :up, 'up' ].each do |c|
39
+ assert_raise Errno::ENXIO do
40
+ @svdir.signal c
41
+ end
42
+ end
43
+ end
44
+
45
+ # Verify svok? == false
46
+ def test_not_svok
47
+ assert @svdir.svok? == false
48
+ end
49
+
50
+ # Verify that the StatusBytes delegates throw ENXIO
51
+ [:down?, :downtime, :paused?, :pid, :up?, :uptime, :want_down?, :want_up?].
52
+ each do |m|
53
+ define_method "test_err_#{m}" do
54
+ assert_raise Errno::ENXIO do
55
+ @svdir.__send__(m)
56
+ end
57
+ end
58
+ end
59
+
60
+ # Verify that normally_up? still functions
61
+ def test_normally_up?
62
+ assert_nothing_raised do
63
+ @svdir.normally_up?
64
+ end
65
+ end
66
+
67
+ # Verify that normally_down? still functions
68
+ def test_normally_down?
69
+ assert_nothing_raised do
70
+ @svdir.normally_down?
71
+ end
72
+ end
73
+
74
+ # Verify that log() still functions
75
+ def test_normally_down?
76
+ assert_nothing_raised do
77
+ @svdir.log
78
+ end
79
+ end
80
+
81
+ end