flappinator 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,23 @@
1
+ # flappinator
2
+
3
+ A command-line utility to help debug flapping processes, including tests.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ gem install flappinator
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ The flappinator repeats any given command a number of times (25 by default). When it fails, the command's output is displayed.
14
+
15
+ ```bash
16
+ flappinator [ --repetitions=TIMES ] COMMAND
17
+ ```
18
+
19
+ For example:
20
+
21
+ ```bash
22
+ flappinator rspec spec/models/flapping_spec.rb
23
+ ```
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'flappinator'
4
+ Flappinator.start(ARGV)
@@ -0,0 +1,11 @@
1
+ require_relative 'flappinator/options'
2
+ require_relative 'flappinator/runner'
3
+
4
+ module Flappinator
5
+ def self.start(args)
6
+ options = Flappinator::Options.new(args)
7
+ options.parse!
8
+
9
+ Flappinator::Runner.start(options)
10
+ end
11
+ end
@@ -0,0 +1,40 @@
1
+ require 'optparse'
2
+
3
+ module Flappinator
4
+ class Options
5
+ attr_reader :command,
6
+ :repetitions
7
+
8
+ def initialize(args)
9
+ @args = args
10
+ @command = []
11
+ @repetitions = 25
12
+ end
13
+
14
+ def parse!
15
+ # Duplicate the arguments, as parsing is destructive.
16
+ args = @args.dup
17
+ parser.parse!(args)
18
+ # Assign the remaining unparsed arguments (the COMMAND).
19
+ @command = args
20
+ raise ArgumentError if @command.empty?
21
+ end
22
+
23
+ private
24
+
25
+ def parser
26
+ OptionParser.new do |parser|
27
+ parser.banner = 'Usage: flappinator [ options ] COMMAND'
28
+
29
+ parser.on('-r', '--repetitions=TIMES', Integer, 'Number of repetitions') do |times|
30
+ @repetitions = times
31
+ end
32
+
33
+ parser.on_tail('-h', '--help', 'Show this message') do
34
+ puts parser
35
+ exit
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,76 @@
1
+ require 'childprocess'
2
+ require 'ruby-progressbar'
3
+ require 'forwardable'
4
+ require 'tempfile'
5
+
6
+ module Flappinator
7
+ class Runner
8
+ def self.start(options)
9
+ @options = options
10
+
11
+ progress_bar
12
+
13
+ runs = @options.repetitions.times.map do |index|
14
+ new(@options.command).tap do |runner|
15
+ runner.run
16
+ log(runner.output) if runner.failed?
17
+ increment
18
+ end
19
+ end
20
+
21
+ summarize(runs)
22
+ end
23
+
24
+ def self.progress_bar
25
+ @progress_bar ||= ProgressBar.create(
26
+ :title => @options.command.join(' '),
27
+ :total => @options.repetitions,
28
+ :format => '%t %E %w'
29
+ )
30
+ end
31
+
32
+ def self.log(output)
33
+ output += "\n"
34
+ progress_bar.log(output)
35
+ end
36
+
37
+ def self.increment
38
+ # Work around a small display bug where intermittently the percentage
39
+ # shown is one frame behind:
40
+ sleep 0.1
41
+ progress_bar.increment
42
+ end
43
+
44
+ def self.summarize(runs)
45
+ puts "\nSuccess: #{runs.count(&:success?)}"
46
+ puts "Failed: #{runs.count(&:failed?)}"
47
+ end
48
+
49
+ def initialize(command)
50
+ @command = command
51
+ @process = ChildProcess.build(*@command)
52
+ @io = Tempfile.new('flappinator')
53
+ end
54
+
55
+ def run
56
+ @process.io.stdout = @io
57
+ @process.io.stderr = @io
58
+ @process.start
59
+ @process.wait
60
+ end
61
+
62
+ def output
63
+ @io.close
64
+ @io.open
65
+ @io.read
66
+ end
67
+
68
+ def success?
69
+ !@process.crashed?
70
+ end
71
+
72
+ def failed?
73
+ @process.crashed?
74
+ end
75
+ end
76
+ end
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flappinator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Todd Mazierski
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-05-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ruby-progressbar
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: childprocess
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: A command-line utility to help debug flapping processes, including tests.
47
+ email:
48
+ - todd@generalassemb.ly
49
+ executables:
50
+ - flappinator
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - README.md
55
+ - lib/flappinator/runner.rb
56
+ - lib/flappinator/options.rb
57
+ - lib/flappinator.rb
58
+ - bin/flappinator
59
+ homepage: https://github.com/toddmazierski/flappinator
60
+ licenses: []
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project:
79
+ rubygems_version: 1.8.23
80
+ signing_key:
81
+ specification_version: 3
82
+ summary: A command-line utility to help debug flapping processes, including tests.
83
+ test_files: []