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:
parent
a8e00045df
commit
f5a585b3a4
10 changed files with 286 additions and 8 deletions
34
spec/integration/deploy_finalize_spec.rb
Normal file
34
spec/integration/deploy_finalize_spec.rb
Normal 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
|
36
spec/integration/deploy_finished_spec.rb
Normal file
36
spec/integration/deploy_finished_spec.rb
Normal 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
|
74
spec/integration/deploy_started_spec.rb
Normal file
74
spec/integration/deploy_started_spec.rb
Normal 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
|
||||
|
45
spec/integration/deploy_update_spec.rb
Normal file
45
spec/integration/deploy_update_spec.rb
Normal 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
|
|
@ -13,6 +13,14 @@ describe Capistrano::DSL do
|
|||
dsl.server 'example4.com', roles: %w{app}, primary: true
|
||||
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
|
||||
subject { dsl.roles(:app) }
|
||||
|
||||
|
@ -64,6 +72,14 @@ describe Capistrano::DSL do
|
|||
dsl.role :app, %w{example4.com}, primary: true
|
||||
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
|
||||
subject { dsl.roles(:app) }
|
||||
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
require 'spec_helper'
|
||||
require 'support/test_app'
|
||||
require 'integration_spec_helper'
|
||||
|
||||
include TestApp
|
||||
|
||||
describe 'cap install' do
|
||||
describe 'cap install', slow: true do
|
||||
|
||||
context 'with defaults' do
|
||||
before :all do
|
||||
|
@ -65,7 +62,7 @@ describe 'cap install' do
|
|||
expect(File.exists?(file)).to be_true
|
||||
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')
|
||||
production = test_app_path.join('config/deploy/production.rb')
|
||||
staging = test_app_path.join('config/deploy/staging.rb')
|
||||
|
|
7
spec/integration_spec_helper.rb
Normal file
7
spec/integration_spec_helper.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'support/test_app'
|
||||
require 'support/matchers'
|
||||
|
||||
include TestApp
|
||||
|
||||
|
|
@ -9,6 +9,8 @@ require 'mocha/api'
|
|||
Dir['#{File.dirname(__FILE__)}/support/**/*.rb'].each {|f| require f}
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.treat_symbols_as_metadata_keys_with_true_values = true
|
||||
config.mock_framework = :mocha
|
||||
config.order = 'random'
|
||||
config.filter_run_excluding :slow
|
||||
end
|
||||
|
|
5
spec/support/matchers.rb
Normal file
5
spec/support/matchers.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
RSpec::Matchers.define :be_a_symlink_to do |expected|
|
||||
match do |actual|
|
||||
File.identical?(expected, actual)
|
||||
end
|
||||
end
|
|
@ -1,7 +1,10 @@
|
|||
require 'fileutils'
|
||||
module TestApp
|
||||
def create_test_app
|
||||
FileUtils.rm_rf(test_app_path)
|
||||
FileUtils.mkdir(test_app_path)
|
||||
[test_app_path, deploy_to].each do |path|
|
||||
FileUtils.rm_rf(path)
|
||||
FileUtils.mkdir(path)
|
||||
end
|
||||
|
||||
File.open(gemfile, 'w+') do |file|
|
||||
file.write "gem 'capistrano', path: '#{path_to_cap}'"
|
||||
|
@ -12,11 +15,66 @@ module TestApp
|
|||
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
|
||||
Pathname.new('/tmp/test_app')
|
||||
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
|
||||
File.expand_path('.')
|
||||
end
|
||||
|
@ -24,4 +82,8 @@ module TestApp
|
|||
def gemfile
|
||||
test_app_path.join('Gemfile')
|
||||
end
|
||||
|
||||
def current_user
|
||||
`whoami`.chomp
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue