From f09e7226910d25f57f9a0628a4dfc39e0ab18979 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sat, 20 Apr 2013 17:02:25 -0300 Subject: [PATCH 01/21] Basic scaffolding for acceptance specs --- spec/Vagrantfile | 13 ++++++ spec/acceptance/sanity_check_spec.rb | 68 ++++++++++++++++++++++++++++ spec/acceptance_helper.rb | 10 ++++ tasks/spec.rake | 3 +- 4 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 spec/Vagrantfile create mode 100644 spec/acceptance/sanity_check_spec.rb create mode 100644 spec/acceptance_helper.rb diff --git a/spec/Vagrantfile b/spec/Vagrantfile new file mode 100644 index 0000000..ca98915 --- /dev/null +++ b/spec/Vagrantfile @@ -0,0 +1,13 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +Vagrant.require_plugin 'vagrant-lxc' + +Vagrant.configure("2") do |config| + config.vm.box = "quantal64" + config.vm.hostname = 'lxc-test-box' + + config.vm.box_url = 'http://dl.dropbox.com/u/13510779/lxc-quantal64-2013-04-10.box' + # Uncomment to test boxes built locally: + # config.vm.box_url = '../boxes/output/lxc-quantal64.box' +end diff --git a/spec/acceptance/sanity_check_spec.rb b/spec/acceptance/sanity_check_spec.rb new file mode 100644 index 0000000..370864b --- /dev/null +++ b/spec/acceptance/sanity_check_spec.rb @@ -0,0 +1,68 @@ +require 'acceptance_helper' + +describe 'Sanity check' do + context 'running a `vagrant up` from scratch' do + before(:all) do + destroy_container + vagrant_up + end + + it 'creates a the container' + + it 'starts the newly created container' + + it 'mounts shared folders with the right permissions' + + it 'provisions the container based on Vagrantfile configs' + + it 'forwards configured ports' + + it "is able to be SSH'ed" + end + + context '`vagrant halt` on a running container' do + before(:all) do + destroy_container + vagrant_up + vagrant_halt + end + + it 'shuts down container' + + it 'clears forwarded ports' + end + + context '`vagrant destroy`' do + before(:all) do + destroy_container + vagrant_up + vagrant_destroy + end + + it 'destroys the underlying container' + end + + def destroy_container + `sudo lxc-shutdown -n \`cat /vagrant/spec/.vagrant/machines/default/lxc/id\`` + `sudo lxc-wait -n \`cat /vagrant/spec/.vagrant/machines/default/lxc/id\` --state STOPPED` + `sudo lxc-destroy -n \`cat /vagrant/spec/.vagrant/machines/default/lxc/id\`` + end + + def vagrant_up + opts = { cwd: 'spec' } + env = Vagrant::Environment.new(opts) + env.cli('up', '--provider', 'lxc') + end + + def vagrant_halt + opts = { cwd: 'spec' } + env = Vagrant::Environment.new(opts) + env.cli('halt') + end + + def vagrant_destroy + opts = { cwd: 'spec' } + env = Vagrant::Environment.new(opts) + env.cli('destroy', '-f') + end +end diff --git a/spec/acceptance_helper.rb b/spec/acceptance_helper.rb new file mode 100644 index 0000000..a71724e --- /dev/null +++ b/spec/acceptance_helper.rb @@ -0,0 +1,10 @@ +require 'spec_helper' + +require 'vagrant' +require 'vagrant-lxc' + +# RSpec.configure do |config| +# config.include AcceptanceExampleGroup, :type => :unit, :example_group => { +# :file_path => /\bspec\/unit\// +# } +# end diff --git a/tasks/spec.rake b/tasks/spec.rake index 8b2f3de..d7e61a6 100644 --- a/tasks/spec.rake +++ b/tasks/spec.rake @@ -1,9 +1,8 @@ begin require 'rspec/core/rake_task' - # TODO: add 'spec:acceptance' and 'spec:integration' then they are in place desc 'Run all specs' - task :spec => ['spec:unit'] + task :spec => ['spec:unit', 'spec:acceptance'] desc 'Default task which runs all specs with code coverage enabled' task :default => ['spec:set_coverage', 'spec'] From cd19ca4edacb0586eeae04e22dec60e2b1fa3ae9 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sat, 20 Apr 2013 17:38:01 -0300 Subject: [PATCH 02/21] Improve simplecov result merging --- spec/acceptance_helper.rb | 4 ++++ spec/spec_helper.rb | 10 ++-------- spec/unit_helper.rb | 4 ++++ tasks/spec.rake | 4 ++++ 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/spec/acceptance_helper.rb b/spec/acceptance_helper.rb index a71724e..0f2e04f 100644 --- a/spec/acceptance_helper.rb +++ b/spec/acceptance_helper.rb @@ -1,5 +1,9 @@ require 'spec_helper' +if defined? SimpleCov + SimpleCov.command_name 'acceptance' +end + require 'vagrant' require 'vagrant-lxc' diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 07038e7..bdbc54b 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -2,14 +2,8 @@ if ENV['COVERAGE'] require 'simplecov' require 'coveralls' - SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[ - SimpleCov::Formatter::HTMLFormatter, - Coveralls::SimpleCov::Formatter - ] - - SimpleCov.start do - add_filter { |source_file| source_file.filename =~ /\/spec\/support/ } - end + SimpleCov.start { add_filter '/spec/' } + SimpleCov.merge_timeout 300 end require 'bundler/setup' diff --git a/spec/unit_helper.rb b/spec/unit_helper.rb index 9104290..d091266 100644 --- a/spec/unit_helper.rb +++ b/spec/unit_helper.rb @@ -1,5 +1,9 @@ require 'spec_helper' +if defined? SimpleCov + SimpleCov.command_name 'unit' +end + RSpec.configure do |config| config.include RSpec::Fire diff --git a/tasks/spec.rake b/tasks/spec.rake index d7e61a6..12a4111 100644 --- a/tasks/spec.rake +++ b/tasks/spec.rake @@ -1,11 +1,15 @@ begin require 'rspec/core/rake_task' + require 'coveralls/rake/task' desc 'Run all specs' task :spec => ['spec:unit', 'spec:acceptance'] desc 'Default task which runs all specs with code coverage enabled' task :default => ['spec:set_coverage', 'spec'] + + Coveralls::RakeTask.new + task :ci => [:default, 'coveralls:push'] rescue LoadError; end namespace :spec do From 89ff86121f5f765e695cdc1263f1eaeae035b2d9 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sat, 20 Apr 2013 19:17:51 -0300 Subject: [PATCH 03/21] Cache apt packages used on acceptance specs to make them run faster --- spec/Vagrantfile | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/spec/Vagrantfile b/spec/Vagrantfile index ca98915..6a72bb2 100644 --- a/spec/Vagrantfile +++ b/spec/Vagrantfile @@ -1,6 +1,16 @@ # -*- mode: ruby -*- # vi: set ft=ruby : +def local_apt_cache(box_name) + cache_dir = File.join(File.expand_path(Vagrant::Environment::DEFAULT_HOME), + 'cache', + 'apt', + box_name) + partial_dir = File.join(cache_dir, 'partial') + FileUtils.mkdir_p(partial_dir) unless File.exists? partial_dir + cache_dir +end + Vagrant.require_plugin 'vagrant-lxc' Vagrant.configure("2") do |config| @@ -10,4 +20,7 @@ Vagrant.configure("2") do |config| config.vm.box_url = 'http://dl.dropbox.com/u/13510779/lxc-quantal64-2013-04-10.box' # Uncomment to test boxes built locally: # config.vm.box_url = '../boxes/output/lxc-quantal64.box' + + cache_dir = local_apt_cache(config.vm.box) + config.vm.synced_folder cache_dir, "/var/cache/apt/archives", id: "vagrant-apt-cache" end From 99bfe0fc4ab3beff3944f6a3d844d5be6ed5505e Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sat, 20 Apr 2013 19:19:11 -0300 Subject: [PATCH 04/21] Moar boilerplate for acceptance specs --- spec/acceptance/sanity_check_spec.rb | 52 ++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/spec/acceptance/sanity_check_spec.rb b/spec/acceptance/sanity_check_spec.rb index 370864b..f79222c 100644 --- a/spec/acceptance/sanity_check_spec.rb +++ b/spec/acceptance/sanity_check_spec.rb @@ -1,5 +1,42 @@ require 'acceptance_helper' +class TestUI < Vagrant::UI::Interface + attr_reader :messages + + METHODS = [:clear_line, :report_progress, :warn, :error, :info, :success] + + def initialize(resource = nil) + super + @messages = METHODS.each_with_object({}) { |m, h| h[m] = [] } + end + + def ask(*args) + super + # Automated tests should not depend on user input, obviously. + raise Errors::UIExpectsTTY + end + + METHODS.each do |method| + define_method(method) do |message, *opts| + @messages[method].push message + end + end +end + +# Monkey patch vagrant in order to reuse the UI test object that is set on +# our Vagrant::Environments +# +# TODO: Find out if this makes sense to be on vagrant core itself +require 'vagrant/machine' +Vagrant::Machine.class_eval do + alias :old_action :action + + define_method :action do |name, extra_env = nil| + extra_env = { ui: @env.ui }.merge(extra_env || {}) + old_action name, extra_env + end +end + describe 'Sanity check' do context 'running a `vagrant up` from scratch' do before(:all) do @@ -52,17 +89,32 @@ describe 'Sanity check' do opts = { cwd: 'spec' } env = Vagrant::Environment.new(opts) env.cli('up', '--provider', 'lxc') + env.unload end def vagrant_halt opts = { cwd: 'spec' } env = Vagrant::Environment.new(opts) env.cli('halt') + env.unload end def vagrant_destroy opts = { cwd: 'spec' } env = Vagrant::Environment.new(opts) env.cli('destroy', '-f') + env.unload + end + + def vagrant_ssh(cmd) + opts = { cwd: 'spec', ui_class: TestUI } + env = Vagrant::Environment.new(opts) + result = env.cli('ssh', '-c', cmd) + if result.to_i != 0 + raise "SSH command failed: '#{cmd}'\n#{env.ui.messages.inspect}" + end + output = env.ui.messages[:info].join("\n").chomp + env.unload + output end end From 72bbfe42dee6bff2b66d4731975027f1793d42f0 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sat, 20 Apr 2013 19:24:24 -0300 Subject: [PATCH 05/21] Implement initial acceptance specs --- spec/acceptance/sanity_check_spec.rb | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/spec/acceptance/sanity_check_spec.rb b/spec/acceptance/sanity_check_spec.rb index f79222c..ba5c966 100644 --- a/spec/acceptance/sanity_check_spec.rb +++ b/spec/acceptance/sanity_check_spec.rb @@ -38,23 +38,37 @@ Vagrant::Machine.class_eval do end describe 'Sanity check' do - context 'running a `vagrant up` from scratch' do + after(:all) { destroy_container } + + context 'running `vagrant up` from scratch' do before(:all) do destroy_container vagrant_up end - it 'creates a the container' + it 'creates a container' do + containers = `sudo lxc-ls`.chomp.split(/\s+/).uniq + expect(containers).to include File.read('/vagrant/spec/.vagrant/machines/default/lxc/id').strip.chomp + end - it 'starts the newly created container' + it 'starts the newly created container' do + status = `sudo lxc-info -n #{File.read('/vagrant/spec/.vagrant/machines/default/lxc/id').strip.chomp}` + expect(status).to include 'RUNNING' + end - it 'mounts shared folders with the right permissions' + it "is able to be SSH'ed" do + expect(vagrant_ssh('hostname')).to eq 'lxc-test-box' + end + + it 'mounts shared folders with the right permissions' do + vagrant_ssh 'mkdir -p /vagrant/tmp && echo "Shared" > /vagrant/tmp/shared' + shared_file_contents = File.read('/vagrant/spec/tmp/shared').chomp + expect(shared_file_contents).to eq 'Shared' + end it 'provisions the container based on Vagrantfile configs' it 'forwards configured ports' - - it "is able to be SSH'ed" end context '`vagrant halt` on a running container' do From af8e787cb24250afa66d46f9c1a66d806a4f6723 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sat, 20 Apr 2013 20:02:56 -0300 Subject: [PATCH 06/21] Add acceptance specs for provisioning and port forwarding --- spec/Vagrantfile | 7 +++++++ spec/acceptance/sanity_check_spec.rb | 14 ++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/spec/Vagrantfile b/spec/Vagrantfile index 6a72bb2..67d553a 100644 --- a/spec/Vagrantfile +++ b/spec/Vagrantfile @@ -23,4 +23,11 @@ Vagrant.configure("2") do |config| cache_dir = local_apt_cache(config.vm.box) config.vm.synced_folder cache_dir, "/var/cache/apt/archives", id: "vagrant-apt-cache" + + config.vm.provision :shell, + inline: 'mkdir -p /vagrant/tmp && echo -n "Provisioned" > /vagrant/tmp/provisioning' + + config.vm.network :forwarded_port, guest: 80, host: 8080 + config.vm.provision :shell, + inline: 'sudo apt-get install apache2 -y' end diff --git a/spec/acceptance/sanity_check_spec.rb b/spec/acceptance/sanity_check_spec.rb index ba5c966..8a46e21 100644 --- a/spec/acceptance/sanity_check_spec.rb +++ b/spec/acceptance/sanity_check_spec.rb @@ -61,14 +61,20 @@ describe 'Sanity check' do end it 'mounts shared folders with the right permissions' do - vagrant_ssh 'mkdir -p /vagrant/tmp && echo "Shared" > /vagrant/tmp/shared' - shared_file_contents = File.read('/vagrant/spec/tmp/shared').chomp + vagrant_ssh 'mkdir -p /vagrant/tmp && echo -n "Shared" > /vagrant/tmp/shared' + shared_file_contents = File.read('/vagrant/spec/tmp/shared') expect(shared_file_contents).to eq 'Shared' end - it 'provisions the container based on Vagrantfile configs' + it 'provisions the container based on Vagrantfile configs' do + provisioned_file_contents = File.read('/vagrant/spec/tmp/provisioning') + expect(provisioned_file_contents).to eq 'Provisioned' + end - it 'forwards configured ports' + it 'forwards configured ports' do + output = `curl -s localhost:8080`.strip.chomp + expect(output).to include 'It works!' + end end context '`vagrant halt` on a running container' do From 8762a2d942b7991aa62f1cc584fd802428902f42 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sat, 20 Apr 2013 20:03:36 -0300 Subject: [PATCH 07/21] Redirect `redir` stdout to /dev/null --- spec/acceptance/sanity_check_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/acceptance/sanity_check_spec.rb b/spec/acceptance/sanity_check_spec.rb index 8a46e21..6762768 100644 --- a/spec/acceptance/sanity_check_spec.rb +++ b/spec/acceptance/sanity_check_spec.rb @@ -103,6 +103,7 @@ describe 'Sanity check' do `sudo lxc-shutdown -n \`cat /vagrant/spec/.vagrant/machines/default/lxc/id\`` `sudo lxc-wait -n \`cat /vagrant/spec/.vagrant/machines/default/lxc/id\` --state STOPPED` `sudo lxc-destroy -n \`cat /vagrant/spec/.vagrant/machines/default/lxc/id\`` + `sudo killall -9 redir 2>/dev/null` end def vagrant_up From c85de745b6778e33cb4de606e0ad8bb21ee11108 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sun, 21 Apr 2013 16:43:35 -0300 Subject: [PATCH 08/21] Clean up Guardfile --- Guardfile | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/Guardfile b/Guardfile index 2486d8a..2858053 100644 --- a/Guardfile +++ b/Guardfile @@ -1,6 +1,3 @@ -# A sample Guardfile -# More info at https://github.com/guard/guard#readme - guard 'bundler' do watch('Gemfile') watch(/^.+\.gemspec/) @@ -15,20 +12,7 @@ guard 'rspec' do watch(%r{^spec/.+_spec\.rb$}) watch(%r{^lib/vagrant-lxc/(.+)\.rb$}) { |m| "spec/unit/#{m[1]}_spec.rb" } watch('spec/unit_helper.rb') { "spec/unit" } + watch('spec/acceptance_helper.rb') { "spec/acceptance" } watch('spec/spec_helper.rb') { "spec/" } - - # Rails example - watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } - watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" } - watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] } - watch(%r{^spec/support/(.+)\.rb$}) { "spec" } - watch('config/routes.rb') { "spec/routing" } - watch('app/controllers/application_controller.rb') { "spec/controllers" } - - # Capybara features specs - watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/features/#{m[1]}_spec.rb" } - - # Turnip features and steps - watch(%r{^spec/acceptance/(.+)\.feature$}) - watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' } + watch(%r{^spec/support/(.+)\.rb$}) { "spec/" } end From 48a344ab8c0345abf4019c7c479ab686e2d4324e Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sun, 21 Apr 2013 16:44:47 -0300 Subject: [PATCH 09/21] Mark some acceptance specs as pending for now --- spec/acceptance/sanity_check_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/acceptance/sanity_check_spec.rb b/spec/acceptance/sanity_check_spec.rb index 6762768..7ec7774 100644 --- a/spec/acceptance/sanity_check_spec.rb +++ b/spec/acceptance/sanity_check_spec.rb @@ -77,7 +77,7 @@ describe 'Sanity check' do end end - context '`vagrant halt` on a running container' do + pending '`vagrant halt` on a running container' do before(:all) do destroy_container vagrant_up @@ -89,7 +89,7 @@ describe 'Sanity check' do it 'clears forwarded ports' end - context '`vagrant destroy`' do + pending '`vagrant destroy`' do before(:all) do destroy_container vagrant_up From ba19285d5312426fae8f378e324d0056511dda04 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sun, 21 Apr 2013 16:50:40 -0300 Subject: [PATCH 10/21] Attempt to fix travis build --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 83b319a..4595a85 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,10 @@ language: ruby +before_script: + - sudo apt-get install -y lxc redir rvm: - 1.9.3 - 2.0.0 matrix: allow_failures: - rvm: 2.0.0 -script: "bundle exec rake" +script: "bundle exec rake ci" From 7f6713e9bbb493cec9a3e4e4374d49a164afbf50 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sun, 21 Apr 2013 16:58:21 -0300 Subject: [PATCH 11/21] 2 failed attempts to run acceptance specs on travis, let just not worry about that for now --- .travis.yml | 2 -- tasks/spec.rake | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4595a85..384fc3f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,4 @@ language: ruby -before_script: - - sudo apt-get install -y lxc redir rvm: - 1.9.3 - 2.0.0 diff --git a/tasks/spec.rake b/tasks/spec.rake index 12a4111..b66fecb 100644 --- a/tasks/spec.rake +++ b/tasks/spec.rake @@ -9,7 +9,7 @@ begin task :default => ['spec:set_coverage', 'spec'] Coveralls::RakeTask.new - task :ci => [:default, 'coveralls:push'] + task :ci => ['spec:set_coverage', 'spec:unit', 'coveralls:push'] rescue LoadError; end namespace :spec do From c1d841271bcc68e27d7bf5e5c6035915e9811bc3 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sun, 21 Apr 2013 17:09:23 -0300 Subject: [PATCH 12/21] Run unit specs only by default during development --- tasks/spec.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/spec.rake b/tasks/spec.rake index b66fecb..ddd4867 100644 --- a/tasks/spec.rake +++ b/tasks/spec.rake @@ -6,7 +6,7 @@ begin task :spec => ['spec:unit', 'spec:acceptance'] desc 'Default task which runs all specs with code coverage enabled' - task :default => ['spec:set_coverage', 'spec'] + task :default => ['spec:set_coverage', 'spec:unit'] Coveralls::RakeTask.new task :ci => ['spec:set_coverage', 'spec:unit', 'coveralls:push'] From ae46fff7c02974492bdd06fb238e22309c09c792 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sun, 21 Apr 2013 17:56:37 -0300 Subject: [PATCH 13/21] Sanity check for vagrant halt and destroy --- spec/acceptance/sanity_check_spec.rb | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/spec/acceptance/sanity_check_spec.rb b/spec/acceptance/sanity_check_spec.rb index 7ec7774..68810c5 100644 --- a/spec/acceptance/sanity_check_spec.rb +++ b/spec/acceptance/sanity_check_spec.rb @@ -77,32 +77,42 @@ describe 'Sanity check' do end end - pending '`vagrant halt` on a running container' do + context '`vagrant halt` on a running container' do before(:all) do destroy_container vagrant_up vagrant_halt end - it 'shuts down container' + it 'shuts down container' do + status = `sudo lxc-info -n #{File.read('/vagrant/spec/.vagrant/machines/default/lxc/id').strip.chomp}` + expect(status).to include 'STOPPED' + end - it 'clears forwarded ports' + it 'clears forwarded ports' do + `curl -s localhost:8080 --connect-timeout 2` + expect($?.exitstatus).to_not eq 0 + end end - pending '`vagrant destroy`' do + context '`vagrant destroy`' do before(:all) do destroy_container vagrant_up + @container_name = File.read('/vagrant/spec/.vagrant/machines/default/lxc/id').strip.chomp vagrant_destroy end - it 'destroys the underlying container' + it 'destroys the underlying container' do + containers = `sudo lxc-ls`.chomp.split(/\s+/).uniq + expect(containers).to_not include @container_name + end end def destroy_container - `sudo lxc-shutdown -n \`cat /vagrant/spec/.vagrant/machines/default/lxc/id\`` - `sudo lxc-wait -n \`cat /vagrant/spec/.vagrant/machines/default/lxc/id\` --state STOPPED` - `sudo lxc-destroy -n \`cat /vagrant/spec/.vagrant/machines/default/lxc/id\`` + `sudo lxc-shutdown -n \`cat /vagrant/spec/.vagrant/machines/default/lxc/id\` 2>/dev/null` + `sudo lxc-wait -n \`cat /vagrant/spec/.vagrant/machines/default/lxc/id\` --state STOPPED 2>/dev/null` + `sudo lxc-destroy -n \`cat /vagrant/spec/.vagrant/machines/default/lxc/id\` 2>/dev/null` `sudo killall -9 redir 2>/dev/null` end From a1c19371c6d12792db04a2bd6228322407ee7d8d Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sun, 21 Apr 2013 18:04:36 -0300 Subject: [PATCH 14/21] Prevent running acceptance specs from outside a dev machine --- spec/acceptance_helper.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/spec/acceptance_helper.rb b/spec/acceptance_helper.rb index 0f2e04f..13708eb 100644 --- a/spec/acceptance_helper.rb +++ b/spec/acceptance_helper.rb @@ -1,5 +1,10 @@ require 'spec_helper' +unless ENV['USER'] == 'vagrant' + puts 'Acceptance specs are supposed to run from one of the vagrant dev machines' + exit 1 +end + if defined? SimpleCov SimpleCov.command_name 'acceptance' end From e86edb7087c9b0d3d18f9a0dc413a1664bde6274 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sun, 21 Apr 2013 18:11:10 -0300 Subject: [PATCH 15/21] Extract acceptance specs test ui out to a separate file --- spec/acceptance/sanity_check_spec.rb | 23 ----------------------- spec/acceptance/support/test_ui.rb | 22 ++++++++++++++++++++++ spec/acceptance_helper.rb | 2 ++ 3 files changed, 24 insertions(+), 23 deletions(-) create mode 100644 spec/acceptance/support/test_ui.rb diff --git a/spec/acceptance/sanity_check_spec.rb b/spec/acceptance/sanity_check_spec.rb index 68810c5..6c891fe 100644 --- a/spec/acceptance/sanity_check_spec.rb +++ b/spec/acceptance/sanity_check_spec.rb @@ -1,28 +1,5 @@ require 'acceptance_helper' -class TestUI < Vagrant::UI::Interface - attr_reader :messages - - METHODS = [:clear_line, :report_progress, :warn, :error, :info, :success] - - def initialize(resource = nil) - super - @messages = METHODS.each_with_object({}) { |m, h| h[m] = [] } - end - - def ask(*args) - super - # Automated tests should not depend on user input, obviously. - raise Errors::UIExpectsTTY - end - - METHODS.each do |method| - define_method(method) do |message, *opts| - @messages[method].push message - end - end -end - # Monkey patch vagrant in order to reuse the UI test object that is set on # our Vagrant::Environments # diff --git a/spec/acceptance/support/test_ui.rb b/spec/acceptance/support/test_ui.rb new file mode 100644 index 0000000..5f9a84c --- /dev/null +++ b/spec/acceptance/support/test_ui.rb @@ -0,0 +1,22 @@ +class TestUI < Vagrant::UI::Interface + attr_reader :messages + + METHODS = [:clear_line, :report_progress, :warn, :error, :info, :success] + + def initialize(resource = nil) + super + @messages = METHODS.each_with_object({}) { |m, h| h[m] = [] } + end + + def ask(*args) + super + # Automated tests should not depend on user input, obviously. + raise Errors::UIExpectsTTY + end + + METHODS.each do |method| + define_method(method) do |message, *opts| + @messages[method].push message + end + end +end diff --git a/spec/acceptance_helper.rb b/spec/acceptance_helper.rb index 13708eb..03105f9 100644 --- a/spec/acceptance_helper.rb +++ b/spec/acceptance_helper.rb @@ -12,6 +12,8 @@ end require 'vagrant' require 'vagrant-lxc' +Dir[File.dirname(__FILE__) + "/acceptance/support/**/*.rb"].each { |f| require f } + # RSpec.configure do |config| # config.include AcceptanceExampleGroup, :type => :unit, :example_group => { # :file_path => /\bspec\/unit\// From 3909a26ea3b8593f21983c7a1cae98a97f2a037c Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sun, 21 Apr 2013 18:13:34 -0300 Subject: [PATCH 16/21] Move unit specs example group related code to spec/unit/support --- spec/support/.gitkeep | 0 spec/{ => unit}/support/unit_example_group.rb | 0 spec/unit_helper.rb | 2 ++ 3 files changed, 2 insertions(+) create mode 100644 spec/support/.gitkeep rename spec/{ => unit}/support/unit_example_group.rb (100%) diff --git a/spec/support/.gitkeep b/spec/support/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/spec/support/unit_example_group.rb b/spec/unit/support/unit_example_group.rb similarity index 100% rename from spec/support/unit_example_group.rb rename to spec/unit/support/unit_example_group.rb diff --git a/spec/unit_helper.rb b/spec/unit_helper.rb index d091266..4122faf 100644 --- a/spec/unit_helper.rb +++ b/spec/unit_helper.rb @@ -1,5 +1,7 @@ require 'spec_helper' +Dir[File.dirname(__FILE__) + "/unit/support/**/*.rb"].each { |f| require f } + if defined? SimpleCov SimpleCov.command_name 'unit' end From 8c8c11f07c0752f0929e85bff8721c5f644d6703 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sun, 21 Apr 2013 18:27:32 -0300 Subject: [PATCH 17/21] Move Vagrant::Machine monkey patch out to a spec support file --- spec/acceptance/sanity_check_spec.rb | 14 -------------- spec/acceptance/support/machine_ext.rb | 13 +++++++++++++ 2 files changed, 13 insertions(+), 14 deletions(-) create mode 100644 spec/acceptance/support/machine_ext.rb diff --git a/spec/acceptance/sanity_check_spec.rb b/spec/acceptance/sanity_check_spec.rb index 6c891fe..782e6aa 100644 --- a/spec/acceptance/sanity_check_spec.rb +++ b/spec/acceptance/sanity_check_spec.rb @@ -1,19 +1,5 @@ require 'acceptance_helper' -# Monkey patch vagrant in order to reuse the UI test object that is set on -# our Vagrant::Environments -# -# TODO: Find out if this makes sense to be on vagrant core itself -require 'vagrant/machine' -Vagrant::Machine.class_eval do - alias :old_action :action - - define_method :action do |name, extra_env = nil| - extra_env = { ui: @env.ui }.merge(extra_env || {}) - old_action name, extra_env - end -end - describe 'Sanity check' do after(:all) { destroy_container } diff --git a/spec/acceptance/support/machine_ext.rb b/spec/acceptance/support/machine_ext.rb new file mode 100644 index 0000000..d09fcff --- /dev/null +++ b/spec/acceptance/support/machine_ext.rb @@ -0,0 +1,13 @@ +# Monkey patch vagrant in order to reuse the UI test object that is set on +# our Vagrant::Environments +# +# TODO: Find out if this makes sense to be on vagrant core itself +require 'vagrant/machine' +Vagrant::Machine.class_eval do + alias :old_action :action + + define_method :action do |name, extra_env = nil| + extra_env = { ui: @env.ui }.merge(extra_env || {}) + old_action name, extra_env + end +end From 6adebb695c1b74f2ac62d042c12febf55ff16419 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sun, 21 Apr 2013 18:38:02 -0300 Subject: [PATCH 18/21] Move acceptance spec "utility methods" out to an example group --- spec/acceptance/sanity_check_spec.rb | 40 ----------------- .../support/acceptance_example_group.rb | 45 +++++++++++++++++++ spec/acceptance_helper.rb | 12 ++--- 3 files changed, 51 insertions(+), 46 deletions(-) create mode 100644 spec/acceptance/support/acceptance_example_group.rb diff --git a/spec/acceptance/sanity_check_spec.rb b/spec/acceptance/sanity_check_spec.rb index 782e6aa..2206bf2 100644 --- a/spec/acceptance/sanity_check_spec.rb +++ b/spec/acceptance/sanity_check_spec.rb @@ -71,44 +71,4 @@ describe 'Sanity check' do expect(containers).to_not include @container_name end end - - def destroy_container - `sudo lxc-shutdown -n \`cat /vagrant/spec/.vagrant/machines/default/lxc/id\` 2>/dev/null` - `sudo lxc-wait -n \`cat /vagrant/spec/.vagrant/machines/default/lxc/id\` --state STOPPED 2>/dev/null` - `sudo lxc-destroy -n \`cat /vagrant/spec/.vagrant/machines/default/lxc/id\` 2>/dev/null` - `sudo killall -9 redir 2>/dev/null` - end - - def vagrant_up - opts = { cwd: 'spec' } - env = Vagrant::Environment.new(opts) - env.cli('up', '--provider', 'lxc') - env.unload - end - - def vagrant_halt - opts = { cwd: 'spec' } - env = Vagrant::Environment.new(opts) - env.cli('halt') - env.unload - end - - def vagrant_destroy - opts = { cwd: 'spec' } - env = Vagrant::Environment.new(opts) - env.cli('destroy', '-f') - env.unload - end - - def vagrant_ssh(cmd) - opts = { cwd: 'spec', ui_class: TestUI } - env = Vagrant::Environment.new(opts) - result = env.cli('ssh', '-c', cmd) - if result.to_i != 0 - raise "SSH command failed: '#{cmd}'\n#{env.ui.messages.inspect}" - end - output = env.ui.messages[:info].join("\n").chomp - env.unload - output - end end diff --git a/spec/acceptance/support/acceptance_example_group.rb b/spec/acceptance/support/acceptance_example_group.rb new file mode 100644 index 0000000..2c28c12 --- /dev/null +++ b/spec/acceptance/support/acceptance_example_group.rb @@ -0,0 +1,45 @@ +module AcceptanceExampleGroup + def self.included(base) + base.metadata[:type] = :acceptance + end + + def destroy_container + `sudo lxc-shutdown -n \`cat /vagrant/spec/.vagrant/machines/default/lxc/id\` 2>/dev/null` + `sudo lxc-wait -n \`cat /vagrant/spec/.vagrant/machines/default/lxc/id\` --state STOPPED 2>/dev/null` + `sudo lxc-destroy -n \`cat /vagrant/spec/.vagrant/machines/default/lxc/id\` 2>/dev/null` + `sudo killall -9 redir 2>/dev/null` + end + + def vagrant_up + opts = { cwd: 'spec' } + env = Vagrant::Environment.new(opts) + env.cli('up', '--provider', 'lxc') + env.unload + end + + def vagrant_halt + opts = { cwd: 'spec' } + env = Vagrant::Environment.new(opts) + env.cli('halt') + env.unload + end + + def vagrant_destroy + opts = { cwd: 'spec' } + env = Vagrant::Environment.new(opts) + env.cli('destroy', '-f') + env.unload + end + + def vagrant_ssh(cmd) + opts = { cwd: 'spec', ui_class: TestUI } + env = Vagrant::Environment.new(opts) + result = env.cli('ssh', '-c', cmd) + if result.to_i != 0 + raise "SSH command failed: '#{cmd}'\n#{env.ui.messages.inspect}" + end + output = env.ui.messages[:info].join("\n").chomp + env.unload + output + end +end diff --git a/spec/acceptance_helper.rb b/spec/acceptance_helper.rb index 03105f9..ff45967 100644 --- a/spec/acceptance_helper.rb +++ b/spec/acceptance_helper.rb @@ -1,7 +1,7 @@ require 'spec_helper' unless ENV['USER'] == 'vagrant' - puts 'Acceptance specs are supposed to run from one of the vagrant dev machines' + puts 'Acceptance specs are supposed to run from one of the vagrant-lxc dev machines' exit 1 end @@ -14,8 +14,8 @@ require 'vagrant-lxc' Dir[File.dirname(__FILE__) + "/acceptance/support/**/*.rb"].each { |f| require f } -# RSpec.configure do |config| -# config.include AcceptanceExampleGroup, :type => :unit, :example_group => { -# :file_path => /\bspec\/unit\// -# } -# end +RSpec.configure do |config| + config.include AcceptanceExampleGroup, :type => :acceptance, :example_group => { + :file_path => /\bspec\/acceptance\// + } +end From 8c7cfd772096d368bfc502cf8fd8d29af8bf33f0 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sun, 21 Apr 2013 18:47:15 -0300 Subject: [PATCH 19/21] Clean up acceptance specs utilities --- .../support/acceptance_example_group.rb | 53 +++++++++++-------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/spec/acceptance/support/acceptance_example_group.rb b/spec/acceptance/support/acceptance_example_group.rb index 2c28c12..e363839 100644 --- a/spec/acceptance/support/acceptance_example_group.rb +++ b/spec/acceptance/support/acceptance_example_group.rb @@ -3,43 +3,54 @@ module AcceptanceExampleGroup base.metadata[:type] = :acceptance end + ID_FILE = "/vagrant/spec/.vagrant/machines/default/lxc/id" + def vagrant_container_name + File.read(ID_FILE).strip.chomp if File.exists?(ID_FILE) + end + def destroy_container - `sudo lxc-shutdown -n \`cat /vagrant/spec/.vagrant/machines/default/lxc/id\` 2>/dev/null` - `sudo lxc-wait -n \`cat /vagrant/spec/.vagrant/machines/default/lxc/id\` --state STOPPED 2>/dev/null` - `sudo lxc-destroy -n \`cat /vagrant/spec/.vagrant/machines/default/lxc/id\` 2>/dev/null` + if name = vagrant_container_name + `sudo lxc-shutdown -n #{name} 2>/dev/null` + `sudo lxc-wait -n #{name} --state STOPPED 2>/dev/null` + `sudo lxc-destroy -n #{name} 2>/dev/null` + end `sudo killall -9 redir 2>/dev/null` end - def vagrant_up - opts = { cwd: 'spec' } + def with_vagrant_environment + opts = { cwd: 'spec', ui_class: TestUI } env = Vagrant::Environment.new(opts) - env.cli('up', '--provider', 'lxc') + yield env env.unload end + def vagrant_up + with_vagrant_environment do |env| + env.cli('up', '--provider', 'lxc') + end + end + def vagrant_halt - opts = { cwd: 'spec' } - env = Vagrant::Environment.new(opts) - env.cli('halt') - env.unload + with_vagrant_environment do |env| + env.cli('halt') + end end def vagrant_destroy - opts = { cwd: 'spec' } - env = Vagrant::Environment.new(opts) - env.cli('destroy', '-f') - env.unload + with_vagrant_environment do |env| + env.cli('destroy', '-f') + end end def vagrant_ssh(cmd) - opts = { cwd: 'spec', ui_class: TestUI } - env = Vagrant::Environment.new(opts) - result = env.cli('ssh', '-c', cmd) - if result.to_i != 0 - raise "SSH command failed: '#{cmd}'\n#{env.ui.messages.inspect}" + output = nil + with_vagrant_environment do |env| + result = env.cli('ssh', '-c', cmd) + if result.to_i != 0 + raise "SSH command failed: '#{cmd}'\n#{env.ui.messages.inspect}" + end + output = env.ui.messages[:info].join("\n").chomp end - output = env.ui.messages[:info].join("\n").chomp - env.unload output end end From 7ce99c4e99299ba8b565651de6d77f1b8393648d Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sun, 21 Apr 2013 18:47:42 -0300 Subject: [PATCH 20/21] Add not about running acceptance specs to README --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index db08a31..35351c9 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,13 @@ If want to develop from your physical machine, just sing that same old song: git clone git://github.com/fgrehm/vagrant-lxc.git cd vagrant-lxc bundle install -bundle exec rake # to run all specs +bundle exec rake # to run unit specs +``` + +To run acceptance specs, you'll have to ssh into one of the [development boxes](development/Vagrantfile) and run: + +``` +bundle exec rake spec:acceptance ``` To build the provided quantal64 box: From b0490c8639ef5c30abc578332b23fcbe395e7b93 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sun, 21 Apr 2013 18:49:26 -0300 Subject: [PATCH 21/21] Clean up sanity check code --- spec/acceptance/sanity_check_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/acceptance/sanity_check_spec.rb b/spec/acceptance/sanity_check_spec.rb index 2206bf2..296ee55 100644 --- a/spec/acceptance/sanity_check_spec.rb +++ b/spec/acceptance/sanity_check_spec.rb @@ -11,11 +11,11 @@ describe 'Sanity check' do it 'creates a container' do containers = `sudo lxc-ls`.chomp.split(/\s+/).uniq - expect(containers).to include File.read('/vagrant/spec/.vagrant/machines/default/lxc/id').strip.chomp + expect(containers).to include vagrant_container_name end it 'starts the newly created container' do - status = `sudo lxc-info -n #{File.read('/vagrant/spec/.vagrant/machines/default/lxc/id').strip.chomp}` + status = `sudo lxc-info -n #{vagrant_container_name}` expect(status).to include 'RUNNING' end @@ -48,7 +48,7 @@ describe 'Sanity check' do end it 'shuts down container' do - status = `sudo lxc-info -n #{File.read('/vagrant/spec/.vagrant/machines/default/lxc/id').strip.chomp}` + status = `sudo lxc-info -n #{vagrant_container_name}` expect(status).to include 'STOPPED' end @@ -62,7 +62,7 @@ describe 'Sanity check' do before(:all) do destroy_container vagrant_up - @container_name = File.read('/vagrant/spec/.vagrant/machines/default/lxc/id').strip.chomp + @container_name = vagrant_container_name vagrant_destroy end