# encoding: UTF-8
require 'spec_helper'
require 'tempfile'
describe Plow::Strategy::UbuntuHardy do
before(:each) do
@context = Plow::Generator.new('steve', 'www.apple.com', 'apple.com')
@strategy = Plow::Strategy::UbuntuHardy.new(@context)
@parsed_users_fixture = [
{ name: "root", password: "x", id: 0, group_id: 0, info: "root", home_path: "/root", shell_path: "/bin/bash" },
{ name: "daemon", password: "x", id: 1, group_id: 1, info: "daemon", home_path: "/usr/sbin", shell_path: "/bin/sh" },
{ name: "bin", password: "x", id: 2, group_id: 2, info: "bin", home_path: "/bin", shell_path: "/bin/sh" },
{ name: "sys", password: "x", id: 3, group_id: 3, info: "sys", home_path: "/dev", shell_path: "/bin/sh" },
{ name: "sync", password: "x", id: 4, group_id: 65534, info: "sync", home_path: "/bin", shell_path: "/bin/sync" },
{ name: "games", password: "x", id: 5, group_id: 60, info: "games", home_path: "/usr/games", shell_path: "/bin/sh" },
{ name: "man", password: "x", id: 6, group_id: 12, info: "man", home_path: "/var/cache/man", shell_path: "/bin/sh" },
{ name: "lp", password: "x", id: 7, group_id: 7, info: "lp", home_path: "/var/spool/lpd", shell_path: "/bin/sh" },
{ name: "mail", password: "x", id: 8, group_id: 8, info: "mail", home_path: "/var/mail", shell_path: "/bin/sh" },
{ name: "news", password: "x", id: 9, group_id: 9, info: "news", home_path: "/var/spool/news", shell_path: "/bin/sh" },
{ name: "uucp", password: "x", id: 10, group_id: 10, info: "uucp", home_path: "/var/spool/uucp", shell_path: "/bin/sh" },
{ name: "proxy", password: "x", id: 13, group_id: 13, info: "proxy", home_path: "/bin", shell_path: "/bin/sh" },
{ name: "www-data", password: "x", id: 33, group_id: 33, info: "www-data", home_path: "/var/www", shell_path: "/bin/sh" },
{ name: "backup", password: "x", id: 34, group_id: 34, info: "backup", home_path: "/var/backups", shell_path: "/bin/sh" },
{ name: "list", password: "x", id: 38, group_id: 38, info: "Mailing List Manager", home_path: "/var/list", shell_path: "/bin/sh" },
{ name: "irc", password: "x", id: 39, group_id: 39, info: "ircd", home_path: "/var/run/ircd", shell_path: "/bin/sh" },
{ name: "gnats", password: "x", id: 41, group_id: 41, info: "Gnats Bug-Reporting System (admin)", home_path: "/var/lib/gnats", shell_path: "/bin/sh" },
{ name: "nobody", password: "x", id: 65534, group_id: 65534, info: "nobody", home_path: "/nonexistent", shell_path: "/bin/sh" },
{ name: "libuuid", password: "x", id: 100, group_id: 101, info: "", home_path: "/var/lib/libuuid", shell_path: "/bin/sh" },
{ name: "dhcp", password: "x", id: 101, group_id: 102, info: "", home_path: "/nonexistent", shell_path: "/bin/false" },
{ name: "syslog", password: "x", id: 102, group_id: 103, info: "", home_path: "/home/syslog", shell_path: "/bin/false" },
{ name: "klog", password: "x", id: 103, group_id: 104, info: "", home_path: "/home/klog", shell_path: "/bin/false" },
{ name: "sshd", password: "x", id: 104, group_id: 65534, info: "", home_path: "/var/run/sshd", shell_path: "/usr/sbin/nologin" },
{ name: "Debian-exim", password: "x", id: 105, group_id: 109, info: "", home_path: "/var/spool/exim4", shell_path: "/bin/false" },
{ name: "sadmin", password: "x", id: 1000, group_id: 1000, info: ",,,", home_path: "/home/sadmin", shell_path: "/bin/bash" },
{ name: "mysql", password: "x", id: 106, group_id: 111, info: "MySQL Server,,,", home_path: "/var/lib/mysql", shell_path: "/bin/false" },
{ name: "steve", password: "x", id: 1001, group_id: 1001, info: ",,,", home_path: "/home/steve", shell_path: "/bin/bash" }
]
end
##################################################################################################
describe ".new" do
it "should set context" do
@strategy.context.should == @context
end
it "should set users file path" do
@strategy.users_file_path.should == '/etc/passwd'
end
it "should set virtual host configuration file name" do
@strategy.vhost_file_name.should == "www.apple.com.conf"
end
it "should set virtual host configuration file path" do
@strategy.vhost_file_path.should == "/etc/apache2/sites-available/www.apple.com.conf"
end
it "should set virtual host configuration template file path" do
expected = File.expand_path(File.dirname(__FILE__) + '/../../../lib/plow/strategy/ubuntu_hardy/templates/apache2-vhost.conf')
@strategy.vhost_template_file_path.should == expected
end
end
##################################################################################################
describe '#say (private)' do
it 'should proxy to Plow::Generator#say' do
@context.should_receive(:say).with("something amazing happened!")
@strategy.send(:say, "something amazing happened!")
end
end
##################################################################################################
describe '#shell (private)' do
it 'should proxy to Plow::Generator#shell' do
@context.should_receive(:shell).with("echo *")
@strategy.send(:shell, "echo *")
end
end
##################################################################################################
describe '#users (private)' do
it "should read and parse a system accounts file (e.g. /etc/passwd)" do
@strategy.stub!(:users_file_path).and_return(FIXTURES_PATH + '/passwd.txt')
@strategy.send(:users) { |user| user.should == @parsed_users_fixture.shift }
end
end
##################################################################################################
describe '#user_exists? (private)' do
before(:each) do
@strategy.stub!(:users_file_path).and_return(FIXTURES_PATH + '/passwd.txt')
end
it "should raise Plow::ReservedSystemUserNameError for a system account where user id < 1000" do
@context.stub!(:user_name).and_return('sshd')
lambda { @strategy.send(:user_exists?) }.should raise_exception(Plow::ReservedSystemUserNameError, 'sshd')
end
it "should raise Plow::ReservedSystemUserNameError for a system account where user id == 65534" do
@context.stub!(:user_name).and_return('nobody')
lambda { @strategy.send(:user_exists?) }.should raise_exception(Plow::ReservedSystemUserNameError, 'nobody')
end
it "should return false when no matching non-system account is found" do
@context.stub!(:user_name).and_return('microsoft-steve')
@strategy.send(:user_exists?).should be_false
end
it "should return true when a matching non-system account is found" do
@context.stub!(:user_name).and_return('steve')
@strategy.send(:user_exists?).should be_true
end
end
##################################################################################################
describe '#create_user! (private)' do
it "should invoke a adduser as a system call" do
@strategy.should_receive(:shell).with("adduser steve")
@strategy.send(:create_user!)
end
end
##################################################################################################
describe '#user_home_exists? (private)' do
before(:each) do
@strategy.stub!(:users_file_path).and_return(FIXTURES_PATH + '/passwd.txt')
end
it "should raise Plow::SystemUserNameNotFoundError if no matching user name is found" do
@context.stub!(:user_name).and_return('microsoft-steve')
lambda { @strategy.send(:user_home_exists?) }.should raise_exception(Plow::SystemUserNameNotFoundError, 'microsoft-steve')
end
describe "when home directory exists for existing user" do
before(:each) do
@user = @parsed_users_fixture.last
@context.stub!(:user_name).and_return(@user[:name])
Dir.should_receive(:exists?).and_return(true)
end
it "should return true" do
@strategy.send(:user_home_exists?).should be_true
end
it "should set user home variable to correct home path" do
@strategy.send(:user_home_exists?)
@strategy.user_home_path.should == '/home/steve'
end
end
describe "when home directory does not exist for existing user" do
before(:each) do
@user = @parsed_users_fixture.last
@context.stub!(:user_name).and_return(@user[:name])
Dir.should_receive(:exists?).and_return(false)
end
it "should return false" do
@strategy.send(:user_home_exists?).should be_false
end
it "should set user home variable to correct home path" do
@strategy.send(:user_home_exists?)
@strategy.user_home_path.should == '/home/steve'
end
end
end
##################################################################################################
describe '#create_user_home! (private)' do
it "should create a user home with the correct ownership" do
@strategy.stub!(:user_home_path).and_return("/home/steve")
@strategy.should_receive(:shell).with(<<-COMMANDS)
mkdir /home/steve
chown steve:steve /home/steve
COMMANDS
@strategy.send(:create_user_home!)
end
end
##################################################################################################
describe '#sites_home_exists? (private)' do
before(:each) do
@user = @parsed_users_fixture.last
@strategy.stub!(:user_home_path).and_return(@user[:home_path])
end
it "should set sites home variable" do
@strategy.send(:sites_home_exists?)
@strategy.sites_home_path.should == "/home/steve/sites"
end
it "should return true if the directory exists" do
Dir.should_receive(:exists?).and_return(true)
@strategy.send(:sites_home_exists?).should be_true
end
it "should return false if the directory does not exist" do
Dir.should_receive(:exists?).and_return(false)
@strategy.send(:sites_home_exists?).should be_false
end
end
##################################################################################################
describe '#create_sites_home! (private)' do
it "should create a sites home with the correct ownership" do
@strategy.stub!(:sites_home_path).and_return("/home/steve/sites")
@strategy.should_receive(:shell).with(<<-COMMANDS)
mkdir /home/steve/sites
chown steve:steve /home/steve/sites
COMMANDS
@strategy.send(:create_sites_home!)
end
end
##################################################################################################
describe '#app_root_exists? (private)' do
before(:each) do
@user = @parsed_users_fixture.last
@strategy.stub!(:sites_home_path).and_return("#{@user[:home_path]}/sites")
end
it "should set sites home variable" do
@strategy.send(:app_root_exists?)
@strategy.app_root_path.should == "/home/steve/sites/www.apple.com"
end
it "should return true if the directory exists" do
Dir.should_receive(:exists?).and_return(true)
@strategy.send(:app_root_exists?).should be_true
end
it "should return false if the directory does not exist" do
Dir.should_receive(:exists?).and_return(false)
@strategy.send(:app_root_exists?).should be_false
end
end
##################################################################################################
describe '#create_app_root! (private)' do
it "should create an application home correctly" do
@strategy.stub!(:app_root_path).and_return('/home/steve/sites/www.apple.com')
@strategy.should_receive(:shell).with(<<-COMMANDS)
mkdir /home/steve/sites/www.apple.com
chown steve:steve /home/steve/sites/www.apple.com
COMMANDS
@strategy.send(:create_app_root!)
end
end
##################################################################################################
describe '#create_app_public! (private)' do
it "should build an application's public files correctly" do
@strategy.stub!(:app_public_path).and_return('/home/steve/sites/www.apple.com/public')
@strategy.should_receive(:shell).with(<<-COMMANDS)
mkdir /home/steve/sites/www.apple.com/public
touch /home/steve/sites/www.apple.com/public/index.html
chown -R steve:steve /home/steve/sites/www.apple.com/public
COMMANDS
@strategy.send(:create_app_public!)
end
end
##################################################################################################
describe '#create_app_logs! (private)' do
it "should build an application's log files correctly" do
@strategy.stub!(:app_log_path).and_return('/home/steve/sites/www.apple.com/log')
@strategy.should_receive(:shell).with(<<-COMMANDS)
mkdir /home/steve/sites/www.apple.com/log
mkdir /home/steve/sites/www.apple.com/log/apache2
chmod 750 /home/steve/sites/www.apple.com/log/apache2
touch /home/steve/sites/www.apple.com/log/apache2/access.log
touch /home/steve/sites/www.apple.com/log/apache2/error.log
chmod 640 /home/steve/sites/www.apple.com/log/apache2/*.log
chown -R steve:steve /home/steve/sites/www.apple.com/log
chown root -R /home/steve/sites/www.apple.com/log/apache2
COMMANDS
@strategy.send(:create_app_logs!)
end
end
##################################################################################################
describe '#vhost_config_exists? (private)' do
it "should return true if the directory exists" do
Dir.should_receive(:exists?).and_return(true)
@strategy.send(:vhost_config_exists?).should be_true
end
it "should return false if the directory does not exist" do
Dir.should_receive(:exists?).and_return(false)
@strategy.send(:vhost_config_exists?).should be_false
end
end
##################################################################################################
describe '#create_vhost_config! (private)' do
before(:each) do
@temp_file = Tempfile.new('generate_vhost_config')
@strategy.stub!(:vhost_file_path).and_return(@temp_file.path)
@strategy.stub!(:app_public_path).and_return('/home/steve/sites/www.apple.com/public')
@strategy.stub!(:app_log_path).and_return('/home/steve/sites/www.apple.com/log')
end
it "should create a vhost config file from template file without site aliases" do
@context.stub!(:site_aliases).and_return([])
@strategy.send(:create_vhost_config!)
File.read(@temp_file.path).should == <<-CONFIG
ServerAdmin webmaster
ServerName www.apple.com
DirectoryIndex index.html
DocumentRoot /home/steve/sites/www.apple.com/public
LogLevel warn
ErrorLog /home/steve/sites/www.apple.com/log/apache2/error.log
CustomLog /home/steve/sites/www.apple.com/log/apache2/access.log combined
CONFIG
end
it "should create a vhost config file from template file with site aliases" do
@strategy.send(:create_vhost_config!)
File.read(@temp_file.path).should == <<-CONFIG
ServerAdmin webmaster
ServerName www.apple.com
ServerAlias apple.com
DirectoryIndex index.html
DocumentRoot /home/steve/sites/www.apple.com/public
LogLevel warn
ErrorLog /home/steve/sites/www.apple.com/log/apache2/error.log
CustomLog /home/steve/sites/www.apple.com/log/apache2/access.log combined
CONFIG
end
end
##################################################################################################
describe '#install_vhost_config! (private)' do
it "should enable vhost and restart apache2" do
@strategy.should_receive(:shell).with(<<-COMMANDS)
a2ensite www.apple.com.conf > /dev/null
apache2ctl graceful
COMMANDS
@strategy.send(:install_vhost_config!)
end
end
##################################################################################################
describe '#execute!' do
before(:each) do
@strategy.stub!(:user_exists?).and_return(false)
@strategy.stub!(:user_home_exists?).and_return(true)
@strategy.stub!(:sites_home_exists?).and_return(false)
@strategy.stub!(:app_root_exists?).and_return(false)
@strategy.stub!(:vhost_config_exists?).and_return(false)
@strategy.stub!(:user_home_path).and_return('/home/steve')
@strategy.stub!(:sites_home_path).and_return('/home/steve/sites')
@strategy.stub!(:app_root_path).and_return('/home/steve/sites/www.apple.com')
$stdout = StringIO.new
end
after(:each) do
$stdout = STDOUT
end
it "should run the default process" do
@strategy.should_receive(:create_user!)
@strategy.should_not_receive(:create_user_home!)
@strategy.should_receive(:create_sites_home!)
@strategy.should_receive(:create_app_root!)
@strategy.should_receive(:create_app_public!)
@strategy.should_receive(:create_app_logs!)
@strategy.should_receive(:create_vhost_config!)
@strategy.should_receive(:install_vhost_config!)
@strategy.execute!
@strategy.app_public_path.should == '/home/steve/sites/www.apple.com/public'
@strategy.app_log_path.should == '/home/steve/sites/www.apple.com/log'
$stdout.string.should == <<-OUTPUT
==> creating steve user
==> existing /home/steve
==> creating /home/steve/sites
==> creating /home/steve/sites/www.apple.com
==> creating /home/steve/sites/www.apple.com/public
==> creating /home/steve/sites/www.apple.com/log
==> creating /etc/apache2/sites-available/www.apple.com.conf
==> installing /etc/apache2/sites-available/www.apple.com.conf
OUTPUT
end
it "should run the existing user process" do
@strategy.stub!(:user_exists?).and_return(true)
@strategy.should_not_receive(:create_user)
@strategy.should_not_receive(:create_user_home!)
@strategy.should_receive(:create_sites_home!)
@strategy.should_receive(:create_app_root!)
@strategy.should_receive(:create_app_public!)
@strategy.should_receive(:create_app_logs!)
@strategy.should_receive(:create_vhost_config!)
@strategy.should_receive(:install_vhost_config!)
@strategy.execute!
@strategy.app_public_path.should == '/home/steve/sites/www.apple.com/public'
@strategy.app_log_path.should == '/home/steve/sites/www.apple.com/log'
$stdout.string.should == <<-OUTPUT
==> existing steve user
==> existing /home/steve
==> creating /home/steve/sites
==> creating /home/steve/sites/www.apple.com
==> creating /home/steve/sites/www.apple.com/public
==> creating /home/steve/sites/www.apple.com/log
==> creating /etc/apache2/sites-available/www.apple.com.conf
==> installing /etc/apache2/sites-available/www.apple.com.conf
OUTPUT
end
it "should run the missing user home process" do
@strategy.stub!(:user_home_exists?).and_return(false)
@strategy.should_receive(:create_user!)
@strategy.should_receive(:create_user_home!)
@strategy.should_receive(:create_sites_home!)
@strategy.should_receive(:create_app_root!)
@strategy.should_receive(:create_app_public!)
@strategy.should_receive(:create_app_logs!)
@strategy.should_receive(:create_vhost_config!)
@strategy.should_receive(:install_vhost_config!)
@strategy.execute!
@strategy.app_public_path.should == '/home/steve/sites/www.apple.com/public'
@strategy.app_log_path.should == '/home/steve/sites/www.apple.com/log'
$stdout.string.should == <<-OUTPUT
==> creating steve user
==> creating /home/steve
==> creating /home/steve/sites
==> creating /home/steve/sites/www.apple.com
==> creating /home/steve/sites/www.apple.com/public
==> creating /home/steve/sites/www.apple.com/log
==> creating /etc/apache2/sites-available/www.apple.com.conf
==> installing /etc/apache2/sites-available/www.apple.com.conf
OUTPUT
end
it "should run the existing sites home process" do
@strategy.stub!(:sites_home_exists?).and_return(true)
@strategy.should_receive(:create_user!)
@strategy.should_not_receive(:create_user_home!)
@strategy.should_not_receive(:create_sites_home!)
@strategy.should_receive(:create_app_root!)
@strategy.should_receive(:create_app_public!)
@strategy.should_receive(:create_app_logs!)
@strategy.should_receive(:create_vhost_config!)
@strategy.should_receive(:install_vhost_config!)
@strategy.execute!
@strategy.app_public_path.should == '/home/steve/sites/www.apple.com/public'
@strategy.app_log_path.should == '/home/steve/sites/www.apple.com/log'
$stdout.string.should == <<-OUTPUT
==> creating steve user
==> existing /home/steve
==> existing /home/steve/sites
==> creating /home/steve/sites/www.apple.com
==> creating /home/steve/sites/www.apple.com/public
==> creating /home/steve/sites/www.apple.com/log
==> creating /etc/apache2/sites-available/www.apple.com.conf
==> installing /etc/apache2/sites-available/www.apple.com.conf
OUTPUT
end
it "should run the existing app root process" do
@strategy.stub!(:app_root_exists?).and_return(true)
@strategy.should_receive(:create_user!)
@strategy.should_not_receive(:create_user_home!)
@strategy.should_receive(:create_sites_home!)
@strategy.should_not_receive(:create_app_root!)
@strategy.should_not_receive(:create_app_public!)
@strategy.should_not_receive(:create_app_logs!)
@strategy.should_not_receive(:create_vhost_config!)
@strategy.should_not_receive(:install_vhost_config!)
lambda { @strategy.execute! }.should raise_exception(Plow::AppRootAlreadyExistsError, '/home/steve/sites/www.apple.com')
$stdout.string.should == <<-OUTPUT
==> creating steve user
==> existing /home/steve
==> creating /home/steve/sites
OUTPUT
end
it "should run the existing vhost config process" do
@strategy.stub!(:vhost_config_exists?).and_return(true)
@strategy.should_receive(:create_user!)
@strategy.should_not_receive(:create_user_home!)
@strategy.should_receive(:create_sites_home!)
@strategy.should_receive(:create_app_root!)
@strategy.should_receive(:create_app_public!)
@strategy.should_receive(:create_app_logs!)
@strategy.should_not_receive(:create_vhost_config!)
@strategy.should_not_receive(:install_vhost_config!)
lambda { @strategy.execute! }.should raise_exception(Plow::ConfigFileAlreadyExistsError, '/etc/apache2/sites-available/www.apple.com.conf')
@strategy.app_public_path.should == '/home/steve/sites/www.apple.com/public'
@strategy.app_log_path.should == '/home/steve/sites/www.apple.com/log'
$stdout.string.should == <<-OUTPUT
==> creating steve user
==> existing /home/steve
==> creating /home/steve/sites
==> creating /home/steve/sites/www.apple.com
==> creating /home/steve/sites/www.apple.com/public
==> creating /home/steve/sites/www.apple.com/log
OUTPUT
end
end
end