1
0
Fork 0
mirror of https://github.com/capistrano/capistrano synced 2023-03-27 23:21:18 -04:00

Add integration tests for deploy task

This commit adds the outlines of a testing framework for Cap tasks.
Currently just the `cap install` and `cap deploy` tasks are covered. For
now, these tests can only be run if it is `ssh localhost` will work for
you and are currently excluded from the suite. It is my intention to
eventually replace the `sshkit` backend with a test backend, but for now
this is good enough to prevent simple regressions.
This commit is contained in:
seenmyfate 2013-06-16 13:08:15 +01:00
parent a8e00045df
commit f5a585b3a4
10 changed files with 286 additions and 8 deletions

View file

@ -0,0 +1,34 @@
require 'integration_spec_helper'
describe 'cap deploy:finished', slow: true do
before do
install_test_app_with(config)
end
describe 'deploy' do
let(:config) {
%{
set :stage, :#{stage}
set :deploy_to, '#{deploy_to}'
set :repo, 'git://github.com/capistrano/capistrano.git'
set :branch, 'v3'
server 'localhost', roles: %w{web app}, user: '#{current_user}'
set :linked_files, %w{config/database.yml}
set :linked_dirs, %w{bin log public/system vendor/bundle}
}
}
describe 'log_revision' do
before do
cap 'deploy:started'
cap 'deploy:update'
cap 'deploy:finalize'
cap 'deploy:finished'
end
it 'writes the log file' do
expect(deploy_to.join('revisions.log')).to be_a_file
end
end
end
end

View file

@ -0,0 +1,36 @@
require 'integration_spec_helper'
describe 'cap deploy:finished', slow: true do
before do
install_test_app_with(config)
end
describe 'deploy' do
let(:config) {
%{
set :stage, :#{stage}
set :deploy_to, '#{deploy_to}'
set :repo, 'git://github.com/capistrano/capistrano.git'
set :branch, 'v3'
server 'localhost', roles: %w{web app}, user: '#{current_user}'
set :linked_files, %w{config/database.yml}
set :linked_dirs, %w{bin log public/system vendor/bundle}
}
}
describe 'symlink' do
before do
cap 'deploy:started'
cap 'deploy:update'
cap 'deploy:finalize'
end
describe 'release' do
it 'symlinks the release to `current`' do
expect(File.symlink?(current_path)).to be_true
expect(File.readlink(current_path)).to match /\/tmp\/test_app\/deploy_to\/releases\/\d{14}/
end
end
end
end
end

View file

@ -0,0 +1,74 @@
require 'integration_spec_helper'
describe 'cap deploy:started', slow: true do
before do
install_test_app_with(config)
end
describe 'deploy:check' do
let(:config) {
%{
set :stage, :#{stage}
set :deploy_to, '#{deploy_to}'
set :repo, 'git://github.com/capistrano/capistrano.git'
set :branch, 'v3'
server 'localhost', roles: %w{web app}, user: '#{current_user}'
set :linked_files, %w{config/database.yml}
set :linked_dirs, %w{bin log public/system vendor/bundle}
}
}
describe 'directories' do
before do
cap 'deploy:check:directories'
end
it 'ensures the directory structure' do
expect(shared_path).to be_a_directory
expect(releases_path).to be_a_directory
end
end
describe 'linked_dirs' do
before do
cap 'deploy:check:linked_dirs'
end
it 'ensure directories to be linked in `shared`' do
[
shared_path.join('bin'),
shared_path.join('log'),
shared_path.join('public/system'),
shared_path.join('vendor/bundle'),
].each do |dir|
expect(dir).to be_a_directory
end
end
end
describe 'linked_files' do
subject { cap 'deploy:check:linked_files' }
context 'file does not exist' do
it 'fails' do
expect(subject).to match 'config/database.yml does not exist'
end
end
context 'file exists' do
before do
create_shared_directory('config')
create_shared_file('config/database.yml')
end
it 'suceeds' do
expect(subject).not_to match 'config/database.yml does not exist'
expect(subject).to match 'successful'
end
end
end
end
end

View file

@ -0,0 +1,45 @@
require 'integration_spec_helper'
describe 'cap deploy:update', slow: true do
before do
install_test_app_with(config)
end
describe 'deploy' do
let(:config) {
%{
set :stage, :#{stage}
set :deploy_to, '#{deploy_to}'
set :repo, 'git://github.com/capistrano/capistrano.git'
set :branch, 'v3'
server 'localhost', roles: %w{web app}, user: '#{current_user}'
set :linked_files, %w{config/database.yml}
set :linked_dirs, %w{bin log public/system vendor/bundle}
}
}
describe 'symlink' do
before do
cap 'deploy:started'
create_shared_directory('config')
create_shared_file('config/database.yml')
cap 'deploy:symlink:shared'
end
describe 'linked_dirs' do
it 'symlinks the directories in shared to `current`' do
%w{bin log public/system vendor/bundle}.each do |dir|
expect(release_path.join(dir)).to be_a_symlink_to shared_path.join(dir)
end
end
end
describe 'linked_files' do
it 'symlinks the files in shared to `current`' do
file = 'config/database.yml'
expect(release_path.join(file)).to be_a_symlink_to shared_path.join(file)
end
end
end
end
end

View file

@ -13,6 +13,14 @@ describe Capistrano::DSL do
dsl.server 'example4.com', roles: %w{app}, primary: true dsl.server 'example4.com', roles: %w{app}, primary: true
end end
describe 'fetching all servers' do
subject { dsl.roles(:all) }
it 'returns all servers' do
expect(subject.map(&:hostname)).to eq %w{example1.com example2.com example3.com example4.com}
end
end
describe 'fetching servers by role' do describe 'fetching servers by role' do
subject { dsl.roles(:app) } subject { dsl.roles(:app) }
@ -64,6 +72,14 @@ describe Capistrano::DSL do
dsl.role :app, %w{example4.com}, primary: true dsl.role :app, %w{example4.com}, primary: true
end end
describe 'fetching all servers' do
subject { dsl.roles(:all) }
it 'returns all servers' do
expect(subject.map(&:hostname)).to eq %w{example1.com example2.com example3.com example4.com}
end
end
describe 'fetching servers by role' do describe 'fetching servers by role' do
subject { dsl.roles(:app) } subject { dsl.roles(:app) }

View file

@ -1,9 +1,6 @@
require 'spec_helper' require 'integration_spec_helper'
require 'support/test_app'
include TestApp describe 'cap install', slow: true do
describe 'cap install' do
context 'with defaults' do context 'with defaults' do
before :all do before :all do
@ -65,7 +62,7 @@ describe 'cap install' do
expect(File.exists?(file)).to be_true expect(File.exists?(file)).to be_true
end end
it 'creates the stage files' do it 'creates the stage files specified, not the defaults' do
qa = test_app_path.join('config/deploy/qa.rb') qa = test_app_path.join('config/deploy/qa.rb')
production = test_app_path.join('config/deploy/production.rb') production = test_app_path.join('config/deploy/production.rb')
staging = test_app_path.join('config/deploy/staging.rb') staging = test_app_path.join('config/deploy/staging.rb')

View file

@ -0,0 +1,7 @@
require 'spec_helper'
require 'support/test_app'
require 'support/matchers'
include TestApp

View file

@ -9,6 +9,8 @@ require 'mocha/api'
Dir['#{File.dirname(__FILE__)}/support/**/*.rb'].each {|f| require f} Dir['#{File.dirname(__FILE__)}/support/**/*.rb'].each {|f| require f}
RSpec.configure do |config| RSpec.configure do |config|
config.treat_symbols_as_metadata_keys_with_true_values = true
config.mock_framework = :mocha config.mock_framework = :mocha
config.order = 'random' config.order = 'random'
config.filter_run_excluding :slow
end end

5
spec/support/matchers.rb Normal file
View file

@ -0,0 +1,5 @@
RSpec::Matchers.define :be_a_symlink_to do |expected|
match do |actual|
File.identical?(expected, actual)
end
end

View file

@ -1,7 +1,10 @@
require 'fileutils'
module TestApp module TestApp
def create_test_app def create_test_app
FileUtils.rm_rf(test_app_path) [test_app_path, deploy_to].each do |path|
FileUtils.mkdir(test_app_path) FileUtils.rm_rf(path)
FileUtils.mkdir(path)
end
File.open(gemfile, 'w+') do |file| File.open(gemfile, 'w+') do |file|
file.write "gem 'capistrano', path: '#{path_to_cap}'" file.write "gem 'capistrano', path: '#{path_to_cap}'"
@ -12,11 +15,66 @@ module TestApp
end end
end end
def install_test_app_with(config)
create_test_app
Dir.chdir(test_app_path) do
%x[bundle exec cap install STAGES=#{stage}]
end
write_local_deploy_file(config)
end
def write_local_deploy_file(config)
File.open(test_stage_path, 'w') do |file|
file.write config
end
end
def create_shared_directory(path)
FileUtils.mkdir_p(shared_path.join(path))
end
def create_shared_file(path)
File.open(shared_path.join(path), 'w')
end
def cap(task)
Dir.chdir(test_app_path) do
%x[bundle exec cap #{stage} #{task}]
end
end
def stage
'test'
end
def test_stage_path
test_app_path.join('config/deploy/test.rb')
end
def test_app_path def test_app_path
Pathname.new('/tmp/test_app') Pathname.new('/tmp/test_app')
end end
def deploy_to
Pathname.new('/tmp/test_app/deploy_to')
end
def shared_path
deploy_to.join('shared')
end
def current_path
deploy_to.join('current')
end
def releases_path
deploy_to.join('releases')
end
def release_path
releases_path.join(Dir.entries(releases_path).last)
end
def path_to_cap def path_to_cap
File.expand_path('.') File.expand_path('.')
end end
@ -24,4 +82,8 @@ module TestApp
def gemfile def gemfile
test_app_path.join('Gemfile') test_app_path.join('Gemfile')
end end
def current_user
`whoami`.chomp
end
end end