1*4882a593Smuzhiyun#!/usr/bin/env python3 2*4882a593Smuzhiyun# 3*4882a593Smuzhiyun# Copyright (C) 2013 Intel Corporation 4*4882a593Smuzhiyun# 5*4882a593Smuzhiyun# SPDX-License-Identifier: MIT 6*4882a593Smuzhiyun# 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun# This script should be used outside of the build system to run image tests. 9*4882a593Smuzhiyun# It needs a json file as input as exported by the build. 10*4882a593Smuzhiyun# E.g for an already built image: 11*4882a593Smuzhiyun#- export the tests: 12*4882a593Smuzhiyun# TEST_EXPORT_ONLY = "1" 13*4882a593Smuzhiyun# TEST_TARGET = "simpleremote" 14*4882a593Smuzhiyun# TEST_TARGET_IP = "192.168.7.2" 15*4882a593Smuzhiyun# TEST_SERVER_IP = "192.168.7.1" 16*4882a593Smuzhiyun# bitbake core-image-sato -c testimage 17*4882a593Smuzhiyun# Setup your target, e.g for qemu: runqemu core-image-sato 18*4882a593Smuzhiyun# cd build/tmp/testimage/core-image-sato 19*4882a593Smuzhiyun# ./runexported.py testdata.json 20*4882a593Smuzhiyun 21*4882a593Smuzhiyunimport sys 22*4882a593Smuzhiyunimport os 23*4882a593Smuzhiyunimport time 24*4882a593Smuzhiyunimport argparse 25*4882a593Smuzhiyun 26*4882a593Smuzhiyuntry: 27*4882a593Smuzhiyun import simplejson as json 28*4882a593Smuzhiyunexcept ImportError: 29*4882a593Smuzhiyun import json 30*4882a593Smuzhiyun 31*4882a593Smuzhiyunsys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "oeqa"))) 32*4882a593Smuzhiyun 33*4882a593Smuzhiyunfrom oeqa.oetest import ExportTestContext 34*4882a593Smuzhiyunfrom oeqa.utils.commands import runCmd, updateEnv 35*4882a593Smuzhiyunfrom oeqa.utils.sshcontrol import SSHControl 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun# this isn't pretty but we need a fake target object 38*4882a593Smuzhiyun# for running the tests externally as we don't care 39*4882a593Smuzhiyun# about deploy/start we only care about the connection methods (run, copy) 40*4882a593Smuzhiyunclass FakeTarget(object): 41*4882a593Smuzhiyun def __init__(self, d): 42*4882a593Smuzhiyun self.connection = None 43*4882a593Smuzhiyun self.ip = None 44*4882a593Smuzhiyun self.server_ip = None 45*4882a593Smuzhiyun self.datetime = time.strftime('%Y%m%d%H%M%S',time.gmtime()) 46*4882a593Smuzhiyun self.testdir = d.getVar("TEST_LOG_DIR") 47*4882a593Smuzhiyun self.pn = d.getVar("PN") 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun def exportStart(self): 50*4882a593Smuzhiyun self.sshlog = os.path.join(self.testdir, "ssh_target_log.%s" % self.datetime) 51*4882a593Smuzhiyun sshloglink = os.path.join(self.testdir, "ssh_target_log") 52*4882a593Smuzhiyun if os.path.lexists(sshloglink): 53*4882a593Smuzhiyun os.remove(sshloglink) 54*4882a593Smuzhiyun os.symlink(self.sshlog, sshloglink) 55*4882a593Smuzhiyun print("SSH log file: %s" % self.sshlog) 56*4882a593Smuzhiyun self.connection = SSHControl(self.ip, logfile=self.sshlog) 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun def run(self, cmd, timeout=None): 59*4882a593Smuzhiyun return self.connection.run(cmd, timeout) 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun def copy_to(self, localpath, remotepath): 62*4882a593Smuzhiyun return self.connection.copy_to(localpath, remotepath) 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun def copy_from(self, remotepath, localpath): 65*4882a593Smuzhiyun return self.connection.copy_from(remotepath, localpath) 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun 68*4882a593Smuzhiyunclass MyDataDict(dict): 69*4882a593Smuzhiyun def getVar(self, key, unused = None): 70*4882a593Smuzhiyun return self.get(key, "") 71*4882a593Smuzhiyun 72*4882a593Smuzhiyundef main(): 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun parser = argparse.ArgumentParser() 75*4882a593Smuzhiyun parser.add_argument("-t", "--target-ip", dest="ip", help="The IP address of the target machine. Use this to \ 76*4882a593Smuzhiyun overwrite the value determined from TEST_TARGET_IP at build time") 77*4882a593Smuzhiyun parser.add_argument("-s", "--server-ip", dest="server_ip", help="The IP address of this machine. Use this to \ 78*4882a593Smuzhiyun overwrite the value determined from TEST_SERVER_IP at build time.") 79*4882a593Smuzhiyun parser.add_argument("-d", "--deploy-dir", dest="deploy_dir", help="Full path to the package feeds, that this \ 80*4882a593Smuzhiyun the contents of what used to be DEPLOY_DIR on the build machine. If not specified it will use the value \ 81*4882a593Smuzhiyun specified in the json if that directory actually exists or it will error out.") 82*4882a593Smuzhiyun parser.add_argument("-l", "--log-dir", dest="log_dir", help="This sets the path for TEST_LOG_DIR. If not specified \ 83*4882a593Smuzhiyun the current dir is used. This is used for usually creating a ssh log file and a scp test file.") 84*4882a593Smuzhiyun parser.add_argument("-a", "--tag", dest="tag", help="Only run test with specified tag.") 85*4882a593Smuzhiyun parser.add_argument("json", help="The json file exported by the build system", default="testdata.json", nargs='?') 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun args = parser.parse_args() 88*4882a593Smuzhiyun 89*4882a593Smuzhiyun with open(args.json, "r") as f: 90*4882a593Smuzhiyun loaded = json.load(f) 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun if args.ip: 93*4882a593Smuzhiyun loaded["target"]["ip"] = args.ip 94*4882a593Smuzhiyun if args.server_ip: 95*4882a593Smuzhiyun loaded["target"]["server_ip"] = args.server_ip 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun d = MyDataDict() 98*4882a593Smuzhiyun for key in loaded["d"].keys(): 99*4882a593Smuzhiyun d[key] = loaded["d"][key] 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun if args.log_dir: 102*4882a593Smuzhiyun d["TEST_LOG_DIR"] = args.log_dir 103*4882a593Smuzhiyun else: 104*4882a593Smuzhiyun d["TEST_LOG_DIR"] = os.path.abspath(os.path.dirname(__file__)) 105*4882a593Smuzhiyun if args.deploy_dir: 106*4882a593Smuzhiyun d["DEPLOY_DIR"] = args.deploy_dir 107*4882a593Smuzhiyun else: 108*4882a593Smuzhiyun if not os.path.isdir(d["DEPLOY_DIR"]): 109*4882a593Smuzhiyun print("WARNING: The path to DEPLOY_DIR does not exist: %s" % d["DEPLOY_DIR"]) 110*4882a593Smuzhiyun 111*4882a593Smuzhiyun parsedArgs = {} 112*4882a593Smuzhiyun parsedArgs["tag"] = args.tag 113*4882a593Smuzhiyun 114*4882a593Smuzhiyun extract_sdk(d) 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun target = FakeTarget(d) 117*4882a593Smuzhiyun for key in loaded["target"].keys(): 118*4882a593Smuzhiyun setattr(target, key, loaded["target"][key]) 119*4882a593Smuzhiyun 120*4882a593Smuzhiyun target.exportStart() 121*4882a593Smuzhiyun tc = ExportTestContext(d, target, True, parsedArgs) 122*4882a593Smuzhiyun tc.loadTests() 123*4882a593Smuzhiyun tc.runTests() 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun return 0 126*4882a593Smuzhiyun 127*4882a593Smuzhiyundef extract_sdk(d): 128*4882a593Smuzhiyun """ 129*4882a593Smuzhiyun Extract SDK if needed 130*4882a593Smuzhiyun """ 131*4882a593Smuzhiyun 132*4882a593Smuzhiyun export_dir = os.path.dirname(os.path.realpath(__file__)) 133*4882a593Smuzhiyun tools_dir = d.getVar("TEST_EXPORT_SDK_DIR") 134*4882a593Smuzhiyun tarball_name = "%s.sh" % d.getVar("TEST_EXPORT_SDK_NAME") 135*4882a593Smuzhiyun tarball_path = os.path.join(export_dir, tools_dir, tarball_name) 136*4882a593Smuzhiyun extract_path = os.path.join(export_dir, "sysroot") 137*4882a593Smuzhiyun if os.path.isfile(tarball_path): 138*4882a593Smuzhiyun print ("Found SDK tarball %s. Extracting..." % tarball_path) 139*4882a593Smuzhiyun result = runCmd("%s -y -d %s" % (tarball_path, extract_path)) 140*4882a593Smuzhiyun for f in os.listdir(extract_path): 141*4882a593Smuzhiyun if f.startswith("environment-setup"): 142*4882a593Smuzhiyun print("Setting up SDK environment...") 143*4882a593Smuzhiyun env_file = os.path.join(extract_path, f) 144*4882a593Smuzhiyun updateEnv(env_file) 145*4882a593Smuzhiyun 146*4882a593Smuzhiyunif __name__ == "__main__": 147*4882a593Smuzhiyun try: 148*4882a593Smuzhiyun ret = main() 149*4882a593Smuzhiyun except Exception: 150*4882a593Smuzhiyun ret = 1 151*4882a593Smuzhiyun import traceback 152*4882a593Smuzhiyun traceback.print_exc() 153*4882a593Smuzhiyun sys.exit(ret) 154