diff options
author | Hakim Cassimally <hakim@mysociety.org> | 2014-05-21 11:42:23 +0000 |
---|---|---|
committer | Matthew Somerville <matthew@mysociety.org> | 2014-12-12 12:41:32 +0000 |
commit | 244b2876c837f65ed9477a57c3ed297f493b44a5 (patch) | |
tree | 0f8c3eb297e59fe98ffc79b74137c5fd5e8f4784 | |
parent | 43c98742ee85c73c4783451ceeea28108bb793c6 (diff) |
Add a script to always test on a clean db/config.
Fixes #786.
-rw-r--r-- | .gitignore | 1 | ||||
-rwxr-xr-x | bin/test-wrapper | 35 | ||||
-rw-r--r-- | conf/.gitignore | 1 | ||||
-rw-r--r-- | cpanfile | 4 | ||||
-rw-r--r-- | cpanfile.snapshot | 18 | ||||
-rw-r--r-- | perllib/FixMyStreet/TestAppProve.pm | 94 | ||||
-rw-r--r-- | t/00-check-config.t | 3 | ||||
-rw-r--r-- | t/00-check-we-are-staging.t | 3 |
8 files changed, 157 insertions, 2 deletions
diff --git a/.gitignore b/.gitignore index 72bc29420..777f3bafd 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.swp *~ ._* +.prove .vagrant .bundle diff --git a/bin/test-wrapper b/bin/test-wrapper new file mode 100755 index 000000000..9cb1791a1 --- /dev/null +++ b/bin/test-wrapper @@ -0,0 +1,35 @@ +#!/usr/bin/env perl +use strict; use warnings; + +BEGIN { + use FindBin; + require "$FindBin::Bin/../setenv.pl"; +} + +use FixMyStreet::TestAppProve; + +=head1 NAME + +bin/test-wrapper - spin up a clean database and configuration for tests + +=head1 USAGE + + bin/test-wrapper t/ # runs prove -r t/ (recursively, saving state) + bin/test-wrapper --state=failed # runs just failing tests + # delete .prove to reset + + bin/test-wrapper t/foo.t # runs with prove -v (single test) + +By default we use conf/general.yml-example as the template, and spin up a fresh +Postgres cluster and database. We can override this by doing: + + bin/test-wrapper --config=general.mycobrand.yml + bin/test-wrapper --db-config=general.yml # e.g. use your current DB settings + bin/test-wrapper --all-config=general.yml # e.g. use your current DB settings + +(NB: passing --state=save automagically is experimental, and will be removed if +it turns out to be annoying.) + +=cut + +FixMyStreet::TestAppProve->run(@ARGV); diff --git a/conf/.gitignore b/conf/.gitignore index 8fa665744..6e77101a1 100644 --- a/conf/.gitignore +++ b/conf/.gitignore @@ -1,5 +1,6 @@ /general.yml /general.yml.deployed +/general.test-autogenerated.yml /httpd.conf /httpd.conf.deployed /crontab @@ -110,6 +110,10 @@ requires 'File::ChangeNotify'; requires 'Path::Tiny'; requires 'File::Find::Rule'; +feature 'test-wrapper', 'Spin up a test database and config to run tests' => sub { + requires 'Test::PostgreSQL'; +}; + # Modules used by the test suite requires 'CGI::Simple'; requires 'HTTP::Headers'; diff --git a/cpanfile.snapshot b/cpanfile.snapshot index c4362b4d1..e5d8b9afc 100644 --- a/cpanfile.snapshot +++ b/cpanfile.snapshot @@ -620,6 +620,12 @@ DISTRIBUTIONS Test::Exception 0.31 Test::More 0.94 perl 5.006 + Class-Accessor-Lite-0.06 + pathname: K/KA/KAZUHO/Class-Accessor-Lite-0.06.tar.gz + provides: + Class::Accessor::Lite 0.06 + requirements: + ExtUtils::MakeMaker 6.42 Class-C3-0.24 pathname: F/FL/FLORA/Class-C3-0.24.tar.gz provides: @@ -5798,6 +5804,18 @@ DISTRIBUTIONS Test::More 0 Test::Tester 0.107 perl 5.006 + Test-PostgreSQL-1.05 + pathname: T/TJ/TJC/Test-PostgreSQL-1.05.tar.gz + provides: + Test::PostgreSQL 1.05 + requirements: + Class::Accessor::Lite 0 + DBD::Pg 0 + DBI 0 + ExtUtils::MakeMaker 6.59 + Test::SharedFork 0.06 + Time::HiRes 0 + perl 5.008 Test-Requires-0.06 pathname: T/TO/TOKUHIROM/Test-Requires-0.06.tar.gz provides: diff --git a/perllib/FixMyStreet/TestAppProve.pm b/perllib/FixMyStreet/TestAppProve.pm new file mode 100644 index 000000000..4d8cdaccb --- /dev/null +++ b/perllib/FixMyStreet/TestAppProve.pm @@ -0,0 +1,94 @@ +use strict; use warnings; +package FixMyStreet::TestAppProve; +use App::Prove; + +use YAML (); +use Path::Tiny 'path'; +use Test::PostgreSQL; +use Data::Dumper; +use Getopt::Long ':config' => qw(bundling pass_through no_ignore_case); + +=head1 NAME + +FixMyStreet::TestAppProve - spin up a clean database and configuration for tests + +=head1 USAGE + +see bin/test-wrapper for usage + +=cut + +sub run { + my ($class, @args) = @_; + local @ARGV = @args; + + my $config_file = 'conf/general.yml-example'; + my $db_config_file; + + my $recurse; + my @state; + + GetOptions ( + # our own config variables + 'config=s' => \$config_file, + 'db-config=s' => \$db_config_file, + + # App::Prove variables we want to munge + 'r|recurse' => \$recurse, + 'state=s@' => \@state, + ); + + my $config = YAML::Load( path($config_file)->slurp ); + my $pg; + if ($db_config_file) { + my $db_config = YAML::Load( path($db_config_file)->slurp ); + $config->{FMS_DB_PORT} = $db_config->{FMS_DB_PORT}; + $config->{FMS_DB_NAME} = $db_config->{FMS_DB_NAME}; + $config->{FMS_DB_USER} = $db_config->{FMS_DB_USER}; + $config->{FMS_DB_HOST} = $db_config->{FMS_DB_HOST}; + $config->{FMS_DB_PASS} = $db_config->{FMS_DB_PASS}; + } + else { + warn "Spinning up a Pg cluster/database...\n"; + $pg = Test::PostgreSQL->new(); + + warn sprintf "# Connected to %s\n", $pg->dsn; + + my $dbh = DBI->connect($pg->dsn); + + my $tmpwarn = $SIG{__WARN__}; + $SIG{__WARN__} = + sub { print STDERR @_ if $_[0] !~ m/NOTICE: CREATE TABLE/; }; + $dbh->do( path('db/schema.sql')->slurp ) or die $!; + $dbh->do( path('db/alert_types.sql')->slurp ) or die $!; + $dbh->do( path('db/generate_secret.sql')->slurp ) or die $!; + $SIG{__WARN__} = $tmpwarn; + + $config->{FMS_DB_PORT} = $pg->port; + $config->{FMS_DB_NAME} = 'test'; + $config->{FMS_DB_USER} = 'postgres'; + $config->{FMS_DB_HOST} = 'localhost'; + $config->{FMS_DB_PASS} = ''; + } + + my $config_out = 'general.test-autogenerated'; + path("conf/$config_out.yml")->spew( YAML::Dump($config) ); + + local $ENV{FMS_OVERRIDE_CONFIG} = $config_out; + + if (@ARGV and -e $ARGV[-1]) { + unshift @ARGV, '--verbose' + if -f $ARGV[-1]; + # verbose if we have a single file + } + + unshift @ARGV, + '--recurse', # we always want to recurse + '--state', (join ',' => @state, 'save'); # we always want to save state + + my $prove = App::Prove->new; + $prove->process_args(@ARGV); + $prove->run; +} + +1; diff --git a/t/00-check-config.t b/t/00-check-config.t index 20f0fe8cf..00e782e74 100644 --- a/t/00-check-config.t +++ b/t/00-check-config.t @@ -16,7 +16,8 @@ use FixMyStreet; # load the config file and store the contents in a readonly hash my $example_config = YAML::LoadFile( FixMyStreet->path_to("conf/general.yml-example") ); -my $local_config = YAML::LoadFile( FixMyStreet->path_to("conf/general.yml") ); +my $CONF_FILE = $ENV{FMS_OVERRIDE_CONFIG} || 'general'; +my $local_config = YAML::LoadFile( FixMyStreet->path_to("conf/${CONF_FILE}.yml") ); # find all keys missing from each config my @missing_from_example = find_missing( $example_config, $local_config ); diff --git a/t/00-check-we-are-staging.t b/t/00-check-we-are-staging.t index a1da68798..4c9a255fe 100644 --- a/t/00-check-we-are-staging.t +++ b/t/00-check-we-are-staging.t @@ -14,7 +14,8 @@ use FixMyStreet; # load the config file and store the contents in a readonly hash -mySociety::Config::set_file( FixMyStreet->path_to("conf/general") ); +my $CONF_FILE = $ENV{FMS_OVERRIDE_CONFIG} || 'general'; +mySociety::Config::set_file( FixMyStreet->path_to("conf/${CONF_FILE}") ); BAIL_OUT( "Test suite modifies databases so should not be run on live servers" ) unless mySociety::Config::get('STAGING_SITE', undef); |