Perl shebang portability changes
[ACE_TAO.git] / ACE / bin / PerlACE / TestTarget_Android.pm
blob3c9ed08d59c67e3053f6d55a8c757131fe1ca672
1 #!/usr/bin/env perl
2 package PerlACE::TestTarget_Android;
4 # ******************************************************************
5 # Description : Creates a PerlACE::Android
6 # Author : Marcel Smit
7 # Create Date : 29/20/2008
8 # ******************************************************************
10 # ******************************************************************
11 # Pragma Section
12 # ******************************************************************
14 use strict;
16 use PerlACE::TestTarget;
17 use PerlACE::ProcessVX;
18 use File::Copy;
19 use File::Glob;
20 use File::Spec;
21 use File::Basename;
22 use Cwd;
23 use English;
25 use POSIX "sys_wait_h";
26 require PerlACE::ProcessAndroid;
28 our @ISA = qw(PerlACE::TestTarget);
30 $PerlACE::TestTarget_Android::EMULATOR_RUNNING = 0;
31 $PerlACE::TestTarget_Android::LIBS = ();
33 sub new
35 my $proto = shift;
36 my $config_name = shift;
37 my $component = shift;
39 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
40 print STDERR "New Android target: $config_name : $component\n";
43 my $class = ref ($proto) || $proto;
44 my $self = {};
45 bless ($self, $class);
47 $self->GetConfigSettings($config_name);
48 $self->{FSROOT} = $ENV{'ANDROID_FS_ROOT'};
49 $self->{PROCESS} = undef;
50 $self->{RUNNING} = 0;
52 # Start the target.
53 if ($PerlACE::TestTarget_Android::EMULATOR_RUNNING == 0) {
54 $self->start_target ();
57 return $self;
60 sub DESTROY
62 my $self = shift;
63 if ($self->{RUNNING} == 1) {
64 # kill the emulator. No need to shutdown gracefully.
65 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
66 print STDERR "Killing the Android emulator\n";
68 $self->KillAll ('emulator*');
69 $self->KillAll ('adb');
70 $PerlACE::TestTarget_Android::EMULATOR_RUNNING = 0;
71 $PerlACE::TestTarget_Android::LIBS = ();
75 # ******************************************************************
76 # Subroutine Section
77 # ******************************************************************
79 sub LocalFile
81 my $self = shift;
82 my $file = shift;
84 my $newfile = $self->{FSROOT} . "/" . $file;
85 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
86 print STDERR "Android LocalFile for $file is $newfile\n";
88 return $newfile;
91 sub AddLibPath ($)
93 my $self = shift;
94 my $dir = shift;
95 my $noarch = shift;
97 # If we have -Config ARCH, use the -ExeSubDir setting as a sub-directory
98 # of the lib path. This is in addition to the regular LibPath.
99 if (!$noarch && defined $self->{ARCH}) {
100 $self->AddLibPath($dir, 1);
101 $dir .= '/' . $self->{EXE_SUBDIR};
104 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
105 print STDERR "Adding libpath $dir\n";
107 $self->{LIBPATH} = PerlACE::concat_path ($self->{LIBPATH}, $dir);
110 sub CreateProcess
112 my $self = shift;
113 my $process = new PerlACE::ProcessAndroid ($self, @_);
114 return $process;
117 sub NeedReboot ($)
119 my $self = shift;
120 $self->{REBOOT_NEEDED} = 1;
123 # Reboot target
124 sub RebootNow ($)
126 my $self = shift;
127 $self->{REBOOT_NEEDED} = undef;
128 print STDERR "Attempting to reboot target...\n";
129 $self->reboot ();
132 sub start_target ()
134 # For now, we're assuming one target (avd) is running in the test environment.
135 # Need to change this when more than one avd's need to start
136 my $self = shift;
137 my $silent;
139 if (!defined $ENV{'ACE_TEST_VERBOSE'}) {
140 $silent = "2> /dev/null"
143 if (! defined ($ENV{'ANDROID_SDK_ROOT'})) {
144 print STDERR "Error: Android SDK root not defined.\n";
145 return 0;
147 if (! defined ($ENV{'ANDROID_AVD_NAME'})) {
148 print STDERR "Error: Android AVD name not defined.\n";
149 return 0;
151 my $avd_name = $ENV{'ANDROID_AVD_NAME'};
152 my $android_process = $ENV{'ANDROID_SDK_ROOT'} . "/tools/android";
153 my $avd_process = $ENV{'ANDROID_SDK_ROOT'} . "/tools/emulator";
154 my $adb_process = $ENV{'ANDROID_SDK_ROOT'} . "/platform-tools/adb";
155 my $user_data_image = $ENV{'ANDROID_SDK_HOME'} . "/.android/avd/" . $avd_name . ".avd/userdata-qemu.img";
157 my $avd_options = "-noaudio -no-window -wipe-data";
159 if (defined ($ENV{'ANDROID_AVD_OPTIONS'})) {
160 print STDERR "Resetting AVD options\n";
161 $avd_options = $ENV{'ANDROID_AVD_OPTIONS'};
164 $self->KillAll ("emulator*");
166 FORK: {
167 if ($self->{PROCESS} = fork) {
168 #parent here
169 bless $self;
171 elsif (defined $self->{PROCESS}) {
172 #child here
173 my $user_image_cmd = "rm -f " . $user_data_image;
174 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
175 print STDERR "Removing user data image: $user_image_cmd\n";
178 system ( $user_image_cmd );
179 if ($? != 0) {
180 print STDERR "failed to execute: $!\n";
183 my $avd_cmd = "$avd_process" .' -avd ' . "$avd_name $avd_options";
184 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
185 print STDERR "Starting emulator cmd: $avd_cmd\n";
188 system ( $avd_cmd );
189 if ($? != 0) {
190 print STDERR "failed to execute: $!\n";
192 exit;
194 elsif ($! =~ /No more process/) {
195 #EAGAIN, supposedly recoverable fork error
196 sleep 5;
197 redo FORK;
199 else {
200 # weird fork error
201 print STDERR "ERROR: Can't fork <" . $avd_process . ">: $!\n";
205 eval {
206 my $timeout = $self->AdbWaitForDeviceTimeout ();
208 local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
209 alarm $timeout;
210 # start the waiting...
211 my $wait_cmd = $adb_process . ' wait-for-device';
212 system ( $wait_cmd );
213 # reset alarm
214 alarm 0;
217 if ($@) {
218 # timed out
219 exit unless $@ eq "alarm\n"; # propagate unexpected errors
221 else {
222 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
223 print STDERR "Emulator is running <$self->{PROCESS}> -> start the tests.\n";
228 # AVD is up and running and ready to spawn executables.
229 # First some preparation.
230 my $cmd = $adb_process . ' shell "mkdir ' . $self->{FSROOT} . '/tmp "' . $silent;
231 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
232 print STDERR "Start to execute : $cmd\n";
234 system ( $cmd );
236 $self->{RUNNING} = 1;
237 $PerlACE::TestTarget_Android::EMULATOR_RUNNING = 1;
238 return 0;
241 sub WaitForFileTimed ($)
243 my $self = shift;
244 my $file = shift;
245 my $timeout = shift;
246 my $silent;
248 if (!defined $ENV{'ACE_TEST_VERBOSE'}) {
249 $silent = ' > /dev/null 2>&1';
252 if ($PerlACE::Process::WAIT_DELAY_FACTOR > 0) {
253 $timeout *= $PerlACE::Process::WAIT_DELAY_FACTOR;
256 my $newfile = $self->LocalFile ($file);
257 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
258 print STDERR "Android waits $timeout seconds for $newfile\n";
261 # Since the file is available on the target (which we cannot reach),
262 # we will try to pull the file from the target to a local directory.
263 # If succeed, the the file is there an we can continue.
264 my $adb_process = $ENV{'ANDROID_SDK_ROOT'} . "/platform-tools/adb";
265 my $fsroot_target = $self->{FSROOT};
267 my $cmd_copy_ior = $adb_process . ' pull ' . $newfile . ' ' .
268 File::Spec->tmpdir() . '/' .
269 basename ($newfile) . $silent;
271 while ($timeout-- != 0) {
272 # copy the ior back to the host sytem
273 if (system ( $cmd_copy_ior ) == 0) {
274 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
275 print STDERR "Pull $newfile succeeded\n";
277 return 0;
279 sleep (1);
281 return -1;
284 sub DeleteFile ($)
286 my $self = shift;
287 my $file = shift;
288 my $adb_process = $ENV{'ANDROID_SDK_ROOT'} . "/platform-tools/adb";
289 my $silent;
291 if (!defined $ENV{'ACE_TEST_VERBOSE'}) {
292 $silent = ' > /dev/null 2>&1';
295 my $targetfile = $self->LocalFile ($file);
296 my $cmd = "$adb_process" . ' shell rm '. "$targetfile" . $silent;
298 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
299 print STDERR "DeleteFile cmd: $cmd\n";
302 system ( $cmd );
303 if ($? != 0) {
304 return -1;
306 return 0;
309 sub Kill ()
311 my $self = shift;
313 if ($self->{RUNNING} == 1) {
314 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
315 print STDERR "Killing emulator process <$self->{PROCESS}>\n";
318 my $cnt = kill (1, $self->{PROCESS});
320 waitpid ($self->{PROCESS}, WNOHANG);
321 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
322 print STDERR "Killed $cnt process(es)\n";
324 # $self->check_return_value ($?);
327 $self->{RUNNING} = 0;
330 sub KillAll ($)
332 my $self = shift;
333 my $procmask = shift;
334 if ($OSNAME eq 'MSWin32') {
335 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
336 print STDERR "Killall not implemented for Windows\n";
337 return;
340 else {
341 my $cmd_killall = "killall -q -r $procmask";
342 system ( $cmd_killall );
346 sub PutFile ($)
348 my $self = shift;
349 my $src = shift;
350 my $silent;
352 if (!defined $ENV{'ACE_TEST_VERBOSE'}) {
353 $silent = "2> /dev/null"
356 my $adb_process = $ENV{'ANDROID_SDK_ROOT'} . "/platform-tools/adb";
358 my $targetfile = $self->LocalFile ($src);
359 my $cmd = "$adb_process" . ' push '. "\"$src\" \"$targetfile\" $silent";
361 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
362 print STDERR "PutFile cmd: $cmd\n";
365 system ( $cmd );
366 if ($? != 0) {
367 return -1;
369 return 0;
372 sub GetFile ($)
374 my $self = shift;
375 my $remote_file = shift;
376 my $local_file = shift;
377 my $silent;
379 if (!defined $ENV{'ACE_TEST_VERBOSE'}) {
380 $silent = "2> /dev/null"
383 my $adb_process = $ENV{'ANDROID_SDK_ROOT'} . "/platform-tools/adb";
385 if (!defined $local_file) {
386 $local_file = $remote_file;
388 $remote_file = $self->LocalFile($remote_file);
389 my $cmd = "$adb_process" . ' pull '. "$remote_file $local_file $silent";
391 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
392 print STDERR "GetFile cmd: $cmd\n";
395 system ( $cmd );
396 if ($? != 0) {
397 return -1;
399 return 0;
402 sub PutLib ($)
404 my $self = shift;
405 my $newlib = shift;
406 my $tgtlib = shift;
407 my $silent;
409 if (!defined $ENV{'ACE_TEST_VERBOSE'}) {
410 $silent = "2> /dev/null"
413 foreach my $lib (@{$PerlACE::TestTarget_Android::LIBS}) {
414 if ($lib eq $newlib) {
415 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
416 print STDERR "Duplicate lib $newlib\n";
418 return 0;
422 my $adb_process = $ENV{'ANDROID_SDK_ROOT'} . "/platform-tools/adb";
424 my $cmd = "$adb_process" . ' push '. "\"$newlib\" \"$tgtlib\" $silent";
426 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
427 print STDERR "PutLib cmd: $cmd\n";
430 system ( $cmd );
431 if ($? != 0) {
432 return -1;
435 # keep tabs on copied libs
436 push(@{$PerlACE::TestTarget_Android::LIBS}, $newlib);
438 return 0;