Last active
December 19, 2015 01:48
-
-
Save pmarreck/5878023 to your computer and use it in GitHub Desktop.
TestStack, a cheap zeus-like bit of code to preload your stack for your iterative test running.
Based on ideas from Jesse Storimer.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# Teststack: A way to preload your Rails app stack for your iterative test running | |
# Based on ideas from Jesse Storimer here: | |
# http://www.jstorimer.com/blogs/workingwithcode/8136295-screencast-faster-rails-test-runs-with-unix | |
# https://gist.github.com/jstorimer/5862436 | |
# Usage: Run this file without args to run the server; run it with test file args to connect to the server and run tests | |
require 'socket' | |
# Monkeypatch IO to make streaming socket IO API nicer... | |
# Based on ideas from http://coderrr.wordpress.com/2008/10/21/when-to-use-readpartial-instead-of-read-in-ruby/ | |
class IO | |
def drain(data = nil) | |
while !self.closed? && buf = readpartial_rescued(1024) | |
data << buf if data && buf | |
yield buf if block_given? | |
end | |
data | |
end | |
private | |
def readpartial_rescued(size) | |
readpartial(size) | |
rescue EOFError | |
nil | |
end | |
end | |
class TestClient | |
def initialize(test_files = ARGV) | |
socket = UNIXSocket.new('.testing.sock') | |
ARGV.each do |test_file| | |
socket.write(test_file + "\n") | |
end | |
socket.close_write | |
socket.drain do |buf| | |
print buf | |
end | |
end | |
end | |
class TestServer | |
def initialize | |
ENV['RAILS_ENV'] = 'test' | |
%w[test lib .].each{ |p| $:.unshift(p) unless $:.include? p } | |
rails_boot = time { | |
require 'config/application' | |
require 'test/test_helper' | |
} | |
puts "Rails, config/application, and test/test_helper loaded after #{'%.2f' % rails_boot}s..." | |
puts "You may now run '#{File.basename __FILE__}' with test file arguments in another terminal window." | |
server = UNIXServer.new('.testing.sock') | |
parent_process_id = Process.pid | |
at_exit { | |
if Process.pid == parent_process_id | |
File.unlink('.testing.sock') | |
end | |
} | |
trap('INT') { exit } | |
loop do | |
client = server.accept | |
test_files = client.read.split("\n") | |
pid = fork do | |
$stdout.reopen(client) | |
test_files.each do |test_file| | |
require test_file | |
$stdout.flush | |
end | |
end | |
Process.wait(pid) | |
client.close | |
end | |
end | |
private | |
def time | |
t = Time.now | |
yield | |
Time.now - t | |
end | |
end | |
if ARGV.empty? | |
TestServer.new | |
else | |
TestClient.new | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment