# crashdctestlib.pm
#
# My copyright
package crashdctestlib;

require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(	$verbose_test
		%vm_name %login_prompt 
		prompt_timeout 
		validate_version
		start_vm
		revert_snapshot
		prepare_for_test
		crash_vm
		reboot_vm
		check_service
		wait_for_prompt
		switch_grub
		);

use Socket;
use vars @EXPORT;

#
# SIGALRM handler for wait_for_prompt
#
sub prompt_timeout {
   $verbose_test && print" Just caught a SIGALRM\n";
   shutdown(SOCK,0); 
#   close(SOCK);
   }

#
# validate_version
#
sub validate_version {
$server=@_[0];

if (! exists $vm_name{$server} ) {
	print "wait_for_prompt : $server Does not exists\n";
	return undef;
	}
   "1";
   }
#
# Start a VM
#
sub start_vm {
   my $vm=@_[0];
   my $errno=0;


   $verbose_test && print "/usr/bin/vmrun -T ws start /work/VM/$vm_name{$vm}/$vm_name{$vm}.vmx\n";
   system "/usr/bin/vmrun -T ws start /work/VM/$vm_name{$vm}/$vm_name{$vm}.vmx\n";
   $errno=$?;

   if ( $errno ) {
      $errno = $errno >> 8;

      print "Unable to start vm at /work/VM/$vm_name{$vm}/$vm_name{$vm}.vmx :  $errno \n";
      return $errno;
      }
   "1";
   }
#
# Revert VM to snapshot
#
sub revert_snapshot {
   my $vm=@_[0];
   my $errno=0;


   $verbose_test && print "/usr/bin/vmrun -T ws revertToSnapshot /work/VM/$vm_name{$vm}/$vm_name{$vm}.vmx \"Ready for Tests\"\n";
   system "/usr/bin/vmrun -T ws revertToSnapshot /work/VM/$vm_name{$vm}/$vm_name{$vm}.vmx \"Ready for Tests\"\n";
   $errno=$?;

   if ( $errno ) {
      $errno = $errno >> 8;

      print "Unable to revert vm $vm_name{$vm} to snapshot \"Ready for Tests\" :  $errno \n";
      return $errno;
      }
   "1";
   }

#
# Prepare the VM for tests
#
sub prepare_for_test {
   $version=@_[0];
   $testfile="prepare_test_".$version;
   $errno=0;


   if (! stat($testfile) ) {
      print "prepare_test_$version does not exist\n";
      return undef;
      }

   $verbose_test && print "Preparing for $version tests on $vm_name{$version}...\n";

   $verbose_test && print "/usr/bin/scp $testfile root\@$vm_name{$version}:/root\n";
   system "/usr/bin/scp $testfile root\@$vm_name{$version}:/root";
   $errno=$?;

   if ( $errno ) {
      return undef;
      }

   $verbose_test && print "/usr/bin/ssh root\@$vm_name{$version} /root/$testfile\n";
   system "/usr/bin/ssh root\@$vm_name{$version} /root/$testfile";
   $errno=$?;

   if ( $errno ) {
      return undef;
      }
   "1";
   }
#
# crash VM
#
sub crash_vm {
   $version=@_[0];
   $errno=0;


   $verbose_test && print "Forcing crash for $version tests on $vm_name{$version}...\n";

   $verbose_test && print "/usr/bin/ssh root\@$vm_name{$version} \"echo c \> /proc/sysrq-trigger\" \> /dev/null 2\>\&1 \&\n";
   system "/usr/bin/ssh root\@$vm_name{$version} \"echo c \> /proc/sysrq-trigger\" \> /dev/null 2\>\&1 \&";
   $errno=$?;
   $verbose_test && print "Sleeping for 30 secs\n";
   sleep 15;

   if ( $errno ) {
      return undef;
      }
   "1";
   }
#
# reboot VM
#
sub reboot_vm {
   $version=@_[0];
   $errno=0;


   $verbose_test && print "rebooting $vm_name{$version}...\n";

   $verbose_test && print "/usr/bin/ssh root\@$vm_name{$version} reboot\n";
   system "/usr/bin/ssh root\@$vm_name{$version} reboot\n";
   $errno=$?;
   sleep 15;

   if ( $errno ) {
      return undef;
      }
   "1";
   }
#
# check service
#
sub check_service {
   $version=@_[0];
   $action=@_[1];
   @valid_action=qw(status generate advanced custom);
   $errno=0;


   @action=grep(/$action/,@valid_action);
   if (! @action ) {
      print "Invalid action\n";
      return undef;
      }
   $action=$action[0];

   if ( $action eq "status" ) {
      $verbose_test && print "status\n";
      $result=qx(/usr/bin/ssh root\@$vm_name{$version} service crashdc $action);
      $errno=$?;
      } elsif ( $action eq "generate" ) {
      $verbose_test && print "generate\n";
      $result=qx(/usr/bin/ssh root\@$vm_name{$version} service crashdc $action);
      $errno=$?;
      } elsif ( $action eq "advanced" ) {
      $verbose_test && print "generate advanced\n";
      $result=qx(/usr/bin/ssh root\@$vm_name{$version} service crashdc generate $action);
      $errno=$?;
      } elsif ( $action eq "custom" ) {
      $verbose_test && print "generate custom\n";
      $result=qx(/usr/bin/ssh root\@$vm_name{$version} service crashdc generate $action /tmp/toto);
      $errno=$?;
      }

   if ( $errno ) {
      return undef;
      }
   $result;
   }

#
# Wait for a prompt, indicating that VM is online & available
#
sub wait_for_prompt {

my $server=@_[0];
my $timeout=@_[1];

$SIG{ALRM} = \&prompt_timeout;


if ( $timeout ) {
   alarm $timeout;
   }

my ($virtual_console,$input,$console_file);

$virtual_console="/work/VM/$vm_name{$server}/vmconsole";

if (! socket(SOCK, PF_UNIX, SOCK_STREAM, 0)) {
   print "wait_for_prompt : socket $virtual_console : $!\n";
   return undef;
   }

if (! connect(SOCK,sockaddr_un($virtual_console))) {
   print "wait_for_prompt : connect $virtual_console : $!\n";
   return undef;
   }

while ( $input = <SOCK> ) {
   chomp $input;
      $verbose_test && print "INPUT : $input\n";
   if ( $input =~ /$login_prompt{$server}/ ) {
      alarm 0;
      shutdown(SOCK,0);
      close(SOCK);
      $gotprompt=1;
      }
   }
   if (! $gotprompt ) {
      return undef;
      }
"1"
}

sub switch_grub {
   $version=@_[0];
   $type=@_[1];
   $errno=0;
   @valid_types=qw(smp xen bigsmp vmipae vmi pae xen xenpae default);

   @type=grep(/^$type$/,@valid_types);
   if (! @type ) {
      print "Invalid type\n";
      return undef;
      }
   $type=$type[0];

   if ( $version eq "rhel5" ) {
      print "rhel5\n";
      if ( $type eq "xen" ) {
	 print "xen\n";
         $result=qx(/usr/bin/ssh root\@$vm_name{$version} "mv /boot/grub/grub.conf /boot/grub/grub.conf.smp;sed 's/^default=2/default=1/' /boot/grub/grub.conf.smp > /boot/grub/grub.conf");
	 $errno=$?;
         } elsif ( $type eq "pae" ) {
	 print "pae\n";
         $result=qx(/usr/bin/ssh root\@$vm_name{$version} "mv /boot/grub/grub.conf /boot/grub/grub.conf.xen;sed 's/^default=1/default=0/' /boot/grub/grub.conf.xen > /boot/grub/grub.conf");
	 $errno=$?;
	 } else {
	 print "invalid type\n";
	 return undef;
	 }
      if ( $errno ) {
         return undef;
         }
      } elsif ( $ version eq "rhel5x" ) {
      print "rhel5x\n";
      if ( $type eq "xen" ) {
	 print "xen\n";
         $result=qx(/usr/bin/ssh root\@$vm_name{$version} "mv /boot/grub/grub.conf /boot/grub/grub.conf.smp;sed 's/^default=1/default=0/' /boot/grub/grub.conf.smp > /boot/grub/grub.conf");
	 } else {
	 print "invalid type\n";
	 return undef;
	 }
      } elsif ( $ version eq "sles10" ) {
      print "sles10\n";
      if ( $type eq "bigsmp" ) {
         print "bigsmp\n";
	 } elsif ( $type eq "vmipae" ) {
	 print "vmipae\n";
	 } elsif ( $type eq "vmi" ) {
	 print "vmi\n";
	 } elsif ( $type eq "xenpae" ) {
	 print "xenpae\n";
	 } elsif ( $type eq "xen" ) {
	 print "xen\n";
	 } elsif ( $type eq "default" ) {
	 print "default\n";
	 } else {
	 print "invalid type\n";
	 return undef;
	 }
      } elsif ( $ version eq "sles10x" ) {
      print "sles10x\n";
      } elsif ( $ version eq "sles11" ) {
      print "sles11\n";
      } elsif ( $ version eq "sles11x" ) {
      print "sles11x\n";
      }
   "1";
   }

%login_prompt = (
	rhel5	=> 'Red Hat Enterprise Linux Server release 5',
	rhel5x	=> 'Red Hat Enterprise Linux Server release 5',
	sles10	=> 'Welcome to SUSE Linux Enterprise Server 10',
	sles10x	=> 'Welcome to SUSE Linux Enterprise Server 10',
	sles11	=> 'crashdcSLES11',
	sles11x	=> 'crashdcSLES11x');

%vm_name = (
	rhel5	=> 'crashdc',
	rhel5x	=> 'crashdcx',
	sles10	=> 'crashdcSLES10',
	sles10x	=> 'crashdcSLES10x',
	sles11	=> 'crashdcSLES11',
	sles11x	=> 'crashdcSLES11x');



1;

__END__

