daptiv-chef-ci 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ pkg
2
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in my_gem.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ gem "mocha", :require => false
8
+ end
data/README.md ADDED
@@ -0,0 +1,2 @@
1
+ # Daptiv Chef CI
2
+ Common tools to help automate Vagrant in CI
data/Rakefile ADDED
@@ -0,0 +1,25 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'rspec/core/rake_task'
4
+
5
+ # Change to the directory of this file.
6
+ Dir.chdir(File.expand_path("../", __FILE__))
7
+
8
+ # For gem creation and bundling
9
+ require "bundler/gem_tasks"
10
+
11
+ # Run the unit test suite
12
+ RSpec::Core::RakeTask.new do |task|
13
+ task.pattern = "spec/**/*_spec.rb"
14
+ task.rspec_opts = [ '--color', '-f documentation' ]
15
+ task.rspec_opts << '-tunit'
16
+ end
17
+
18
+ # Default task is to run tests
19
+ task :default => "spec"
20
+
21
+ desc 'Run foodcritic with default rule set.'
22
+ task :path do
23
+ puts ENV['PATH']
24
+ end
25
+
@@ -0,0 +1,58 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.authors = ["Shawn Neal"]
5
+ gem.email = ["sneal@daptiv.com"]
6
+ gem.description = %q{Vagrant automation for CI}
7
+ gem.summary = %q{A small gem to reduce Rake duplication}
8
+ gem.homepage = ""
9
+
10
+ # The following block of code determines the files that should be included
11
+ # in the gem. It does this by reading all the files in the directory where
12
+ # this gemspec is, and parsing out the ignored files from the gitignore.
13
+ # Note that the entire gitignore(5) syntax is not supported, specifically
14
+ # the "!" syntax, but it should mostly work correctly.
15
+ root_path = File.dirname(__FILE__)
16
+ all_files = Dir.chdir(root_path) { Dir.glob("**/{*,.*}") }
17
+ all_files.reject! { |file| [".", ".."].include?(File.basename(file)) }
18
+ gitignore_path = File.join(root_path, ".gitignore")
19
+ gitignore = File.readlines(gitignore_path)
20
+ gitignore.map! { |line| line.chomp.strip }
21
+ gitignore.reject! { |line| line.empty? || line =~ /^(#|!)/ }
22
+
23
+ unignored_files = all_files.reject do |file|
24
+ # Ignore any directories, the gemspec only cares about files
25
+ next true if File.directory?(file)
26
+
27
+ # Ignore any paths that match anything in the gitignore. We do
28
+ # two tests here:
29
+ #
30
+ # - First, test to see if the entire path matches the gitignore.
31
+ # - Second, match if the basename does, this makes it so that things
32
+ # like '.DS_Store' will match sub-directories too (same behavior
33
+ # as git).
34
+ #
35
+ gitignore.any? do |ignore|
36
+ File.fnmatch(ignore, file, File::FNM_PATHNAME) ||
37
+ File.fnmatch(ignore, File.basename(file), File::FNM_PATHNAME)
38
+ end
39
+ end
40
+
41
+ gem.files = unignored_files
42
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
43
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
44
+ gem.name = "daptiv-chef-ci"
45
+ gem.require_paths = ["lib"]
46
+ gem.version = '0.0.1'
47
+
48
+ gem.add_runtime_dependency "mixlib-shellout", "~> 1.2.0"
49
+ gem.add_runtime_dependency "log4r", "~> 1.1.10"
50
+ gem.add_runtime_dependency "erubis", "~> 2.7.0"
51
+
52
+ gem.add_development_dependency "rake"
53
+ gem.add_development_dependency "rspec-core", "~> 2.12.2"
54
+ gem.add_development_dependency "rspec-expectations", "~> 2.12.1"
55
+ gem.add_development_dependency "rspec-mocks", "~> 2.12.1"
56
+ gem.add_development_dependency "simplecov"
57
+ gem.add_development_dependency "mocha", "~> 0.14.0"
58
+ end
@@ -0,0 +1,33 @@
1
+ module DaptivChefCI
2
+ class Logger
3
+
4
+ # Initializes and enables logging to the given environments level
5
+ # By default logging only occurs at ERROR level or higher.
6
+ # Set CHEF_CI_LOG env var to change logging levels
7
+ def self.init()
8
+ require 'log4r'
9
+
10
+ # Set the logging level on all "chef-ci" namespaced
11
+ # logs as long as we have a valid level.
12
+ logger = Log4r::Logger.new("daptiv_chef_ci")
13
+ logger.outputters = Log4r::Outputter.stderr
14
+ logger.level = log_level()
15
+ logger = nil
16
+ end
17
+
18
+ # LogLevels = ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL']
19
+ # DEBUG = 1
20
+ # INFO = 2
21
+ # WARN = 3
22
+ # ERROR = 4
23
+ # FATAL = 5
24
+ def self.log_level()
25
+ level = ENV['CHEF_CI_LOG'].upcase().to_s()
26
+ level_i = Log4r::Log4rConfig::LogLevels.index(level)
27
+ level_i + 1
28
+ rescue
29
+ return 4 # error
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,54 @@
1
+ require 'log4r'
2
+ require 'mixlib/shellout'
3
+ require 'bundler'
4
+
5
+ module DaptivChefCI
6
+ class Shell
7
+
8
+ def initialize()
9
+ @logger = Log4r::Logger.new("daptiv_chef_ci::shell")
10
+ end
11
+
12
+ # Executes the specified shell command and returns the stdout.
13
+ #
14
+ # This method ensure that any invoked command use the same PATH environment
15
+ # that the user has outside Ruby/Bundler.
16
+ #
17
+ # @param [String] The command line to execute
18
+ # @return [Array] Each entry represents a line from the stdout
19
+ def exec_cmd(command)
20
+ @logger.info("Calling command [#{command}]")
21
+ path_at_start = ENV['PATH']
22
+ begin
23
+ ENV['PATH'] = path_without_gem_dir()
24
+ @logger.debug("Temporarily setting PATH: #{ENV['PATH']}")
25
+ out = `#{command}`
26
+ @logger.debug(out)
27
+ out.split("\n")
28
+ ensure
29
+ @logger.debug("Resetting PATH: #{path_at_start}")
30
+ ENV['PATH'] = path_at_start
31
+ end
32
+ end
33
+
34
+ # Returns the PATH environment variable as it was before Bundler prepended
35
+ # the system gem directory to it.
36
+ #
37
+ # This can happen if the user has invoked "require 'bundler/setup'" somewhere,
38
+ # like in this gems Rakefile.
39
+ #
40
+ # This is needed because sometimes a user will have the Vagrant gem installed
41
+ # on their system and we don't want to use it, we should use the one that's in
42
+ # their PATH as if they invoked vagrant themselves (i.e. the installed version)
43
+ #
44
+ # @return [String] The ENV['PATH] without the Bundler system gem dir prepended
45
+ def path_without_gem_dir
46
+ paths = ENV['PATH'].split(':')
47
+ system_gem_dir = "#{Bundler.bundle_path}/bin"
48
+ @logger.debug("System gem dir: #{system_gem_dir}")
49
+ paths.delete_if { |p| p.downcase() == system_gem_dir.downcase() }
50
+ paths.join(':')
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,41 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant.configure("2") do |config|
5
+ chef_repo_dir = '<%= chef_repo_dir %>'
6
+
7
+ config.berkshelf.enabled = true
8
+
9
+ config.vm.box = '<%= box_name %>'
10
+ <% if !box_url.nil? %>
11
+ config.vm.box_url = '<%= box_url %>'
12
+ <% end %>
13
+
14
+ <% if guest_os == :windows %>
15
+ config.vm.guest = :windows
16
+
17
+ config.windows.halt_timeout = 15
18
+ config.winrm.username = "vagrant"
19
+ config.winrm.password = "vagrant"
20
+
21
+ config.vm.network :forwarded_port, guest: 3389, host: 3389
22
+ config.vm.network :forwarded_port, guest: 5985, host: 5985
23
+ <% end %>
24
+
25
+ config.vm.provision :chef_solo do |chef|
26
+ chef.node_name = '<%= node_name %>'
27
+ chef.log_level = :info
28
+ chef.roles_path = File.join(chef_repo_dir, 'roles')
29
+ chef.data_bags_path = File.join(chef_repo_dir, 'data_bags')
30
+ chef.encrypted_data_bag_secret_key_path = '/etc/chef/encrypted_data_bag_secret'
31
+ chef.add_recipe 'minitest-handler'
32
+ <% run_list.each do |recipe| %>
33
+ chef.add_recipe '<%= recipe %>'
34
+ <% end %>
35
+ <% if !chef_json.nil? %>
36
+ chef.json = {
37
+ <%= chef_json %>
38
+ }
39
+ <% end %>
40
+ end
41
+ end
@@ -0,0 +1,95 @@
1
+ require 'log4r'
2
+ require 'socket'
3
+ require 'erubis'
4
+ require_relative 'shell'
5
+
6
+ module DaptivChefCI
7
+ class VagrantDriver
8
+
9
+ # Constructs a new Vagrant management instance
10
+ #
11
+ # @param [Shell] The CLI
12
+ # @param [Hash] The options to pass to the Vagrantfile
13
+ #
14
+ # options[:guest_os] - defaults to :linux
15
+ # options[:chef_repo_dir] - The chef-repo root directory, defaults to ~/src/chef-repo
16
+ # options[:box_name] - defaults to 'Vagrant-hostname'
17
+ # options[:node_name] - The chef node name, defaults to 'Vagrant-hostname'
18
+ # options[:box_url] - URL to the box download location, this is optional.
19
+ # options[:run_list] - The Chef run list, defaults to empty.
20
+ # options[:chef_json] - Any additional Chef attributes in json format.
21
+ def initialize(shell, options)
22
+ @logger = Log4r::Logger.new("daptiv_chef_ci::vagrant")
23
+ @shell = shell
24
+
25
+ options[:guest_os] ||= :linux
26
+ options[:box_name] ||= "Vagrant-#{Socket.gethostname}"
27
+ options[:box_url] ||= nil
28
+ options[:node_name] ||= options[:box_name]
29
+ options[:run_list] ||= []
30
+ options[:chef_repo_dir] = "#{ENV['HOME']}/src/chef-repo"
31
+ options[:chef_json] ||= nil
32
+ @options = options
33
+ end
34
+
35
+ def create_vagrantfile()
36
+ @logger.debug('Creating Vagrantfile')
37
+ File.open('Vagrantfile', 'w') do |f|
38
+ f.write render_vagrantfile()
39
+ end
40
+ end
41
+
42
+ def render_vagrantfile()
43
+ Erubis::Eruby.new(vagrantfile_erb()).result(@options)
44
+ end
45
+
46
+ def destroy()
47
+ @shell.exec_cmd('vagrant destroy -f')
48
+ end
49
+
50
+ def halt()
51
+ @shell.exec_cmd('vagrant halt')
52
+ end
53
+
54
+ def up()
55
+ @shell.exec_cmd('vagrant up')
56
+ end
57
+
58
+ def provision()
59
+ @shell.exec_cmd('vagrant provision')
60
+ end
61
+
62
+ def reload()
63
+ @shell.exec_cmd('vagrant reload')
64
+ end
65
+
66
+
67
+ private
68
+
69
+ def vagrantfile_erb()
70
+ path = vagrantfile_erb_path()
71
+ @logger.info("Using #{path} to render Vangrantfile")
72
+ File.read(vagrantfile_erb_path())
73
+ end
74
+
75
+ def vagrantfile_erb_path()
76
+ erbs = [
77
+ File.join(Dir.pwd, 'Vagrantfile.erb'),
78
+ File.join(Dir.pwd, 'build/Vagrantfile.erb'),
79
+ File.expand_path('Vagrantfile.erb', template_dir())
80
+ ]
81
+
82
+ erbs.each do |erb|
83
+ @logger.debug("Searching for #{erb}")
84
+ return erb if File.exists?(erb)
85
+ end
86
+ # This should never happen
87
+ raise 'Couldn\'t find a Vagrantfile.erb!'
88
+ end
89
+
90
+ def template_dir()
91
+ File.join(File.expand_path(File.dirname(__FILE__)), 'templates')
92
+ end
93
+
94
+ end
95
+ end
@@ -0,0 +1,115 @@
1
+ require 'rake'
2
+ require 'rake/tasklib'
3
+ require_relative 'vagrant_driver'
4
+ require_relative 'virtualbox_driver'
5
+ require_relative 'shell'
6
+ require_relative 'logger'
7
+
8
+ begin
9
+ # Support Rake > 0.8.7
10
+ require 'rake/dsl_definition'
11
+ rescue LoadError
12
+ end
13
+
14
+ DaptivChefCI::Logger.init()
15
+
16
+ class Vagrant
17
+
18
+ # This class lets you define Rake tasks to drive Vagrant.
19
+ #
20
+ # @example Run the Python and NGinx cookbooks on a Linux guest
21
+ # Vagrant::RakeTask.new do |task|
22
+ # task.box_name = 'vagrant-FreeBSD'
23
+ # task.run_list = [ 'python', 'nginx' ]
24
+ # task.chef_repo_dir = '/Users/me/chef-repo'
25
+ # end
26
+ #
27
+ # @example Run the Python and NGinx cookbooks on a Windows guest
28
+ # Vagrant::RakeTask.new do |task|
29
+ # task.guest_os = :windows
30
+ # task.box_name = 'vagrant-windows-server-r2'
31
+ # task.box_url = 'http://example.com/boxes/vagrant-windows-server-r2.box'
32
+ # task.run_list = [ 'python', 'nginx' ]
33
+ # task.chef_repo_dir = '/Users/me/chef-repo'
34
+ # end
35
+ #
36
+ class RakeTask < ::Rake::TaskLib
37
+ include ::Rake::DSL if defined? ::Rake::DSL
38
+
39
+ attr_accessor :guest_os
40
+ attr_accessor :box_url
41
+ attr_accessor :box_name
42
+ attr_accessor :run_list
43
+ attr_accessor :node_name
44
+ attr_accessor :chef_repo_dir
45
+ attr_accessor :chef_json
46
+
47
+ # @param [String] name The task name.
48
+ # @param [String] desc Description of the task.
49
+ def initialize(name = 'vagrant', desc = 'Daptiv Vagrant Tasks')
50
+ @name, @desc = name, desc
51
+ @guest_os = nil
52
+ @box_url = nil
53
+ @box_name = nil
54
+ @run_list = []
55
+ @node_name = nil
56
+ @chef_repo_dir = nil
57
+ @chef_json = nil
58
+
59
+ yield self if block_given?
60
+
61
+ define_task
62
+ end
63
+
64
+
65
+ private
66
+
67
+ def define_task
68
+ desc @desc
69
+ task @name do
70
+
71
+ options = {
72
+ :guest_os => @guest_os,
73
+ :box_url => @box_url,
74
+ :box_name => @box_name,
75
+ :run_list => @run_list,
76
+ :node_name => @node_name,
77
+ :chef_repo_dir => @chef_repo_dir,
78
+ :chef_json => @chef_json }
79
+
80
+ shell = DaptivChefCI::Shell.new()
81
+ vagrant = DaptivChefCI::VagrantDriver.new(shell, options)
82
+
83
+ vagrant.create_vagrantfile()
84
+
85
+ begin
86
+ vagrant.destroy()
87
+ rescue SystemExit => ex
88
+ exit(ex.status)
89
+ rescue Exception => ex
90
+ print_err(ex)
91
+ end
92
+
93
+ begin
94
+ vagrant.up()
95
+ rescue SystemExit => ex
96
+ exit(ex.status)
97
+ rescue Exception => ex
98
+ print_err(ex)
99
+ exit(1)
100
+ ensure
101
+ vagrant.halt()
102
+ vagrant.destroy()
103
+ end
104
+
105
+ end
106
+ end
107
+
108
+ def print_err(ex)
109
+ STDERR.puts("#{ex.message} (#{ex.class})")
110
+ STDERR.puts(ex.backtrace.join("\n"))
111
+ end
112
+
113
+ end
114
+ end
115
+
@@ -0,0 +1,48 @@
1
+ require 'log4r'
2
+ require_relative 'shell'
3
+
4
+ module DaptivChefCI
5
+ class VirtualBoxDriver
6
+
7
+ def initialize(shell)
8
+ @logger = Log4r::Logger.new("daptiv_chef_ci::virtual_box")
9
+ @shell = shell
10
+ end
11
+
12
+ # Remove any running vms that have the same name as this box
13
+ def cleanup_vms(box_name)
14
+ list_all_running_vms().each do |vm|
15
+ if vm.include?(box_name)
16
+ machine_name = vm.split[0]
17
+ @logger.debug("Found matching VBox #{machine_name} - Running")
18
+ poweroff(machine_name)
19
+ unregister(machine_name)
20
+ else
21
+ @logger.debug("Found no matching VBox #{machine_name}")
22
+ end
23
+ end
24
+ end
25
+
26
+
27
+ private
28
+
29
+ # Power off the named virtual box
30
+ def poweroff(machine_name)
31
+ @logger.info("Powering off VM: #{machine_name}")
32
+ @shell.exec_cmd("vboxmanage controlvm #{machine_name} poweroff")
33
+ end
34
+
35
+ # Unregister the virtual box. Must be powered off first.
36
+ def unregister(machine_name)
37
+ @logger.info("Unregistering VM: #{machine_name}")
38
+ @shell.exec_cmd("vboxmanage unregistervm #{machine_name}")
39
+ end
40
+
41
+ # Get a list of running vms
42
+ def list_all_running_vms()
43
+ @logger.info("List running VMs")
44
+ @shell.exec_cmd('vboxmanage list runningvms') || ''
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,41 @@
1
+ require 'mocha/api'
2
+ require 'daptiv-chef-ci/logger'
3
+ require 'log4r'
4
+
5
+ describe DaptivChefCI::Logger, :unit => true do
6
+
7
+ describe 'init' do
8
+
9
+ # get logging level before running any of these tests
10
+ before(:all) do
11
+ @chef_ci_log = ENV['CHEF_CI_LOG']
12
+ end
13
+
14
+ # reset logging back to starting state before this fixture
15
+ after(:all) do
16
+ ENV['CHEF_CI_LOG'] = @chef_ci_log
17
+ DaptivChefCI::Logger.init()
18
+ end
19
+
20
+ # reset logging back to default state before every test
21
+ before(:each) do
22
+ ENV['CHEF_CI_LOG'] = ''
23
+ DaptivChefCI::Logger.init()
24
+ end
25
+
26
+ it 'should initialize logging to error by default' do
27
+ DaptivChefCI::Logger.init()
28
+ logger = Log4r::Logger.new("daptiv_chef_ci::logger_spec")
29
+ expect(logger.level).to eq(4)
30
+ end
31
+
32
+ it 'should initialize logging to the specified level' do
33
+ ENV['CHEF_CI_LOG'] = 'DEBUG'
34
+ DaptivChefCI::Logger.init()
35
+ logger = Log4r::Logger.new("daptiv_chef_ci::logger_spec")
36
+ expect(logger.level).to eq(1)
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,36 @@
1
+ require 'mocha/api'
2
+ require 'daptiv-chef-ci/virtualbox_driver'
3
+ require 'daptiv-chef-ci/logger'
4
+ require 'bundler'
5
+
6
+ describe DaptivChefCI::Shell, :unit => true do
7
+
8
+ describe 'exec_cmd' do
9
+
10
+ it 'should split output by line' do
11
+ shell = DaptivChefCI::Shell.new()
12
+ out = shell.exec_cmd('ls -l')
13
+ expect(out.count).to be > 1
14
+ end
15
+
16
+ it 'should revert path when method returns' do
17
+ path_before = ENV['PATH']
18
+ shell = DaptivChefCI::Shell.new()
19
+ shell.exec_cmd('ls -l')
20
+ expect(ENV['PATH']).to eq(path_before)
21
+ end
22
+
23
+ end
24
+
25
+ describe 'path_without_gem_dir' do
26
+
27
+ it 'should not be prefixed by the system gem dir' do
28
+ shell = DaptivChefCI::Shell.new()
29
+ path = shell.path_without_gem_dir()
30
+ expect(path).not_to include(Bundler.bundle_path.to_s())
31
+ expect(ENV['PATH']).to include(path)
32
+ end
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,93 @@
1
+ require 'mocha/api'
2
+ require 'daptiv-chef-ci/vagrant_driver'
3
+ require 'daptiv-chef-ci/logger'
4
+
5
+ describe DaptivChefCI::VagrantDriver, :unit => true do
6
+
7
+ before(:each) do
8
+ @shell = mock()
9
+ @options = {}
10
+ @vagrant = DaptivChefCI::VagrantDriver.new(@shell, @options)
11
+ end
12
+
13
+ describe 'render_vagrantfile' do
14
+ it 'should default chef-repo dir to ~/src/chef-repo' do
15
+ vagrantfile = @vagrant.render_vagrantfile()
16
+ expect(vagrantfile).to include("chef_repo_dir = '#{ENV['HOME']}/src/chef-repo'")
17
+ end
18
+
19
+ it 'should not include box url when not set' do
20
+ vagrantfile = @vagrant.render_vagrantfile()
21
+ expect(vagrantfile).not_to include("config.vm.box_url")
22
+ end
23
+
24
+ it 'should include box url when set' do
25
+ @options[:box_url] = 'http://example.com/boxes/freebsd.box'
26
+ vagrantfile = @vagrant.render_vagrantfile()
27
+ expect(vagrantfile).to include("config.vm.box_url = 'http://example.com/boxes/freebsd.box'")
28
+ end
29
+
30
+ it 'should include windows section when guest is set to windows' do
31
+ @options[:guest_os] = :windows
32
+ vagrantfile = @vagrant.render_vagrantfile()
33
+ expect(vagrantfile).to include('config.vm.guest = :windows')
34
+ expect(vagrantfile).to include('config.windows.halt_timeout = 15')
35
+ expect(vagrantfile).to include('config.winrm.username = "vagrant"')
36
+ expect(vagrantfile).to include('config.winrm.password = "vagrant"')
37
+ expect(vagrantfile).to include('config.vm.network :forwarded_port, guest: 5985, host: 5985')
38
+ end
39
+
40
+ it 'should expand runlist' do
41
+ @options[:run_list] = ['python', 'nginx']
42
+ vagrantfile = @vagrant.render_vagrantfile()
43
+ expect(vagrantfile).to include("chef.add_recipe 'python'")
44
+ expect(vagrantfile).to include("chef.add_recipe 'nginx'")
45
+ end
46
+ end
47
+
48
+ describe 'destroy' do
49
+ it 'should force shutdown vagrant' do
50
+ @shell.expects(:exec_cmd).with do |cmd|
51
+ expect(cmd).to eq('vagrant destroy -f')
52
+ end
53
+ @vagrant.destroy()
54
+ end
55
+ end
56
+
57
+ describe 'halt' do
58
+ it 'should halt vagrant' do
59
+ @shell.expects(:exec_cmd).with do |cmd|
60
+ expect(cmd).to eq('vagrant halt')
61
+ end
62
+ @vagrant.halt()
63
+ end
64
+ end
65
+
66
+ describe 'up' do
67
+ it 'should up vagrant' do
68
+ @shell.expects(:exec_cmd).with do |cmd|
69
+ expect(cmd).to eq('vagrant up')
70
+ end
71
+ @vagrant.up()
72
+ end
73
+ end
74
+
75
+ describe 'provision' do
76
+ it 'should provision vagrant' do
77
+ @shell.expects(:exec_cmd).with do |cmd|
78
+ expect(cmd).to eq('vagrant provision')
79
+ end
80
+ @vagrant.provision()
81
+ end
82
+ end
83
+
84
+ describe 'reload' do
85
+ it 'should reload vagrant' do
86
+ @shell.expects(:exec_cmd).with do |cmd|
87
+ expect(cmd).to eq('vagrant reload')
88
+ end
89
+ @vagrant.reload()
90
+ end
91
+ end
92
+
93
+ end
@@ -0,0 +1,32 @@
1
+ require 'mocha/api'
2
+ require 'daptiv-chef-ci/virtualbox_driver'
3
+ require 'daptiv-chef-ci/logger'
4
+
5
+ describe DaptivChefCI::VirtualBoxDriver, :unit => true do
6
+
7
+ describe 'cleanup_vms' do
8
+ it 'should poweroff and unregister all machines with a matching name' do
9
+ boxes = [
10
+ '"aspnet_1372120179" {b1937a1c-c6c4-4777-88d0-dfa9066fb126}',
11
+ '"aspnet_1379346156" {7bb1bbce-c6cc-47a2-9c51-57ede42e02b5}',
12
+ '"python_1372120178" {c1937a1c-c6c4-4777-88d0-dfa9066fb156}'
13
+ ]
14
+ @shell = mock()
15
+ @vbox = DaptivChefCI::VirtualBoxDriver.new(@shell)
16
+
17
+ @shell.expects(:exec_cmd).with('vboxmanage list runningvms').returns(boxes)
18
+
19
+ @shell.expects(:exec_cmd).with('vboxmanage controlvm "aspnet_1372120179" poweroff').once()
20
+ @shell.expects(:exec_cmd).with('vboxmanage unregistervm "aspnet_1372120179"').once()
21
+
22
+ @shell.expects(:exec_cmd).with('vboxmanage controlvm "aspnet_1379346156" poweroff').once()
23
+ @shell.expects(:exec_cmd).with('vboxmanage unregistervm "aspnet_1379346156"').once()
24
+
25
+ @shell.expects(:exec_cmd).with('vboxmanage controlvm "python_1372120178" poweroff').never()
26
+ @shell.expects(:exec_cmd).with('vboxmanage unregistervm "python_1372120178"').never()
27
+
28
+ @vbox.cleanup_vms('aspnet')
29
+ end
30
+ end
31
+
32
+ end
metadata ADDED
@@ -0,0 +1,215 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: daptiv-chef-ci
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Shawn Neal
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-10-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mixlib-shellout
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.2.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 1.2.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: log4r
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 1.1.10
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.1.10
46
+ - !ruby/object:Gem::Dependency
47
+ name: erubis
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 2.7.0
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 2.7.0
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec-core
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 2.12.2
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 2.12.2
94
+ - !ruby/object:Gem::Dependency
95
+ name: rspec-expectations
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: 2.12.1
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 2.12.1
110
+ - !ruby/object:Gem::Dependency
111
+ name: rspec-mocks
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 2.12.1
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: 2.12.1
126
+ - !ruby/object:Gem::Dependency
127
+ name: simplecov
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: mocha
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ~>
148
+ - !ruby/object:Gem::Version
149
+ version: 0.14.0
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ~>
156
+ - !ruby/object:Gem::Version
157
+ version: 0.14.0
158
+ description: Vagrant automation for CI
159
+ email:
160
+ - sneal@daptiv.com
161
+ executables: []
162
+ extensions: []
163
+ extra_rdoc_files: []
164
+ files:
165
+ - daptiv-chef-ci.gemspec
166
+ - Gemfile
167
+ - lib/daptiv-chef-ci/logger.rb
168
+ - lib/daptiv-chef-ci/shell.rb
169
+ - lib/daptiv-chef-ci/templates/Vagrantfile.erb
170
+ - lib/daptiv-chef-ci/vagrant_driver.rb
171
+ - lib/daptiv-chef-ci/vagrant_task.rb
172
+ - lib/daptiv-chef-ci/virtualbox_driver.rb
173
+ - pkg/daptiv-chef-ci-0.0.1.gem
174
+ - Rakefile
175
+ - README.md
176
+ - spec/daptiv-chef-ci/logger_spec.rb
177
+ - spec/daptiv-chef-ci/shell_spec.rb
178
+ - spec/daptiv-chef-ci/vagrant_driver_spec.rb
179
+ - spec/daptiv-chef-ci/virtualbox_driver_spec.rb
180
+ - .gitignore
181
+ homepage: ''
182
+ licenses: []
183
+ post_install_message:
184
+ rdoc_options: []
185
+ require_paths:
186
+ - lib
187
+ required_ruby_version: !ruby/object:Gem::Requirement
188
+ none: false
189
+ requirements:
190
+ - - ! '>='
191
+ - !ruby/object:Gem::Version
192
+ version: '0'
193
+ segments:
194
+ - 0
195
+ hash: -2620113271490867274
196
+ required_rubygems_version: !ruby/object:Gem::Requirement
197
+ none: false
198
+ requirements:
199
+ - - ! '>='
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ segments:
203
+ - 0
204
+ hash: -2620113271490867274
205
+ requirements: []
206
+ rubyforge_project:
207
+ rubygems_version: 1.8.23
208
+ signing_key:
209
+ specification_version: 3
210
+ summary: A small gem to reduce Rake duplication
211
+ test_files:
212
+ - spec/daptiv-chef-ci/logger_spec.rb
213
+ - spec/daptiv-chef-ci/shell_spec.rb
214
+ - spec/daptiv-chef-ci/vagrant_driver_spec.rb
215
+ - spec/daptiv-chef-ci/virtualbox_driver_spec.rb