faultinjection 0.0.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.
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+ require 'fault_injection.rb'
3
+
4
+ include FaultInjection
5
+
6
+ describe Parser do
7
+ it "should return FaultConditionLine on 'foo.rb:32'" do
8
+ c = Parser.compile('foo.rb:32')
9
+ c.instance_of?(FaultConditionLine).should be_true
10
+ c.line.should be_eql(32)
11
+ c.file.should be_eql('foo.rb')
12
+ end
13
+
14
+ it "can parse 'Class#method' format." do
15
+ c = Parser.compile('Array#size')
16
+ c.instance_of?(FaultConditionCall).should be_true
17
+ c.stack_pattern.should be_eql([[:Array,:size]])
18
+ end
19
+
20
+ it "should raise NameError with invalid class" do
21
+ Proc.new{
22
+ c = Parser.compile("00#size")
23
+ }.should raise_error(ArgumentError)
24
+ end
25
+
26
+ it "should raise NameError with invalid method" do
27
+ Proc.new{
28
+ c = Parser.compile("Array#3")
29
+ }
30
+ end
31
+
32
+ it "can parse multiple method chain" do
33
+ c = Parser.compile("Array#push > String#size")
34
+ c.instance_of?(FaultConditionCall).should be_true
35
+
36
+ c.stack_pattern.should be_eql([[:String,:size],[:Array,:push]])
37
+ end
38
+ end
@@ -0,0 +1,45 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+ require 'fault_injection.rb'
3
+
4
+ include FaultInjection
5
+
6
+ class Foo
7
+ def foo
8
+ end
9
+ end
10
+
11
+ class Bar
12
+ def bar
13
+ f = Foo.new
14
+ f.foo
15
+ end
16
+ end
17
+
18
+ describe FaultConditionCall do
19
+
20
+ it "matches method calling backtrace" do
21
+ c = FaultConditionCall.new
22
+ c.stack_pattern = [[:Array,:each]]
23
+ c.should_raise_on([[:Array,:each]]).should be_true
24
+
25
+ c.should_raise_on([[:Hash,:keys],
26
+ [:Array,:each]]).should be_true
27
+
28
+ c.should_raise_on([[:Integer,:to_f]]).should_not be_true
29
+
30
+ c.stack_pattern = [
31
+ [:Array,:each], # callee first
32
+ [:Hash, :keys],
33
+ [:Integer, :to_s]
34
+ ]
35
+ c.should_raise_on([[:Array,:each]]).should_not be_true
36
+ c.should_raise_on(c.stack_pattern.reverse).should be_true
37
+ bt = [
38
+ [:String,:size], # caller first
39
+ [:Integer, :to_s],
40
+ [:Hash, :keys],
41
+ [:Array,:each]
42
+ ]
43
+ c.should_raise_on(bt).should be_true
44
+ end
45
+ end
@@ -0,0 +1,89 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+ require 'fault_injection.rb'
3
+
4
+ include FaultInjection
5
+ $LOAD_PATH << File.dirname(__FILE__)
6
+
7
+ describe "Argument Checking" do
8
+ it "raises if a line number is less than 0" do
9
+ Proc.new{
10
+ inject_fault({:file => 'target_00.rb',:line => -5})
11
+ }.should raise_error(ArgumentError)
12
+ end
13
+
14
+ it "raises if a err_class is not a subclass of Exception" do
15
+ Proc.new {
16
+ inject_fault({:file => 'target_00.rb',:line => 1}, 3)
17
+ }.should raise_error(ArgumentError)
18
+ end
19
+ end
20
+
21
+ describe "'File & line' fault-injection." do
22
+ require 'target_00.rb'
23
+
24
+ after(:each) do
25
+ clear
26
+ end
27
+
28
+ it "works on Hash format for file & line specification" do
29
+ Proc.new{ target_func_00 }.should_not raise_error
30
+ inject_fault({:file => 'target_00.rb', :line => 9})
31
+
32
+ begin
33
+ target_func_00
34
+ violate "target_func_00 must raise RuntimeError"
35
+ rescue
36
+ $!.instance_of?(RuntimeError).should be_true
37
+ $!.backtrace[0].should match(/target_00\.rb/)
38
+ $target_00['one'].should be_eql(1)
39
+ $target_00['two'].should be_nil
40
+ $target_00['three'].should be_nil
41
+ end
42
+ end
43
+
44
+ it "works on 'file:line' format injection command." do
45
+ Proc.new{ target_func_00 }.should_not raise_error
46
+
47
+ inject_fault "target_00.rb:9", SecurityError, "This is a error"
48
+ Proc.new{
49
+ target_func_00
50
+ }.should raise_error(SecurityError,"This is a error")
51
+
52
+ end
53
+ end
54
+
55
+ describe "Method tracing fault-injection" do
56
+ require 'target_02.rb'
57
+
58
+ after(:each) do
59
+ clear
60
+ end
61
+
62
+ it "should check arguments in Array format command." do
63
+ Proc.new{ Bar.new.bar }.should_not raise_error
64
+
65
+ Proc.new{ inject_fault([]) }.should raise_error(ArgumentError)
66
+ Proc.new{ inject_fault([:Array]) }.should raise_error(ArgumentError)
67
+ end
68
+
69
+ it "should inject faults properly with Array format command" do
70
+ Proc.new{ Bar.new.bar }.should_not raise_error
71
+
72
+ # raise on method calling chane, "Bar#bar --> Foo#foo"
73
+ inject_fault [:Bar,:bar,:Foo,:foo],RangeError
74
+ Proc.new{ Bar.new.bar }.should raise_error(RangeError)
75
+ end
76
+ end
77
+
78
+ describe "Specifying Exception class" do
79
+ require 'target_01.rb'
80
+
81
+ it "can inject fault with specified Exception class" do
82
+ inject_fault({:file => 'target_01.rb', :line => 3},ArgumentError)
83
+
84
+ Proc.new{ target_func_01 }.should raise_error(ArgumentError)
85
+
86
+ clear
87
+ end
88
+ end
89
+
@@ -0,0 +1,81 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+ require 'fault_injection.rb'
3
+
4
+ include FaultInjection
5
+
6
+ describe FaultConditionLine do
7
+ it "raise if invalid arguments are specified" do
8
+ Proc.new{
9
+ FaultConditionLine.new({:file=>'foo.rb', :line=>-5})
10
+ }.should raise_error(ArgumentError)
11
+ end
12
+
13
+ it "implements attr_accessors" do
14
+ c = FaultConditionLine.new("foo.rb",300)
15
+ c.file.should be_eql("foo.rb")
16
+ c.line.should be_eql(300)
17
+ end
18
+
19
+ it "matches file name and line numbers" do
20
+ c = FaultConditionLine.new("foo.rb",300)
21
+ c.should_raise_on("foo.rb",300).should be_true
22
+ c.should_raise_on("foo.rb",305).should_not be_true
23
+ c.should_raise_on("bar.rb",300).should_not be_true
24
+ c.should_raise_on("bar.rb",199).should_not be_true
25
+
26
+ c.should_raise_on("dir/foo.rb",300).should be_true
27
+ c.should_raise_on("dir/bar.rb",300).should_not be_true
28
+ c.should_raise_on("dir/foo.rb",390).should_not be_true
29
+
30
+ c.should_raise_on(caller).should_not be_true
31
+ end
32
+
33
+ it "can inject a fault with probability" do
34
+ c = FaultConditionLine.new("foo.rb",99)
35
+ c.probability = 0.5
36
+
37
+ try_count = 3000
38
+ raise_count = 0
39
+ try_count.times { raise_count += 1 if c.should_raise_on('foo.rb',99) }
40
+
41
+ probab = raise_count.to_f / try_count
42
+ probab.should be_close(0.5,0.05)
43
+
44
+ c.should_raise_on('bar.rb',99).should_not be_true
45
+ end
46
+
47
+ it "can inject a fault with count limit." do
48
+ c = FaultConditionLine.new('foo.rb',99)
49
+ c.limit_times = 5
50
+
51
+ 5.times do
52
+ c.should_raise_on('foo.rb',99).should be_true
53
+ c.should_raise_on('foo.rb',100).should_not be_true
54
+ end
55
+
56
+ c.limit_times.should be_eql(0)
57
+ c.should_raise_on('foo.rb',99).should_not be_true
58
+ c.should_raise_on('foo.rb',100).should_not be_true
59
+ end
60
+
61
+ it "can inject a fault with both count limit and probability" do
62
+ try_count = 3000
63
+
64
+ c = FaultConditionLine.new("foo.rb",99)
65
+ c.probability = 0.5
66
+ c.limit_times = try_count
67
+
68
+ raise_count = 0
69
+ all_count = 0
70
+ while raise_count < try_count
71
+ all_count += 1
72
+ raise_count += 1 if c.should_raise_on('foo.rb',99)
73
+ end
74
+
75
+ probab = raise_count.to_f / all_count
76
+ probab.should be_close(0.5,0.05)
77
+
78
+ c.limit_times.should be_eql(0)
79
+ c.should_raise_on('foo.rb',99).should_not be_true
80
+ end
81
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,10 @@
1
+ $LOAD_PATH << File.dirname(__FILE__) + '/../lib'
2
+
3
+ begin
4
+ require 'spec'
5
+ rescue LoadError
6
+ require 'rubygems'
7
+ gem 'rspec'
8
+ require 'spec'
9
+ end
10
+
data/spec/target_00.rb ADDED
@@ -0,0 +1,11 @@
1
+
2
+ def target_func_00
3
+ if $target_00.nil? or $target_00.keys.size > 0
4
+ $target_00 = Hash.new
5
+ end
6
+
7
+ # This comment is line 7
8
+ $target_00['one'] = 1
9
+ $target_00['two'] = 2
10
+ $target_00['three'] = 3
11
+ end
data/spec/target_01.rb ADDED
@@ -0,0 +1,5 @@
1
+ def target_func_01
2
+ a = 1 + 1
3
+ b = 2 + 2
4
+ c = 3 + 3
5
+ end
data/spec/target_02.rb ADDED
@@ -0,0 +1,13 @@
1
+ class Foo
2
+ def foo
3
+ return 3**3 # do something
4
+ end
5
+ end
6
+
7
+ class Bar
8
+ def bar
9
+ f = Foo.new
10
+ f.foo
11
+ end
12
+ end
13
+
@@ -0,0 +1,34 @@
1
+ desc 'Release the website and new gem version'
2
+ task :deploy => [:check_version, :website, :release] do
3
+ puts "Remember to create SVN tag:"
4
+ puts "svn copy svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/trunk " +
5
+ "svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/tags/REL-#{VERS} "
6
+ puts "Suggested comment:"
7
+ puts "Tagging release #{CHANGES}"
8
+ end
9
+
10
+ desc 'Runs tasks website_generate and install_gem as a local deployment of the gem'
11
+ task :local_deploy => [:website_generate, :install_gem]
12
+
13
+ task :check_version do
14
+ unless ENV['VERSION']
15
+ puts 'Must pass a VERSION=x.y.z release version'
16
+ exit
17
+ end
18
+ unless ENV['VERSION'] == VERS
19
+ puts "Please update your version.rb to match the release version, currently #{VERS}"
20
+ exit
21
+ end
22
+ end
23
+
24
+ desc 'Install the package as a gem, without generating documentation(ri/rdoc)'
25
+ task :install_gem_no_doc => [:clean, :package] do
26
+ sh "#{'sudo ' unless Hoe::WINDOZE }gem install pkg/*.gem --no-rdoc --no-ri"
27
+ end
28
+
29
+ namespace :manifest do
30
+ desc 'Recreate Manifest.txt to include ALL files'
31
+ task :refresh do
32
+ `rake check_manifest | patch -p0 > Manifest.txt`
33
+ end
34
+ end
@@ -0,0 +1,7 @@
1
+ task :ruby_env do
2
+ RUBY_APP = if RUBY_PLATFORM =~ /java/
3
+ "jruby"
4
+ else
5
+ "ruby"
6
+ end unless defined? RUBY_APP
7
+ end
data/tasks/rspec.rake ADDED
@@ -0,0 +1,21 @@
1
+ # begin
2
+ # require 'spec'
3
+ # rescue LoadError
4
+ # require 'rubygems'
5
+ # require 'spec'
6
+ # end
7
+ begin
8
+ require 'spec/rake/spectask'
9
+ rescue LoadError
10
+ puts <<-EOS
11
+ To use rspec for testing you must install rspec gem:
12
+ gem install rspec
13
+ EOS
14
+ exit(0)
15
+ end
16
+
17
+ desc "Run the specs under spec/models"
18
+ Spec::Rake::SpecTask.new do |t|
19
+ t.spec_opts = ['--options', "spec/spec.opts"]
20
+ t.spec_files = FileList['spec/*_spec.rb']
21
+ end
@@ -0,0 +1,17 @@
1
+ desc 'Generate website files'
2
+ task :website_generate => :ruby_env do
3
+ (Dir['website/**/*.txt'] - Dir['website/version*.txt']).each do |txt|
4
+ sh %{ #{RUBY_APP} script/txt2html #{txt} > #{txt.gsub(/txt$/,'html')} }
5
+ end
6
+ end
7
+
8
+ desc 'Upload website files to rubyforge'
9
+ task :website_upload do
10
+ host = "#{rubyforge_username}@rubyforge.org"
11
+ remote_dir = "/var/www/gforge-projects/#{PATH}/"
12
+ local_dir = 'website'
13
+ sh %{rsync -aCv #{local_dir}/ #{host}:#{remote_dir}}
14
+ end
15
+
16
+ desc 'Generate and upload website files'
17
+ task :website => [:website_generate, :website_upload, :publish_docs]
@@ -0,0 +1,138 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <link rel="stylesheet" href="stylesheets/screen.css" type="text/css" media="screen" />
6
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
+ <title>
8
+ fault_injection.rb
9
+ </title>
10
+ <script src="javascripts/rounded_corners_lite.inc.js" type="text/javascript"></script>
11
+ <style>
12
+
13
+ </style>
14
+ <!--
15
+ <script type="text/javascript">
16
+ window.onload = function() {
17
+ settings = {
18
+ tl: { radius: 10 },
19
+ tr: { radius: 10 },
20
+ bl: { radius: 10 },
21
+ br: { radius: 10 },
22
+ antiAlias: true,
23
+ autoPad: true,
24
+ validTags: ["div"]
25
+ }
26
+ var versionBox = new curvyCorners(settings, document.getElementById("version"));
27
+ versionBox.applyCornersToAll();
28
+ }
29
+ </script>
30
+ -->
31
+ </head>
32
+ <body>
33
+ <div id="main">
34
+
35
+ <h1>fault_injection.rb</h1>
36
+ <div style="text-align:right;">
37
+ Last version: <a href="http://rubyforge.org/projects/fault_injection" class="numbers">0.0.1</a>
38
+ </div>
39
+ <h2>Overview</h2>
40
+
41
+
42
+ <h3>What is it?</h3>
43
+
44
+
45
+ <p>A &#8216;fault injection&#8217; tool for ruby.</p>
46
+
47
+
48
+ <h3>What is a &#8216;fault injection&#8217;? What is it used for?</h3>
49
+
50
+
51
+ <p>Fault injection is one of testing techniques.
52
+ It makes easier to test your application&#8217;s error handling behavior or
53
+ to improve the coverage of your tests.</p>
54
+
55
+
56
+ <p>See <a herf="http://en.wikipedia.org/wiki/Fault_injection">
57
+ http://en.wikipedia.org/wiki/Fault_injection
58
+ </a> for more details.</p>
59
+
60
+
61
+ <h3>Can I use it in my application code?</h3>
62
+
63
+
64
+ <p>No. It is for your testing code.</p>
65
+
66
+
67
+ <h3>Can I use it everywhere in my test code?</h3>
68
+
69
+
70
+ <p>You should not. It is for some limited situation that rarely
71
+ happen or difficult to set up (ex. IOError).
72
+ If you can make &#8216;evil situation&#8217; easily, that&#8217;s better ;)</p>
73
+
74
+
75
+ <h2>Installing</h2>
76
+
77
+
78
+ <p><pre class='syntax'><span class="ident">sudo</span> <span class="ident">gem</span> <span class="ident">install</span> <span class="ident">faultinjection</span></pre></p>
79
+
80
+
81
+ <h2>Sample codes</h2>
82
+
83
+
84
+ <p><pre class='syntax'>
85
+
86
+ <span class="comment"># sample.rb</span>
87
+ <span class="keyword">class </span><span class="class">Foo</span>
88
+ <span class="keyword">def </span><span class="method">foo</span>
89
+ <span class="ident">puts</span> <span class="punct">&quot;</span><span class="string">I love injection</span><span class="punct">&quot;</span>
90
+ <span class="keyword">end</span>
91
+
92
+ <span class="keyword">def </span><span class="method">bar</span>
93
+ <span class="number">10</span> <span class="punct">/</span> <span class="number">2</span> <span class="comment"># this is line 7</span>
94
+ <span class="keyword">end</span>
95
+ <span class="keyword">end</span>
96
+
97
+ <span class="comment"># test.rb</span>
98
+ <span class="ident">require</span> <span class="punct">'</span><span class="string">fault_injection</span><span class="punct">'</span>
99
+ <span class="ident">include</span> <span class="constant">FaultInjection</span>
100
+
101
+ <span class="ident">inject</span> <span class="punct">&quot;</span><span class="string">Foo#foo &gt; Kernel#puts</span><span class="punct">&quot;,</span> <span class="constant">IOError</span><span class="punct">,</span> <span class="punct">&quot;</span><span class="string">IO error</span><span class="punct">&quot;</span>
102
+
103
+ <span class="ident">f</span> <span class="punct">=</span> <span class="constant">Foo</span><span class="punct">.</span><span class="ident">new</span>
104
+ <span class="ident">f</span><span class="punct">.</span><span class="ident">foo</span> <span class="comment">#=&gt; IOError</span>
105
+
106
+ <span class="ident">inject</span> <span class="punct">&quot;</span><span class="string">sample.rb:7</span><span class="punct">&quot;,</span><span class="constant">ZeroDivisionError</span>
107
+
108
+ <span class="ident">f</span><span class="punct">.</span><span class="ident">bar</span> <span class="comment">#=&gt; ZeroDivisionError</span>
109
+
110
+ </pre></p>
111
+
112
+
113
+ <h2>License</h2>
114
+
115
+
116
+ <p>This code is free to use under the terms of the <span class="caps">MIT</span> license.</p>
117
+
118
+
119
+ <h2>Contact</h2>
120
+
121
+
122
+ <p>The <span class="caps">SVN</span> repository is available at http://faultinjection.rubyforge.org/svn/ for anonymous access.</p>
123
+
124
+
125
+ <p>Comments are welcome. Feel free to Send an email to keisukefukuda.spam@gmail.com</p>
126
+
127
+
128
+ <p>(Please remove &#8221;.spam&#8221; from the address for anti-spam, and include &#8216;ruby&#8217; or &#8216;fault_injection&#8217; in the title)</p>
129
+ <p class="coda">
130
+ <a href="keisukefukuda.spam@gmail.com">Keisuke Fukuda</a>, 11th January 2008<br>
131
+ Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
132
+ </p>
133
+ </div>
134
+
135
+ <!-- insert site tracking codes here, like Google Urchin -->
136
+
137
+ </body>
138
+ </html>
data/website/index.txt ADDED
@@ -0,0 +1,74 @@
1
+ h1. fault_injection.rb
2
+
3
+ h2. Overview
4
+
5
+ h3. What is it?
6
+
7
+ A 'fault injection' tool for ruby.
8
+
9
+ h3. What is a 'fault injection'? What is it used for?
10
+
11
+ Fault injection is one of testing techniques.
12
+ It makes easier to test your application's error handling behavior or
13
+ to improve the coverage of your tests.
14
+
15
+ See <a herf="http://en.wikipedia.org/wiki/Fault_injection">
16
+ http://en.wikipedia.org/wiki/Fault_injection
17
+ </a> for more details.
18
+
19
+ h3. Can I use it in my application code?
20
+
21
+ No. It is for your testing code.
22
+
23
+ h3. Can I use it everywhere in my test code?
24
+
25
+ You should not. It is for some limited situation that rarely
26
+ happen or difficult to set up (ex. IOError).
27
+ If you can make 'evil situation' easily, that's better ;)
28
+
29
+ h2. Installing
30
+
31
+ <pre syntax="ruby">sudo gem install faultinjection</pre>
32
+
33
+ h2. Sample codes
34
+
35
+ <pre syntax="ruby">
36
+
37
+ # sample.rb
38
+ class Foo
39
+ def foo
40
+ puts "I love injection"
41
+ end
42
+
43
+ def bar
44
+ 10 / 2 # this is line 7
45
+ end
46
+ end
47
+
48
+ # test.rb
49
+ require 'fault_injection'
50
+ include FaultInjection
51
+
52
+ inject "Foo#foo > Kernel#puts", IOError, "IO error"
53
+
54
+ f = Foo.new
55
+ f.foo #=> IOError
56
+
57
+ inject "sample.rb:7",ZeroDivisionError
58
+
59
+ f.bar #=> ZeroDivisionError
60
+
61
+ </pre>
62
+
63
+ h2. License
64
+
65
+ This code is free to use under the terms of the MIT license.
66
+
67
+ h2. Contact
68
+
69
+ The SVN repository is available at http://faultinjection.rubyforge.org/svn/ for anonymous access.
70
+
71
+ Comments are welcome. Feel free to Send an email to keisukefukuda.spam@gmail.com
72
+
73
+ (Please remove ".spam" from the address for anti-spam, and include 'ruby' or 'fault_injection' in the title)
74
+