Home | History | Annotate | Download | only in dejagnu
      1 #
      2 # Initialize the board. The function is executed before any test.
      3 #
      4 proc __boardname___init { board } {
      5   set hostname [board_info $board hostname]
      6   set timeout [board_info $board timeout]
      7   set ssh_options [board_info $board ssh,options]
      8   set runtimes [board_info $board runtimes]
      9   set tmpdir [board_info $board tmpdir]
     10   verbose -log "Opening persistent connection ..." 1
     11   eval "exec ssh -N -f $ssh_options root@$hostname &"
     12   local_exec "ssh -n $ssh_options root@$hostname sh -c 'mkdir -p $tmpdir'" \
     13     {} {}  $timeout
     14 }
     15 
     16 #
     17 # Remove test run by-products. The function is executed at DejaGNU exit.
     18 #
     19 proc __boardname___exit {} {
     20   set board "__boardname__"
     21   set hostname [board_info $board hostname]
     22   set ssh_options [board_info $board ssh,options]
     23   set tmpdir [board_info $board tmpdir]
     24   verbose -log "Closing persistent connection ..." 1
     25   local_exec "ssh $ssh_options -O exit root@$hostname" {} {} 10
     26   verbose -log "Cleaning up - executing on board 'rm -fr $tmpdir' ..." 1
     27   local_exec "ssh -n $ssh_options root@$hostname sh -c 'rm -fr $tmpdir'" \
     28     {} {} 10
     29 }
     30 
     31 #
     32 # Upload a file to the board. Uses scp over persistent SSH connection.
     33 #
     34 proc __boardname___download { board file args } {
     35   set hostname [board_info $board hostname]
     36   set tmpdir [board_info $board tmpdir]
     37   set timeout [board_info $board timeout]
     38   set ssh_options [board_info $board ssh,options]
     39   set destfile [lindex [file split $file] end]
     40   verbose -log "scp -q $ssh_options $file root@$hostname:$tmpdir/"
     41   set result [local_exec "scp -q $ssh_options $file root@$hostname:$tmpdir/" \
     42                 {} {} $timeout]
     43   if { [lindex $result 0] != 0 } {
     44     verbose -log "failed to upload \'$file\' to \'$tmpdir/$destfile\'"
     45   } else {
     46     verbose -log "uploaded \"$file\' to remote board@\'$tmpdir/$destfile\'"
     47     return "$tmpdir/$destfile"
     48   }
     49 }
     50 
     51 #
     52 # Download a file to the host machine. Uses scp over persistent SSH connection.
     53 #
     54 proc __boardname___upload { board file args } {
     55   set hostname [board_info $board hostname]
     56   set tmpdir [board_info $board tmpdir]
     57   set timeout [board_info $board timeout]
     58   set ssh_options [board_info $board ssh,options]
     59   set filen [file tail $file]
     60   verbose -log "scp -q $ssh_options \"root@$hostname:$tmpdir/$filen\" ."
     61   set result [local_exec \
     62                 "scp -q $ssh_options \"root@$hostname:$tmpdir/$filen\" ." \
     63                 {} {} $timeout]
     64   if { [lindex $result 0] != 0 } {
     65     verbose -log \
     66       "failed to transfer \"root@$hostname:$tmpdir/$filen\" to \".\""
     67   } else {
     68     verbose -log "transferred \"root@$hostname:$tmpdir/$filen\" to \".\""
     69     # In case of success, always return the original file.
     70     return "$file"
     71   }
     72 }
     73 
     74 #
     75 # Cache program output within different invoking of __boardname___exec.
     76 # For example, the following command sequence will be executed
     77 #   > cd /tmp/dejagnu_xxxx/ && ./xxx.x0
     78 #   <output1 here>
     79 #   return [0, <output1>]   (a)
     80 #   > rm /tmp/dejagnu_xxxx/xxxx.x0
     81 #   <output2 here>
     82 #   return [0, <output2>]   (b)
     83 # We need <output1>, not <output2>. What we do here is to keep <output1> in
     84 # $program_output and in (b) we return [0, <output1>].
     85 #
     86 set program_output ""
     87 
     88 #
     89 # Execute a test on remote machine. Log into the target machine using
     90 # persistent SSH connection and run a command in modified environment.
     91 #
     92 proc __boardname___exec { board program args } {
     93   global program_output
     94   if { [llength $args] > 0 } {
     95     set pargs [lindex $args 0]
     96   } else {
     97     set pargs ""
     98   }
     99 
    100   if { [llength $args] > 1 } {
    101     set inp "[lindex $args 1]"
    102   } else {
    103     set inp ""
    104   }
    105 
    106   if { [llength $args] > 2 } {
    107     set outp "[lindex $args 2]"
    108   } else {
    109     set outp ""
    110   }
    111 
    112   if { [llength $args] > 3 } {
    113     set timeout "[lindex $args 3]"
    114   } else {
    115     set timeout [board_info $board timeout]
    116   }
    117 
    118   set hostname [board_info $board hostname]
    119   set tmpdir [board_info $board tmpdir]
    120   set other_file ""
    121 
    122   # Check if a file to be executed was copied from host machine.  If so, we
    123   # need to run it in copied runtimes.
    124   set is_program "0"
    125   if { [string match "$tmpdir/*" $program] } {
    126     set path [file dirname $program]
    127     # "$program" would usually be like "/x/y/z.out", set command to be "z.out".
    128     set command [file tail $program]
    129     set rootname [file rootname $command]
    130     # TODO(shenhan): using rsync to copy all test case relatd stuff to host
    131     # machine in case ".o" files are different from the exe files.
    132     set other_file [file join $path "${rootname}.*"]
    133     # Change directory to "/x/y", then execute "./z.out" - we want the working
    134     # directory to be "/x/y". Setting GCOV_PREFIX_STRIP and GCOV_PREFIX is to
    135     # force generating ".gcda" file under "/x/y" instead of some host path.
    136     set program "cd $path && GCOV_PREFIX_STRIP=999 GCOV_PREFIX=$tmpdir/ \
    137                  [file join "." $command]"
    138     set is_program "1"
    139   }
    140   verbose -log "Exec: $program"
    141   set ssh_options [board_info $board ssh,options]
    142   set retv [local_exec \
    143               "ssh -n $ssh_options root@$hostname sh -c '$program $pargs'" \
    144               $inp $outp $timeout]
    145   set status [lindex $retv 0]
    146   if { $is_program == "1" } {
    147     set program_output [lindex $retv 1]
    148   }
    149 
    150   # Before returning the execution status, we try to transfer the ".gcda"
    151   # (and/or other files that have the same base name as the program) file to
    152   # host, though for every program that runs, there is no corresponding "other"
    153   # file. We have no idea when such an other file will be generated for the
    154   # program, so every time, we assume there is an "other" file and try to do the
    155   # transfer.
    156   if { $status == 0 && $other_file != "" } {
    157     set upv [${board}_upload $board $other_file ""]
    158     if { $upv == "" } {
    159       verbose -log "Safely ignored - \"$other_file\" does not exist."
    160     }
    161   }
    162 
    163   return [list $status $program_output]
    164 }
    165 
    166 load_generic_config "unix"
    167 load_base_board_description "linux-libremote"
    168 
    169 set_board_info hostname "__board_hostname__"
    170 set_board_info tmpdir "__tmp_dir__"
    171 
    172 set_board_info isremote 1
    173 set_board_info timeout 60
    174 set_board_info ssh,options "-i __tmp_testing_rsa__ -o ControlMaster=auto \
    175 -o ControlPath=__tmp_dir__/%r@%h:%p -o StrictHostKeyChecking=no "
    176