svdir 0.2 → 0.2.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b4b6357ab1c95fa4608ee186cc532dae0e0f50e8317b54ee3e09cb2665feffa4
4
+ data.tar.gz: cda53444f8c7175634cc4bc8f95a796b6c8c51e0f47851e25eb0595eafe640aa
5
+ SHA512:
6
+ metadata.gz: 1a0e227bcbfd23d90398446612ae6742613b3f1c405606ed66aa08dae06cc2a26c1bcf6aa64ce5ae817b51333ef0e54f4e10631837ea807072739e4337a9ec0e
7
+ data.tar.gz: edf2e03c564aa99b0faa6e8d6c38abd43cc381434ab4e6a52206ee5061bcbb2658e62b5e982733b3b99c1c5f16203bc7986c6ab946876e91575abfc6fb940c08
data/CHANGELOG CHANGED
@@ -1,3 +1,12 @@
1
+ 2026-06-19 mjp version 0.2.1
2
+ [bug] Replace deprecated `File.exists?`/`Dir::mkdir`/`Dir::tmpdir` calls for
3
+ Ruby 3.2+ compatibility. Fix TAI64N nanosecond divisor (`10e9` → `1e9`).
4
+ [pkg] Modernize Rakefile, extract svdir.gemspec.
5
+ [tst] Fix duplicate test name and loop variable in test helpers. Add TAI64N
6
+ timestamp tests.
7
+ [int] Freeze mutable constants (`VERSION`, `Commands`).
8
+ [doc] Update copyright notices.
9
+
1
10
  2011-02-28 mjp version 0.2
2
11
  [doc] Documentation touch-up, move from Qualys SVN to github.
3
12
 
data/README CHANGED
@@ -1,5 +1,5 @@
1
+ Copyright (c) 2026 Mike Pomraning
1
2
  Copyright (c) 2010, 2011 Qualys, Inc.
2
-
3
3
  Copyright (c) 2008 - 2010 Nemean Networks, LLC.
4
4
 
5
5
  = Overview
@@ -54,14 +54,10 @@ generate module documentation.
54
54
 
55
55
  = To Do
56
56
 
57
- * Further testing
58
- - log()
59
- - TAI64 testing
60
-
61
57
  * Possible extensions
62
58
  - <tt>SvDir.new(d) &block</tt> - persist StatusBytes object for block?
63
59
  - <tt>normally_down!</tt> and <tt>normally_up!</tt>
64
60
 
65
61
  = Author
66
62
 
67
- Mike Pomraning ("mpomraning" at "qualys" dot "com")
63
+ Mike Pomraning ("mjp" at "pilcrow" dot "madison" dot "wi" dot "us")
data/Rakefile CHANGED
@@ -1,41 +1,19 @@
1
- require 'rubygems'
2
- require 'rake/gempackagetask'
3
- require 'rake/rdoctask'
1
+ require 'rubygems/package_task'
2
+ require 'rdoc/task'
4
3
  require 'rake/testtask'
5
4
 
6
- FILES = FileList['Rakefile', 'CHANGELOG', 'LICENSE', 'README',
7
- 'lib/**/*.rb', 'test/**/*', 'example/*'].to_a
8
- TESTS = FileList['test/ts_*.rb']
5
+ spec = Gem::Specification.load('svdir.gemspec')
9
6
 
10
- spec = Gem::Specification.new do |s|
11
- s.platform = Gem::Platform::RUBY
12
- s.author = "Mike Pomraning"
13
- s.summary = "An interface to service directories ala supervise/runsv"
14
- s.name = 'svdir'
15
- s.version = '0.2'
16
- s.require_path = 'lib'
17
- s.description = <<eodesc
18
- The svdir package controls service directories, a scheme for reliably
19
- controlling daemon processes as implemented in Dan Bernstein's daemontools
20
- software ("supervise") or Gerit Pape's runit software ("runsv").
21
- eodesc
22
- s.files = FILES
23
- s.test_files = TESTS
24
- s.has_rdoc = true
25
- end
26
-
27
- Rake::GemPackageTask.new(spec) do |pkg|
28
- pkg.package_dir = 'pkg'
29
- pkg.need_tar = true
7
+ Gem::PackageTask.new(spec) do |pkg|
8
+ pkg.package_dir = 'pkg'
9
+ pkg.need_tar = true
30
10
  end
31
11
 
32
12
  desc "Generate rdoc"
33
- Rake::RDocTask.new("rdoc") do |rdoc|
13
+ RDoc::Task.new("rdoc") do |rdoc|
34
14
  rdoc.rdoc_dir = 'doc/rdoc'
35
15
  rdoc.title = "svdir"
36
- # Show source inline with line numbers
37
16
  rdoc.options << "--inline-source" << "--line-numbers"
38
- # Make the readme file the start page for the generated html
39
17
  rdoc.options << '--main' << 'README'
40
18
  rdoc.rdoc_files.include('lib/**/*.rb',
41
19
  'CHANGELOG',
@@ -46,7 +24,7 @@ end
46
24
  desc "Run included tests"
47
25
  Rake::TestTask.new do |t|
48
26
  t.libs << "test"
49
- t.test_files = TESTS
27
+ t.test_files = Dir['test/ts_*.rb']
50
28
  t.libs << "lib"
51
29
  end
52
30
 
@@ -54,7 +32,7 @@ desc "Run test coverage (rcov)"
54
32
  begin
55
33
  require 'rcov/rcovtask'
56
34
  Rcov::RcovTask.new do |t|
57
- t.test_files = TESTS
35
+ t.test_files = Dir['test/ts_*.rb']
58
36
  t.libs << "test" << "lib"
59
37
  t.rcov_opts << '--exclude /gems/,/Library/,/usr/,spec,lib/tasks'
60
38
  end
@@ -1,6 +1,7 @@
1
1
  #
2
2
  # Author:: Mike Pomraning
3
3
  # Copyright:: Copyright (c) 2011 Qualys, Inc.
4
+ # Copyright:: Copyright (c) 2026 Mike Pomraning
4
5
  # License:: MIT (see the file LICENSE)
5
6
  #
6
7
 
@@ -42,7 +43,7 @@ module Sv # :nodoc:
42
43
  if @epoch <= 0
43
44
  @epoch = 0.0
44
45
  else
45
- @epoch += nano/10e9
46
+ @epoch += nano / 1e9
46
47
  end
47
48
 
48
49
  @epoch
data/lib/sys/sv/svdir.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  # Author:: Mike Pomraning
4
4
  # Copyright:: Copyright (c) 2011 Qualys, Inc.
5
+ # Copyright:: Copyright (c) 2026 Mike Pomraning
5
6
  # License:: MIT (see the file LICENSE)
6
7
  #
7
8
 
@@ -31,7 +32,7 @@ module Sv # :nodoc:
31
32
 
32
33
  class SvDir
33
34
 
34
- VERSION = '0.2'
35
+ VERSION = '0.2.1'.freeze
35
36
 
36
37
  attr_reader :path
37
38
 
@@ -55,6 +56,8 @@ module Sv # :nodoc:
55
56
  }.each do | cmds, byte |
56
57
  cmds.each { |c| h[c] = byte }
57
58
  end
59
+ h.each_value(&:freeze)
60
+ h.freeze
58
61
  const_set(:Commands, h)
59
62
  end
60
63
 
@@ -110,7 +113,7 @@ module Sv # :nodoc:
110
113
  # end
111
114
  def log
112
115
  fn = File.join(@path, 'log')
113
- return self.class.new(fn) if File.exists? fn
116
+ return self.class.new(fn) if File.directory? fn
114
117
  end
115
118
 
116
119
  # Returns +true+ if the service directory's _supervisor_ is running.
@@ -142,7 +145,7 @@ module Sv # :nodoc:
142
145
  #
143
146
  # See also the #want_down? method documentation.
144
147
  def normally_down?
145
- File.exists? File.join(@path, 'down')
148
+ File.exist? File.join(@path, 'down')
146
149
  end
147
150
 
148
151
  # Returns the number of seconds the service has been down,
data/lib/sys/sv/util.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  #
2
2
  # Author:: Mike Pomraning
3
3
  # Copyright:: Copyright (c) 2011 Qualys, Inc.
4
+ # Copyright:: Copyright (c) 2016 Mike Pomraning
4
5
  # License:: MIT (see the file LICENSE)
5
6
  #
6
7
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  # Author:: Mike Pomraning
4
4
  # Copyright:: Copyright (c) 2011 Qualys, Inc.
5
+ # Copyright:: Copyright (c) 2026 Mike Pomraning
5
6
  # License:: MIT (see the file LICENSE)
6
7
 
7
8
  require 'tmpdir' # Dir.tmpdir
@@ -18,15 +19,15 @@ module Fixtures
18
19
 
19
20
  # make a temporary dir
20
21
  begin
21
- @svdirname = File.join(Dir::tmpdir, "TempSvDir.#{$$}.#{i}")
22
+ @svdirname = File.join(Dir.tmpdir, "TempSvDir.#{$$}.#{i}")
22
23
  i += 1
23
- Dir::mkdir(@svdirname)
24
+ Dir.mkdir(@svdirname)
24
25
  rescue Errno::EEXIST
25
26
  retry if i < 100
26
- raise RuntimeError.new("Unable to create a mock svc dir. Check #{Dir::tmpdir}")
27
+ raise RuntimeError.new("Unable to create a mock svc dir. Check #{Dir.tmpdir}")
27
28
  end
28
29
 
29
- Dir::mkdir File.join(@svdirname, "supervise")
30
+ Dir.mkdir File.join(@svdirname, "supervise")
30
31
 
31
32
  # Make and hold open our FIFOs
32
33
  @fifos = {}
data/test/testbase.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  # Author:: Mike Pomraning
4
4
  # Copyright:: Copyright (c) 2011 Qualys, Inc.
5
+ # Copyright:: Copyright (c) 2026 Mike Pomraning
5
6
  # License:: MIT (see the file LICENSE)
6
7
 
7
8
  require 'test/unit'
@@ -13,8 +14,8 @@ class Test::Unit::TestCase
13
14
  if self == Test::Unit::TestCase
14
15
 
15
16
  for s in [sym, *optional]
16
- load "fixtures/#{sym}.rb"
17
- self.__send__(:include, Module.const_get(:Fixtures).const_get(sym))
17
+ load "fixtures/#{s}.rb"
18
+ self.__send__(:include, Module.const_get(:Fixtures).const_get(s))
18
19
  end
19
20
 
20
21
  end
@@ -4,6 +4,7 @@
4
4
  #
5
5
  # Author:: Mike Pomraning
6
6
  # Copyright:: Copyright (c) 2011 Qualys, Inc.
7
+ # Copyright:: Copyright (c) 2026 Mike Pomraning
7
8
  # License:: MIT (see the file LICENSE)
8
9
  #
9
10
 
@@ -72,7 +73,7 @@ class TestSvcNoSupervisor < Test::Unit::TestCase
72
73
  end
73
74
 
74
75
  # Verify that log() still functions
75
- def test_normally_down?
76
+ def test_log
76
77
  assert_nothing_raised do
77
78
  @svdir.log
78
79
  end
data/test/ts_tai64n.rb ADDED
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Test TAI64N timestamp parsing and the nanosecond field
4
+ #
5
+ # Author:: Mike Pomraning
6
+ # Copyright:: Copyright (c) 2026 Mike Pomraning
7
+ # License:: MIT (see the file LICENSE)
8
+ #
9
+
10
+ require 'testbase'
11
+ require 'sys/sv/statusbytes'
12
+
13
+ class TC_Tai64N < Test::Unit::TestCase
14
+ include Sys::Sv
15
+
16
+ # Build an 18-byte status buffer from a raw TAI64N timestamp.
17
+ # The 12-byte TAI64N label stores (tai64_secs) as an 8-byte big-endian
18
+ # uint64 split into hi/lo 32-bit words, plus nanoseconds as 4 bytes.
19
+ def make_status(tai64_hi, tai64_lo, nano, pid = 0, pause = 0, want = "\x00")
20
+ [tai64_hi, tai64_lo, nano].pack('NNN') +
21
+ [pid].pack('V') + [pause].pack('c') + [want].pack('a')
22
+ end
23
+
24
+ # The on-wire TAI64 value is: tai64 = unix_epoch + TAI_EPOCH
25
+ # where TAI_EPOCH = 2^62 + 10 (the TAI representation of Unix time 0).
26
+ # StatusBytes reverses this: unix_epoch = tai64 - TAI_EPOCH.
27
+ def tai64_from_unix(unix_epoch)
28
+ unix_epoch + StatusBytes::TAI_EPOCH
29
+ end
30
+
31
+ # split a 64-bit value into hi/lo 32-bit halves for big-endian packing
32
+ def hi32(val)
33
+ val >> 32
34
+ end
35
+
36
+ def lo32(val)
37
+ val & 0xFFFFFFFF
38
+ end
39
+
40
+ # Unix epoch 2009-02-13 23:31:20 +0000 = 1234567880
41
+ def test_known_timestamp
42
+ tai64 = tai64_from_unix(1234567880)
43
+ buf = make_status(hi32(tai64), lo32(tai64), 500_000_000)
44
+ sb = StatusBytes.new(buf)
45
+ assert_in_delta(1234567880.5, sb.epoch, 0.000_001)
46
+ end
47
+
48
+ # Zero nanoseconds
49
+ def test_zero_nano
50
+ tai64 = tai64_from_unix(1000)
51
+ buf = make_status(hi32(tai64), lo32(tai64), 0)
52
+ sb = StatusBytes.new(buf)
53
+ assert_in_delta(1000.0, sb.epoch, 0.000_001)
54
+ end
55
+
56
+ # Max nanoseconds (999999999)
57
+ def test_max_nano
58
+ tai64 = tai64_from_unix(1000)
59
+ buf = make_status(hi32(tai64), lo32(tai64), 999_999_999)
60
+ sb = StatusBytes.new(buf)
61
+ assert_in_delta(1000.999999999, sb.epoch, 0.000_001)
62
+ end
63
+
64
+ # elapsed returns a positive Float (epoch 0 edge case)
65
+ def test_elapsed
66
+ tai64 = tai64_from_unix(0)
67
+ buf = make_status(hi32(tai64), lo32(tai64), 500_000_000)
68
+ sb = StatusBytes.new(buf)
69
+ assert_kind_of(Float, sb.elapsed)
70
+ assert(sb.elapsed > 0)
71
+ end
72
+ end
metadata CHANGED
@@ -1,117 +1,101 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: svdir
3
- version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: "0.2"
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
6
5
  platform: ruby
7
- authors:
6
+ authors:
8
7
  - Mike Pomraning
9
- autorequire:
10
8
  bindir: bin
11
9
  cert_chain: []
12
-
13
- date: 2011-02-28 00:00:00 -06:00
14
- default_executable:
10
+ date: 1980-01-02 00:00:00.000000000 Z
15
11
  dependencies: []
16
-
17
12
  description: |
18
13
  The svdir package controls service directories, a scheme for reliably
19
14
  controlling daemon processes as implemented in Dan Bernstein's daemontools
20
15
  software ("supervise") or Gerit Pape's runit software ("runsv").
21
-
22
- email:
23
16
  executables: []
24
-
25
17
  extensions: []
26
-
27
18
  extra_rdoc_files: []
28
-
29
- files:
30
- - Rakefile
19
+ files:
31
20
  - CHANGELOG
32
21
  - LICENSE
33
22
  - README
34
- - lib/sys/sv/util.rb
23
+ - Rakefile
24
+ - example/svctl
35
25
  - lib/sys/sv/statusbytes.rb
36
26
  - lib/sys/sv/svdir.rb
37
- - test/services/corrupt-zero-normu/supervise/ok
38
- - test/services/corrupt-zero-normu/supervise/status
39
- - test/services/up-12816-normd-nowant/down
40
- - test/services/up-12816-normd-nowant/supervise/ok
41
- - test/services/up-12816-normd-nowant/supervise/status
42
- - test/services/up-16464-normd-wantd/down
43
- - test/services/up-16464-normd-wantd/supervise/ok
44
- - test/services/up-16464-normd-wantd/supervise/status
45
- - test/services/up-12868-normd-wantu/down
46
- - test/services/up-12868-normd-wantu/supervise/ok
47
- - test/services/up-12868-normd-wantu/supervise/status
48
- - test/services/down-0-normu-nowant/supervise/ok
49
- - test/services/down-0-normu-nowant/supervise/status
50
- - test/services/corrupt-normu/supervise/ok
51
- - test/services/corrupt-normu/supervise/status
27
+ - lib/sys/sv/util.rb
28
+ - test/fixtures/PrefabSvDir.rb
29
+ - test/fixtures/TempSvDir.rb
52
30
  - test/services/corrupt-normd/down
53
31
  - test/services/corrupt-normd/supervise/ok
54
32
  - test/services/corrupt-normd/supervise/status
55
- - test/services/up-12581-normd-wantd-paused/down
56
- - test/services/up-12581-normd-wantd-paused/supervise/ok
57
- - test/services/up-12581-normd-wantd-paused/supervise/status
58
- - test/services/up-12868-normu-wantu-paused/supervise/ok
59
- - test/services/up-12868-normu-wantu-paused/supervise/status
60
- - test/services/up-12581-normu-wantd-paused/supervise/ok
61
- - test/services/up-12581-normu-wantd-paused/supervise/status
33
+ - test/services/corrupt-normu/supervise/ok
34
+ - test/services/corrupt-normu/supervise/status
62
35
  - test/services/corrupt-zero-normd/down
63
36
  - test/services/corrupt-zero-normd/supervise/ok
64
37
  - test/services/corrupt-zero-normd/supervise/status
65
- - test/services/up-12868-normu-wantu/supervise/ok
66
- - test/services/up-12868-normu-wantu/supervise/status
67
- - test/services/up-12816-normu-nowant/supervise/ok
68
- - test/services/up-12816-normu-nowant/supervise/status
38
+ - test/services/corrupt-zero-normu/supervise/ok
39
+ - test/services/corrupt-zero-normu/supervise/status
69
40
  - test/services/down-0-normd-nowant/down
70
41
  - test/services/down-0-normd-nowant/supervise/ok
71
42
  - test/services/down-0-normd-nowant/supervise/status
43
+ - test/services/down-0-normu-nowant/supervise/ok
44
+ - test/services/down-0-normu-nowant/supervise/status
72
45
  - test/services/up-12526-normu-wantd/supervise/ok
73
46
  - test/services/up-12526-normu-wantd/supervise/status
47
+ - test/services/up-12581-normd-wantd-paused/down
48
+ - test/services/up-12581-normd-wantd-paused/supervise/ok
49
+ - test/services/up-12581-normd-wantd-paused/supervise/status
50
+ - test/services/up-12581-normu-wantd-paused/supervise/ok
51
+ - test/services/up-12581-normu-wantd-paused/supervise/status
52
+ - test/services/up-12816-normd-nowant/down
53
+ - test/services/up-12816-normd-nowant/supervise/ok
54
+ - test/services/up-12816-normd-nowant/supervise/status
55
+ - test/services/up-12816-normu-nowant/supervise/ok
56
+ - test/services/up-12816-normu-nowant/supervise/status
74
57
  - test/services/up-12868-normd-wantu-paused/down
75
58
  - test/services/up-12868-normd-wantu-paused/supervise/ok
76
59
  - test/services/up-12868-normd-wantu-paused/supervise/status
60
+ - test/services/up-12868-normd-wantu/down
61
+ - test/services/up-12868-normd-wantu/supervise/ok
62
+ - test/services/up-12868-normd-wantu/supervise/status
63
+ - test/services/up-12868-normu-wantu-paused/supervise/ok
64
+ - test/services/up-12868-normu-wantu-paused/supervise/status
65
+ - test/services/up-12868-normu-wantu/supervise/ok
66
+ - test/services/up-12868-normu-wantu/supervise/status
67
+ - test/services/up-16464-normd-wantd/down
68
+ - test/services/up-16464-normd-wantd/supervise/ok
69
+ - test/services/up-16464-normd-wantd/supervise/status
70
+ - test/testbase.rb
77
71
  - test/ts_corrupt.rb
78
- - test/fixtures/TempSvDir.rb
79
- - test/fixtures/PrefabSvDir.rb
72
+ - test/ts_nosupervisor.rb
80
73
  - test/ts_signal.rb
81
74
  - test/ts_svstat.rb
82
- - test/testbase.rb
83
- - test/ts_nosupervisor.rb
84
- - example/svctl
85
- has_rdoc: true
86
- homepage:
87
- licenses: []
88
-
89
- post_install_message:
75
+ - test/ts_tai64n.rb
76
+ licenses:
77
+ - MIT
78
+ metadata: {}
90
79
  rdoc_options: []
91
-
92
- require_paths:
80
+ require_paths:
93
81
  - lib
94
- required_ruby_version: !ruby/object:Gem::Requirement
95
- none: false
96
- requirements:
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
97
84
  - - ">="
98
- - !ruby/object:Gem::Version
99
- version: "0"
100
- required_rubygems_version: !ruby/object:Gem::Requirement
101
- none: false
102
- requirements:
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
103
89
  - - ">="
104
- - !ruby/object:Gem::Version
105
- version: "0"
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
106
92
  requirements: []
107
-
108
- rubyforge_project:
109
- rubygems_version: 1.5.0
110
- signing_key:
111
- specification_version: 3
93
+ rubygems_version: 3.6.9
94
+ specification_version: 4
112
95
  summary: An interface to service directories ala supervise/runsv
113
- test_files:
96
+ test_files:
114
97
  - test/ts_corrupt.rb
98
+ - test/ts_nosupervisor.rb
115
99
  - test/ts_signal.rb
116
100
  - test/ts_svstat.rb
117
- - test/ts_nosupervisor.rb
101
+ - test/ts_tai64n.rb