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

653 lines
21 KiB
Ruby
Raw Normal View History

require 'spec_helper'
describe Capistrano::DSL do
let(:dsl) { Class.new.extend Capistrano::DSL }
before do
Capistrano::Configuration.reset!
end
describe 'setting and fetching hosts' do
describe 'when defining a host using the `server` syntax' do
before do
2016-02-28 18:14:50 -05:00
dsl.server 'example1.com', :roles => %w{web}, :active => true
dsl.server 'example2.com', :roles => %w{web}
dsl.server 'example3.com', :roles => %w{app web}, :active => true
dsl.server 'example4.com', :roles => %w{app}, :primary => true
dsl.server 'example5.com', :roles => %w{db}, :no_release => true, :active => 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 example5.com}
end
end
describe 'fetching all release servers' do
context 'with no additional options' do
subject { dsl.release_roles(:all) }
it 'returns all release servers' do
expect(subject.map(&:hostname)).to eq %w{example1.com example2.com example3.com example4.com}
end
end
context 'with property filter options' do
2016-02-28 18:14:50 -05:00
subject { dsl.release_roles(:all, :filter => :active) }
it 'returns all release servers that match the property filter' do
expect(subject.map(&:hostname)).to eq %w{example1.com example3.com}
end
end
end
describe 'fetching servers by multiple roles' do
it "does not confuse the last role with options" do
expect(dsl.roles(:app, :web).count).to eq 4
2016-02-28 18:14:50 -05:00
expect(dsl.roles(:app, :web, :filter => :active).count).to eq 2
end
end
describe 'fetching servers by role' do
subject { dsl.roles(:app) }
it 'returns the servers' do
expect(subject.map(&:hostname)).to eq %w{example3.com example4.com}
end
end
describe 'fetching servers by an array of roles' do
subject { dsl.roles([:app]) }
it 'returns the servers' do
expect(subject.map(&:hostname)).to eq %w{example3.com example4.com}
end
end
describe 'fetching filtered servers by role' do
2016-02-28 18:14:50 -05:00
subject { dsl.roles(:app, :filter => :active) }
it 'returns the servers' do
expect(subject.map(&:hostname)).to eq %w{example3.com}
end
end
describe 'fetching selected servers by role' do
2016-02-28 18:14:50 -05:00
subject { dsl.roles(:app, :select => :active) }
it 'returns the servers' do
expect(subject.map(&:hostname)).to eq %w{example3.com}
end
end
describe 'fetching the primary server by role' do
context 'when inferring primary status based on order' do
subject { dsl.primary(:web) }
it 'returns the servers' do
expect(subject.hostname).to eq 'example1.com'
end
end
context 'when the attribute `primary` is explicitly set' do
subject { dsl.primary(:app) }
it 'returns the servers' do
expect(subject.hostname).to eq 'example4.com'
end
end
end
describe 'setting an internal host filter' do
subject { dsl.roles(:app) }
it 'is ignored' do
2016-02-28 18:14:50 -05:00
dsl.set :filter, { :host => 'example3.com' }
expect(subject.map(&:hostname)).to eq(['example3.com', 'example4.com'])
end
end
describe 'setting an internal role filter' do
subject { dsl.roles(:app) }
it 'ignores it' do
2016-02-28 18:14:50 -05:00
dsl.set :filter, { :role => :web }
expect(subject.map(&:hostname)).to eq(['example3.com','example4.com'])
end
end
describe 'setting an internal host and role filter' do
subject { dsl.roles(:app) }
it 'ignores it' do
2016-02-28 18:14:50 -05:00
dsl.set :filter, { :role => :web, :host => 'example1.com' }
expect(subject.map(&:hostname)).to eq(['example3.com','example4.com'])
end
end
describe 'setting an internal regexp host filter' do
subject { dsl.roles(:all) }
it 'is ignored' do
2016-02-28 18:14:50 -05:00
dsl.set :filter, { :host => /1/ }
expect(subject.map(&:hostname)).to eq(%w{example1.com example2.com example3.com example4.com example5.com})
end
end
describe 'setting an internal hosts filter' do
subject { dsl.roles(:app) }
it 'is ignored' do
2016-02-28 18:14:50 -05:00
dsl.set :filter, { :hosts => 'example3.com' }
expect(subject.map(&:hostname)).to eq(['example3.com', 'example4.com'])
end
end
describe 'setting an internal roles filter' do
subject { dsl.roles(:app) }
it 'ignores it' do
2016-02-28 18:14:50 -05:00
dsl.set :filter, { :roles => :web }
expect(subject.map(&:hostname)).to eq(['example3.com','example4.com'])
end
end
describe 'setting an internal hosts and roles filter' do
subject { dsl.roles(:app) }
it 'ignores it' do
2016-02-28 18:14:50 -05:00
dsl.set :filter, { :roles => :web, :hosts => 'example1.com' }
expect(subject.map(&:hostname)).to eq(['example3.com','example4.com'])
end
end
describe 'setting an internal regexp hosts filter' do
subject { dsl.roles(:all) }
it 'is ignored' do
2016-02-28 18:14:50 -05:00
dsl.set :filter, { :hosts => /1/ }
expect(subject.map(&:hostname)).to eq(%w{example1.com example2.com example3.com example4.com example5.com})
end
end
end
describe 'when defining role with reserved name' do
it 'fails with ArgumentError' do
expect {
dsl.role :all, %w{example1.com}
}.to raise_error(ArgumentError, "all reserved name for role. Please choose another name")
end
end
describe 'when defining hosts using the `role` syntax' do
before do
dsl.role :web, %w{example1.com example2.com example3.com}
2016-02-28 18:14:50 -05:00
dsl.role :web, %w{example1.com}, :active => true
dsl.role :app, %w{example3.com example4.com}
2016-02-28 18:14:50 -05:00
dsl.role :app, %w{example3.com}, :active => true
dsl.role :app, %w{example4.com}, :primary => true
dsl.role :db, %w{example5.com}, :no_release => 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 example5.com}
end
end
describe 'fetching all release servers' do
context 'with no additional options' do
subject { dsl.release_roles(:all) }
it 'returns all release servers' do
expect(subject.map(&:hostname)).to eq %w{example1.com example2.com example3.com example4.com}
end
end
context 'with filter options' do
2016-02-28 18:14:50 -05:00
subject { dsl.release_roles(:all, :filter => :active) }
it 'returns all release servers that match the filter' do
expect(subject.map(&:hostname)).to eq %w{example1.com example3.com}
end
end
end
describe 'fetching servers by role' do
subject { dsl.roles(:app) }
it 'returns the servers' do
expect(subject.map(&:hostname)).to eq %w{example3.com example4.com}
end
end
describe 'fetching servers by an array of roles' do
subject { dsl.roles([:app]) }
it 'returns the servers' do
expect(subject.map(&:hostname)).to eq %w{example3.com example4.com}
end
end
describe 'fetching filtered servers by role' do
2016-02-28 18:14:50 -05:00
subject { dsl.roles(:app, :filter => :active) }
it 'returns the servers' do
expect(subject.map(&:hostname)).to eq %w{example3.com}
end
end
describe 'fetching selected servers by role' do
2016-02-28 18:14:50 -05:00
subject { dsl.roles(:app, :select => :active) }
it 'returns the servers' do
expect(subject.map(&:hostname)).to eq %w{example3.com}
end
end
describe 'fetching the primary server by role' do
context 'when inferring primary status based on order' do
subject { dsl.primary(:web) }
it 'returns the servers' do
expect(subject.hostname).to eq 'example1.com'
end
end
context 'when the attribute `primary` is explicity set' do
subject { dsl.primary(:app) }
it 'returns the servers' do
expect(subject.hostname).to eq 'example4.com'
end
end
end
end
describe 'when defining a host using a combination of the `server` and `role` syntax' do
before do
2016-02-28 18:14:50 -05:00
dsl.server 'db@example1.com:1234', :roles => %w{db}, :active => true
dsl.server 'root@example1.com:1234', :roles => %w{web}, :active => true
dsl.server 'example1.com:5678', :roles => %w{web}, :active => true
dsl.role :app, %w{deployer@example1.com:1234}
dsl.role :app, %w{example1.com:5678}
end
describe 'fetching all servers' do
2015-09-10 11:09:23 -04:00
it 'creates one server per hostname, ignoring user combinations' do
expect(dsl.roles(:all).size).to eq(2)
end
end
describe 'fetching servers for a role' do
it 'roles defined using the `server` syntax are included' do
as = dsl.roles(:web).map { |server| "#{server.user}@#{server.hostname}:#{server.port}" }
2015-09-10 11:09:23 -04:00
expect(as.size).to eq(2)
expect(as[0]).to eq("deployer@example1.com:1234")
expect(as[1]).to eq("@example1.com:5678")
end
it 'roles defined using the `role` syntax are included' do
as = dsl.roles(:app).map { |server| "#{server.user}@#{server.hostname}:#{server.port}" }
2015-09-10 11:09:23 -04:00
expect(as.size).to eq(2)
expect(as[0]).to eq("deployer@example1.com:1234")
expect(as[1]).to eq("@example1.com:5678")
end
end
end
describe 'when setting user and port' do
subject { dsl.roles(:all).map { |server| "#{server.user}@#{server.hostname}:#{server.port}" }.first }
describe "using the :user property" do
it "takes precedence over in the host string" do
2016-02-28 18:14:50 -05:00
dsl.server 'db@example1.com:1234', :roles => %w{db}, :active => true, :user => 'brian'
expect(subject).to eq("brian@example1.com:1234")
end
end
describe "using the :port property" do
it "takes precedence over in the host string" do
2016-02-28 18:14:50 -05:00
dsl.server 'db@example1.com:9090', :roles => %w{db}, :active => true, :port => 1234
expect(subject).to eq("db@example1.com:1234")
end
end
end
end
describe 'setting and fetching variables' do
before do
dsl.set :scm, :git
end
context 'without a default' do
context 'when the variables is defined' do
it 'returns the variable' do
expect(dsl.fetch(:scm)).to eq :git
end
end
context 'when the variables is undefined' do
it 'returns nil' do
expect(dsl.fetch(:source_control)).to be_nil
end
end
end
context 'with a default' do
context 'when the variables is defined' do
it 'returns the variable' do
expect(dsl.fetch(:scm, :svn)).to eq :git
end
end
context 'when the variables is undefined' do
it 'returns the default' do
expect(dsl.fetch(:source_control, :svn)).to eq :svn
end
end
end
context 'with a block' do
context 'when the variables is defined' do
it 'returns the variable' do
expect(dsl.fetch(:scm) { :svn }).to eq :git
end
end
context 'when the variables is undefined' do
it 'calls the block' do
expect(dsl.fetch(:source_control) { :svn }).to eq :svn
end
end
end
end
describe 'asking for a variable' do
before do
dsl.ask(:scm, :svn)
$stdout.stubs(:print)
end
context 'variable is provided' do
before do
$stdin.expects(:gets).returns('git')
end
it 'sets the input as the variable' do
expect(dsl.fetch(:scm)).to eq 'git'
end
end
context 'variable is not provided' do
before do
$stdin.expects(:gets).returns('')
end
it 'sets the variable as the default' do
expect(dsl.fetch(:scm)).to eq :svn
end
end
end
describe 'checking for presence' do
subject { dsl.any? :linked_files }
before do
dsl.set(:linked_files, linked_files)
end
context 'variable is an non-empty array' do
let(:linked_files) { %w{1} }
2014-08-12 14:52:37 -04:00
it { expect(subject).to be_truthy }
end
context 'variable is an empty array' do
let(:linked_files) { [] }
2014-08-12 14:52:37 -04:00
it { expect(subject).to be_falsey }
end
context 'variable exists, is not an array' do
let(:linked_files) { stub }
2014-08-12 14:52:37 -04:00
it { expect(subject).to be_truthy }
end
context 'variable is nil' do
let(:linked_files) { nil }
2014-08-12 14:52:37 -04:00
it { expect(subject).to be_falsey }
end
end
2013-06-14 05:02:59 -04:00
describe 'configuration SSHKit' do
let(:config) { SSHKit.config }
let(:backend) { SSHKit.config.backend.config }
2016-02-28 18:14:50 -05:00
let(:default_env) { { :rails_env => :production } }
2013-06-14 05:02:59 -04:00
before do
dsl.set(:format, :dot)
dsl.set(:log_level, :debug)
dsl.set(:default_env, default_env)
dsl.set(:pty, true)
dsl.set(:connection_timeout, 10)
dsl.set(:ssh_options, {
2016-02-28 18:14:50 -05:00
:keys => %w(/home/user/.ssh/id_rsa),
:forward_agent => false,
:auth_methods => %w(publickey password)
})
2013-06-14 05:02:59 -04:00
dsl.configure_backend
end
it 'sets the output' do
expect(config.output).to be_a SSHKit::Formatter::Dot
end
it 'sets the output verbosity' do
expect(config.output_verbosity).to eq 0
end
it 'sets the default env' do
expect(config.default_env).to eq default_env
end
it 'sets the backend pty' do
2014-08-12 14:52:37 -04:00
expect(backend.pty).to be_truthy
2013-06-14 05:02:59 -04:00
end
it 'sets the backend connection timeout' do
expect(backend.connection_timeout).to eq 10
end
it 'sets the backend ssh_options' do
expect(backend.ssh_options[:keys]).to eq %w(/home/user/.ssh/id_rsa)
expect(backend.ssh_options[:forward_agent]).to eq false
expect(backend.ssh_options[:auth_methods]).to eq %w(publickey password)
end
2013-06-14 05:02:59 -04:00
end
describe 'on()' do
describe "when passed server objects" do
before do
2016-02-28 18:14:50 -05:00
dsl.server 'example1.com', :roles => %w{web}, :active => true
dsl.server 'example2.com', :roles => %w{web}
dsl.server 'example3.com', :roles => %w{app web}, :active => true
dsl.server 'example4.com', :roles => %w{app}, :primary => true
dsl.server 'example5.com', :roles => %w{db}, :no_release => true
@coordinator = mock('coordinator')
@coordinator.expects(:each).returns(nil)
ENV.delete 'ROLES'
ENV.delete 'HOSTS'
end
it 'filters by role from the :filter variable' do
hosts = dsl.roles(:web)
all = dsl.roles(:all)
SSHKit::Coordinator.expects(:new).with(hosts).returns(@coordinator)
2016-02-28 18:14:50 -05:00
dsl.set :filter, { :role => 'web' }
dsl.on(all)
end
it 'filters by host and role from the :filter variable' do
all = dsl.roles(:all)
SSHKit::Coordinator.expects(:new).with([]).returns(@coordinator)
2016-02-28 18:14:50 -05:00
dsl.set :filter, { :role => 'db', :host => 'example3.com' }
dsl.on(all)
end
it 'filters by roles from the :filter variable' do
hosts = dsl.roles(:web)
all = dsl.roles(:all)
SSHKit::Coordinator.expects(:new).with(hosts).returns(@coordinator)
2016-02-28 18:14:50 -05:00
dsl.set :filter, { :roles => 'web' }
dsl.on(all)
end
it 'filters by hosts and roles from the :filter variable' do
all = dsl.roles(:all)
SSHKit::Coordinator.expects(:new).with([]).returns(@coordinator)
2016-02-28 18:14:50 -05:00
dsl.set :filter, { :roles => 'db', :hosts => 'example3.com' }
dsl.on(all)
end
it 'filters from ENV[ROLES]' do
hosts = dsl.roles(:db)
all = dsl.roles(:all)
SSHKit::Coordinator.expects(:new).with(hosts).returns(@coordinator)
ENV['ROLES'] = 'db'
dsl.on(all)
end
it 'filters from ENV[HOSTS]' do
hosts = dsl.roles(:db)
all = dsl.roles(:all)
SSHKit::Coordinator.expects(:new).with(hosts).returns(@coordinator)
ENV['HOSTS'] = 'example5.com'
dsl.on(all)
end
it 'filters by ENV[HOSTS] && ENV[ROLES]' do
all = dsl.roles(:all)
SSHKit::Coordinator.expects(:new).with([]).returns(@coordinator)
ENV['HOSTS'] = 'example5.com'
ENV['ROLES'] = 'web'
dsl.on(all)
end
end
describe "when passed server literal names" do
before do
ENV.delete 'ROLES'
ENV.delete 'HOSTS'
@coordinator = mock('coordinator')
@coordinator.expects(:each).returns(nil)
end
it "selects nothing when a role filter is present" do
2016-02-28 18:14:50 -05:00
dsl.set :filter, { :role => 'web' }
SSHKit::Coordinator.expects(:new).with([]).returns(@coordinator)
dsl.on('my.server')
end
it "selects using the string when a host filter is present" do
2016-02-28 18:14:50 -05:00
dsl.set :filter, { :host => 'server.local' }
SSHKit::Coordinator.expects(:new).with(['server.local']).returns(@coordinator)
dsl.on('server.local')
end
it "doesn't select when a host filter is present that doesn't match" do
2016-02-28 18:14:50 -05:00
dsl.set :filter, { :host => 'ruby.local' }
SSHKit::Coordinator.expects(:new).with([]).returns(@coordinator)
dsl.on('server.local')
end
it "selects nothing when a roles filter is present" do
2016-02-28 18:14:50 -05:00
dsl.set :filter, { :roles => 'web' }
SSHKit::Coordinator.expects(:new).with([]).returns(@coordinator)
dsl.on('my.server')
end
it "selects using the string when a hosts filter is present" do
2016-02-28 18:14:50 -05:00
dsl.set :filter, { :hosts => 'server.local' }
SSHKit::Coordinator.expects(:new).with(['server.local']).returns(@coordinator)
dsl.on('server.local')
end
it "doesn't select when a hosts filter is present that doesn't match" do
2016-02-28 18:14:50 -05:00
dsl.set :filter, { :hosts => 'ruby.local' }
SSHKit::Coordinator.expects(:new).with([]).returns(@coordinator)
dsl.on('server.local')
end
end
end
describe 'role_properties()' do
before do
2016-02-28 18:14:50 -05:00
dsl.role :redis, %w[example1.com example2.com], :redis => { :port => 6379, :type => :slave }
dsl.server 'example1.com', :roles => %w{web}, :active => true, :web => { :port => 80 }
dsl.server 'example2.com', :roles => %w{web redis}, :web => { :port => 81 }, :redis => { :type => :master }
dsl.server 'example3.com', :roles => %w{app}, :primary => true
end
it 'retrieves properties for a single role as a set' do
rps = dsl.role_properties(:app)
2016-02-28 18:14:50 -05:00
expect(rps).to eq(Set[{ :hostname => 'example3.com', :role => :app}])
end
it 'retrieves properties for multiple roles as a set' do
rps = dsl.role_properties(:app, :web)
2016-02-28 18:14:50 -05:00
expect(rps).to eq(Set[{ :hostname => 'example3.com', :role => :app},{ :hostname => 'example1.com', :role => :web, :port => 80},{ :hostname => 'example2.com', :role => :web, :port => 81}])
end
it 'yields the properties for a single role' do
recipient = mock('recipient')
2016-02-28 18:14:50 -05:00
recipient.expects(:doit).with('example1.com', :redis, { :port => 6379, :type => :slave})
recipient.expects(:doit).with('example2.com', :redis, { :port => 6379, :type => :master})
dsl.role_properties(:redis) do |host, role, props|
recipient.doit(host, role, props)
end
end
it 'yields the properties for multiple roles' do
recipient = mock('recipient')
2016-02-28 18:14:50 -05:00
recipient.expects(:doit).with('example1.com', :redis, { :port => 6379, :type => :slave})
recipient.expects(:doit).with('example2.com', :redis, { :port => 6379, :type => :master})
recipient.expects(:doit).with('example3.com', :app, nil)
dsl.role_properties(:redis, :app) do |host, role, props|
recipient.doit(host, role, props)
end
end
it 'yields the merged properties for multiple roles' do
recipient = mock('recipient')
2016-02-28 18:14:50 -05:00
recipient.expects(:doit).with('example1.com', :redis, { :port => 6379, :type => :slave})
recipient.expects(:doit).with('example2.com', :redis, { :port => 6379, :type => :master})
recipient.expects(:doit).with('example1.com', :web, { :port => 80 })
recipient.expects(:doit).with('example2.com', :web, { :port => 81 })
dsl.role_properties(:redis, :web) do |host, role, props|
recipient.doit(host, role, props)
end
end
it 'honours a property filter before yielding' do
recipient = mock('recipient')
2016-02-28 18:14:50 -05:00
recipient.expects(:doit).with('example1.com', :redis, { :port => 6379, :type => :slave})
recipient.expects(:doit).with('example1.com', :web, { :port => 80 })
dsl.role_properties(:redis, :web, :select => :active) do |host, role, props|
recipient.doit(host, role, props)
end
end
end
end