Add `rake acceptance:boxes` to download required boxes for tests

This commit is contained in:
Mitchell Hashimoto 2011-11-13 13:37:30 -08:00
parent 71e23bd27c
commit bb06a20843
3 changed files with 104 additions and 3 deletions

View File

@ -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

View File

@ -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__)

View File

@ -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