Refactor tests and add CentOS6 image

This commit does a fairly major refactor of how the spec tests
are laid out.  The main goal was to make it easier to run
a subset of the tests--e.g., the ability to only run tests
on a single OS via a simple rspec command.

The test logic is now defined in some shared examples in the
`support` directory.  There are now spec folders for each
distro, which contain some stubs to include the shared examples
as well as a Vagrantfile for the particular distro.

Also, the system-default postgres package tests now run
successfully against the CentOS6 VM that is defined by the
Vagrantfile.
This commit is contained in:
Chris Price 2012-12-02 15:28:25 -08:00
parent bdecbe6503
commit df92c96791
15 changed files with 305 additions and 290 deletions

View file

@ -25,10 +25,16 @@ class postgresql::initdb(
$user = 'postgres'
) inherits postgresql::params {
exec { "${initdb_path} --encoding '${encoding}' --pgdata '${datadir}'":
$initdb_command = "${initdb_path} --encoding '${encoding}' --pgdata '${datadir}'"
exec { $initdb_command:
creates => "${datadir}/PG_VERSION",
user => $user,
group => $group,
require => Package["$postgresql::params::server_package_name"],
group => $group
}
if defined(Package["$postgresql::params::server_package_name"]) {
Package["$postgresql::params::server_package_name"] ->
Exec[$initdb_command]
}
}

25
spec/README.md Normal file
View file

@ -0,0 +1,25 @@
Warning: these spec tests are pretty resource intensive!
You will need the following in order to run them:
* Virtualbox
* vagrant
* 'sahara' gem
* A decent chunk of free disk space (~300MB per distro tested)
* Patience :)
If you just run:
rspec ./spec
then, for each distro that has a Vagrantfile in the spec/distros directory,
vagrant will download a base image from the web, fire up a VM, and run
the suite of tests against the VM.
If you only want to run the tests against an individual distro, you can
instead do something like:
rspec ./spec/distros/ubuntu_lucid_64
For some options that might speed up the testing process a bit during development,
please see `spec/support/test_config.rb`.

53
spec/Vagrantfile vendored
View file

@ -1,53 +0,0 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
# puppet-postgresql
# For all details and documentation:
# http://github.com/inkling/puppet-postgresql
#
# Copyright 2012- Inkling Systems, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
Vagrant::Config.run do |config|
config.vm.define :lucid do |lucid_config|
# Test on 64 bit lucid
lucid_config.vm.box = "lucid64"
lucid_config.vm.box_url = "http://files.vagrantup.com/lucid64.box"
end
config.vm.define :cent6 do |cent_config|
cent_config.vm.box = "cent63_64"
cent_config.vm.box_url = "https://dl.dropbox.com/u/7225008/Vagrant/CentOS-6.3-x86_64-minimal.box"
end
# Resolve DNS via NAT
config.vm.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
# Share the stdlib module
# TODO: it would be better to install this via the puppet module tool
config.vm.share_folder "puppetlabs-stdlib-module", "/usr/share/puppet/modules/stdlib", "../../puppetlabs-stdlib"
# Share the postgressql module
config.vm.share_folder "puppet-postgresql-module", "/usr/share/puppet/modules/postgresql", ".."
# Share the module of test classes
config.vm.share_folder "puppet-postgresql-tests", "/usr/share/puppet/modules/postgresql_tests", "."
# Provision with a base puppet config just so we don't have to repeat the puppet user/group
config.vm.provision :puppet do |puppet|
puppet.manifests_path = "."
puppet.manifest_file = "base.pp"
end
end

12
spec/distros/centos6_64/Vagrantfile vendored Normal file
View file

@ -0,0 +1,12 @@
require File.expand_path(File.join(__FILE__, '../../../support/vagrant_common'))
Vagrant::Config.run do |config|
config.vm.define :centos6 do |vm_config|
vm_config.vm.box = "cent63_64"
vm_config.vm.box_url = "https://dl.dropbox.com/u/7225008/Vagrant/CentOS-6.3-x86_64-minimal.box"
end
apply_common_vagrant_config(config)
end

View file

@ -0,0 +1,7 @@
require 'support/shared_examples/non_default_postgres'
describe "CentOS6, 64-bit: non-default postgres" do
let(:vagrant_dir) { File.dirname(__FILE__) }
let(:vm) { :centos6 }
it_behaves_like :non_default_postgres
end

View file

@ -0,0 +1,8 @@
require 'support/shared_examples/system_default_postgres'
describe "CentOS6, 64-bit: default system postgres" do
let(:vagrant_dir) { File.dirname(__FILE__) }
let(:vm) { :centos6 }
let(:service_name) { 'postgresql' }
it_behaves_like :system_default_postgres
end

View file

@ -0,0 +1,13 @@
require File.expand_path(File.join(__FILE__, '../../../support/vagrant_common'))
Vagrant::Config.run do |config|
config.vm.define :lucid do |vm_config|
# Test on 64 bit lucid
vm_config.vm.box = "lucid64"
vm_config.vm.box_url = "http://files.vagrantup.com/lucid64.box"
end
apply_common_vagrant_config(config)
end

View file

@ -0,0 +1,7 @@
require 'support/shared_examples/non_default_postgres'
describe "Ubuntu Lucid, 64-bit: non-default postgres" do
let(:vagrant_dir) { File.dirname(__FILE__) }
let(:vm) { :lucid }
it_behaves_like :non_default_postgres
end

View file

@ -0,0 +1,8 @@
require 'support/shared_examples/system_default_postgres'
describe "Ubuntu Lucid, 64-bit: default system postgres" do
let(:vagrant_dir) { File.dirname(__FILE__) }
let(:vm) { :lucid }
let(:service_name) { 'postgresql-8.4' }
it_behaves_like :system_default_postgres
end

View file

@ -18,9 +18,6 @@
class postgresql_tests::test_initdb {
include postgresql::server
include postgresql::initdb
class { "postgresql::initdb":
require => Class['postgresql::server']
}
}

View file

@ -1,230 +0,0 @@
# puppet-postgresql
# For all details and documentation:
# http://github.com/inkling/puppet-postgresql
#
# Copyright 2012- Inkling Systems, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
require 'logger'
require 'vagrant'
# VM-based tests for postgresql::* defined resource types.
#
# The general structure is:
#
# - Roll back the VM
# - Apply a minimal puppet config for the type and fail only on crashes
# - Apply it again and fail if there were any new changes reported
# - Check the state of the system
describe "postgresql" do
# Tests are pretty slow w/sahara, and when we destroy the VMs at the beginning
# of the test run. This can be a hindrance for development but is very
# valuable for final testing. This constant allows you to toggle between
# strict testing and less strict testing--the latter being useful for
# development purposes.
HardCoreTesting = false
if HardCoreTesting
# this will just make sure that we throw an error if the user tries to
# run w/o having Sahara installed
require 'sahara'
end
def sudo_and_log(vm, cmd)
@logger.debug("Running command: '#{cmd}'")
result = ""
@env.vms[vm].channel.sudo(cmd) do |ch, data|
result << data
@logger.debug(data)
end
result
end
before(:all) do
@logger = Logger.new(STDOUT)
@logger.level = Logger::DEBUG # TODO: get from environment or rspec?
vagrant_dir = File.dirname(__FILE__)
@env = Vagrant::Environment::new(:cwd => vagrant_dir)
# Sahara ignores :cwd so we have to chdir for now, see https://github.com/jedi4ever/sahara/issues/9
Dir.chdir(vagrant_dir)
end
basic_testing_vms = [:lucid]
basic_testing_vms.each do |vm|
describe "basic (system default postgres) tests (vm: #{vm})" do
before (:all) do
if HardCoreTesting
@env.cli("destroy", vm.to_s, "--force") # Takes too long
end
@env.cli("up", vm.to_s)
# We are not testing the "package" resource type, so pull stuff in in advance
sudo_and_log(vm, 'apt-get update')
sudo_and_log(vm, 'apt-get install --yes --download-only postgresql-8.4')
if HardCoreTesting
@env.cli("sandbox", "on", vm.to_s)
end
end
after(:each) do
if HardCoreTesting
@env.cli("sandbox", "rollback", vm.to_s)
end
end
describe 'postgresql::initdb' do
it "should idempotently create a working --pgdata directory so postgres can run" do
@logger.info("starting")
# A bare-minimum class to initdb the specified dir
test_class = 'class {"postgresql_tests::test_initdb": }'
# Run once to check for crashes
sudo_and_log(vm, "puppet apply -e '#{test_class}'")
# Run again to check for idempotence via --detailed-exitcodes
sudo_and_log(vm, "puppet apply --detailed-exitcodes -e '#{test_class}'")
sudo_and_log(vm, "service postgresql-8.4 restart")
# Connect to it and list the databases
sudo_and_log(vm, 'sudo -n -u postgres /usr/lib/postgresql/8.4/bin/psql --list --tuples-only')
end
end
describe 'postgresql::db' do
it 'should idempotently create a db that we can connect to' do
# A bare-minimum class to add a DB to postgres, which will be running due to ubuntu
test_class = 'class {"postgresql_tests::test_db": db => "postgresql_test_db" }'
begin
# Run once to check for crashes
sudo_and_log(vm, "puppet apply --detailed-exitcodes -e '#{test_class}'; [ $? == 2 ]")
# Run again to check for idempotence
sudo_and_log(vm, "puppet apply --detailed-exitcodes -e '#{test_class}'")
# Check that the database name is present
sudo_and_log(vm, 'sudo -u postgres psql postgresql_test_db --command="select datname from pg_database limit 1"')
ensure
sudo_and_log(vm, 'sudo -u postgres psql --command="drop database postgresql_test_db" postgres')
end
end
end
describe 'postgresql::psql' do
it 'should emit a deprecation warning' do
test_class = 'class {"postgresql_tests::test_psql": command => "SELECT * FROM pg_datbase limit 1", unless => "SELECT 1 WHERE 1=1" }'
data = sudo_and_log(vm, "puppet apply --detailed-exitcodes -e '#{test_class}'; [ $? == 2 ]")
data.should match /postgresql::psql is deprecated/
end
end
describe 'postgresql_psql' do
it 'should run some SQL when the unless query returns no rows' do
test_class = 'class {"postgresql_tests::test_ruby_psql": command => "SELECT 1", unless => "SELECT 1 WHERE 1=2" }'
# Run once to get all packages set up
sudo_and_log(vm, "puppet apply -e '#{test_class}'")
# Check for exit code 2
sudo_and_log(vm, "puppet apply --detailed-exitcodes -e '#{test_class}' ; [ $? == 2 ]")
end
it 'should not run SQL when the unless query returns rows' do
test_class = 'class {"postgresql_tests::test_ruby_psql": command => "SELECT * FROM pg_datbase limit 1", unless => "SELECT 1 WHERE 1=1" }'
# Run once to get all packages set up
sudo_and_log(vm, "puppet apply -e '#{test_class}'")
# Check for exit code 0
sudo_and_log(vm, "puppet apply --detailed-exitcodes -e '#{test_class}'")
end
end
describe 'postgresql::user' do
it 'should idempotently create a user who can log in' do
test_class = 'class {"postgresql_tests::test_user": user => "postgresql_test_user", password => "postgresql_test_password" }'
# Run once to check for crashes
sudo_and_log(vm, "puppet apply -e '#{test_class}'")
# Run again to check for idempotence
sudo_and_log(vm, "puppet apply --detailed-exitcodes -e '#{test_class}'")
# Check that the user can log in
sudo_and_log(vm, 'sudo -u postgresql_test_user psql --command="select datname from pg_database limit 1" postgres')
end
end
describe 'postgresql::grant' do
it 'should grant access so a user can create in a database' do
test_class = 'class {"postgresql_tests::test_grant_create": db => "postgres", user => "psql_grant_tester", password => "psql_grant_pw" }'
# Run once to check for crashes
sudo_and_log(vm, "puppet apply -e '#{test_class}'")
# Run again to check for idempotence
sudo_and_log(vm, "puppet apply --detailed-exitcodes -e '#{test_class}'")
# Check that the user can create a table in the database
sudo_and_log(vm, 'sudo -u psql_grant_tester psql --command="create table foo (foo int)" postgres')
sudo_and_log(vm, 'sudo -u psql_grant_tester psql --command="drop table foo" postgres')
end
end
end
end
non_default_testing_vms = [:cent6]
non_default_testing_vms.each do |vm|
describe "non-system-default postgres version tests (vm: #{vm})" do
before (:all) do
if HardCoreTesting
@env.cli("destroy", vm.to_s, "--force") # Takes too long
end
@env.cli("up", vm.to_s)
if HardCoreTesting
@env.cli("sandbox", "on", vm.to_s)
end
end
after(:each) do
if HardCoreTesting
@env.cli("sandbox", "rollback", vm.to_s)
end
end
it "should have the echo command" do
sudo_and_log(vm, 'echo "hi"')
end
end
end
end

View file

@ -0,0 +1,4 @@
shared_examples :non_default_postgres do
it "doesn't have any tests yet'" do
end
end

View file

@ -0,0 +1,176 @@
require 'logger'
require 'vagrant'
require 'support/test_config'
shared_examples :system_default_postgres do
if TestConfig::HardCoreTesting
# this will just make sure that we throw an error if the user tries to
# run w/o having Sahara installed
require 'sahara'
end
def sudo_and_log(vm, cmd)
@logger.debug("Running command: '#{cmd}'")
result = ""
@env.vms[vm].channel.sudo("cd /tmp && #{cmd}") do |ch, data|
result << data
@logger.debug(data)
end
result
end
def sudo_psql_and_log(vm, psql_cmd, user = 'postgres')
sudo_and_log(vm, "su #{user} -c 'psql #{psql_cmd}'")
end
before(:all) do
@logger = Logger.new(STDOUT)
@logger.level = Logger::DEBUG # TODO: get from environment or rspec?
@env = Vagrant::Environment::new(:cwd => vagrant_dir)
end
after(:all) do
if TestConfig::SuspendVMsAfterSuite
@logger.debug("Suspending VM")
@env.cli("suspend", vm.to_s)
end
end
describe "basic (system default postgres) tests" do
before (:all) do
if TestConfig::HardCoreTesting
@env.cli("destroy", vm.to_s, "--force") # Takes too long
end
@env.cli("up", vm.to_s)
if TestConfig::HardCoreTesting
sudo_and_log(vm, '[ "$(facter osfamily)" == "Debian" ] && apt-get update')
end
sudo_and_log(vm, 'puppet apply -e "include postgresql::server"')
if TestConfig::HardCoreTesting
# Sahara ignores :cwd so we have to chdir for now, see https://github.com/jedi4ever/sahara/issues/9
Dir.chdir(vagrant_dir)
@env.cli("sandbox", "on", vm.to_s)
end
end
after(:each) do
if TestConfig::HardCoreTesting
@env.cli("sandbox", "rollback", vm.to_s)
end
end
describe 'postgresql::initdb' do
it "should idempotently create a working --pgdata directory so postgres can run" do
@logger.info("starting")
# A bare-minimum class to initdb the specified dir
test_class = 'class {"postgresql_tests::test_initdb": }'
# Run once to check for crashes
sudo_and_log(vm, "puppet apply -e '#{test_class}'")
# Run again to check for idempotence via --detailed-exitcodes
sudo_and_log(vm, "puppet apply --detailed-exitcodes -e '#{test_class}'")
sudo_and_log(vm, "service #{service_name} restart")
# Connect to it and list the databases
sudo_psql_and_log(vm, '--list --tuples-only')
end
end
describe 'postgresql::db' do
it 'should idempotently create a db that we can connect to' do
# A bare-minimum class to add a DB to postgres, which will be running due to ubuntu
test_class = 'class {"postgresql_tests::test_db": db => "postgresql_test_db" }'
begin
# Run once to check for crashes
sudo_and_log(vm, "puppet apply --detailed-exitcodes -e '#{test_class}'; [ $? == 2 ]")
# Run again to check for idempotence
sudo_and_log(vm, "puppet apply --detailed-exitcodes -e '#{test_class}'")
# Check that the database name is present
sudo_psql_and_log(vm, 'postgresql_test_db --command="select datname from pg_database limit 1"')
ensure
sudo_psql_and_log(vm, '--command="drop database postgresql_test_db" postgres')
end
end
end
describe 'postgresql::psql' do
it 'should emit a deprecation warning' do
test_class = 'class {"postgresql_tests::test_psql": command => "SELECT * FROM pg_datbase limit 1", unless => "SELECT 1 WHERE 1=1" }'
data = sudo_and_log(vm, "puppet apply --detailed-exitcodes -e '#{test_class}'; [ $? == 2 ]")
data.should match /postgresql::psql is deprecated/
end
end
describe 'postgresql_psql' do
it 'should run some SQL when the unless query returns no rows' do
test_class = 'class {"postgresql_tests::test_ruby_psql": command => "SELECT 1", unless => "SELECT 1 WHERE 1=2" }'
# Run once to get all packages set up
sudo_and_log(vm, "puppet apply -e '#{test_class}'")
# Check for exit code 2
sudo_and_log(vm, "puppet apply --detailed-exitcodes -e '#{test_class}' ; [ $? == 2 ]")
end
it 'should not run SQL when the unless query returns rows' do
test_class = 'class {"postgresql_tests::test_ruby_psql": command => "SELECT * FROM pg_datbase limit 1", unless => "SELECT 1 WHERE 1=1" }'
# Run once to get all packages set up
sudo_and_log(vm, "puppet apply -e '#{test_class}'")
# Check for exit code 0
sudo_and_log(vm, "puppet apply --detailed-exitcodes -e '#{test_class}'")
end
end
describe 'postgresql::user' do
it 'should idempotently create a user who can log in' do
test_class = 'class {"postgresql_tests::test_user": user => "postgresql_test_user", password => "postgresql_test_password" }'
# Run once to check for crashes
sudo_and_log(vm, "puppet apply -e '#{test_class}'")
# Run again to check for idempotence
sudo_and_log(vm, "puppet apply --detailed-exitcodes -e '#{test_class}'")
# Check that the user can log in
sudo_psql_and_log(vm, '--command="select datname from pg_database limit 1" postgres', 'postgresql_test_user')
end
end
describe 'postgresql::grant' do
it 'should grant access so a user can create in a database' do
test_class = 'class {"postgresql_tests::test_grant_create": db => "postgres", user => "psql_grant_tester", password => "psql_grant_pw" }'
# Run once to check for crashes
sudo_and_log(vm, "puppet apply -e '#{test_class}'")
# Run again to check for idempotence
sudo_and_log(vm, "puppet apply --detailed-exitcodes -e '#{test_class}'")
# Check that the user can create a table in the database
sudo_psql_and_log(vm, '--command="create table foo (foo int)" postgres', 'psql_grant_tester')
sudo_psql_and_log(vm, '--command="drop table foo" postgres', 'psql_grant_tester')
end
end
end
end

View file

@ -0,0 +1,14 @@
module TestConfig
# Tests are pretty slow w/sahara, and when we destroy the VMs at the beginning
# of the test run. This can be a hindrance for development but is very
# valuable for final testing. This constant allows you to toggle between
# strict testing and less strict testing--the latter being useful for
# development purposes.
HardCoreTesting = true
# If this value is set to true, then each VM will be suspended after the tests
# against it are completed. This will slow things down a ton during
# iterative development, but will save a lot of system resources by not
# keeping all of the VMs running at the same time.
SuspendVMsAfterSuite = true
end

View file

@ -0,0 +1,21 @@
def apply_common_vagrant_config(config)
# Resolve DNS via NAT
config.vm.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
# Share the stdlib module
# TODO: it would be better to install this via the puppet module tool
config.vm.share_folder "puppetlabs-stdlib-module", "/usr/share/puppet/modules/stdlib", "../../../../puppetlabs-stdlib"
# Share the postgressql module
config.vm.share_folder "puppet-postgresql-module", "/usr/share/puppet/modules/postgresql", "../../.."
# Share the module of test classes
config.vm.share_folder "puppet-postgresql-tests", "/usr/share/puppet/modules/postgresql_tests", "../.."
# Provision with a base puppet config just so we don't have to repeat the puppet user/group
config.vm.provision :puppet do |puppet|
puppet.manifests_path = "../../"
puppet.manifest_file = "base.pp"
end
end