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