reckoner 0.4.0 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'mail'
data/History.txt CHANGED
@@ -1,3 +1,7 @@
1
+ === 0.9.0 / 2010-3-31
2
+ * Moving to github and gemcutter
3
+ * Switched to new 'mail' gem instead of rolling my own
4
+
1
5
  === 0.2.0 / 2009-06-19
2
6
 
3
7
  * Still more to do:
data/README.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  = reckoner
2
2
 
3
- * http://reckoner.rubyforge.com
3
+ * http://github.com/geoffk/reckoner
4
4
 
5
5
  == DESCRIPTION:
6
6
 
@@ -26,16 +26,16 @@ the CONFIG FILE argument or from stdin.
26
26
 
27
27
  *Options*
28
28
 
29
- -d --debug Output debugging information
30
-
31
- -q --quiet Suppress the check output
32
-
33
- -c --checks=FILE Specifies a Ruby file that contains
34
- additional checks that can be performed.
29
+ -d, --debug Output debugging information
30
+ -q, --quiet Do not print final report
31
+ -e, --email-off Do not send email, even if configured
32
+ -c, --checks=FILE Additional checks file
33
+ -s, --sample-config FILE Create a sample config named FILE
35
34
 
36
35
  == REQUIREMENTS:
37
36
 
38
37
  * Ruby
38
+ * Ruby 'mail' gem
39
39
 
40
40
  == INSTALL:
41
41
 
data/lib/main.rb CHANGED
@@ -2,13 +2,13 @@ require 'net/smtp'
2
2
  require 'rubygems'
3
3
  require 'yaml'
4
4
  require 'optparse'
5
- require 'ftools'
5
+ require 'fileutils'
6
+ require 'mail'
6
7
 
7
8
  require 'rfile.rb'
8
9
  require 'abstract_check.rb'
9
- require 'reckoner'
10
- require 'sendmail'
11
- require 'sample'
10
+ require 'reckoner.rb'
11
+ require 'sample.rb'
12
12
 
13
13
  =begin rdoc
14
14
  The Main class ties together the core Reckoner functionality
@@ -97,24 +97,25 @@ class Main
97
97
 
98
98
  def send_email(cm,mail_config)
99
99
  raise "Mail section must have a 'to' parameter" unless mail_config['to']
100
- mailobj = Sendmail.new(mail_config['sendmail_path'],
101
- mail_config['sendmail_options'])
102
100
 
103
- from = mail_config['from'] || ENV['USER']
104
101
  always_mail = mail_config['always_mail'] || true
105
- subject = mail_config['subject_prefix'] || 'Reckoner:'
106
- subject.strip!
107
- subject << ' '
102
+
103
+ mail = Mail.new
104
+ mail[:from] = mail_config['from'] || ENV['USER'] + '@' + ENV['HOSTNAME']
105
+ mail[:to] = mail_config['to']
106
+
107
+ prefix = mail_config['subject_prefix'] || 'Reckoner:'
108
+ prefix.strip
108
109
 
109
110
  if !cm.errors.empty?
110
- subject << "Found #{cm.errors.length} problem(s)"
111
- body = cm.errors.join("\n")
112
- mailobj.send(mail_config['to'],from,subject,body)
111
+ mail[:subject] = "#{prefix} Found #{cm.errors.length} problem(s)"
112
+ mail[:body] = cm.errors.join("\n")
113
113
  elsif always_mail
114
- subject << "No problems found"
115
- body = "No problems found"
116
- mailobj.send(mail_config['to'],from,subject,body)
114
+ mail[:subject] = "#{prefix} No problems found"
115
+ mail[:body] = "No problems found"
117
116
  end
117
+
118
+ mail.deliver!
118
119
  end
119
120
 
120
121
  def output_results(cm)
data/lib/reckoner.rb CHANGED
@@ -58,6 +58,8 @@ class Reckoner
58
58
 
59
59
  base_path = checks.delete('base_path')
60
60
 
61
+ files = [files] unless files.is_a? Array
62
+
61
63
  files.each do |f|
62
64
  if base_path
63
65
  file_path = File.join(base_path,f.strip)
data/lib/sample.rb CHANGED
@@ -47,8 +47,6 @@ mail:
47
47
  to: DESTINATION EMAIL ADDRESS
48
48
  #from: defaults to current user
49
49
  #subject_prefix: "RECKONER:"
50
- #sendmail_path: sendmail
51
- #sendmail_options: -i -t
52
50
  #always_email: true
53
51
 
54
52
  SAMPLE
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reckoner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 9
8
+ - 2
9
+ version: 0.9.2
5
10
  platform: ruby
6
11
  authors:
7
12
  - Geoff Kloess
@@ -9,94 +14,77 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2009-07-02 00:00:00 -07:00
17
+ date: 2010-03-31 00:00:00 -07:00
13
18
  default_executable:
14
19
  dependencies:
15
20
  - !ruby/object:Gem::Dependency
16
- name: hoe
17
- type: :development
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
21
+ name: mail
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
20
24
  requirements:
21
25
  - - ">="
22
26
  - !ruby/object:Gem::Version
23
- version: 2.2.0
24
- version:
25
- description: |-
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
32
+ description: |
26
33
  Ruby Reckoner is an easily-configurable program that monitors
27
34
  files and can send notifications when it finds problems.
28
35
 
29
36
  Currently it can only check that files exist, have been updated
30
37
  recently and that they have a minimum size, however it is easy to add
31
38
  your own checks written in Ruby.
32
- email:
33
- - geoff.kloess@gmail.com
39
+
40
+ email: geoff.kloess@gmail.com
34
41
  executables:
35
42
  - reckoner
36
43
  extensions: []
37
44
 
38
- extra_rdoc_files:
39
- - History.txt
40
- - Manifest.txt
41
- - README.txt
45
+ extra_rdoc_files: []
46
+
42
47
  files:
48
+ - Gemfile
43
49
  - History.txt
44
- - Manifest.txt
45
50
  - README.txt
46
- - Rakefile
47
51
  - bin/reckoner
48
- - lib/main.rb
49
- - lib/reckoner.rb
50
52
  - lib/abstract_check.rb
51
53
  - lib/rfile.rb
54
+ - lib/standard_checks.rb
55
+ - lib/main.rb
52
56
  - lib/sendmail.rb
57
+ - lib/reckoner.rb
53
58
  - lib/sample.rb
54
- - lib/standard_checks.rb
55
- - test/support.rb
56
- - test/test_abstract_check.rb
57
- - test/test_exist.rb
58
- - test/test_freshness.rb
59
- - test/test_main.rb
60
- - test/test_minimum_size.rb
61
- - test/test_rfile.rb
62
- - test/test_support.rb
63
- - test/files/one-k.bin
64
- - test/files/additional_checks.rb
65
59
  has_rdoc: true
66
- homepage: http://reckoner.rubyforge.com
60
+ homepage: http://github.com/geoffk/reckoner
67
61
  licenses: []
68
62
 
69
63
  post_install_message:
70
- rdoc_options:
71
- - --main
72
- - README.txt
64
+ rdoc_options: []
65
+
73
66
  require_paths:
74
67
  - lib
75
68
  required_ruby_version: !ruby/object:Gem::Requirement
76
69
  requirements:
77
70
  - - ">="
78
71
  - !ruby/object:Gem::Version
72
+ segments:
73
+ - 0
79
74
  version: "0"
80
- version:
81
75
  required_rubygems_version: !ruby/object:Gem::Requirement
82
76
  requirements:
83
77
  - - ">="
84
78
  - !ruby/object:Gem::Version
79
+ segments:
80
+ - 0
85
81
  version: "0"
86
- version:
87
82
  requirements: []
88
83
 
89
- rubyforge_project: reckoner
90
- rubygems_version: 1.3.4
84
+ rubyforge_project:
85
+ rubygems_version: 1.3.6
91
86
  signing_key:
92
87
  specification_version: 3
93
- summary: Ruby Reckoner is an easily-configurable program that monitors files and can send notifications when it finds problems
94
- test_files:
95
- - test/test_abstract_check.rb
96
- - test/test_exist.rb
97
- - test/test_freshness.rb
98
- - test/test_main.rb
99
- - test/test_minimum_size.rb
100
- - test/test_reckoner.rb
101
- - test/test_rfile.rb
102
- - test/test_support.rb
88
+ summary: Checks user-specified files and sends alert emails when not found.
89
+ test_files: []
90
+
data/Manifest.txt DELETED
@@ -1,22 +0,0 @@
1
- History.txt
2
- Manifest.txt
3
- README.txt
4
- Rakefile
5
- bin/reckoner
6
- lib/main.rb
7
- lib/reckoner.rb
8
- lib/abstract_check.rb
9
- lib/rfile.rb
10
- lib/sendmail.rb
11
- lib/sample.rb
12
- lib/standard_checks.rb
13
- test/support.rb
14
- test/test_abstract_check.rb
15
- test/test_exist.rb
16
- test/test_freshness.rb
17
- test/test_main.rb
18
- test/test_minimum_size.rb
19
- test/test_rfile.rb
20
- test/test_support.rb
21
- test/files/one-k.bin
22
- test/files/additional_checks.rb
data/Rakefile DELETED
@@ -1,11 +0,0 @@
1
- # -*- ruby -*-
2
-
3
- require 'rubygems'
4
- require 'hoe'
5
-
6
- Hoe.spec 'reckoner' do
7
- # self.rubyforge_name = 'reckonerx' # if different than 'reckoner'
8
- self.developer('Geoff Kloess', 'geoff.kloess@gmail.com')
9
- end
10
-
11
- # vim: syntax=ruby
@@ -1,10 +0,0 @@
1
-
2
- class Extension < AbstractCheck
3
-
4
- def check(path_obj,options)
5
- unless path_obj.extname == options.strip
6
- add_error 'is not a txt file'
7
- end
8
- end
9
- end
10
-
data/test/files/one-k.bin DELETED
Binary file
data/test/support.rb DELETED
@@ -1,41 +0,0 @@
1
- ####
2
- # Offers support for running backup check tests
3
-
4
- require 'fileutils'
5
-
6
- module BackupCheckSupport
7
- include FileUtils
8
-
9
- ROOT = '/tmp/file_verifier_tests'
10
-
11
- #Makes a set of file that meet the specified options
12
- def makef(root,name,options = {})
13
- mkdir root unless File.exists?(root.to_s)
14
- if name.is_a? Hash
15
- name.each do |k,n|
16
- makef File.join(root,k.to_s),n,options
17
- end
18
- elsif name.is_a? Array
19
- name.each do |n|
20
- makef(root,n,options)
21
- end
22
- elsif name.is_a?(String) || name.is_a?(Symbol)
23
- path = File.join(root,name.to_s)
24
- touch path
25
- File.chmod(options[:chmod],path) if options[:chmod]
26
- File.utime(options[:atime],options[:atime],path) if options[:atime]
27
- end
28
- end
29
-
30
- #Converts days to seconds
31
- def d2s(days)
32
- days * 24 * 60 * 60
33
- end
34
-
35
- #Determines if the object has any errors matching the regular
36
- #expression.
37
- def has_error(cmain,reg)
38
- cmain.errors.any?{|msg| reg.match msg}
39
- end
40
-
41
- end
@@ -1,36 +0,0 @@
1
- require 'test/support'
2
- require 'lib/main'
3
- require 'test/unit'
4
-
5
- class TestCheck < AbstractCheck
6
- check_name 'test_check'
7
- end
8
-
9
- class TestCheckTwo < AbstractCheck
10
- end
11
-
12
- class AbstractTest < Test::Unit::TestCase
13
- include BackupCheckSupport
14
-
15
- #Test that the name of a test is set correctly and
16
- #that it can be over-ridden.
17
- def test_abstract_check
18
- assert_equal 'test_check', TestCheck.get_check_name
19
- assert_equal 'test_check_two', TestCheckTwo.get_check_name
20
-
21
- tc2 = TestCheckTwo.new('.')
22
- assert tc2.is_a?(AbstractCheck)
23
- end
24
-
25
- def test_unit_parse
26
- uhash = { /^inch/ => 1, /^feet/ => 12, /^foot/ => 12, 'default' => 1 }
27
- ac = AbstractCheck.new(__FILE__)
28
- assert_equal 1, ac.unit_parse("1", uhash)
29
- assert_equal 1, ac.unit_parse("1 inch", uhash)
30
- assert_equal 1, ac.unit_parse("1inch", uhash)
31
- assert_equal 1.5, ac.unit_parse("1.5inch", uhash)
32
- assert_equal 12, ac.unit_parse("1 foot", uhash)
33
- assert_equal 24, ac.unit_parse("2 feet", uhash)
34
- end
35
-
36
- end
data/test/test_exist.rb DELETED
@@ -1,36 +0,0 @@
1
- require 'test/support'
2
- require 'lib/main'
3
- require 'test/unit'
4
-
5
- class ExistsTest < Test::Unit::TestCase
6
- include BackupCheckSupport
7
-
8
- def setup
9
- @root = '/tmp/test'
10
- makef(@root,['one','two','three'])
11
- end
12
-
13
- def teardown
14
- rm_rf @root
15
- end
16
-
17
- def test_files_exist
18
- cm = Reckoner.new()
19
- cm.check('test'=> {'files'=>'/tmp/test/one'})
20
- assert cm.errors.empty?
21
-
22
- cm.check('test'=> {'files'=>['/tmp/test/one','/tmp/test/two']})
23
- assert cm.errors.empty?
24
-
25
- cm.check('test'=> {'base_path'=>'/tmp/test','files'=>['one','two']})
26
- assert cm.errors.empty?
27
- end
28
-
29
- def test_errors
30
- cm = Reckoner.new(nil)
31
- cm.check('test'=>{'files'=>'nofile'})
32
- assert_equal 1,cm.errors.length
33
- assert has_error(cm,/does not exist/)
34
- end
35
-
36
- end
@@ -1,49 +0,0 @@
1
- require 'test/unit'
2
- require 'date'
3
- require 'test/support'
4
- require 'lib/main'
5
-
6
- class FreshnessTest < Test::Unit::TestCase
7
- include BackupCheckSupport
8
-
9
- def setup
10
- makef(ROOT,['one','two','three',
11
- {'dir' => ['four','five']}], :atime => Time.now - d2s(10))
12
- makef(ROOT,'six', :atime => Time.now - d2s(1))
13
- @cm = Reckoner.new()
14
- end
15
-
16
- def teardown
17
- rm_rf ROOT
18
- end
19
-
20
- def test_single_file_success
21
- @cm.check('test'=> {'files'=>File.join(ROOT,'one'), 'freshness' => '20'})
22
- assert @cm.errors.empty?
23
-
24
- @cm.check('test'=> {'files'=>File.join(ROOT,'six'), 'freshness' => '30 hours'})
25
- assert @cm.errors.empty?
26
- end
27
-
28
- def test_single_file_failure
29
- @cm.check('test'=> {'files'=>File.join(ROOT,'one'), 'freshness' => '5'})
30
- assert_equal 1, @cm.errors.length
31
- assert has_error(@cm,/file is too old/)
32
- end
33
-
34
- def test_hour_failure
35
- @cm.check('test'=> {'files'=>File.join(ROOT,'six'), 'freshness' => '22 hours'})
36
- assert_equal 1, @cm.errors.length
37
- assert has_error(@cm,/file is too old/)
38
- end
39
-
40
- def test_recursive_success
41
- hundred_days_ago = Time.now - d2s(100)
42
- File.utime(hundred_days_ago,hundred_days_ago,ROOT)
43
- assert_equal File.mtime(ROOT).to_s,hundred_days_ago.to_s
44
-
45
- @cm.check('test'=> {'files'=>ROOT, 'freshness' => '20'})
46
- assert @cm.errors.empty?
47
- end
48
-
49
- end
data/test/test_main.rb DELETED
@@ -1,60 +0,0 @@
1
- require 'test/unit'
2
- require 'date'
3
- require 'test/support'
4
- require 'lib/main'
5
-
6
- class MainTest < Test::Unit::TestCase
7
- include BackupCheckSupport
8
-
9
- def setup
10
- makef(ROOT,[{'d1' => ['d1f1', 'd1f2', 'd1f3']},
11
- 'f4','h1.txt',
12
- ['f5', 'f6', 'f7'],
13
- {'d2' => ['d2f1', 'd2f2']}])
14
- @good_config = <<-CONFIG
15
- check:
16
- default_check:
17
- base_path: #{ROOT}
18
- f4:
19
- files: f4
20
- d1:
21
- files: [d1, d1/d1f1]
22
- CONFIG
23
- end
24
-
25
- def teardown
26
- rm_rf ROOT
27
- end
28
-
29
- def test_simple
30
- m = Main.new([])
31
- out = m.run_config(@good_config)
32
- assert(/No failed checks/.match(out))
33
- end
34
-
35
- def test_sample_config
36
- fname = ROOT + '/sample.yaml'
37
- m1 = Main.new(['-s',fname])
38
- m1.run_reckoner
39
- assert File.exists?(fname)
40
-
41
- m2 = Main.new(['-e',fname])
42
- out = m2.run_reckoner
43
- assert(/Reckoner found a problem with '\/etc\/fake-file'/.match(out))
44
- assert out.split("\n").length > 4
45
- end
46
-
47
- def test_additional_checks
48
- m1 = Main.new(['-c','test/files/additional_checks.rb'])
49
- out = m1.run_config <<-CONFIG
50
- check:
51
- default_check:
52
- base_path: #{ROOT}
53
- txt:
54
- files: [d1, h1.txt]
55
- extension: .txt
56
- CONFIG
57
- assert_equal 2,out.split("\n").length
58
- assert(/Extension found a problem with '\/tmp\/file_verifier_tests\/d1'/.match(out))
59
- end
60
- end
@@ -1,33 +0,0 @@
1
- require 'test/unit'
2
- require 'date'
3
- require 'test/support'
4
- require 'lib/main'
5
-
6
- class MinimumSizeTest < Test::Unit::TestCase
7
- include BackupCheckSupport
8
-
9
- def setup
10
- @cm = Reckoner.new()
11
- @bin = File.join('test','files','one-k.bin')
12
- end
13
-
14
- def test_file_right_size
15
- @cm.check('test'=> {'files'=>@bin, 'minimum_size' => '1'})
16
- assert @cm.errors.empty?
17
- end
18
-
19
- def test_file_too_small
20
- @cm.check('test'=> {'files'=>@bin, 'minimum_size' => '2048'})
21
- assert_equal 1, @cm.errors.length
22
- assert has_error(@cm,/file is too small/)
23
- end
24
-
25
- def kilobyte_parsing
26
- @cm.check('test'=> {'files'=>@bin, 'minimum_size' => '1kb'})
27
- assert @cm.errors.empty?
28
-
29
- @cm.check('test'=> {'files'=>@bin, 'minimum_size' => '2kb'})
30
- assert_equal 1, @cm.errors.length
31
- assert has_error(@cm,/file is too small/)
32
- end
33
- end
@@ -1,38 +0,0 @@
1
- require 'test/unit'
2
- require 'date'
3
- require 'test/support'
4
- require 'lib/main'
5
-
6
- class ReckonerTest < Test::Unit::TestCase
7
- include BackupCheckSupport
8
-
9
- def setup
10
- makef(ROOT,['one','two','three'], :atime => Time.now - d2s(10))
11
- @cm = Reckoner.new()
12
- end
13
-
14
- def teardown
15
- rm_rf ROOT
16
- end
17
-
18
- def test_non_existant_check
19
- assert_raise RuntimeError do
20
- @cm.check('test'=> {'files'=> File.join(ROOT,'one'), 'nocheck' => '20'})
21
- end
22
- end
23
-
24
- def test_multiple_files
25
- @cm.check('test'=> {'files'=> [File.join(ROOT,'one'), File.join(ROOT,'two')]})
26
- assert @cm.errors.empty?
27
-
28
- @cm.check('test'=> {'files'=> [File.join(ROOT,'one'),
29
- File.join(ROOT,'blah'),
30
- File.join(ROOT,'two'),
31
- File.join(ROOT,'other'),
32
- ]})
33
- assert_equal 2, @cm.errors.length
34
- assert(/file does not exist/.match(@cm.errors[0]))
35
- assert(/file does not exist/.match(@cm.errors[1]))
36
- end
37
-
38
- end
data/test/test_rfile.rb DELETED
@@ -1,37 +0,0 @@
1
- require 'test/unit'
2
- require 'date'
3
- require 'test/support'
4
- require 'lib/main'
5
-
6
- class RFileTest < Test::Unit::TestCase
7
- include BackupCheckSupport
8
-
9
- def setup
10
- makef(ROOT,[{:d1 => [:f1, :f2, :f3]},
11
- {:d2 => [{ :d3 => :f3 }, :f4]}])
12
- @cfile = RFile.new(ROOT)
13
- end
14
-
15
- def teardown
16
- rm_rf ROOT
17
- end
18
-
19
- def test_methods
20
- assert_equal @cfile.path, ROOT
21
- assert_equal @cfile.atime, File.atime(ROOT)
22
- assert_equal @cfile.mtime, File.mtime(ROOT)
23
- assert_equal @cfile.stat, File.stat(ROOT)
24
- assert_equal @cfile.basename, File.basename(ROOT)
25
- assert_equal @cfile.expand_path, File.expand_path(ROOT)
26
- end
27
-
28
- def test_recurse_functions
29
- assert_equal 9, @cfile.sub_node_array.length
30
- assert_equal 5, @cfile.sub_node_array(:directories => false).length
31
- assert_equal 4, @cfile.sub_node_array(:files => false).length
32
-
33
- assert @cfile.all_sub_nodes?{|f| f.basename.length == 2 || f.directory? }
34
- assert @cfile.any_sub_node?{|f| f.basename == 'f3' }
35
- end
36
-
37
- end
data/test/test_support.rb DELETED
@@ -1,28 +0,0 @@
1
- require 'test/unit'
2
- require 'date'
3
- require 'test/support'
4
-
5
- class SupportTest < Test::Unit::TestCase
6
- include BackupCheckSupport
7
-
8
- def test_makef
9
- makef(ROOT,[{'d1' => ['d1f1', 'd1f2', 'd1f3']},
10
- 'f4',
11
- ['f5', 'f6', 'f7'],
12
- {'d2' => ['d2f1', 'd2f2']}])
13
-
14
- assert File.exists?(File.join(ROOT,'d1'))
15
- assert File.exists?(File.join(ROOT,'f4'))
16
- assert File.exists?(File.join(ROOT,'f5'))
17
- assert File.exists?(File.join(ROOT,'f6'))
18
- assert File.exists?(File.join(ROOT,'f7'))
19
- assert File.exists?(File.join(ROOT,'d1','d1f1'))
20
- assert File.exists?(File.join(ROOT,'d1','d1f2'))
21
- assert File.exists?(File.join(ROOT,'d1','d1f3'))
22
- assert File.exists?(File.join(ROOT,'d2'))
23
- assert File.exists?(File.join(ROOT,'d2','d2f1'))
24
- assert File.exists?(File.join(ROOT,'d2','d2f2'))
25
- rm_rf ROOT
26
- end
27
-
28
- end