2013-11-26 09:18:21 +00:00
# Copyright (C) 2013 Intel Corporation
#
# Released under the MIT license (see COPYING.MIT)
# This module is used by testimage.bbclass for setting up and controlling a target machine.
import os
import shutil
import subprocess
import bb
2014-01-16 12:48:59 +00:00
import traceback
2014-03-07 11:34:05 +00:00
import sys
2013-11-26 09:18:21 +00:00
from oeqa . utils . sshcontrol import SSHControl
from oeqa . utils . qemurunner import QemuRunner
2014-01-30 06:25:54 +00:00
from oeqa . controllers . testtargetloader import TestTargetLoader
2014-02-27 15:46:15 +00:00
from abc import ABCMeta , abstractmethod
2013-11-26 09:18:21 +00:00
def get_target_controller ( d ) :
2014-01-16 12:48:59 +00:00
testtarget = d . getVar ( " TEST_TARGET " , True )
# old, simple names
if testtarget == " qemu " :
2013-11-26 09:18:21 +00:00
return QemuTarget ( d )
2014-01-16 12:48:59 +00:00
elif testtarget == " simpleremote " :
2013-11-26 09:18:21 +00:00
return SimpleRemoteTarget ( d )
else :
2014-01-16 12:48:59 +00:00
# use the class name
try :
# is it a core class defined here?
2014-03-07 11:34:05 +00:00
controller = getattr ( sys . modules [ __name__ ] , testtarget )
2014-01-16 12:48:59 +00:00
except AttributeError :
# nope, perhaps a layer defined one
try :
2014-01-30 06:25:54 +00:00
bbpath = d . getVar ( " BBPATH " , True ) . split ( ' : ' )
testtargetloader = TestTargetLoader ( )
controller = testtargetloader . get_controller_module ( testtarget , bbpath )
2014-01-16 12:48:59 +00:00
except ImportError as e :
2014-01-30 06:25:54 +00:00
bb . fatal ( " Failed to import {0} from available controller modules: \n {1} " . format ( testtarget , traceback . format_exc ( ) ) )
except AttributeError as e :
bb . fatal ( " Invalid TEST_TARGET - " + str ( e ) )
2014-01-16 12:48:59 +00:00
return controller ( d )
2013-11-26 09:18:21 +00:00
class BaseTarget ( object ) :
2014-02-27 15:46:15 +00:00
__metaclass__ = ABCMeta
2014-06-06 19:14:32 +00:00
supported_image_fstypes = [ ]
2013-11-26 09:18:21 +00:00
def __init__ ( self , d ) :
self . connection = None
self . ip = None
self . server_ip = None
self . datetime = d . getVar ( ' DATETIME ' , True )
self . testdir = d . getVar ( " TEST_LOG_DIR " , True )
self . pn = d . getVar ( " PN " , True )
2014-02-27 15:46:15 +00:00
@abstractmethod
2013-11-26 09:18:21 +00:00
def deploy ( self ) :
self . sshlog = os . path . join ( self . testdir , " ssh_target_log. %s " % self . datetime )
sshloglink = os . path . join ( self . testdir , " ssh_target_log " )
if os . path . islink ( sshloglink ) :
os . unlink ( sshloglink )
os . symlink ( self . sshlog , sshloglink )
bb . note ( " SSH log file: %s " % self . sshlog )
2014-02-27 15:46:15 +00:00
@abstractmethod
def start ( self , params = None ) :
pass
@abstractmethod
def stop ( self ) :
pass
2014-06-06 19:14:32 +00:00
@classmethod
def get_image_fstype ( self , d , image_fstypes = None ) :
if not image_fstypes :
image_fstypes = d . getVar ( ' IMAGE_FSTYPES ' , True ) . split ( ' ' )
possible_image_fstypes = [ fstype for fstype in self . supported_image_fstypes if fstype in image_fstypes ]
if possible_image_fstypes :
return possible_image_fstypes [ 0 ]
else :
bb . fatal ( " no possible image_fstype could not be determined. IMAGE_FSTYPES= \" %s \" and supported_image_fstypes= \" %s \" : " % ( ' , ' . join ( map ( str , image_fstypes ) ) , ' , ' . join ( map ( str , self . supported_image_fstypes ) ) ) )
2014-02-27 15:46:15 +00:00
def restart ( self , params = None ) :
2014-04-30 12:31:58 +00:00
self . stop ( )
self . start ( params )
2014-02-27 15:46:15 +00:00
2013-11-26 09:18:21 +00:00
def run ( self , cmd , timeout = None ) :
return self . connection . run ( cmd , timeout )
def copy_to ( self , localpath , remotepath ) :
return self . connection . copy_to ( localpath , remotepath )
def copy_from ( self , remotepath , localpath ) :
return self . connection . copy_from ( remotepath , localpath )
class QemuTarget ( BaseTarget ) :
2014-06-06 19:14:32 +00:00
supported_image_fstypes = [ ' ext3 ' ]
2013-11-26 09:18:21 +00:00
def __init__ ( self , d ) :
super ( QemuTarget , self ) . __init__ ( d )
2014-06-06 19:14:32 +00:00
self . image_fstype = self . get_image_fstype ( d )
2013-11-26 09:18:21 +00:00
self . qemulog = os . path . join ( self . testdir , " qemu_boot_log. %s " % self . datetime )
2014-06-06 19:14:32 +00:00
self . origrootfs = os . path . join ( d . getVar ( " DEPLOY_DIR_IMAGE " , True ) , d . getVar ( " IMAGE_LINK_NAME " , True ) + ' . ' + self . image_fstype )
self . rootfs = os . path . join ( self . testdir , d . getVar ( " IMAGE_LINK_NAME " , True ) + ' -testimage. ' + self . image_fstype )
2013-11-26 09:18:21 +00:00
self . runner = QemuRunner ( machine = d . getVar ( " MACHINE " , True ) ,
rootfs = self . rootfs ,
tmpdir = d . getVar ( " TMPDIR " , True ) ,
deploy_dir_image = d . getVar ( " DEPLOY_DIR_IMAGE " , True ) ,
display = d . getVar ( " BB_ORIGENV " , False ) . getVar ( " DISPLAY " , True ) ,
logfile = self . qemulog ,
boottime = int ( d . getVar ( " TEST_QEMUBOOT_TIMEOUT " , True ) ) )
def deploy ( self ) :
try :
shutil . copyfile ( self . origrootfs , self . rootfs )
except Exception as e :
bb . fatal ( " Error copying rootfs: %s " % e )
qemuloglink = os . path . join ( self . testdir , " qemu_boot_log " )
if os . path . islink ( qemuloglink ) :
os . unlink ( qemuloglink )
os . symlink ( self . qemulog , qemuloglink )
bb . note ( " rootfs file: %s " % self . rootfs )
bb . note ( " Qemu log file: %s " % self . qemulog )
super ( QemuTarget , self ) . deploy ( )
def start ( self , params = None ) :
if self . runner . start ( params ) :
self . ip = self . runner . ip
self . server_ip = self . runner . server_ip
self . connection = SSHControl ( ip = self . ip , logfile = self . sshlog )
else :
2014-04-30 12:32:01 +00:00
self . stop ( )
2013-11-26 09:18:21 +00:00
raise bb . build . FuncFailed ( " %s - FAILED to start qemu - check the task log and the boot log " % self . pn )
def stop ( self ) :
self . runner . stop ( )
self . connection = None
self . ip = None
self . server_ip = None
def restart ( self , params = None ) :
if self . runner . restart ( params ) :
self . ip = self . runner . ip
self . server_ip = self . runner . server_ip
self . connection = SSHControl ( ip = self . ip , logfile = self . sshlog )
else :
raise bb . build . FuncFailed ( " %s - FAILED to re-start qemu - check the task log and the boot log " % self . pn )
class SimpleRemoteTarget ( BaseTarget ) :
def __init__ ( self , d ) :
super ( SimpleRemoteTarget , self ) . __init__ ( d )
2014-03-07 11:08:30 +00:00
addr = d . getVar ( " TEST_TARGET_IP " , True ) or bb . fatal ( ' Please set TEST_TARGET_IP with the IP address of the machine you want to run the tests on. ' )
self . ip = addr . split ( " : " ) [ 0 ]
try :
self . port = addr . split ( " : " ) [ 1 ]
except IndexError :
self . port = None
2013-11-26 09:18:21 +00:00
bb . note ( " Target IP: %s " % self . ip )
self . server_ip = d . getVar ( " TEST_SERVER_IP " , True )
if not self . server_ip :
try :
2014-02-25 10:46:11 +00:00
self . server_ip = subprocess . check_output ( [ ' ip ' , ' route ' , ' get ' , self . ip ] ) . split ( " \n " ) [ 0 ] . split ( ) [ - 1 ]
2013-11-26 09:18:21 +00:00
except Exception as e :
bb . fatal ( " Failed to determine the host IP address (alternatively you can set TEST_SERVER_IP with the IP address of this machine): %s " % e )
bb . note ( " Server IP: %s " % self . server_ip )
def deploy ( self ) :
super ( SimpleRemoteTarget , self ) . deploy ( )
def start ( self , params = None ) :
2014-03-07 11:08:30 +00:00
self . connection = SSHControl ( self . ip , logfile = self . sshlog , port = self . port )
2013-11-26 09:18:21 +00:00
def stop ( self ) :
self . connection = None
self . ip = None
self . server_ip = None