Merge branch 'master' into topic/dt_feature_search
[sgn.git] / t / test_fixture.pl
blobc99d6cb036d27c975edd65c68082a7de8689e315
1 #!/usr/bin/env perl
3 use strict;
4 use warnings;
6 use DateTime;
7 use LWP::Simple;
8 use App::Prove;
9 use Data::Dumper;
11 use Pod::Usage;
12 use Getopt::Long;
13 use File::Slurp;
14 use Config::Any;
16 use Catalyst::ScriptRunner;
18 use lib 'lib';
19 use SGN::Devel::MyDevLibs;
21 my $verbose = 0;
22 my $nocleanup;
23 my $noserver;
24 my $noparallel = 0;
25 GetOptions(
26 "carpalways" => \( my $carpalways = 0 ),
27 "verbose" => \$verbose ,
28 "nocleanup" => \$nocleanup,
29 "noserver" => \$noserver,
30 "noparallel" => \$noparallel,
33 require Carp::Always if $carpalways;
35 my @prove_args = @ARGV;
36 @prove_args = ( 't' ) unless @prove_args;
38 #my $parallel = (grep /^-j\d*$/, @ARGV) ? 1 : 0;
40 $ENV{SGN_CONFIG_LOCAL_SUFFIX} = 'fixture';
41 #my $conf_file_base = 'sgn_local.conf'; # which conf file the sgn_fixture.conf should be based on
42 my $conf_file_base = 'sgn_local.conf';
43 my $template_file = 'sgn_fixture_template.conf';
44 # get some defaults from sgn_local.conf
46 my $cfg = Config::Any->load_files({files=> [$conf_file_base, $template_file], use_ext=>1 });
48 my $config = $cfg->[0]->{$conf_file_base};
49 my $template = $cfg->[1]->{$template_file};
51 #print STDERR Dumper($cfg);
52 my $db_user_password = $config->{dbpass};
53 my $dbhost = $config->{dbhost};
54 my $db_postgres_password = $config->{DatabaseConnection}->{sgn_test}->{password};
55 my $test_dsn = $config->{DatabaseConnection}->{sgn_test}->{dsn};
56 my $catalyst_server_port = 3010;
58 # replace the keys in the sgn local file with what's in the template
60 foreach my $k (keys %{$template}) {
61 #print STDERR "Replacing key $k : $config->{$k} with $template->{$k}\n";
62 $config->{$k} = $template->{$k};
65 # load the database fixture
67 my $now = DateTime->now();
68 my $dbname = join "_", map { $now->$_ } (qw | year month day hour minute |);
69 $dbname = 'test_db_'.$dbname;
70 $dbname .= $$;
72 print STDERR "# Writing a .pgpass file... ";
73 # format = hostname:port:database:username:password
74 open(my $PGPASS, ">", "$ENV{HOME}/.pgpass") || die "Can't open .pgpass for writing.";
75 print $PGPASS "$dbhost:5432:$dbname:web_usr:$db_user_password\n";
76 print $PGPASS "$dbhost:5432:*:postgres:$db_postgres_password\n";
77 close($PGPASS);
78 system("chmod 0600 $ENV{HOME}/.pgpass");
79 print STDERR "Done.\n";
81 print STDERR "# Loading database fixture... ";
82 my $database_fixture_dump = $ENV{DATABASE_FIXTURE_PATH} || '../cxgn_fixture.sql';
83 system("createdb -h $config->{dbhost} -U postgres -T template0 -E SQL_ASCII --no-password $dbname");
84 system("cat $database_fixture_dump | psql -h $config->{dbhost} -U postgres $dbname > /dev/null");
86 print STDERR "Done.\n";
88 print STDERR "# Creating sgn_fixture.conf file... ";
89 $config->{dbname} = $dbname;
90 $test_dsn =~ s/dbname=(.*)$/dbname=$dbname/;
91 $config->{DatabaseConnection}->{sgn_test}->{dsn} = $test_dsn;
93 #print STDERR Dumper($config);
95 my $new_conf = hash2config($config);
97 open(my $NEWCONF, ">", "sgn_fixture.conf") || die "Can't open sgn_fixture.conf for writing";
98 print $NEWCONF $new_conf;
99 close($NEWCONF);
101 print STDERR "Done.\n";
103 # start the test web server
105 my $server_pid;
106 my $logfile;
107 if ($noserver) {
108 print STDERR "# [ --noserver option: not starting web server]\n";
110 else {
111 $server_pid = fork;
112 $logfile = "logfile.$$.txt";
114 unless( $server_pid ) {
116 # web server process
118 #$ENV{SGN_TEST_MODE} = 1;
119 @ARGV = (
120 -p => $catalyst_server_port,
121 ( $noparallel ? () : ('--fork') ),
124 if (!$verbose) {
125 print STDERR "# [Server logfile at $logfile]\n";
126 open (STDERR, ">$logfile") || die "can't open logfile.";
128 Catalyst::ScriptRunner->run('SGN', 'Server');
130 exit;
132 print STDERR "# Starting web server (PID=$server_pid)... ";
136 # wait for the test server to start
139 local $SIG{CHLD} = sub {
140 waitpid $server_pid, 0;
141 die "\nTest server failed to start. Aborting.\n";
143 print STDERR "Done.\n";
145 if (!$noserver) {
146 sleep 1 until !kill(0, $server_pid) || get "http://localhost:$catalyst_server_port";
150 my $prove_pid = fork;
151 unless( $prove_pid ) {
153 # test harness process
155 print STDERR "# Starting tests... \n";
157 # set up env vars for prove and the tests
159 $ENV{SGN_TEST_SERVER} = "http://localhost:$catalyst_server_port";
160 if(! $noparallel ) {
161 $ENV{SGN_PARALLEL_TESTING} = 1;
162 $ENV{SGN_SKIP_LEAK_TEST} = 1;
165 # now run the tests against it
167 my $app = App::Prove->new;
168 $app->process_args(
169 '-lr',
170 ( map { -I => $_ } @INC ),
171 @prove_args
173 exit( $app->run ? 0 : 1 );
176 #$SIG{CHLD} = 'IGNORE'; # problematic
177 $SIG{INT} = sub { kill 15, $server_pid, $prove_pid };
178 $SIG{KILL} = sub { kill 9, $server_pid, $prove_pid };
180 print STDERR "# Start prove (PID $prove_pid)... \n";
181 waitpid $prove_pid, 0;
182 print STDERR "# Prove finished, stopping web server PID $server_pid... ";
184 END { kill 15, $server_pid if $server_pid }
185 waitpid $server_pid, 0;
186 sleep(3);
187 print STDERR "Done.\n";
189 if (!$nocleanup) {
190 print STDERR "# Removing test database ($dbname)... ";
191 system("dropdb -h $config->{dbhost} -U postgres --no-password $dbname");
192 print STDERR "Done.\n";
194 if ($noserver) {
195 print STDERR "# [ --noserver option: No logfile to remove]\n";
197 else {
198 print STDERR "# Delete server logfile... ";
199 close($logfile);
200 unlink $logfile;
201 print STDERR "Done.\n";
203 print STDERR "# Delete fixture conf file... ";
204 unlink "sgn_fixture.conf";
205 print STDERR "Done.\n";
208 else {
209 print STDERR "# --nocleanup option: not removing db or files.\n";
211 print STDERR "# Test run complete.\n\n";
215 sub hash2config {
216 my $hash = shift;
218 my $s = "";
219 foreach my $k (keys(%$hash)) {
220 if (ref($hash->{$k}) eq "ARRAY") {
221 foreach my $v (@{$hash->{$k}}) {
222 $s .= "$k $v\n";
225 elsif (ref($hash->{$k}) eq "HASH") {
226 foreach my $n (keys(%{$hash->{$k}})) {
227 if (ref($hash->{$k}->{$n}) eq "HASH") {
228 $s .= "<$k $n>\n";
229 $s .= hash2config($hash->{$k}->{$n});
231 else {
232 $s .= "<$k>\n";
233 $s .= hash2config($hash->{$k});
235 $s .= "</$k>\n";
238 else {
239 $s .= "$k $hash->{$k}\n";
243 # if nothing matched the replace keys, add them here
246 # if (exists($hash->{dbname})) {
247 # $s .= "dbname $dbname\n";
250 return $s;
255 __END__
257 =head1 NAME
259 test_fixture.pl - start a dev server and run tests against it
261 =head1 SYNOPSIS
263 t/test_fixture.pl --carpalways -- -v -j5 t/mytest.t t/mydiroftests/
265 =head1 OPTIONS
267 -v verbose - the output of the server is not re-directed to file,
268 but rather output to the screen.
270 --carpalways Load Carp::Always in both the server and the test process
271 to force backtraces of all warnings and errors
273 --nocleanup Do not clean up database and logfile
275 --noserver Do not start webserver (if running unit_fixture tests only)
277 --noparallel Do not run the server in parallel mode.
279 =head1 AUTHORS
281 Robert Buels (initial script)
282 Lukas Mueller <lam87@cornell.edu> (fixture implementation)
284 =cut