Skip to content

Commit

Permalink
Add rake acceptance:boxes to download required boxes for tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchellh committed Nov 13, 2011
1 parent 71e23bd commit bb06a20
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 3 deletions.
38 changes: 38 additions & 0 deletions lib/vagrant/util/file_checksum.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# This is an "interface" that should be implemented by any digest class
# passed into FileChecksum. Note that this isn't strictly enforced at
# the moment, and this class isn't directly used. It is merely here for
# documentation of structure of the class.
class DigestClass
def update(string); end
def hexdigest; end
end

class FileChecksum
BUFFER_SIZE = 1024

# Initializes an object to calculate the checksum of a file. The given
# ``digest_klass`` should implement the ``DigestClass`` interface. Note
# that the built-in Ruby digest classes duck type this properly:
# Digest::MD5, Digest::SHA1, etc.
def initialize(path, digest_klass)
@digest_klass = digest_klass
@path = path
end

# This calculates the checksum of the file and returns it as a
# string.
#
# @return [String]
def checksum
digest= @digest_klass.new

File.open(@path, "r") do |f|
while !f.eof
buf = f.readpartial(BUFFER_SIZE)
digest.update(buf)
end
end

return digest.hexdigest
end
end
62 changes: 59 additions & 3 deletions tasks/acceptance.rake
Original file line number Diff line number Diff line change
@@ -1,9 +1,65 @@
require 'digest/sha1'
require 'pathname'
require 'yaml'

require 'posix-spawn'

require 'vagrant/util/file_checksum'

namespace :acceptance do
desc "Downloads the boxes required for running the acceptance tests."
task :boxes, :directory do |t, args|
# Create the directory where the boxes will be downloaded
box_dir = Pathname.new(args[:directory] || File.expand_path("../../test/tmp/boxes", __FILE__))
box_dir.mkpath
puts "Boxes will be placed in: #{box_dir}"

# Load the required boxes
boxes = YAML.load_file(File.expand_path("../../test/config/acceptance_boxes.yml", __FILE__))

boxes.each do |box|
puts "Box: #{box["name"]}"
box_file = box_dir.join("#{box["name"]}.box")
checksum = FileChecksum.new(box_file, Digest::SHA1)

# If the box exists, we need to check the checksum and determine if we need
# to redownload the file.
if box_file.exist?
print "Box exists, checking SHA1 sum... "
if checksum.checksum == box["checksum"]
puts "OK"
next
else
puts "FAIL"
end
end

# Download the file
puts "Downloading: #{box["url"]}"

# TODO: This isn't Windows friendly yet. Move to a OS-independent
# download.
pid, _stdin, stdout, stderr =
POSIX::Spawn.popen4("wget", box["url"], "-O", box_file.to_s)
pid, status = Process.waitpid2(pid)
if status.exitstatus != 0
puts "Download failed!"
puts stdout.read
puts stderr.read
abort
end

# Check the checksum of the new file to verify that it
# downloaded properly. This shouldn't happen, but it can!
if checksum.checksum != box["checksum"]
puts "Checksum didn't match! Download was corrupt!"
abort
end
end
end

desc "Generates the configuration for acceptance tests from current source."
task :config do
require 'yaml'
require 'posix-spawn'

require File.expand_path("../lib/vagrant/version", __FILE__)
require File.expand_path('../test/acceptance/support/tempdir', __FILE__)

Expand Down
7 changes: 7 additions & 0 deletions test/config/acceptance_boxes.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# This is the list of required boxes for acceptance tests, and
# their locations. The locations are used to download the boxes
# on the fly, if necessary. Additionally, a SHA1 checksum is
# given to determine if the box needs to be updated.
- name: default
url: http://files.vagrantup.com/test/boxes/default.box
checksum: 1b0a7eb6e152c5b43f45485654ff4965a7f9f604

0 comments on commit bb06a20

Please sign in to comment.