Box downloading works (Actions::Box::Download)

This commit is contained in:
Mitchell Hashimoto 2010-02-22 17:34:44 -08:00
parent 6b705cbe42
commit 1856d56431
10 changed files with 128 additions and 5 deletions

View File

@ -3,7 +3,7 @@ $:.unshift(libdir)
PROJECT_ROOT = File.join(libdir, '..') unless defined?(PROJECT_ROOT)
# The libs which must be loaded prior to the rest
%w{ftools json pathname logger virtualbox net/ssh tarruby
%w{tempfile open-uri ftools json pathname logger virtualbox net/ssh tarruby
net/scp fileutils vagrant/util vagrant/actions/base}.each do |f|
require f
end

View File

@ -2,6 +2,15 @@ module Vagrant
module Actions
module Box
class Add < Base
def initialize(runner, name, path, *args)
super
@name = name
@uri = path
end
def prepare
@runner.add_action(Download, @uri)
end
end
end
end

View File

@ -4,6 +4,36 @@ module Vagrant
# An action which acts on a box by downloading the box file from
# the given URI into a temporary location.
class Download < Base
BASENAME = "box"
BUFFERSIZE = 1048576 # 1 MB
def initialize(runner, uri, *args)
super
@uri = uri
end
def execute!
with_tempfile do |tempfile|
copy_uri_to(tempfile)
end
end
def with_tempfile
logger.info "Creating tempfile for storing box file..."
Tempfile.open(BASENAME, Env.tmp_path) do |tempfile|
yield tempfile
end
end
def copy_uri_to(f)
logger.info "Copying box to temporary location..."
open(@uri) do |remote_file|
loop do
break if remote_file.eof?
f.write(remote_file.read(BUFFERSIZE))
end
end
end
end
end
end

View File

@ -139,6 +139,8 @@ error
# which action to take and calls the respective action method
# (see {box_add} and {box_remove})
def box(argv)
Env.load!
sub_commands = ["add", "remove"]
if !sub_commands.include?(argv[0])

View File

@ -13,6 +13,8 @@ module Vagrant
def persisted_vm; @@persisted_vm; end
def root_path; @@root_path; end
def dotfile_path; File.join(root_path, Vagrant.config.dotfile_name); end
def home_path; File.expand_path(Vagrant.config.vagrant.home); end
def tmp_path; File.join(home_path, "tmp"); end
def load!
load_root_path!

View File

@ -66,15 +66,15 @@ class Test::Unit::TestCase
end
# Sets up the mocks and instantiates an action for testing
def mock_action(action_klass)
def mock_action(action_klass, *args)
@vm = mock("vboxvm")
@mock_vm = mock("vm")
@mock_vm.stubs(:vm).returns(@vm)
@mock_vm.stubs(:vm=)
@mock_vm.stubs(:invoke_callback)
@mock_vm.stubs(:invoke_around_callback).yields
@action = action_klass.new(@mock_vm)
@action = action_klass.new(@mock_vm, *args)
[@mock_vm, @vm, @action]
end

View File

@ -0,0 +1,10 @@
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
class AddBoxActionTest < Test::Unit::TestCase
setup do
@wrapper_vm, @vm, @action = mock_action(Vagrant::Actions::Box::Add)
mock_config
end
# TODO: Everything, once add does anything.
end

View File

@ -2,7 +2,60 @@ require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
class DownloadBoxActionTest < Test::Unit::TestCase
setup do
@wrapper_vm, @vm, @action = mock_action(Vagrant::Actions::Box::Download)
@uri = "foo.com"
@wrapper_vm, @vm, @action = mock_action(Vagrant::Actions::Box::Download, @uri)
mock_config
Vagrant::Env.stubs(:tmp_path).returns("foo")
end
context "executing" do
setup do
@tempfile = mock("tempfile")
end
should "make a tempfile and copy the URI contents to it" do
@action.expects(:with_tempfile).yields(@tempfile)
@action.expects(:copy_uri_to).with(@tempfile)
@action.execute!
end
end
context "tempfile" do
should "create a tempfile in the vagrant tmp directory" do
Tempfile.expects(:open).with(Vagrant::Actions::Box::Download::BASENAME, Vagrant::Env.tmp_path).once
@action.with_tempfile
end
should "yield the tempfile object" do
@tempfile = mock("tempfile")
Tempfile.expects(:open).yields(@tempfile)
@action.with_tempfile do |otherfile|
assert @tempfile.equal?(otherfile)
end
end
end
context "copying URI file" do
setup do
@tempfile = mock("tempfile")
@tempfile.stubs(:write)
@file = mock("file")
@file.stubs(:read)
@file.stubs(:eof?).returns(false)
@action.stubs(:open).yields(@file)
end
should "read from the file and write to the tempfile" do
data = mock("data")
write_seq = sequence("write_seq")
@file.stubs(:eof?).returns(false).in_sequence(write_seq)
@file.expects(:read).returns(data).in_sequence(write_seq)
@tempfile.expects(:write).with(data).in_sequence(write_seq)
@file.stubs(:eof?).returns(true).in_sequence(write_seq)
@action.copy_uri_to(@tempfile)
end
end
end

View File

@ -173,6 +173,11 @@ class CommandsTest < Test::Unit::TestCase
Vagrant::Commands.stubs(:box_remove)
end
should "load the environment" do
Vagrant::Env.expects(:load!).once
Vagrant::Commands.box(["add"])
end
should "error and exit if the first argument is not 'add' or 'remove'" do
Vagrant::Commands.expects(:error_and_exit).once
Vagrant::Commands.box(["foo"])

View File

@ -180,4 +180,16 @@ class EnvTest < Test::Unit::TestCase
assert_equal path, Vagrant::Env.root_path
end
end
context "home directory paths" do
should "return the expanded config for `home_path`" do
assert_equal File.expand_path(Vagrant.config.vagrant.home), Vagrant::Env.home_path
end
should "return the home_path joined with tmp for a tmp path" do
@home_path = "foo"
Vagrant::Env.stubs(:home_path).returns(@home_path)
assert_equal File.join(@home_path, "tmp"), Vagrant::Env.tmp_path
end
end
end