Commit 6795045a authored by Eric Cano's avatar Eric Cano
Browse files

bug #72215: Remove the TAPEGATEWAYREQUEST table from the schema, and drop the...

bug #72215: Remove the TAPEGATEWAYREQUEST table from the schema, and drop the triggers that populate it.

Further refactoring of the tests, increase of the timeout to a more friendly 10 minutes, started to use the modules's tracking structure more extensively.
parent 1d563e60
......@@ -40,40 +40,41 @@ our $VERSION = 1.00;
our @ISA = qw(Exporter);
our @export = qw(
read_config
check_environment
get_environment
make_seed
make_localfile
open_db
getConfParam
getCastorConfParam
daemonIsRunning
killDaemonWithTimeout
startDaemons
genBackupFileName
getNbTapeCopiesInStagerDb
insertCastorFile
deleteCastorFile
setFileClassNbCopies
overrideCheckPermission
insertTapeCopy
deleteTapeCopy
deleteAllStreamsTapeCopiesAndCastorFiles
executeSQLPlusScript
executeSQLPlusScriptNoError
wipeAndRecreateDefaultLxcastodev03
migrateToNewTapeGatewaySchema
stopAndSwitchToTapeGatewayd
stopAndSwitchToRtcpclientd
getLdLibraryPathFromSrcPath
check_leftovers
check_leftovers_poll_timeout
nullize_arrays_undefs
print_leftovers
getOrastagerconfigParam
cleanup
); # Symbols to autoexport (:DEFAULT tag)
read_config
check_environment
get_environment
register_remote_file
make_seed
make_localfile
open_db
getConfParam
getCastorConfParam
daemonIsRunning
killDaemonWithTimeout
startDaemons
genBackupFileName
getNbTapeCopiesInStagerDb
insertCastorFile
deleteCastorFile
setFileClassNbCopies
overrideCheckPermission
insertTapeCopy
deleteTapeCopy
deleteAllStreamsTapeCopiesAndCastorFiles
executeSQLPlusScript
executeSQLPlusScriptNoError
wipeAndRecreateDefaultLxcastodev03
migrateToNewTapeGatewaySchema
stopAndSwitchToTapeGatewayd
stopAndSwitchToRtcpclientd
getLdLibraryPathFromSrcPath
check_leftovers
check_leftovers_poll_timeout
nullize_arrays_undefs
print_leftovers
getOrastagerconfigParam
cleanup
); # Symbols to autoexport (:DEFAULT tag)
# keep track of the locally created files and of the recalled and locally rfcped files.
my @local_files;
......@@ -94,15 +95,15 @@ sub read_config ( $ )
chomp $local_host;
$environment{hostname} = $local_host;
my @per_host_vars = ( 'username', 'checkout_location', 'file_size', 'file_number', 'castor_directory',
'migration_timeout', 'poll_interval');
'migration_timeout', 'poll_interval');
my @global_vars = ( 'dbDir' , 'tstDir', 'stageUid', 'stageGid', 'adminList',
'originalDbSchema', 'originalDropSchema', 'castor_single_subdirectory',
'castor_dual_subdirectory' );
'originalDbSchema', 'originalDropSchema', 'castor_single_subdirectory',
'castor_dual_subdirectory' );
for my $i ( @per_host_vars ) {
$environment{$i}=getConfParam('TAPETEST', $i.'_'.$local_host, $config_file );
$environment{$i}=getConfParam('TAPETEST', $i.'_'.$local_host, $config_file );
}
for my $i ( @global_vars ) {
$environment{$i}=getConfParam('TAPETEST', $i, $config_file );
$environment{$i}=getConfParam('TAPETEST', $i, $config_file );
}
}
......@@ -111,16 +112,16 @@ sub check_environment ( )
{
my $pass = 0;
for my $i ( @{$environment{allowed_stagers}} ) {
if ( $environment{hostname} eq $i ) {
$pass = 1;
}
if ( $environment{hostname} eq $i ) {
$pass = 1;
}
}
if ( !$pass ) { die "Wrong host"; }
if ( ( ! -e $environment{checkout_location}.'/'.$environment{dbDir} ) ||
( ! -e $environment{checkout_location}.'/'.$environment{dbDir}.'/'.$environment{originalDbSchema} ) ||
( ! -e $environment{checkout_location}.'/'.$environment{dbDir}.'/'.$environment{originalDropSchema} ) ||
( ! -e $environment{checkout_location}.'/'.$environment{tstDir} ) ) {
die "Necessary file or directory not found";
( ! -e $environment{checkout_location}.'/'.$environment{dbDir}.'/'.$environment{originalDbSchema} ) ||
( ! -e $environment{checkout_location}.'/'.$environment{dbDir}.'/'.$environment{originalDropSchema} ) ||
( ! -e $environment{checkout_location}.'/'.$environment{tstDir} ) ) {
die "Necessary file or directory not found";
}
}
......@@ -129,15 +130,41 @@ sub get_environement ( $ )
{
my $vname = shift;
if ( defined $environment{$vname} ) {
return $environment{$vname}
return $environment{$vname}
} else {
die "Variable $vname not found in environment";
die "Variable $vname not found in environment";
}
}
# Register remote file
# keep track of a remote file that can be subsequently checked, modified,
# sabotaged (to test robustness) and eventually dropped (also automatically)
# here, we just record the name
sub register_remote ( $$ )
{
my ( $filename, $type ) = ( shift, shift );
if ( ! defined $type ) { $type = "file"; }
my %file_record = ( 'name' => $filename, 'type' => $type );
my $file_index = push @remote_files, \%file_record;
return $file_index - 1;
}
# Returns true if the file is of size zero or migrated (m bit), false otherwise
# Dies on the first problem.
sub check_migrated ( $ )
{
my $file_name = shift;
my $nsls=`nsls $file_name`;
if ($nsls=~ /^([\w-]+)\s+(\d+)\s+(\w+)\s+(\w+)\s+(\d+)/ ) {
return ('m' eq substr ($1,0,1)) || $5 = 0;
} else {
die "Failed to find file $remote_files[$file_index]";
}
}
# create a local seed file, returning the index to the file.
# Take 1 parameter: the size in
sub make_seed ( $ )
sub make_seed ( $ )
{
my $size = shift;
((defined $size) || ($size < 0)) or die "In $package_name::make_seed: size not defined";
......@@ -210,7 +237,91 @@ sub make_localfile ( $$ )
my $file_index = push @local_files, \%file_entry;
$file_index --;
return $file_index;
}
# remote files statuses:
# rfcped => migrated
# rfcp file to either single or dual copy directory and push all the
# know properties of the local file to the remote file created for the occasion
sub rfcp_localfile ( $$ )
{
my ( $local_index, $is_dual_copy ) = ( shift, shift );
my $dest = $environment{castor_directory};
if ( $is_dual_copy ) {
$dest .= $environment{castor_dual_subdirectory};
} else {
$dest .= $environment{castor_single_subdirectory};
}
my $local = $local_files[$local_index]->{name};
my $remote = $dest;
if ( $local =~ /\/[^\/]*$/ ) {
$remote .= "/".$1;
} else {
die "Wrong file path in rfcp_localfile";
}
`su $environment{username} -c \"STAGE_SVCCLASS=dev rfcp $local $remote\"`;
my %remote_entry = ( 'name' => $remote,
'type' =>
'size' => $local_files[$local_index]->{size},
'adler32' => $local_files[$local_index]->{size},
'status' => 'rfcped' );
push @remote_files, \%remote_entry;
}
# Check remote entries: check presence (should be always true) and then status of all files listed in remote files list
# returns true is any file has changed status, allowig a caller function to tiem out on "nothing moves anymore"
sub check_remote_entries ()
{
my $changed_entries = 0;
for my $i ( 0 .. scalar (@remote_files) - 1 ) {
my %entry = %{$remote_files[$i]};
# check presence
my $nslsresult=`nsls -d $entry{name} 2>&1`;
if ( $nslsresult =~ /No such file or directory$/) {
die "Entry not found in name server: $entry{name}";
}
# if it's a file, check the migration status
if ( %entry{type} eq "file" ) {
if ( %entry{status} eq "rfcpied" ) {
if ( check_migrated ( $entry{name} ) ) {
$remote_files[$i]->{status} = "migrated";
$changed_entries ++;
}
}
}
}
return $changed_entries;
}
# Get the number of non-migrated files
sub count_to_be_migrated ()
{
my $ret = 0;
for ( @remote_files ) {
if ( ($_->{type} eq "file" ) && ($_ ->{status} eq "rfcped" ) ) {
$ret++;
}
}
return $ret;
}
# Check that all the files have migrated
sub poll_moving_entries ( $$ )
{
my ( $poll_interval, $timeout ) = ( shift, shift );
my $starttime = `date +%s`;
while ( count_to_be_migrated() > 0 && ((`date +%s` - $starttime) < $timeout) ) {
if ( check_remote_entries () ) {
print "Saw at least one migration...\n";
$starttime = `date +%s`;
}
sleep ( $poll_interval );
}
if (count_to_be_migrated() == 0 ) {
return;
}
die "Timeout with ".count_to_be_migrated()." files to be migrated after $timeout s.";
}
# Returns the value of the specified ORASTAGERCONFIG parameter.
......@@ -225,14 +336,14 @@ sub getOrastagerconfigParam ( $ )
my $paramName = $_[0];
open(CONFIG, "</etc/castor/ORASTAGERCONFIG")
or die "Failed to open /etc/castor/ORASTAGERCONFIG: $!";
or die "Failed to open /etc/castor/ORASTAGERCONFIG: $!";
while(<CONFIG>) {
chomp;
if(m/^DbCnvSvc\s+$paramName\s+(\w+)/) {
close CONFIG;
return $1;
}
chomp;
if(m/^DbCnvSvc\s+$paramName\s+(\w+)/) {
close CONFIG;
return $1;
}
}
close CONFIG;
......@@ -282,14 +393,14 @@ sub getConfParam ( $ $ $ )
my $confFilename = $_[2];
open(CONFIG, $confFilename)
or die "Failed to open $confFilename: $!";
or die "Failed to open $confFilename: $!";
while(<CONFIG>) {
chomp;
if(m/^$paramCategory\s+$paramName\s+([^\s]+$)/) {
close CONFIG;
return $1;
}
chomp;
if(m/^$paramCategory\s+$paramName\s+([^\s]+$)/) {
close CONFIG;
return $1;
}
}
close CONFIG;
die("ABORT: Failed to get $confFilename parameter: category=$paramCategory, name=$paramName\n");
......@@ -366,15 +477,15 @@ sub startDaemons ()
{
# Simply start all of them, demons not needed will jsut not start.
for ('jobmanagerd',
'mighunterd',
'rechandlerd',
'rhd',
'rmmasterd',
'rtcpclientd',
'stagerd',
'tapegatewayd') {
'mighunterd',
'rechandlerd',
'rhd',
'rmmasterd',
'rtcpclientd',
'stagerd',
'tapegatewayd') {
if (/tapegatewayd/) {
my $checkout_location=$environment{checkout_location};
my $checkout_location=$environment{checkout_location};
`( cd $checkout_location; LD_LIBRARY_PATH=\`find ./ -name "*.so*" | perl -p -e \'s|[^/]*\$|\n|\' | sort | uniq | tr \"\n\" \":\" | perl -p -e \'s/:\$/\n/\'\` ./castor/tape/tapegateway/tapegatewayd)`
} else {
`service $_ start`
......@@ -783,7 +894,7 @@ sub check_leftovers ( $ )
$sth -> execute();
my @row = $sth->fetchrow_array();
if ($row[0] == 0) {
return 0;
return 0;
}
$sth = $dbh -> prepare("SELECT count (*) from (
SELECT dc.id from diskcopy dc where
......@@ -801,9 +912,9 @@ sub check_leftovers_poll_timeout ( $$$ )
my ( $dbh, $interval, $timeout ) = ( shift, shift, shift );
my $start_time = `date +%s`;
while (check_leftovers($dbh)) {
if (`date +%s`> $start_time + $timeout) {
return 1;
}
if (`date +%s`> $start_time + $timeout) {
return 1;
}
}
return 0;
}
......@@ -814,8 +925,8 @@ sub nullize_arrays_undefs ( $ )
my $row=shift;
for my $i ( 0 .. ( scalar(@{$row}) -1) ) {
if ( ! defined ($row->[$i]) ) {
$row->[$i] = 'NULL';
}
$row->[$i] = 'NULL';
}
}
}
......@@ -831,9 +942,9 @@ sub print_leftovers ( $ )
WHERE dc.status NOT IN ( 0 )");
$sth -> execute();
while ( my @row = $sth->fetchrow_array() ) {
nullize_arrays_undefs ( \@row );
print( "Remaining catorfile for $row[0]\n\twith diskcopy (id=$row[1], ".
"status=$row[2]) and tapecopy (id=$row[3], status=$row[4])\n" );
nullize_arrays_undefs ( \@row );
print( "Remaining catorfile for $row[0]\n\twith diskcopy (id=$row[1], ".
"status=$row[2]) and tapecopy (id=$row[3], status=$row[4])\n" );
}
# print any other tapecopy not covered previously
$sth = $dbh -> prepare ("SELECT cf.lastknownfilename, dc.id, dc.status, tc.id, tc.status
......@@ -843,9 +954,9 @@ sub print_leftovers ( $ )
WHERE dc.status IS NULL OR dc.status IN ( 0 )");
$sth -> execute();
while ( my @row = $sth->fetchrow_array() ) {
nullize_arrays_undefs ( \@row );
print( "Remaining tapecopy for $row[0]\n\twith diskcopy (id=$row[1], ".
"status=$row[2]) and tapecopy (id=$row[3], status=$row[4])\n" );
nullize_arrays_undefs ( \@row );
print( "Remaining tapecopy for $row[0]\n\twith diskcopy (id=$row[1], ".
"status=$row[2]) and tapecopy (id=$row[3], status=$row[4])\n" );
}
}
......@@ -856,17 +967,17 @@ sub wipeAndRecreateDefaultLxcastodev03 ()
my $uid = POSIX::getuid;
my $gid = POSIX::getgid;
if($uid != 0 || $gid !=0) {
print("ABORT: This script must be ran as root\n");
exit(-1);
print("ABORT: This script must be ran as root\n");
exit(-1);
}
# Make sure we're running on the proper machine.
my $host = `uname -n`;
if ( ! $host =~ /^lxcastordev03($|\.)/i ) {
print('ABORT: This script is only made to be run on host lxcastordev03\n');
exit -1;
print('ABORT: This script is only made to be run on host lxcastordev03\n');
exit -1;
}
# Ensure all of the daemons accessing the stager-database are dead
killDaemonWithTimeout('jobmanagerd' , 2);
killDaemonWithTimeout('mighunterd' , 2);
......@@ -880,9 +991,9 @@ sub wipeAndRecreateDefaultLxcastodev03 ()
# Ensure there is no leftover in the DB
my $dbh = open_db ();
if ( check_leftovers ( $dbh ) ) {
print_leftovers ( $dbh );
$dbh->disconnect();
die ("Found leftovers in the stager's DB. Stopping here.");
print_leftovers ( $dbh );
$dbh->disconnect();
die ("Found leftovers in the stager's DB. Stopping here.");
}
my $checkout_location = $environment{checkout_location};
......@@ -897,15 +1008,15 @@ sub wipeAndRecreateDefaultLxcastodev03 ()
if ! -e $originalDropSchemaFullpath;
die "ABORT: $originalDbSchema does not exist\n"
if ! -e $originalDbSchemaFullpath;
if ! -e $originalDbSchemaFullpath;
my $dbUser = &getOrastagerconfigParam("user");
my $dbPasswd = &getOrastagerconfigParam("passwd");
my $dbName = &getOrastagerconfigParam("dbName");
executeSQLPlusScript ( $dbUser, $dbPasswd, $dbName,
$originalDropSchemaFullpath,
"Dropping schema");
$originalDropSchemaFullpath,
"Dropping schema");
my $stageGid = $environment{stageGid};
my $stageUid = $environment{stageUid};
......@@ -921,7 +1032,7 @@ sub wipeAndRecreateDefaultLxcastodev03 ()
`sed -i s/\\&stageUid/$stageUid/g $hacked_creation`;
`sed -i s/\\&adminList/$adminList/g $hacked_creation`;
executeSQLPlusScript ( $dbUser, $dbPasswd, $dbName,
$hacked_creation, "Re-creating schema");
$hacked_creation, "Re-creating schema");
unlink $hacked_creation;
# Restart the demons
......@@ -978,17 +1089,17 @@ sub wipeAndRecreateDefaultLxcastodev04 ()
my $uid = POSIX::getuid;
my $gid = POSIX::getgid;
if($uid != 0 || $gid !=0) {
print("ABORT: This script must be ran as root\n");
exit(-1);
print("ABORT: This script must be ran as root\n");
exit(-1);
}
# Make sure we're running on the proper machine.
my $host = `uname -n`;
if ( ! $host =~ /^lxcastordev04($|\.)/i ) {
print('ABORT: This script is only made to be run on host lxcastordev04\n');
exit -1;
print('ABORT: This script is only made to be run on host lxcastordev04\n');
exit -1;
}
# Ensure all of the daemons accessing the stager-database are dead
killDaemonWithTimeout('jobmanagerd' , 2);
killDaemonWithTimeout('mighunterd' , 2);
......@@ -1002,9 +1113,9 @@ sub wipeAndRecreateDefaultLxcastodev04 ()
# Ensure there is no leftover in the DB
my $dbh = open_db ();
if ( check_leftovers ( $dbh ) ) {
print_leftovers ( $dbh );
$dbh->disconnect();
die ("Found leftovers in the stager's DB. Stopping here.");
print_leftovers ( $dbh );
$dbh->disconnect();
die ("Found leftovers in the stager's DB. Stopping here.");
}
my $checkout_location = $environment{checkout_location};
......@@ -1019,15 +1130,15 @@ sub wipeAndRecreateDefaultLxcastodev04 ()
if ! -e $originalDropSchemaFullpath;
die "ABORT: $originalDbSchema does not exist\n"
if ! -e $originalDbSchemaFullpath;
if ! -e $originalDbSchemaFullpath;
my $dbUser = &getOrastagerconfigParam("user");
my $dbPasswd = &getOrastagerconfigParam("passwd");
my $dbName = &getOrastagerconfigParam("dbName");
executeSQLPlusScript ( $dbUser, $dbPasswd, $dbName,
$originalDropSchemaFullpath,
"Dropping schema");
$originalDropSchemaFullpath,
"Dropping schema");
my $stageGid = $environment{stageGid};
my $stageUid = $environment{stageUid};
......@@ -1043,7 +1154,7 @@ sub wipeAndRecreateDefaultLxcastodev04 ()
`sed -i s/\\&stageUid/$stageUid/g $hacked_creation`;
`sed -i s/\\&adminList/$adminList/g $hacked_creation`;
executeSQLPlusScript ( $dbUser, $dbPasswd, $dbName,
$hacked_creation, "Re-creating schema");
$hacked_creation, "Re-creating schema");
unlink $hacked_creation;
# Restart the demons
......@@ -1103,7 +1214,7 @@ sub migrateToNewTapeGatewaySchema ()
}
}
my $full_test_dir=$environment{checkout_location}.'/'.
$environment{tstDir}.'/';
$environment{tstDir}.'/';
for my $i ('switchToTapegatewayd-no-triggers.sql',
'tape_gateway_refactor_to_drop_tgsubrequest_table.sql',
'tape_gateway_refactor_to_drop_tgrequest_table_and_triggers.sql',
......@@ -1173,9 +1284,16 @@ sub getLdLibraryPathFromSrcPath ( $ ) {
sub cleanup () {
print "In CastorTapeTests::cleanup: cleaning up files\n";
for (@local_files) {
print "Cleanup: removing ".$_->{name}."\n";
unlink $_->{name};
}
print "Cleanup: removing ".$_->{name}."\n";
unlink $_->{name};
}
for my $i ( scalar ( @remote_files ) - 1 .. 0 ) {
#reverse order files removal to removes directories in the end.
if ($remote_files[$i]->{type} eq "file") {
`su $environment{username} -c \"stager_rm -M $remote_files[$i]->{name}\"`;
}
`su $environment{username} -c \"nsrm $remote_files[$i]->{name}\"`;
}
}
# Final cleanup of the library.
......@@ -1183,6 +1301,11 @@ sub cleanup () {
END {
print "In CastorTapeTests::END: calling cleanup\n";
cleanup();
print "Cleanup complete. Printing leftovers.\n";
my $bdh = open_db();
print_leftovers ($dbh);
$dbh->disconnect();
print "End of leftovers\n";
}
# # create a local
1; # this should be your last line
......@@ -6,7 +6,7 @@ TAPETEST checkout_location_lxcastordev03 /var/scratch/canoc3/test_gateway_r2126
TAPETEST file_size_lxcastordev03 10485760
TAPETEST file_number_lxcastordev03 10
TAPETEST castor_directory_lxcastordev03 /castor/cern.ch/dev/c/canoc3/
TAPETEST migration_timeout_lxcastordev03 60
TAPETEST migration_timeout_lxcastordev03 600
TAPETEST poll_interval_lxcastordev03 5
TAPETEST username_lxcastordev04 murrayc3
......@@ -14,7 +14,7 @@ TAPETEST checkout_location_lxcastordev04 /var/some_checkout
TAPETEST file_size_lxcastordev04 10485760
TAPETEST file_number_lxcastordev04 10
TAPETEST castor_directory_lxcastordev04 /castor/cern.ch/dev/c/murrayc3/
TAPETEST migration_timeout_lxcastordev04 60
TAPETEST migration_timeout_lxcastordev04 600
TAPETEST poll_interval_lxcastordev04 5
......
......@@ -68,22 +68,22 @@ sub main ()
my $dbh = CastorTapeTests::open_db();
my $ret = 0;
if (CastorTapeTests::check_leftovers ( $dbh )) {
my $userless; # workaround to prevent emacs from fscking the indentation.
my $userless; # workaround to prevent emacs from fscking the indentation.
CastorTapeTests::print_leftovers ( $dbh );
$dbh->disconnect();
exit 1;
$dbh->disconnect();
exit 1;
}
$dbh->disconnect();
# Nuke and start clean
my $host = `hostname -s`; chomp $host;
if ( $host eq 'lxcastordev03' ) {
my $u;
CastorTapeTests::wipeAndRecreateDefaultLxcastodev03();
CastorTapeTests::wipeAndRecreateDefaultLxcastodev03();
} elsif ( $host eq 'lxcastordev04' ) {
my $u;
CastorTapeTests::wipeAndRecreateDefaultLxcastodev04();
my $u;
CastorTapeTests::wipeAndRecreateDefaultLxcastodev04();
} else {
die "Unexpected host.";
die "Unexpected host.";
}
my $seed_index = CastorTapeTests::make_seed ($file_size);
......@@ -98,8 +98,10 @@ sub main ()
# Re-create the directories:
print `su $username -c "nsmkdir $castor_directory$single_subdir"`;
print `su $username -c "nschclass largeuser $castor_directory$single_subdir"`;
CastorTapeTests::register_remote (