spex 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -12,6 +12,7 @@ begin
12
12
  gem.authors = ["Bruce Williams"]
13
13
  gem.add_dependency "colored"
14
14
  gem.add_dependency "diff-lcs"
15
+ gem.add_dependency "facter"
15
16
  end
16
17
  Jeweler::GemcutterTasks.new
17
18
  rescue LoadError
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.2
1
+ 0.6.0
@@ -0,0 +1,16 @@
1
+ # Note: We use the more specific 'postfix/master' as the process name so
2
+ # we don't confused with spex running this file (postfix.rb)
3
+ scenario "Postfix process management" do
4
+ executing "sudo postfix start" do
5
+ assert 'postfix/master', :started => true
6
+ end
7
+ executing "sudo postfix stop" do
8
+ assert 'postfix/master', :stopped => true
9
+ end
10
+ executing "sudo postfix start" do
11
+ assert 'postfix/master', :started => true
12
+ end
13
+ executing "sudo postfix stop && sudo postfix start" do
14
+ assert 'postfix/master', :restarted => true
15
+ end
16
+ end
data/lib/spex.rb CHANGED
@@ -1,3 +1,9 @@
1
+ begin
2
+ require 'facter'
3
+ rescue LoadError
4
+ abort "Requires 'facter'"
5
+ end
6
+
1
7
  module Spex
2
8
  autoload :Assertion, 'spex/assertion'
3
9
  autoload :CLI, 'spex/cli'
@@ -0,0 +1,28 @@
1
+ module Spex
2
+ class ProcessAssertion < Assertion
3
+
4
+ def pattern
5
+ @pattern ||= target.is_a?(Regexp) ? target : Regexp.new(target)
6
+ end
7
+
8
+ def ps_executable
9
+ ps = Facter.value(:ps)
10
+ if ps && !ps.empty?
11
+ ps
12
+ else
13
+ abort "Facter does not support 'ps' fact."
14
+ end
15
+ end
16
+
17
+ def current_pid
18
+ table = IO.popen(ps_executable) { |ps| ps.readlines }
19
+ table.each do |line|
20
+ if pattern.match(line)
21
+ return line.sub(/^\s+/, '').split(/\s+/)[1]
22
+ end
23
+ end
24
+ nil
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ module Spex
2
+ class RestartedAssertion < ProcessAssertion
3
+ as :restarted, 'process restart'
4
+ example "Process was restarted", "assert 'postfix', :restarted => true"
5
+ example "Process was not restarted", "assert 'postfix', :restarted => false"
6
+
7
+ def before
8
+ @before_pid = current_pid
9
+ assert @before_pid, "Process '#{target}' is not running"
10
+ end
11
+
12
+ def after
13
+ after_pid = current_pid
14
+ assert after_pid, "Process '#{target}' is not running"
15
+ if active?
16
+ assert_not_equal @before_pid, after_pid, "Process '#{target}' pid was not changed (still #{@before_pid})"
17
+ else
18
+ assert_equal @before_pid, after_pid, "Process '#{target}' pid was changed (was #{@before_pid}, now #{after_pid})"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ module Spex
2
+ class StartedAssertion < ProcessAssertion
3
+ as :started, 'process start'
4
+ example "Process was started", "assert 'postfix', :started => true"
5
+ example "Process was not started", "assert 'postfix', :started => false"
6
+
7
+ def before
8
+ pid = current_pid
9
+ assert !pid, "Process '#{target}' is already running (pid #{pid})"
10
+ end
11
+
12
+ def after
13
+ if active?
14
+ assert current_pid, "Process '#{target}' was not started"
15
+ else
16
+ pid = current_pid
17
+ assert_nil pid, "Process '#{target}' was started (pid #{pid})"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ module Spex
2
+ class StoppedAssertion < ProcessAssertion
3
+ as :stopped, 'process stop'
4
+ example "Process was stopped", "assert 'postfix', :stopped => true"
5
+ example "Process was not stopped", "assert 'postfix', :stopped => false"
6
+
7
+ def before
8
+ assert current_pid, "Process '#{target}' is not running (will not be stopped)"
9
+ end
10
+
11
+ def after
12
+ pid = current_pid
13
+ if active?
14
+ assert_nil pid, "Process '#{target}' is still running (pid #{pid})"
15
+ else
16
+ assert_not_nil pid, "Process '#{target}' was stopped"
17
+ end
18
+ end
19
+ end
20
+ end
data/lib/spex/runner.rb CHANGED
@@ -15,10 +15,10 @@ module Spex
15
15
  end
16
16
 
17
17
  def run
18
- puts %(Running scenario "#{scenario.name}").bold
18
+ puts %(Running scenario "#{scenario.name}").magenta.bold
19
19
  proceed = true
20
20
  scenario.each do |execution|
21
- puts "Checking pre-assertions"
21
+ puts %(Preparing to execute "#{execution.command}").bold
22
22
  execution.assertions.each do |assertion|
23
23
  print "Pre-assertions for #{assertion}: "
24
24
  assertion.prepare
@@ -26,24 +26,26 @@ module Spex
26
26
  break unless proceed
27
27
  end
28
28
  if proceed
29
- puts %(Executing "#{execution.command}")
29
+ print %(Executing "#{execution.command}": )
30
+ start = Time.now
30
31
  log = execute(execution)
32
+ elapsed = Time.now - start
33
+ puts 'DONE (%.2fs)' % elapsed
31
34
  passed = true
32
35
  execution.assertions.reverse.each do |assertion|
33
36
  print "Post-assertions for #{assertion}: "
34
37
  passed = report { assertion.after }
35
38
  break unless passed
36
39
  end
37
- if passed
38
- puts "SCENARIO PASSED".green.bold
39
- else
40
- abort "SCENARIO FAILED".red.bold
40
+ unless passed
41
+ abort "SCENARIO ASSERTIONS FAILED".red.bold
41
42
  end
42
43
  output_log(execution, log)
43
44
  else
44
45
  abort "SCENARIO FAILED (EXECUTION ABORTED)".red.bold
45
46
  end
46
47
  end
48
+ puts "SCENARIO PASSED".green.bold
47
49
  end
48
50
 
49
51
  def report(&block)
data/test/helper.rb CHANGED
@@ -7,6 +7,7 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
7
  $LOAD_PATH.unshift(File.dirname(__FILE__))
8
8
  require 'spex'
9
9
  require 'fakefs/safe'
10
+ require 'flexmock/test_unit'
10
11
 
11
12
  class Test::Unit::TestCase
12
13
 
@@ -23,10 +24,27 @@ class Test::Unit::TestCase
23
24
  @assertion.after
24
25
  end
25
26
 
27
+ def assertion_fails_before
28
+ assert_raises Test::Unit::AssertionFailedError do
29
+ @assertion.prepare
30
+ @assertion.before
31
+ end
32
+ end
33
+
26
34
  def assertion_fails(&block)
27
35
  assert_raises Test::Unit::AssertionFailedError do
28
36
  assertion_passes(&block)
29
37
  end
30
38
  end
39
+
40
+ def start_process!(pid = '100')
41
+ flexmock(@assertion).flexmock_teardown
42
+ flexmock(@assertion).should_receive(:current_pid).and_return(pid)
43
+ end
44
+
45
+ def stop_process!
46
+ flexmock(@assertion).flexmock_teardown
47
+ flexmock(@assertion).should_receive(:current_pid).and_return(nil)
48
+ end
31
49
 
32
50
  end
@@ -1,6 +1,6 @@
1
1
  require 'helper'
2
2
 
3
- class TestAssertion < Test::Unit::TestCase
3
+ class TestModifiedAssertion < Test::Unit::TestCase
4
4
 
5
5
  def set_assertion(options = {})
6
6
  @assertion = Spex::ModifiedAssertion.new(@filename, options)
@@ -0,0 +1,77 @@
1
+ require 'helper'
2
+
3
+ class TestRestartedAssertion < Test::Unit::TestCase
4
+
5
+ def set_assertion(options = {})
6
+ @assertion = Spex::RestartedAssertion.new('testproc', options)
7
+ end
8
+
9
+ context "Restarted Assertion" do
10
+ context "instances" do
11
+ context "set to true" do
12
+ setup do
13
+ set_assertion(true)
14
+ end
15
+ context "process running before execution" do
16
+ setup do
17
+ start_process!
18
+ end
19
+ context "and process running after execution" do
20
+ context "with the same pid" do
21
+ should 'fail' do
22
+ assertion_fails
23
+ end
24
+ end
25
+ context "with a different pid" do
26
+ should 'pass' do
27
+ assertion_passes { start_process!('101') }
28
+ end
29
+ end
30
+ end
31
+ context "but process not running after execution" do
32
+ should "fail" do
33
+ assertion_fails
34
+ end
35
+ end
36
+ end
37
+ context "process not running before execution" do
38
+ should "fail" do
39
+ assertion_fails_before
40
+ end
41
+ end
42
+ end
43
+ context "set to false" do
44
+ setup do
45
+ set_assertion(false)
46
+ end
47
+ context "process running before execution" do
48
+ setup do
49
+ start_process!
50
+ end
51
+ context "and process running after execution" do
52
+ context "with the same pid" do
53
+ should 'pass' do
54
+ assertion_passes
55
+ end
56
+ end
57
+ context "with a different pid" do
58
+ should 'fail' do
59
+ assertion_fails { start_process!('101') }
60
+ end
61
+ end
62
+ end
63
+ context "but process not running after execution" do
64
+ should "fail" do
65
+ assertion_fails { stop_process! }
66
+ end
67
+ end
68
+ end
69
+ context "process not running before execution" do
70
+ should "fail" do
71
+ assertion_fails_before
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,63 @@
1
+ require 'helper'
2
+
3
+ class TestStartedAssertion < Test::Unit::TestCase
4
+
5
+ def set_assertion(options = {})
6
+ @assertion = Spex::StartedAssertion.new('testproc', options)
7
+ end
8
+
9
+ context "Started Assertion" do
10
+ context "instances" do
11
+ context "set to true" do
12
+ setup do
13
+ set_assertion(true)
14
+ end
15
+ context "process running before execution" do
16
+ setup do
17
+ start_process!
18
+ end
19
+ should "fail" do
20
+ assertion_fails_before
21
+ end
22
+ end
23
+ context "process not running before execution" do
24
+ context "process running after execution" do
25
+ should "pass" do
26
+ assertion_passes { start_process! }
27
+ end
28
+ end
29
+ context "process not running after execution" do
30
+ should 'fail' do
31
+ assertion_fails
32
+ end
33
+ end
34
+ end
35
+ end
36
+ context "set to false" do
37
+ setup do
38
+ set_assertion(false)
39
+ end
40
+ context "process running before execution" do
41
+ setup do
42
+ start_process!
43
+ end
44
+ should "fail" do
45
+ assertion_fails_before
46
+ end
47
+ end
48
+ context "process not running before execution" do
49
+ context "but process running after execution" do
50
+ should "fail" do
51
+ assertion_fails { start_process! }
52
+ end
53
+ end
54
+ context "but process not running after execution" do
55
+ should 'pass' do
56
+ assertion_passes
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,63 @@
1
+ require 'helper'
2
+
3
+ class TestStoppedAssertion < Test::Unit::TestCase
4
+
5
+ def set_assertion(options = {})
6
+ @assertion = Spex::StoppedAssertion.new('testproc', options)
7
+ end
8
+
9
+ context "Stopped Assertion" do
10
+ context "instances" do
11
+ context "set to true" do
12
+ setup do
13
+ set_assertion(true)
14
+ end
15
+ context "process running before execution" do
16
+ setup do
17
+ start_process!
18
+ end
19
+ context "and process running after execution" do
20
+ should 'fail' do
21
+ assertion_fails
22
+ end
23
+ end
24
+ context "but process not running after execution" do
25
+ should "pass" do
26
+ assertion_passes { stop_process! }
27
+ end
28
+ end
29
+ end
30
+ context "process not running before execution" do
31
+ should "fail" do
32
+ assertion_fails_before
33
+ end
34
+ end
35
+ end
36
+ context "set to false" do
37
+ setup do
38
+ set_assertion(false)
39
+ end
40
+ context "process running before execution" do
41
+ setup do
42
+ start_process!
43
+ end
44
+ context "and process running after execution" do
45
+ should 'pass' do
46
+ assertion_passes
47
+ end
48
+ end
49
+ context "but process not running after execution" do
50
+ should "fail" do
51
+ assertion_fails { stop_process! }
52
+ end
53
+ end
54
+ end
55
+ context "process not running before execution" do
56
+ should "fail" do
57
+ assertion_fails_before
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 5
8
- - 2
9
- version: 0.5.2
7
+ - 6
8
+ - 0
9
+ version: 0.6.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Bruce Williams
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-14 00:00:00 -07:00
17
+ date: 2010-04-15 00:00:00 -07:00
18
18
  default_executable: spex
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -41,6 +41,18 @@ dependencies:
41
41
  version: "0"
42
42
  type: :runtime
43
43
  version_requirements: *id002
44
+ - !ruby/object:Gem::Dependency
45
+ name: facter
46
+ prerelease: false
47
+ requirement: &id003 !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ segments:
52
+ - 0
53
+ version: "0"
54
+ type: :runtime
55
+ version_requirements: *id003
44
56
  description: An easy-to-use test harness that runs assertions before and after and executable is run
45
57
  email: bruce@codefluency.com
46
58
  executables:
@@ -61,6 +73,7 @@ files:
61
73
  - examples/chgrp.rb
62
74
  - examples/chmod.rb
63
75
  - examples/chown.rb
76
+ - examples/postfix.rb
64
77
  - examples/puppet.rb
65
78
  - examples/touch.rb
66
79
  - examples/writing.rb
@@ -72,7 +85,11 @@ files:
72
85
  - lib/spex/assertions/created_assertion.rb
73
86
  - lib/spex/assertions/file_assertion.rb
74
87
  - lib/spex/assertions/modified_assertion.rb
88
+ - lib/spex/assertions/process_assertion.rb
75
89
  - lib/spex/assertions/removed_assertion.rb
90
+ - lib/spex/assertions/restarted_assertion.rb
91
+ - lib/spex/assertions/started_assertion.rb
92
+ - lib/spex/assertions/stopped_assertion.rb
76
93
  - lib/spex/cli.rb
77
94
  - lib/spex/execution.rb
78
95
  - lib/spex/runner.rb
@@ -81,7 +98,10 @@ files:
81
98
  - test/helper.rb
82
99
  - test/test_assertion.rb
83
100
  - test/test_modified_assertion.rb
101
+ - test/test_restarted_assertion.rb
84
102
  - test/test_script.rb
103
+ - test/test_started_assertion.rb
104
+ - test/test_stopped_assertion.rb
85
105
  has_rdoc: true
86
106
  homepage: http://github.com/bruce/spex
87
107
  licenses: []
@@ -116,10 +136,14 @@ test_files:
116
136
  - test/helper.rb
117
137
  - test/test_assertion.rb
118
138
  - test/test_modified_assertion.rb
139
+ - test/test_restarted_assertion.rb
119
140
  - test/test_script.rb
141
+ - test/test_started_assertion.rb
142
+ - test/test_stopped_assertion.rb
120
143
  - examples/chgrp.rb
121
144
  - examples/chmod.rb
122
145
  - examples/chown.rb
146
+ - examples/postfix.rb
123
147
  - examples/puppet.rb
124
148
  - examples/touch.rb
125
149
  - examples/writing.rb