First "up" based acceptance test. Multiple fixes to test harness.

* First test that uses "vagrant up"
* Allow interaction with processes executed during `execute` so that
  we can enter input into STDIN and receive data from STDOUT in
  real time.
* Fix some issue with `waitpid2`, which actually speeds up all tests
  quite a bit.
This commit is contained in:
Mitchell Hashimoto 2011-11-06 13:30:49 -08:00
parent 74b054a3d1
commit 421a1fb341
4 changed files with 82 additions and 11 deletions

View File

@ -36,8 +36,8 @@ class AcceptanceTest < Test::Unit::TestCase
# is just a shortcut to IsolatedEnvironment#execute.
#
# @return [Object]
def execute(*args)
@environment.execute(*args)
def execute(*args, &block)
@environment.execute(*args, &block)
end
# This is a shortcut method to instantiate an Output matcher.
@ -47,6 +47,15 @@ class AcceptanceTest < Test::Unit::TestCase
Acceptance::Output.new(text)
end
# This method is an assertion helper for asserting that a process
# succeeds. It is a wrapper around `execute` that asserts that the
# exit status was successful.
def assert_execute(*args, &block)
result = execute(*args, &block)
assert(result.success?, "expected '#{args.join(" ")}' to succeed")
result
end
setup do
# Setup the environment so that we have an isolated area
# to run Vagrant. We do some configuration here as well in order

View File

@ -41,7 +41,10 @@ module Acceptance
@homedir.mkdir
@workdir.mkdir
# Set the home directory and virtualbox home directory environmental
# variables so that Vagrant and VirtualBox see the proper paths here.
@env["HOME"] = @homedir.to_s
@env["VBOX_USER_HOME"] = @homedir.to_s
end
# Executes a command in the context of this isolated environment.
@ -57,26 +60,48 @@ module Acceptance
# return the IO streams.
@logger.info("Executing: #{command} #{argN.inspect}. Output will stream in...")
pid, stdin, stdout, stderr = popen4(@env, command, *argN)
status = nil
io_data = {
stdout => "",
stderr => ""
}
while results = IO.select([stdout, stderr], nil, nil, 5)
rs = results[0]
next if rs.empty?
while results = IO.select([stdout, stderr], [stdin], nil, 5)
# Check the readers first to see if they're ready
readers = results[0]
if !readers.empty?
begin
readers.each do |r|
data = r.readline
io_data[r] += data
rs.each do |r|
data = r.readline
io_data[r] += data
io_name = r == stdout ? "stdout" : "stderr"
@logger.debug("[#{io_name}] #{data.chomp}")
yield io_name.to_sym, data if block_given?
end
rescue EOFError
# Process exited, so break out of this while loop
break
end
end
io_name = r == stdout ? "stdout" : "stderr"
@logger.debug("[#{io_name}] #{data.chomp}")
# Check here if the process has exited, and if so, exit the
# loop.
exit_pid, status = Process.waitpid2(pid, Process::WNOHANG)
break if exit_pid
# Check the writers to see if they're ready, and notify any
# listeners...
if !results[1].empty?
yield :stdin, stdin if block_given?
end
end
_pid, status = Process.waitpid2(pid)
# Only load the exit status if we don't already have it, since
# it is possible that it could've been obtained in the above
# while loop.
_pid, status = Process.waitpid2(pid) if !status
@logger.debug("Exit status: #{status.exitstatus}")
return ExecuteProcess.new(status.exitstatus, io_data[stdout], io_data[stderr])

View File

@ -32,5 +32,11 @@ module Acceptance
def is_version?(version)
@text =~ /^Vagrant version #{version}$/
end
# This checks that the VM with the given `vm_name` has the
# status of `status`.
def status(vm_name, status)
@text =~ /^#{vm_name}\s+#{status}$/
end
end
end

View File

@ -0,0 +1,31 @@
require File.expand_path("../../base", __FILE__)
class BasicUpTest < AcceptanceTest
should "bring up a running virtual machine" do
assert_execute("vagrant", "box", "add", "base", config.boxes["default"])
assert_execute("vagrant", "init")
assert_execute("vagrant", "up")
result = assert_execute("vagrant", "status")
assert(output(result.stdout).status("default", "running"),
"Virtual machine should be running")
end
=begin
This shows how we can test that SSH is working. We'll use
this code later, but for now have no test that exercises it.
outputted = false
result = assert_execute("vagrant", "ssh") do |io_type, data|
if io_type == :stdin and !outputted
data.puts("echo hello")
data.puts("exit")
outputted = true
end
end
assert_equal("hello", result.stdout.chomp,
"Vagrant should bring up a virtual machine and be able to SSH in."
=end
end