diff options
Diffstat (limited to 'ACE/bin/PerlACE/ProcessAndroid.pm')
-rw-r--r-- | ACE/bin/PerlACE/ProcessAndroid.pm | 426 |
1 files changed, 426 insertions, 0 deletions
diff --git a/ACE/bin/PerlACE/ProcessAndroid.pm b/ACE/bin/PerlACE/ProcessAndroid.pm new file mode 100644 index 00000000000..e710041ca1d --- /dev/null +++ b/ACE/bin/PerlACE/ProcessAndroid.pm @@ -0,0 +1,426 @@ +#! /usr/bin/perl +# $Id$ + +package PerlACE::ProcessAndroid; + +use POSIX "sys_wait_h"; +use File::Basename; +use File::Spec; +use FileHandle; +use Cwd; + +use strict; + +sub new +{ + my $proto = shift; + my $class = ref ($proto) || $proto; + my $self = {}; + + $self->{RUNNING} = 0; + $self->{IGNOREEXESUBDIR} = 1; + $self->{IGNOREHOSTROOT} = 0; + $self->{PROCESS} = undef; + $self->{EXECUTABLE} = shift; + + # Only set argument when they are really supplied via the + # CreateProcess call. If the weren't supplied, an error like + # Process_Android::HASH (0x...) is generated. + if (@_ == 2) { + $self->{ARGUMENTS} = shift; + } + else { + $self->{ARGUMENTS} = ""; + } + $self->{FSROOT} = $ENV{'ANDROID_FS_ROOT'}; + + bless ($self, $class); + + # copy the test executable to the target at forehand + $self->copy_executable (); + + return $self; +} + +sub Arguments +{ + my $self = shift; + + if (@_ != 0) { + $self->{ARGUMENTS} = shift; + } + + return $self->{ARGUMENTS}; +} + +sub Executable +{ + my $self = shift; + + if (@_ != 0) { + $self->{EXECUTABLE} = shift; + } + + my $executable = $self->{EXECUTABLE}; + + # If the target's config has a different ACE_ROOT, rebase the executable + # from $ACE_ROOT to the target's root. + if (defined $self->{TARGET} && + $self->{TARGET}->ACE_ROOT() ne $ENV{'ACE_ROOT'}) { + $executable = PerlACE::rebase_path ($executable, + $ENV{'ACE_ROOT'}, + $self->{TARGET}->ACE_ROOT()); + } + + if ($self->{IGNOREHOSTROOT} == 0) { + if (PerlACE::is_vxworks_test()) { + $executable = PerlACE::VX_HostFile ($executable); + } + } + + if ($self->{IGNOREEXESUBDIR}) { + return $executable; + } + + my $basename = basename ($executable); + my $dirname = dirname ($executable).'/'; + + my $subdir = $PerlACE::Process::ExeSubDir; + if (defined $self->{TARGET} && defined $self->{TARGET}->{EXE_SUBDIR}) { + $subdir = $self->{TARGET}->{EXE_SUBDIR}; + } + + $executable = $dirname . $subdir . $basename; + + return $executable; +} + +sub Wait ($) +{ + my $self = shift; + my $timeout = shift; + if (!defined $timeout || $timeout < 0) { + waitpid ($self->{PROCESS}, 0); + } else { + return TimedWait($self, $timeout); + } +} + +sub TimedWait ($) +{ + my $self = shift; + my $timeout = shift; + + if ($PerlACE::Process::WAIT_DELAY_FACTOR > 0) { + $timeout *= $PerlACE::Process::WAIT_DELAY_FACTOR; + } + + if (defined $ENV{'ACE_TEST_VERBOSE'} && $self->{PROCESS} > 0) { + print STDERR "Wait $timeout to finish executable $self->{PROCESS}. "; + print STDERR "RUNNING: $self->{RUNNING}\n"; + } + while ($timeout-- != 0 && $self->{PROCESS} > 0 && $self->{RUNNING} == 1) { + my $pid = waitpid ($self->{PROCESS}, WNOHANG); + if ($pid == $self->{PROCESS}) { + if (defined $ENV{'ACE_TEST_VERBOSE'}) { + print STDERR "Wait for process <$self->{PROCESS}> ended. $timeout seconds left.\n"; + } + return 0; + } + sleep 1; + } + + if (defined $ENV{'ACE_TEST_VERBOSE'}) { + print STDERR "Exit TimedWait with Process: $self->{PROCESS}, Running: $self->{RUNNING}\n"; + } + if ($self->{PROCESS} == 0 || $self->{RUNNING} == 0) { + return 0; + } + return -1; +} + +sub Kill () +{ + my $self = shift; + + if ($self->{RUNNING} == 1) { + if (defined $ENV{'ACE_TEST_VERBOSE'}) { + print STDERR "Killing process <$self->{PROCESS}>\n"; + } + # killing the adb process, not the actual test executable. + kill (1, $self->{PROCESS}); + + my $pid = waitpid ($self->{PROCESS}, WNOHANG); + if ($pid == -1) { + if (defined $ENV{'ACE_TEST_VERBOSE'}) { + print STDERR "Process <$self->{PROCESS}> already ended\n"; + } + } + elsif ($pid == $self->{PROCESS}) { + if (defined $ENV{'ACE_TEST_VERBOSE'}) { + print STDERR "Process <$self->{PROCESS}> ended\n"; + } + } + } + + $self->{RUNNING} = 0; +} + +sub WaitKill ($) +{ + my $self = shift; + my $timeout = shift; + + my $pid = waitpid ($self->{PROCESS}, WNOHANG); + if ($pid == $self->{PROCESS}) { + $self->{RUNNING} = 0; + } + + if ($self->{RUNNING} == 0) { + return 0; + } + + my $status = $self->TimedWait ($timeout); + + if ($status == -1) { + print STDERR "ERROR: $self->{EXECUTABLE} timedout\n"; + $self->Kill (); + } + + $self->{RUNNING} = 0; + + return $status; +} + + +# Do a Spawn and immediately WaitKill +# +sub SpawnWaitKill ($) +{ + my $self = shift; + my $timeout = shift; + + if ($self->Spawn () == -1) { + return -1; + } + my $result = 0; + + if ($self->{RUNNING} == 1) { + $result = $self->WaitKill ($timeout); + } + + return $result; +} + +sub TerminateWaitKill ($) +{ + my $self = shift; + my $timeout = shift; + + if ($self->{RUNNING}) { + print STDERR "INFO: $self->{EXECUTABLE} being killed.\n"; + kill ('TERM', $self->{PROCESS}); + } + + return $self->WaitKill ($timeout); +} + +sub IgnoreExeSubDir +{ + my $self = shift; + + if (@_ != 0) { + $self->{IGNOREEXESUBDIR} = shift; + } + + return $self->{IGNOREEXESUBDIR}; +} + +sub IgnoreHostRoot +{ + my $self = shift; + + if (@_ != 0) { + $self->{IGNOREHOSTROOT} = shift; + } + + return $self->{IGNOREHOSTROOT}; +} + +sub Spawn () +{ + my $self = shift; + + if ($self->{RUNNING} == 1) { + print STDERR "ERROR: Cannot Spawn: <", $self->Executable (), + "> already running\n"; + return -1; + } + + if (!defined $self->{EXECUTABLE}) { + print STDERR "ERROR: Cannot Spawn: No executable specified\n"; + return -1; + } + + if ($self->{IGNOREEXESUBDIR} == 0) { + if (!-f $self->Executable ()) { + print STDERR "ERROR: Cannot Spawn: <", $self->Executable (), + "> not found\n"; + return -1; + } + } + my $status = 0; + + my $fsroot_target = $ENV{'ANDROID_FS_ROOT'}; + my $exe = $self->Executable (); + my $program = "$fsroot_target/$exe"; + + my($test, $dir, $suffix) = fileparse($program); + + my $adb_process = $ENV{'ANDROID_SDK_ROOT'} . "/platform-tools/adb"; + my $cmd = $adb_process . ' shell "cd ' . $dir . ' && LD_LIBRARY_PATH=' . $fsroot_target . '/lib:$LD_LIBRARY_PATH ./' . $test . ' ' . $self->{ARGUMENTS} . '"'; + + FORK: { + if ($self->{PROCESS} = fork) { + bless $self; + } + elsif (defined $self->{PROCESS}) { + $self->{RUNNING} = 1; + + if (defined $ENV{'ACE_TEST_VERBOSE'}) { + print STDERR "Start to execute: $cmd\n"; + } + exec ( $cmd ); + exit; + } + elsif ($! =~ /No more process/) { + sleep 5; + redo FORK; + } + else { + print STDERR "ERROR: Can't fork <" . $cmd . ">: $!\n"; + } + } + + if (defined $ENV{'ACE_TEST_VERBOSE'}) { + print STDERR "Forked process started with ID <$self->{PROCESS}>\n"; + } + $self->{RUNNING} = 1; + + return 0; +} + +sub copy_executable () +{ + my $self = shift; + + my $fsroot_target = $ENV{'ANDROID_FS_ROOT'}; + my $program = $self->Executable (); + my $exe = "$fsroot_target/$program"; + + $self->PutFile ("$program", $exe); + + if ($PerlACE::Static == 0) { + my $vxtest_file = "$ENV{'ACE_ROOT'}/$program" . '.vxtest'; + if (defined $ENV{'ACE_TEST_VERBOSE'}) { + print STDERR "Analyzing vxtest file <$vxtest_file>\n"; + } + copy_vxtest_files ($self, $vxtest_file); + } +} + +sub copy_vxtest_files () +{ + my $self = shift; + my $vxtestfile = shift; + my $fh = new FileHandle; + + if (defined $ENV{'ACE_TEST_VERBOSE'}) { + print STDERR "Analyzing vxtest file <$vxtestfile>\n"; + } + + if (open ($fh, $vxtestfile)) { + my $line1 = <$fh>; + chomp $line1; + if (defined $ENV{'ACE_TEST_VERBOSE'}) { + print STDERR "Analyzing vxtest file: Found line $line1\n"; + } + while(<$fh>) { + $line1 = $_; + chomp $line1; + if (defined $ENV{'ACE_TEST_VERBOSE'}) { + print STDERR "Analyzing vxtest file: Found line $line1\n"; + } + + $self->copy_library ($line1); + } + } + close $fh; +} + +sub copy_library () +{ + my $self = shift; + my $name = shift; + + my $cdir = getcwd (); + + chdir ("$ENV{'ACE_ROOT'}/lib"); + + my $query = "lib$name.so"; + if (-e $query) { + # MSM: Using exclude wildcards, like !(b*) + if (defined $ENV{'ACE_TEST_VERBOSE'}) { + print STDERR "Found $name in library directory\n"; + } + my @files = glob ($query . '*'); + foreach my $file (@files) { + $self->PutFile ($file, "$self->{FSROOT}/lib/$file"); + } + } + else { + chdir ("$ENV{'ACE_ROOT'}/tests"); + + if (-e $query) { + if (defined $ENV{'ACE_TEST_VERBOSE'}) { + print STDERR "Found $name in tests directory\n"; + } + + my @files = glob ($query . '*'); + foreach my $file (@files) { + $self->PutFile ($file, "$self->{FSROOT}/lib/$file"); + } + } + } + chdir ("$cdir"); +} + + +sub PutFile ($) +{ + my $self = shift; + my $src = shift; + my $dest = shift; + + my $silent; + + if (!defined $ENV{'ACE_TEST_VERBOSE'}) { + $silent = "2> /dev/null" + } + + my $adb_process = $ENV{'ANDROID_SDK_ROOT'} . "/platform-tools/adb"; + + my $cmd = "$adb_process" . ' push '. "$src $dest $silent"; + + if (defined $ENV{'ACE_TEST_VERBOSE'}) { + print STDERR "PutFile cmd: $cmd\n"; + } + + system ( $cmd ); + if ($? != 0) { + return -1; + } + return 0; +} + +1; |