daptiv-chef-ci 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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