diff options
author | Luke Kanies <luke@puppetlabs.com> | 2010-06-10 12:54:50 -0400 |
---|---|---|
committer | test branch <puppet-dev@googlegroups.com> | 2010-02-17 06:50:53 -0800 |
commit | 182c0033dcc1885a42bd0cbb429d278f53ae9480 (patch) | |
tree | 89151e30f8c39af556033dd9f0ea91f359562d1a /autotest | |
parent | 3a44f0e4826b8677323d3c1be55263dfa94f3305 (diff) | |
download | puppet-182c0033dcc1885a42bd0cbb429d278f53ae9480.tar.gz puppet-182c0033dcc1885a42bd0cbb429d278f53ae9480.tar.xz puppet-182c0033dcc1885a42bd0cbb429d278f53ae9480.zip |
Fixing #3988 - adding support for watchr
Also added a readme file explaining a bit of how the
continuous testing tools work.
Signed-off-by: Luke Kanies <luke@puppetlabs.com>
Diffstat (limited to 'autotest')
-rw-r--r-- | autotest/README.markdown | 45 | ||||
-rw-r--r-- | autotest/images/fail.png | bin | 0 -> 19978 bytes | |||
-rw-r--r-- | autotest/images/pass.png | bin | 0 -> 21763 bytes | |||
-rw-r--r-- | autotest/images/pending.png | bin | 0 -> 19745 bytes | |||
-rw-r--r-- | autotest/watcher.rb | 138 |
5 files changed, 183 insertions, 0 deletions
diff --git a/autotest/README.markdown b/autotest/README.markdown new file mode 100644 index 000000000..4cb3d8370 --- /dev/null +++ b/autotest/README.markdown @@ -0,0 +1,45 @@ +# Continuous Testing + +This directory contains configurations for continuous testing, using +either autotest (part of the ZenTest gem) or watchr (in the watchr +gem). The purpose of these tools is to automatically run the +appropriate test when a file is changed or, if appropriate, all +tests. In general, they do a straightforward mapping from a given +code file to its unit and/or integration test. + +It is highly recommended that you have one of these running at all +times during development, as they provide immediate and continuous +feedback as to your development process. There are some general +usability downsides as you have to track the running process, but +those downsides are easily worth it. + +# How to use + +To use autotest, install ZenTest and run it with no arguments +from the root of the puppet repository: + + $ autotest + +It is currently only configured to run specs. + +To use watchr, run it with the watchr file specified as its argument: + + $ watchr autotest/watcher.rb + +Both will use growl if installed on a Mac, but watchr assumes the +presence of growl and will likely fail without it. Autotest is a bit +more mature and should be resilient to either. + +The primary reason to use to use watchr over autotest is that it uses +filesystem events to detect changes (theoretically portably although +only tested on OS X), thus eliminating the need for polling for +changes across all files being monitored. + +# Gotchas + +Autotest will start out by running all tests; if you don't want that, +stick a syntax error in one of the tests to force a failure, then fix +it and go on your merry way. + +Watchr, on the other hand, will default to only running the files you +change. diff --git a/autotest/images/fail.png b/autotest/images/fail.png Binary files differnew file mode 100644 index 000000000..2d5539442 --- /dev/null +++ b/autotest/images/fail.png diff --git a/autotest/images/pass.png b/autotest/images/pass.png Binary files differnew file mode 100644 index 000000000..cbe537186 --- /dev/null +++ b/autotest/images/pass.png diff --git a/autotest/images/pending.png b/autotest/images/pending.png Binary files differnew file mode 100644 index 000000000..b8cf9a391 --- /dev/null +++ b/autotest/images/pending.png diff --git a/autotest/watcher.rb b/autotest/watcher.rb new file mode 100644 index 000000000..61baf49d0 --- /dev/null +++ b/autotest/watcher.rb @@ -0,0 +1,138 @@ +ENV["WATCHR"] = "1" +ENV['AUTOTEST'] = 'true' + +def run_comp(cmd) + puts cmd + results = [] + old_sync = $stdout.sync + $stdout.sync = true + line = [] + begin + open("| #{cmd}", "r") do |f| + until f.eof? do + c = f.getc + putc c + line << c + if c == ?\n then + results << if RUBY_VERSION >= "1.9" then + line.join + else + line.pack "c*" + end + line.clear + end + end + end + ensure + $stdout.sync = old_sync + end + results.join +end + +def clear + #system("clear") +end + +def growl(message, status) + # Strip the color codes + message.gsub!(/\[\d+m/, '') + + growlnotify = `which growlnotify`.chomp + return if growlnotify.empty? + title = "Watchr Test Results" + image = status == :pass ? "autotest/images/pass.png" : "autotest/images/fail.png" + options = "-w -n Watchr --image '#{File.expand_path(image)}' -m '#{message}' '#{title}'" + system %(#{growlnotify} #{options} &) +end + +def file2specs(file) + %w{spec/unit spec/integration}.collect { |d| + file.sub('lib/puppet', d) + }.find_all { |f| + File.exist?(f) + } +end + +def file2test(file) + result = file.sub('lib/puppet', 'test') + return nil unless File.exist?(result) + result +end + +def run_spec(command) + clear + result = run_comp(command).split("\n").last + status = result.include?('0 failures') ? :pass : :fail + growl result, status +end + +def run_test(command) + clear + result = run_comp(command).split("\n").last + status = result.include?('0 failures, 0 errors') ? :pass : :fail + growl result.split("\n").last rescue nil +end + +def run_test_file(file) + run_test(%Q(#{file})) +end + +def run_spec_files(files) + files = Array(files) + return if files.empty? + opts = File.readlines('spec/spec.opts').collect { |l| l.chomp }.join(" ") + run_spec("spec #{files.join(' ')}") +end + +def run_all_tests + run_test("rake unit") +end + +def run_all_specs + run_test("rake spec") +end + +def run_suite + run_all_tests + run_all_specs +end + +watch('spec/spec_helper.rb') { run_all_specs } +watch(%r%^spec/(unit|integration)/.*\.rb$%) { |md| run_spec_files(md[0]) } +watch(%r%^lib/puppet/(.*)\.rb$%) { |md| + run_spec_files(file2specs(md[0])) + if t = file2test(md[0]) + run_test_file(t) + end +} +watch(%r!^spec/lib/spec.*!) { |md| run_all_specs } +watch(%r!^spec/lib/monkey_patches/.*!) { |md| run_all_specs } +watch(%r{test/.+\.rb}) { |md| + if md[0] =~ /\/lib\// + run_all_tests + else + run_test_file(md[0]) + end +} + +# Ctrl-\ +Signal.trap 'QUIT' do + puts " --- Running all tests ---\n\n" + run_suite +end + +@interrupted = false + +# Ctrl-C +Signal.trap 'INT' do + if @interrupted then + @wants_to_quit = true + abort("\n") + else + puts "Interrupt a second time to quit; wait for rerun of tests" + @interrupted = true + Kernel.sleep 1.5 + # raise Interrupt, nil # let the run loop catch it + run_suite + end +end |