require 'digest/sha1' require 'net/http' require 'pathname' require 'uri' require 'yaml' require 'childprocess' 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("../../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"] print "OK\n" next else print "FAIL\n" end end # Download the file. Note that this has no error checking and just uses # pure net/http. There could be a better way. puts "Downloading: #{box["url"]}" destination = box_file.open("wb") uri = URI.parse(box["url"]) Net::HTTP.new(uri.host, uri.port).start do |http| http.request_get(uri.request_uri) do |response| total = response.content_length progress = 0 count = 0 response.read_body do |segment| # Really elementary progress meter progress += segment.length count += 1 puts "Progress: #{(progress.to_f / total.to_f) * 100}%" if count % 300 == 0 # Write out to the destination file destination.write(segment) end end end destination.close # 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, :box_dir do |t, args| require File.expand_path("../../lib/vagrant/version", __FILE__) require File.expand_path('../../test/support/tempdir', __FILE__) # Get the directory for the boxes box_dir = Pathname.new(args[:box_dir] || File.expand_path("../../boxes", __FILE__)) # Generate the binstubs for the Vagrant binary tempdir = Tempdir.new process = ChildProcess.build("bundle", "install", "--binstubs", tempdir.path) process.io.inherit! process.start process.poll_for_exit(64000) if process.exit_code != 0 # Bundle install failed... puts "Bundle install failed!" abort end # Generate the actual configuration config = { "vagrant_path" => File.join(tempdir.path, "vagrant"), "vagrant_version" => Vagrant::VERSION, "env" => { "BUNDLE_GEMFILE" => File.expand_path("../../Gemfile", __FILE__) }, "box_directory" => box_dir.to_s } File.open("acceptance_config.yml", "w+") do |f| f.write(YAML.dump(config)) end puts <<-OUTPUT Acceptance test configuration is now in this directory in "acceptance_config.yml." Set your ACCEPTANCE_CONFIG environmental variable to this file and run any of the acceptance tests now. OUTPUT end end