Merge pull request #3635 from solgenomics/topic/fix_vcfgenotypes.t
[sgn.git] / t / test_fixture.pl
blob237bf64e93933c2683a16c2a1c51da7c5618def2
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 File::Basename qw(dirname);
17 use Cwd qw(abs_path);
19 use Catalyst::ScriptRunner;
21 use lib 'lib';
22 use SGN::Devel::MyDevLibs;
24 my $verbose = 0;
25 my $nocleanup;
26 my $noserver;
27 my $dumpupdatedfixture;
28 my $noparallel = 0;
29 my $list_config = "";
30 my $logfile = "logfile.$$.txt";
31 # relative to `sgn/ (or parent of wherever this script is located)
32 my $fixture_path = 't/data/fixture/cxgn_fixture.sql';
34 GetOptions(
35 "carpalways" => \(my $carpalways = 0),
36 "verbose" => \$verbose,
37 "nocleanup" => \$nocleanup,
38 "dumpupdatedfixture" => \$dumpupdatedfixture,
39 "noserver" => \$noserver,
40 "noparallel" => \$noparallel,
41 "fixture_path" => \$fixture_path,
42 "list_config" => \$list_config,
43 "logfile=s" => \$logfile
46 require Carp::Always if $carpalways;
49 my @prove_args = @ARGV;
50 if(@prove_args){
51 @prove_args = map {abs_path($_)} @prove_args;
54 #Change cwd to `sgn/` (or parent of wherever this script is located)
55 my $sgn_dir = abs_path(dirname(abs_path($0))."/../");
56 print STDERR "####### ".$sgn_dir." #######";
57 chdir($sgn_dir);
58 @prove_args = ( 't' ) unless @prove_args;
60 #my $parallel = (grep /^-j\d*$/, @ARGV) ? 1 : 0;
62 $ENV{SGN_CONFIG_LOCAL_SUFFIX} = 'fixture';
63 #my $conf_file_base = 'sgn_local.conf'; # which conf file the sgn_fixture.conf should be based on
64 # relative to `sgn/`
65 my $conf_file_base = $ENV{SGN_TEST_CONF} || 'sgn_test.conf';
66 my $template_file = 'sgn_fixture_template.conf';
67 # get some defaults from sgn_local.conf
69 my $cfg = Config::Any->load_files({files=> [$conf_file_base, $template_file], use_ext=>1 });
71 my $config = $cfg->[0]->{$conf_file_base};
72 my $template = $cfg->[1]->{$template_file};
74 if ($list_config) {
75 print STDERR Dumper($cfg);
78 my $db_user_password = $config->{dbpass};
79 my $dbhost = $config->{dbhost} || 'localhost';
80 my $dbport = $config->{dbport} || '5432';
81 my $db_postgres_password = $config->{DatabaseConnection}->{sgn_test}->{password};
82 print STDERR "Using $dbhost:$dbport\n";
83 my $test_dsn = $config->{DatabaseConnection}->{sgn_test}->{dsn};
84 my $catalyst_server_port = 3010;
86 # replace the keys in the sgn local file with what's in the template
88 foreach my $k (keys %{$template}) {
89 #print STDERR "Replacing key $k : $config->{$k} with $template->{$k}\n";
90 $config->{$k} = $template->{$k};
93 # load the database fixture
95 my $dbname;
97 if ($ENV{TEST_DB_NAME}) { $dbname = $ENV{TEST_DB_NAME}; }
99 else {
100 my $now = DateTime->now();
101 $dbname = join "_", map { $now->$_ } (qw | year month day hour minute |);
102 $dbname = 'test_db_'.$dbname;
103 $dbname .= $$;
106 print STDERR "# Writing a .pgpass file... ";
107 # format = hostname:port:database:username:password
108 open(my $PGPASS, ">", "$ENV{HOME}/.pgpass") || die "Can't open .pgpass for writing.";
109 print $PGPASS "$dbhost:$dbport:$dbname:web_usr:$db_user_password\n";
110 print $PGPASS "$dbhost:$dbport:*:postgres:$db_postgres_password\n";
111 close($PGPASS);
112 system("chmod 0600 $ENV{HOME}/.pgpass");
113 print STDERR "Done.\n";
115 # load fixture only if no TEST_DB_NAME env var was provided
116 if (! $ENV{TEST_DB_NAME}) {
117 my $database_fixture_dump = $ENV{DATABASE_FIXTURE_PATH} || $fixture_path;
118 print STDERR "# Loading database fixture... $database_fixture_dump ... ";
119 system("createdb -h $config->{dbhost} -U postgres -T template0 -E SQL_ASCII --no-password $dbname");
120 # will emit an error if web_usr role already exists, but that's OK
121 system("psql -h $config->{dbhost} -U postgres $dbname -c \"CREATE USER web_usr PASSWORD '$db_user_password'\"");
122 system("cat $database_fixture_dump | psql -h $config->{dbhost} -U postgres $dbname > /dev/null");
124 print STDERR "Done.\n";
127 print STDERR "# Creating sgn_fixture.conf file... ";
128 $config->{dbname} = $dbname;
129 $test_dsn =~ s/dbname=(.*)$/dbname=$dbname/;
130 $config->{DatabaseConnection}->{sgn_test}->{dsn} = $test_dsn;
132 #print STDERR Dumper($config);
134 my $new_conf = hash2config($config);
136 open(my $NEWCONF, ">", "sgn_fixture.conf") || die "Can't open sgn_fixture.conf for writing";
137 print $NEWCONF $new_conf;
138 close($NEWCONF);
140 #run fixture and db patches.
141 system("t/data/fixture/patches/run_fixture_and_db_patches.pl -u postgres -p $db_postgres_password -h $dbhost -d $dbname -e janedoe -s 145");
143 # run the materialized views creation script
145 print STDERR "Running matview refresh with -H $dbhost -D $dbname -U postgres -P $db_postgres_password -m fullview\n";
146 system("perl bin/refresh_matviews.pl -H $dbhost -D $dbname -U postgres -P $db_postgres_password -m fullview");
148 if ($dumpupdatedfixture){
149 print STDERR "Dumping new updated fixture with all patches run on it to t/data/fixture/cxgn_fixture.sql\n";
150 system("pg_dump -U postgres $dbname > t/data/fixture/cxgn_fixture.sql");
153 print STDERR "Done.\n";
155 # start the test web server
157 my $server_pid;
158 if ($noserver) {
159 print STDERR "# [ --noserver option: not starting web server]\n";
161 else {
162 $server_pid = fork;
164 unless( $server_pid ) {
166 # web server process
168 #$ENV{SGN_TEST_MODE} = 1;
169 @ARGV = (
170 -p => $catalyst_server_port,
171 ( $noparallel ? () : ('--fork') ),
174 if (!$verbose) {
175 print STDERR "# [Server logfile at $logfile]\n";
176 open (STDERR, ">$logfile") || die "can't open logfile.";
178 Catalyst::ScriptRunner->run('SGN', 'Server');
180 if (!$nocleanup) {
181 print STDERR "# Removing test database ($dbname)... ";
183 if ($noserver) {
184 print STDERR "# [ --noserver option: No logfile to remove]\n";
186 else {
187 print STDERR "# Delete server logfile... ";
188 close($logfile);
189 unlink $logfile;
190 print STDERR "Done.\n";
194 exit;
196 print STDERR "# Starting web server (PID=$server_pid)... ";
200 # wait for the test server to start
203 local $SIG{CHLD} = sub {
204 waitpid $server_pid, 0;
205 die "\nTest server failed to start. Aborting.\n";
207 print STDERR "Done.\n";
209 if (!$noserver) {
210 sleep 1 until !kill(0, $server_pid) || get "http://localhost:$catalyst_server_port";
214 my $prove_pid = fork;
215 unless( $prove_pid ) {
217 # test harness process
219 print STDERR "# Starting tests... \n";
221 # set up env vars for prove and the tests
223 $ENV{SGN_TEST_SERVER} ||= "http://localhost:$catalyst_server_port";
224 if(! $noparallel ) {
225 $ENV{SGN_PARALLEL_TESTING} = 1;
226 $ENV{SGN_SKIP_LEAK_TEST} = 1;
229 # now run the tests against it
231 my $app = App::Prove->new;
233 my $v = $verbose ? 'v' : '';
235 $app->process_args(
236 '-lr'.$v,
237 ( map { -I => $_ } @INC ),
238 @prove_args
240 exit( $app->run ? 0 : 1 );
243 #$SIG{CHLD} = 'IGNORE'; # problematic
244 $SIG{INT} = sub { kill 15, $server_pid, $prove_pid };
245 $SIG{KILL} = sub { kill 9, $server_pid, $prove_pid };
247 print STDERR "# Start prove (PID $prove_pid)... \n";
248 waitpid $prove_pid, 0;
249 print STDERR "# Prove finished, stopping web server PID $server_pid... ";
251 END { kill 15, $server_pid if $server_pid }
252 waitpid $server_pid, 0;
253 sleep(3);
254 print STDERR "Done.\n";
256 if (!$nocleanup) {
257 if ($ENV{TEST_DB_NAME}) {
258 print STDERR "Not removing test database (TEST_DB_NAME = $ENV{TEST_DB_NAME} is set.\n";
260 else {
261 print STDERR "# Removing test database ($dbname)... ";
262 system("dropdb -h $config->{dbhost} -U postgres --no-password $dbname");
263 print STDERR "Done.\n";
266 if ($noserver) {
267 print STDERR "# [ --noserver option: No logfile to remove]\n";
269 else {
270 # print STDERR "# Delete server logfile... ";
271 # close($logfile);
272 # unlink $logfile;
273 # print STDERR "Done.\n";
275 print STDERR "# Delete fixture conf file... ";
276 unlink "sgn_fixture.conf";
277 print STDERR "Done.\n";
280 else {
281 print STDERR "# --nocleanup option: not removing db or files.\n";
283 print STDERR "# Test run complete.\n\n";
287 sub hash2config {
288 my $hash = shift;
290 my $s = "";
291 foreach my $k (keys(%$hash)) {
292 if (ref($hash->{$k}) eq "ARRAY") {
293 foreach my $v (@{$hash->{$k}}) {
294 $s .= "$k $v\n";
297 elsif (ref($hash->{$k}) eq "HASH") {
298 foreach my $n (keys(%{$hash->{$k}})) {
299 if (ref($hash->{$k}->{$n}) eq "HASH") {
300 $s .= "<$k $n>\n";
301 $s .= hash2config($hash->{$k}->{$n});
303 else {
304 $s .= "<$k>\n";
305 $s .= hash2config($hash->{$k});
307 $s .= "</$k>\n";
310 else {
311 $s .= "$k $hash->{$k}\n";
315 # if nothing matched the replace keys, add them here
318 # if (exists($hash->{dbname})) {
319 # $s .= "dbname $dbname\n";
322 return $s;
327 __END__
329 =head1 NAME
331 test_fixture.pl - start a dev server and run tests against it
333 =head1 SYNOPSIS
335 t/test_fixture.pl --carpalways -- -v -j5 t/mytest.t t/mydiroftests/
337 =head1 OPTIONS
339 -v verbose - the output of the server is not re-directed to file,
340 but rather output to the screen.
342 --carpalways Load Carp::Always in both the server and the test process
343 to force backtraces of all warnings and errors
345 --nocleanup Do not clean up database and logfile
347 --noserver Do not start webserver (if running unit_fixture tests only)
349 --noparallel Do not run the server in parallel mode.
351 --fixture_path specify a path to the fixture different from the default
352 (t/data/fixture/cxgn_fixture.pl). Note: You can also set the env
353 variable DATABASE_FIXTURE_PATH, which will overrule this
354 option.
356 --list_config lists the configuration information
358 -- -v options specified after two dashes will be passed to prove
359 directly, such -v will run prove in verbose mode.
361 By default, the configuration will be taken from the file sgn_test.conf. To use another configuration file, set the environment variable SGN_TEST_CONF to the name of the file you would like to use.
363 To use an existing database as the fixture, set the environment variable TEST_DB_NAME to the name of the database you would like to use.
365 =head1 AUTHORS
367 Robert Buels (initial script)
368 Lukas Mueller <lam87@cornell.edu> (fixture implementation)
370 =cut