nitra 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/README +3 -0
  2. data/bin/nitra +4 -0
  3. data/lib/nitra.rb +129 -0
  4. metadata +69 -0
data/README ADDED
@@ -0,0 +1,3 @@
1
+ Nitra is a multi-process rspec runner.
2
+
3
+ Copyright 2011 Powershop Limited, YouDo Limited. MIT licence.
data/bin/nitra ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'nitra'
4
+ Nitra.new.run
data/lib/nitra.rb ADDED
@@ -0,0 +1,129 @@
1
+ class Nitra
2
+ def run
3
+ start_time = Time.now
4
+ ENV["RAILS_ENV"] = "nitra"
5
+
6
+ process_count = 4
7
+ debug = false
8
+
9
+ if false
10
+ process_count.times do |index|
11
+ puts "initialising database #{index+1}..."
12
+ ENV["TEST_ENV_NUMBER"] = (index + 1).to_s
13
+ system("bundle exec rake db:schema:load")
14
+ end
15
+ end
16
+
17
+ puts "loading rails environment..." if debug
18
+
19
+ ENV["TEST_ENV_NUMBER"] = "1"
20
+
21
+ require 'config/environment'
22
+ require 'rspec'
23
+ require 'stringio'
24
+
25
+ ActiveRecord::Base.connection.disconnect!
26
+
27
+ trap("SIGINT") { Process.kill("SIGKILL", Process.pid) }
28
+
29
+ pipes = (0...process_count).collect do |index|
30
+ server_sender_pipe = IO.pipe
31
+ client_sender_pipe = IO.pipe
32
+ fork do
33
+ server_sender_pipe[1].close
34
+ client_sender_pipe[0].close
35
+ rd = server_sender_pipe[0]
36
+ wr = client_sender_pipe[1]
37
+
38
+ ENV["TEST_ENV_NUMBER"] = (index + 1).to_s
39
+
40
+ database_config = YAML.load(ERB.new(IO.read("#{Rails.root}/config/database.yml")).result)[ENV["RAILS_ENV"]]
41
+ ActiveRecord::Base.establish_connection(database_config)
42
+ Rails.cache.reset if Rails.cache.respond_to?(:reset)
43
+
44
+ puts "announcing availability" if debug
45
+ wr.write("0\n")
46
+
47
+ io = StringIO.new
48
+ loop do
49
+ puts "#{index} waiting for next job" if debug
50
+ filename = rd.gets
51
+ exit if filename.blank?
52
+ filename = filename.chomp
53
+ puts "#{index} starting to process #{filename}" if debug
54
+
55
+ RSpec::Core::CommandLine.new(["-f", "p", filename]).run(io, io)
56
+ RSpec.reset
57
+
58
+ wr.write("#{io.string.length}\n#{io.string}")
59
+ io.string = ""
60
+ end
61
+ end
62
+ server_sender_pipe[0].close
63
+ client_sender_pipe[1].close
64
+ [client_sender_pipe[0], server_sender_pipe[1]]
65
+ end
66
+
67
+ readers = pipes.collect(&:first)
68
+ files = Dir["spec/**/*_spec.rb"]
69
+
70
+ return if files.empty?
71
+
72
+ puts "Running rspec on #{files.length} files spread across #{process_count} processes\n\n"
73
+
74
+ @columns = (ENV['COLUMNS'] || 120).to_i
75
+ @file_count = files.length
76
+ @files_completed = 0
77
+ @example_count = 0
78
+ @failure_count = 0
79
+
80
+ result = ""
81
+ while readers.length > 0
82
+ print_progress
83
+ fds = IO.select(readers)
84
+ fds.first.each do |fd|
85
+ length = fd.gets
86
+
87
+ if length.nil?
88
+ break
89
+ elsif length.to_i > 0
90
+ data = fd.read(length.to_i)
91
+
92
+ @files_completed += 1
93
+ if m = data.match(/(\d+) examples?, (\d+) failure/)
94
+ @example_count += m[1].to_i
95
+ @failure_count += m[2].to_i
96
+ end
97
+
98
+ result << data.gsub(/^[.FP]+$/, '').gsub(/\nFailed examples:.+/m, '').gsub(/^Finished in.+$/, '').gsub(/^\d+ example.+$/, '').gsub(/^No examples found.$/, '').gsub(/^Failures:$/, '')
99
+ else
100
+ puts "ZERO LENGTH" if debug
101
+ end
102
+
103
+ wr = pipes.detect {|rd, wr| rd == fd}[1]
104
+ if files.length.zero?
105
+ wr.puts ""
106
+ readers.delete(fd)
107
+ else
108
+ puts "master is sending #{files.first} to fd #{wr}" if debug
109
+ wr.puts files.shift
110
+ end
111
+ end
112
+ end
113
+
114
+ print_progress
115
+ puts ""
116
+ result = result.gsub(/\n\n\n+/, "\n\n")
117
+ puts result
118
+ puts "\nFinished in #{"%0.1f" % (Time.now-start_time)} seconds"
119
+ end
120
+
121
+ protected
122
+ def print_progress
123
+ bar_length = @columns - 50
124
+ progress = @files_completed / @file_count.to_f
125
+ length_completed = (progress * bar_length).to_i
126
+ length_to_go = bar_length - length_completed
127
+ print "[#{"X" * length_completed}#{"." * length_to_go}] #{@files_completed}/#{@file_count} (#{"%0.1f%%" % (progress*100)}) * #{@example_count} examples, #{@failure_count} failures\r"
128
+ end
129
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nitra
3
+ version: !ruby/object:Gem::Version
4
+ hash: 57
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 9
9
+ - 1
10
+ version: 0.9.1
11
+ platform: ruby
12
+ authors:
13
+ - Roger Nesbitt
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-11-22 00:00:00 +13:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Multi-process rspec runner
23
+ email: roger@youdo.co.nz
24
+ executables:
25
+ - nitra
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - README
32
+ - lib/nitra.rb
33
+ - bin/nitra
34
+ has_rdoc: true
35
+ homepage:
36
+ licenses: []
37
+
38
+ post_install_message:
39
+ rdoc_options: []
40
+
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ hash: 3
49
+ segments:
50
+ - 0
51
+ version: "0"
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ requirements: []
62
+
63
+ rubyforge_project:
64
+ rubygems_version: 1.5.3
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: Multi-process rspec runner
68
+ test_files: []
69
+