16 use File
::Basename
qw(dirname);
19 use Catalyst
::ScriptRunner
;
22 use SGN
::Devel
::MyDevLibs
;
27 my $dumpupdatedfixture;
31 my $logfile = "logfile.$$.txt";
32 my $print_environment;
33 # relative to `sgn/ (or parent of wherever this script is located)
34 my $fixture_path = 't/data/fixture/cxgn_fixture.sql';
37 "carpalways" => \
(my $carpalways = 0),
38 "verbose" => \
$verbose,
39 "nocleanup" => \
$nocleanup,
40 "dumpupdatedfixture" => \
$dumpupdatedfixture,
41 "noserver" => \
$noserver,
42 "noparallel" => \
$noparallel,
43 "nopatch" => \
$nopatch,
44 "fixture_path" => \
$fixture_path,
45 "list_config" => \
$list_config,
46 "logfile=s" => \
$logfile,
47 "env" => \
$print_environment,
50 require Carp
::Always
if $carpalways;
52 if ($print_environment) { print STDERR
"CURRENT ENV: ".Dumper
(\
%ENV); }
54 my @prove_args = @ARGV;
56 @prove_args = map {abs_path
($_)} @prove_args;
59 #Change cwd to `sgn/` (or parent of wherever this script is located)
60 my $sgn_dir = abs_path
(dirname
(abs_path
($0))."/../");
61 print STDERR
"####### ".$sgn_dir." #######";
63 @prove_args = ( 't' ) unless @prove_args;
65 #my $parallel = (grep /^-j\d*$/, @ARGV) ? 1 : 0;
67 $ENV{SGN_CONFIG_LOCAL_SUFFIX
} = 'fixture';
68 #my $conf_file_base = 'sgn_local.conf'; # which conf file the sgn_fixture.conf should be based on
70 my $conf_file_base = $ENV{SGN_TEST_CONF
} || 'sgn_test.conf';
71 my $template_file = 'sgn_fixture_template.conf';
72 # get some defaults from sgn_local.conf
74 my $cfg = Config
::Any
->load_files({files
=> [$conf_file_base, $template_file], use_ext
=>1 });
76 my $config = $cfg->[0]->{$conf_file_base};
77 my $template = $cfg->[1]->{$template_file};
80 print STDERR Dumper
($cfg);
83 my $db_user_password = $config->{dbpass
};
84 my $dbhost = $config->{dbhost
} || 'localhost';
85 my $dbport = $config->{dbport
} || '5432';
86 my $db_postgres_password = $config->{DatabaseConnection
}->{sgn_test
}->{password
};
87 print STDERR
"Using $dbhost:$dbport\n";
88 my $test_dsn = $config->{DatabaseConnection
}->{sgn_test
}->{dsn
};
89 my $catalyst_server_port = 3010;
91 # replace the keys in the sgn local file with what's in the template
93 foreach my $k (keys %{$template}) {
94 #print STDERR "Replacing key $k : $config->{$k} with $template->{$k}\n";
95 $config->{$k} = $template->{$k};
98 # load the database fixture
102 if ($ENV{TEST_DB_NAME
}) { $dbname = $ENV{TEST_DB_NAME
}; }
105 my $now = DateTime
->now();
106 $dbname = join "_", map { $now->$_ } (qw
| year month day hour minute
|);
107 $dbname = 'test_db_'.$dbname;
111 print STDERR
"# Writing a .pgpass file... ";
112 # format = hostname:port:database:username:password
113 open(my $PGPASS, ">", "$ENV{HOME}/.pgpass") || die "Can't open .pgpass for writing.";
114 print $PGPASS "$dbhost:$dbport:$dbname:web_usr:$db_user_password\n";
115 print $PGPASS "$dbhost:$dbport:*:postgres:$db_postgres_password\n";
117 system("chmod 0600 $ENV{HOME}/.pgpass");
118 print STDERR
"Done.\n";
120 # load fixture only if no TEST_DB_NAME env var was provided
121 if (! $ENV{TEST_DB_NAME
}) {
122 my $database_fixture_dump = $ENV{DATABASE_FIXTURE_PATH
} || $fixture_path;
123 print STDERR
"# Loading database fixture... $database_fixture_dump ... ";
124 system("createdb -h $config->{dbhost} -U postgres -T template0 -E UTF8 --no-password $dbname");
125 # will emit an error if web_usr role already exists, but that's OK
126 system("psql -h $config->{dbhost} -U postgres $dbname -c \"CREATE USER web_usr PASSWORD '$db_user_password'\"");
127 system("cat $database_fixture_dump | psql -h $config->{dbhost} -U postgres $dbname > /dev/null");
129 print STDERR
"Done.\n";
132 print STDERR
"# Creating sgn_fixture.conf file... ";
133 $config->{dbname
} = $dbname;
134 $test_dsn =~ s/dbname=(.*)$/dbname=$dbname/;
135 $config->{DatabaseConnection
}->{sgn_test
}->{dsn
} = $test_dsn;
137 #print STDERR Dumper($config);
139 my $new_conf = hash2config
($config);
141 open(my $NEWCONF, ">", "sgn_fixture.conf") || die "Can't open sgn_fixture.conf for writing";
142 print $NEWCONF $new_conf;
145 #run fixture and db patches.
147 print STDERR
"Running patches... ";
148 system("t/data/fixture/patches/run_fixture_and_db_patches.pl -u postgres -p $db_postgres_password -h $dbhost -d $dbname -e janedoe -s 157 > /dev/null");
149 print STDERR
"Done\n";
152 # run the materialized views creation script
154 print STDERR
"Running matview refresh with -H $dbhost -D $dbname -U postgres -P $db_postgres_password -m fullview\n";
155 system("perl bin/refresh_matviews.pl -H $dbhost -D $dbname -U postgres -P $db_postgres_password -m fullview");
157 if ($dumpupdatedfixture){
158 print STDERR
"Dumping new updated fixture with all patches run on it to t/data/fixture/cxgn_fixture.sql\n";
159 system("pg_dump -h $config->{dbhost} -U postgres $dbname > t/data/fixture/cxgn_fixture.sql");
162 print STDERR
"Done.\n";
164 # start the test web server
168 print STDERR
"# [ --noserver option: not starting web server]\n";
173 unless( $server_pid ) {
177 #$ENV{SGN_TEST_MODE} = 1;
179 -p
=> $catalyst_server_port,
180 ( $noparallel ?
() : ('--fork') ),
184 print STDERR
"# [Server logfile at $logfile]\n";
185 open (STDERR
, ">$logfile") || die "can't open logfile.";
187 Catalyst
::ScriptRunner
->run('SGN', 'Server');
190 print STDERR
"# Removing test database ($dbname)... ";
193 print STDERR
"# [ --noserver option: No logfile to remove]\n";
196 print STDERR
"# Delete server logfile... ";
199 print STDERR
"Done.\n";
205 print STDERR
"# Starting web server (PID=$server_pid)... ";
209 # wait for the test server to start
212 local $SIG{CHLD
} = sub {
213 waitpid $server_pid, 0;
214 die "\nTest server failed to start. Aborting.\n";
216 print STDERR
"Done.\n";
219 sleep 1 until !kill(0, $server_pid) || get
"http://localhost:$catalyst_server_port";
223 my $prove_pid = fork;
224 unless( $prove_pid ) {
226 # test harness process
228 print STDERR
"# Starting tests... \n";
230 # set up env vars for prove and the tests
232 $ENV{SGN_TEST_SERVER
} ||= "http://localhost:$catalyst_server_port";
234 $ENV{SGN_PARALLEL_TESTING
} = 1;
235 $ENV{SGN_SKIP_LEAK_TEST
} = 1;
238 # now run the tests against it
240 my $app = App
::Prove
->new;
242 my $v = $verbose ?
'v' : '';
246 ( map { -I
=> $_ } @INC ),
249 exit( $app->run ?
0 : 1 );
252 #$SIG{CHLD} = 'IGNORE'; # problematic
253 $SIG{INT
} = sub { kill 15, $server_pid, $prove_pid };
254 $SIG{KILL
} = sub { kill 9, $server_pid, $prove_pid };
256 print STDERR
"# Start prove (PID $prove_pid)... \n";
257 waitpid $prove_pid, 0;
258 my $prove_pid_exit_status = $?
>> 8;
259 print STDERR
"# Prove finished, stopping web server PID $server_pid... ";
261 END { kill 15, $server_pid if $server_pid }
262 waitpid $server_pid, 0;
264 print STDERR
"Done.\n";
267 if ($ENV{TEST_DB_NAME
}) {
268 print STDERR
"Not removing test database (TEST_DB_NAME = $ENV{TEST_DB_NAME} is set.\n";
271 print STDERR
"# Removing test database ($dbname)... ";
272 system("dropdb -h $config->{dbhost} -U postgres --no-password $dbname");
273 print STDERR
"Done.\n";
277 print STDERR
"# [ --noserver option: No logfile to remove]\n";
280 # print STDERR "# Delete server logfile... ";
283 # print STDERR "Done.\n";
285 print STDERR
"# Delete fixture conf file... ";
286 unlink "sgn_fixture.conf";
287 print STDERR
"Done.\n";
291 print STDERR
"# --nocleanup option: not removing db or files.\n";
293 print STDERR
"# Test run complete.\n\n";
294 exit($prove_pid_exit_status); # exit with non-zero exit status if any tests failed
302 foreach my $k (keys(%$hash)) {
303 if (ref($hash->{$k}) eq "ARRAY") {
304 foreach my $v (@
{$hash->{$k}}) {
308 elsif (ref($hash->{$k}) eq "HASH") {
309 foreach my $n (keys(%{$hash->{$k}})) {
310 if (ref($hash->{$k}->{$n}) eq "HASH") {
312 $s .= hash2config
($hash->{$k}->{$n});
316 $s .= hash2config
($hash->{$k});
322 $s .= "$k $hash->{$k}\n";
326 # if nothing matched the replace keys, add them here
329 # if (exists($hash->{dbname})) {
330 # $s .= "dbname $dbname\n";
342 test_fixture.pl - start a dev server and run tests against it
346 t/test_fixture.pl --carpalways -- -v -j5 t/mytest.t t/mydiroftests/
350 -v verbose - the output of the server is not re-directed to file,
351 but rather output to the screen.
353 --carpalways Load Carp::Always in both the server and the test process
354 to force backtraces of all warnings and errors
356 --nocleanup Do not clean up database and logfile
358 --noserver Do not start webserver (if running unit_fixture tests only)
360 --noparallel Do not run the server in parallel mode.
362 --nopatch Do not run fixture and database patches
364 --fixture_path specify a path to the fixture different from the default
365 (t/data/fixture/cxgn_fixture.pl). Note: You can also set the env
366 variable DATABASE_FIXTURE_PATH, which will overrule this
369 --list_config lists the configuration information
371 -- -v options specified after two dashes will be passed to prove
372 directly, such -v will run prove in verbose mode.
374 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.
376 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.
380 Robert Buels (initial script)
381 Lukas Mueller <lam87@cornell.edu> (fixture implementation)