use strict;
use warnings;
use File::Basename;
use lib File::Basename::dirname(__FILE__)."/../../../lib";
use lib File::Basename::dirname(__FILE__)."/../..";
use URT;
use IO::File;
use Test::More;
my ($oracle,$postgres,$mysql);
BEGIN {
eval "use DBD::mysql";
eval "use DBD::Pg";
eval "use DBD::Oracle";
$oracle = $INC{"DBD/Oracle.pm"};
$mysql = $INC{"DBD/mysql.pm"};
$postgres = $INC{"DBD/Pg.pm"};
my $tests = 33;
$tests += 12 if $oracle;
$tests += 12 if $postgres;
$tests += 12 if $mysql;
plan tests => $tests;
}
BEGIN {
use_ok('UR::Namespace::Command::Define::Datasource');
use_ok('UR::Namespace::Command::Define::Datasource::Sqlite');
use_ok('UR::Namespace::Command::Define::Datasource::Oracle');
use_ok('UR::Namespace::Command::Define::Datasource::Mysql');
use_ok('UR::Namespace::Command::Define::Datasource::Pg');
}
my $data_source_dir = URT->get_base_directory_name() . '/DataSource/';
my @FILES_TO_DELETE = map { $data_source_dir . $_ }
qw(
TestcaseSqlite.pm
TestcaseSqlite.sqlite3
TestcaseSqlite2.pm
TestcaseOracle.pm
TestcaseMysql.pm
TestcasePg.pm
);
push @FILES_TO_DELETE, '/tmp/TestcaseSqlite.sqlite3';
chdir $data_source_dir;
my $cleanup_files = sub { unlink @FILES_TO_DELETE };
&$cleanup_files;
UR::Namespace::Command::Define::Datasource->dump_status_messages(0); # don't print to the terminal
# SQLite
{
my($delegate_class, $create_params) = UR::Namespace::Command::Define::Datasource->resolve_class_and_params_for_argv(
qw(sqlite --dsname TestcaseSqlite)
);
ok($delegate_class, "Resolving parameters for define datasource, delegate class $delegate_class");
my $command = $delegate_class->create(%$create_params);
ok($command,'Created command obj for defining SQLite DS');
ok($command->execute(),'Executed SQLite define');
my $expected_path = $command->namespace_path . '/DataSource/TestcaseSqlite.sqlite3';
ok(-f $expected_path, 'Created SQLite database file');
$expected_path = $command->namespace_path . '/DataSource/TestcaseSqlite.pm';
ok(-f $expected_path, 'Created SQLite DS module');
my $src = _read_file($expected_path);
# Not an exhaustive syntax check, just look for some things
like($src, qr/package URT::DataSource::TestcaseSqlite/, 'package line looks ok');
like($src, qr/class URT::DataSource::TestcaseSqlite/, 'class line looks ok');
like($src, qr/is.*UR::DataSource::SQLite/, "'is' line looks ok");
like($src, qr/sub server \{ \S+\/URT\/DataSource\/TestcaseSqlite.sqlite3/, 'server line looks ok');
unlike($src, qr/sub owner/, 'No owner line, as expected');
unlike($src, qr/sub login/, 'No login line, as expected');
unlike($src, qr/sub auth/, 'No auth line, as expected');
&$cleanup_files;
}
{
my $db_file = '/tmp/TestcaseSqlite.sqlite3';
IO::File->new($db_file, 'w')->close();
my($delegate_class, $create_params) = UR::Namespace::Command::Define::Datasource->resolve_class_and_params_for_argv(
qw(sqlite --dsname TestcaseSqlite2 --server /tmp/TestcaseSqlite.sqlite3 )
);
ok($delegate_class, "Resolving parameters for define datasource, delegate class $delegate_class");
my $command = $delegate_class->create(%$create_params);
ok($command,'Created command obj for defining SQLite DS');
ok($command->execute(),'Executed SQLite define');
my $expected_path = '/tmp/TestcaseSqlite.sqlite3';
ok(-f $expected_path, 'Created SQLite database file');
$expected_path = $command->namespace_path . '/DataSource/TestcaseSqlite2.pm';
ok(-f $expected_path, 'Created SQLite DS module');
my $src = _read_file($expected_path);
# Not an exhaustive syntax check, just look for some things
like($src, qr/package URT::DataSource::TestcaseSqlite/, 'package line looks ok');
like($src, qr/class URT::DataSource::TestcaseSqlite/, 'class line looks ok');
like($src, qr/is.*UR::DataSource::SQLite/, "'is' line looks ok");
like($src, qr/sub server \{ '\/tmp\/TestcaseSqlite.sqlite3/, 'server line looks ok');
unlike($src, qr/sub owner/, 'No owner line, as expected');
unlike($src, qr/sub login/, 'No login line, as expected');
unlike($src, qr/sub auth/, 'No auth line, as expected');
# Don't remove the files because we want to test failure next
}
{
my($delegate_class, $create_params) = UR::Namespace::Command::Define::Datasource->resolve_class_and_params_for_argv(
qw(sqlite --dsname TestcaseSqlite)
);
ok($delegate_class, "Resolving parameters for define datasource, delegate class $delegate_class");
my $command = $delegate_class->create(%$create_params);
ok($command,'Created command obj for defining SQLite DS');
$command->dump_error_messages(0);
ok(! $command->execute(), 'Execute correctly returned failure');
my $message = $command->error_message;
is($message,'A data source named URT::DataSource::TestcaseSqlite already exists',
'Error message mentions the target datasource module already exists');
&$cleanup_files;
}
# Oracle
if($oracle)
{
my($delegate_class, $create_params) = UR::Namespace::Command::Define::Datasource->resolve_class_and_params_for_argv(
qw(oracle --dsname TestcaseOracle --owner foo --login me --auth passwd)
);
ok($delegate_class, "Resolving parameters for define datasource, delegate class $delegate_class");
my $command = $delegate_class->create(%$create_params);
ok($command,'Created command obj for defining Oracle DS');
open my $old_stderr, ">&STDERR";
close(STDERR);
$command->dump_error_messages(0);
# The execute() here will fail because TestcaseOracle isn't a real database
# and the connection test at the end of the command will fail
my $retval = eval { $command->execute() };
open STDERR, ">&", $old_stderr;
ok(!$retval,'Executing Oracle define failed as expected');
like($@, qr/Failed to connect to the database/, 'Failure was because it could not connect to the database');
my $expected_path = $command->namespace_path . '/DataSource/TestcaseOracle.pm';
ok(-f $expected_path, 'Created Oracle DS module');
my $src = _read_file($expected_path);
# Not an exhaustive syntax check, just look for some things
like($src, qr/package URT::DataSource::TestcaseOracle/, 'package line looks ok');
like($src, qr/class URT::DataSource::TestcaseOracle/, 'class line looks ok');
like($src, qr/is.*UR::DataSource::Oracle/, "'is' line looks ok");
like($src, qr/sub server \{ 'TestcaseOracle' \}/, 'server line looks ok');
like($src, qr/sub owner \{ 'foo' \}/, 'owner line looks ok');
like($src, qr/sub login \{ 'me' \}/, 'login line looks ok');
like($src, qr/sub auth \{ 'passwd' \}/, 'auth line looks ok');
&$cleanup_files;
}
else {
diag "skipping Oracle tests since DBD::Oracle is not installed and configured";
}
# PostgreSQL
if ($postgres)
{
my($delegate_class, $create_params) = UR::Namespace::Command::Define::Datasource->resolve_class_and_params_for_argv(
qw(pg --dsname TestcasePg --owner foo --login me --auth passwd)
);
ok($delegate_class, "Resolving parameters for define datasource, delegate class $delegate_class");
my $command = $delegate_class->create(%$create_params);
ok($command,'Created command obj for defining Pg DS');
$command->dump_error_messages(0);
open my $old_stderr, ">&STDERR";
close(STDERR);
# The execute() here will fail because TestcasePg isn't a real database
# and the connection test at the end of the command will fail
my $retval = eval { $command->execute() };
open STDERR, ">&", $old_stderr;
ok(!$retval,'Executing Pg define failed as expected');
like($@, qr/(Failed to connect to the database)|(Can't load \S+ for module DBD::Pg)/, 'Failure was because it could not connect to the database');
my $expected_path = $command->namespace_path . '/DataSource/TestcasePg.pm';
ok(-f $expected_path, 'Created Pg DS module');
my $src = _read_file($expected_path);
# Not an exhaustive syntax check, just look for some things
like($src, qr/package URT::DataSource::TestcasePg/, 'package line looks ok');
like($src, qr/class URT::DataSource::TestcasePg/, 'class line looks ok');
like($src, qr/is.*UR::DataSource::Pg/, "'is' line looks ok");
like($src, qr/sub server \{ 'TestcasePg' \}/, 'server line looks ok');
like($src, qr/sub owner \{ 'foo' \}/, 'owner line looks ok');
like($src, qr/sub login \{ 'me' \}/, 'login line looks ok');
like($src, qr/sub auth \{ 'passwd' \}/, 'auth line looks ok');
&$cleanup_files;
}
else {
diag "skipping PostgreSQL tests since DBD::pg is not installed";
}
# MySQL
if($mysql)
{
my($delegate_class, $create_params) = UR::Namespace::Command::Define::Datasource->resolve_class_and_params_for_argv(
qw(mysql --dsname TestcaseMysql --owner foo --login me --auth passwd)
);
ok($delegate_class, "Resolving parameters for define datasource, delegate class $delegate_class");
my $command = $delegate_class->create(%$create_params);
ok($command,'Created command obj for defining Mysql DS');
$command->dump_error_messages(0);
open my $old_stderr, ">&STDERR";
close(STDERR);
# The execute() here will fail because TestcaseMysql isn't a real database
# and the connection test at the end of the command will fail
my $retval = eval { $command->execute() };
open STDERR, ">&", $old_stderr;
ok(!$retval,'Executing Mysql define failed as expected');
like($@, qr/Failed to connect to the database/, 'Failure was because it could not connect to the database');
my $expected_path = $command->namespace_path . '/DataSource/TestcaseMysql.pm';
ok(-f $expected_path, 'Created Mysql DS module');
my $src = _read_file($expected_path);
# Not an exhaustive syntax check, just look for some things
like($src, qr/package URT::DataSource::TestcaseMysql/, 'package line looks ok');
like($src, qr/class URT::DataSource::TestcaseMysql/, 'class line looks ok');
like($src, qr/is.*UR::DataSource::MySQL/, "'is' line looks ok");
like($src, qr/sub server \{ 'TestcaseMysql' \}/, 'server line looks ok');
like($src, qr/sub owner \{ 'foo' \}/, 'owner line looks ok');
like($src, qr/sub login \{ 'me' \}/, 'login line looks ok');
like($src, qr/sub auth \{ 'passwd' \}/, 'auth line looks ok');
&$cleanup_files;
}
else {
diag "skipping MySQL tests since DBD::mysql is not installed";
}
sub _read_file {
my $path = shift;
my $fh = IO::File->new($path);
die "Can't open $path: $!" unless $fh;
# Read in the whole file
local $/;
undef $/;
my $src = <$fh>;
$fh->close();
return $src;
}