summaryrefslogtreecommitdiff
path: root/meta/lib/oeqa/runexported.py
blob: 58867393bb7e55a0fbf928192285861e3592d7ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/usr/bin/env python3


# Copyright (C) 2013 Intel Corporation
#
# Released under the MIT license (see COPYING.MIT)

# This script should be used outside of the build system to run image tests.
# It needs a json file as input as exported by the build.
# E.g for an already built image:
#- export the tests:
#   TEST_EXPORT_ONLY = "1"
#   TEST_TARGET  = "simpleremote"
#   TEST_TARGET_IP = "192.168.7.2"
#   TEST_SERVER_IP = "192.168.7.1"
# bitbake core-image-sato -c testimage
# Setup your target, e.g for qemu: runqemu core-image-sato
# cd build/tmp/testimage/core-image-sato
# ./runexported.py testdata.json

import sys
import os
import time
import argparse

try:
    import simplejson as json
except ImportError:
    import json

sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "oeqa")))

from oeqa.oetest import ExportTestContext
from oeqa.utils.commands import runCmd
from oeqa.utils.sshcontrol import SSHControl

# this isn't pretty but we need a fake target object
# for running the tests externally as we don't care
# about deploy/start we only care about the connection methods (run, copy)
class FakeTarget(object):
    def __init__(self, d):
        self.connection = None
        self.ip = None
        self.server_ip = None
        self.datetime = time.strftime('%Y%m%d%H%M%S',time.gmtime())
        self.testdir = d.getVar("TEST_LOG_DIR", True)
        self.pn = d.getVar("PN", True)

    def exportStart(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.lexists(sshloglink):
            os.remove(sshloglink)
        os.symlink(self.sshlog, sshloglink)
        print("SSH log file: %s" %  self.sshlog)
        self.connection = SSHControl(self.ip, logfile=self.sshlog)

    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 MyDataDict(dict):
    def getVar(self, key, unused = None):
        return self.get(key, "")

def main():

    parser = argparse.ArgumentParser()
    parser.add_argument("-t", "--target-ip", dest="ip", help="The IP address of the target machine. Use this to \
            overwrite the value determined from TEST_TARGET_IP at build time")
    parser.add_argument("-s", "--server-ip", dest="server_ip", help="The IP address of this machine. Use this to \
            overwrite the value determined from TEST_SERVER_IP at build time.")
    parser.add_argument("-d", "--deploy-dir", dest="deploy_dir", help="Full path to the package feeds, that this \
            the contents of what used to be DEPLOY_DIR on the build machine. If not specified it will use the value \
            specified in the json if that directory actually exists or it will error out.")
    parser.add_argument("-l", "--log-dir", dest="log_dir", help="This sets the path for TEST_LOG_DIR. If not specified \
            the current dir is used. This is used for usually creating a ssh log file and a scp test file.")
    parser.add_argument("json", help="The json file exported by the build system", default="testdata.json", nargs='?')

    args = parser.parse_args()

    with open(args.json, "r") as f:
        loaded = json.load(f)

    if args.ip:
        loaded["target"]["ip"] = args.ip
    if args.server_ip:
        loaded["target"]["server_ip"] = args.server_ip

    d = MyDataDict()
    for key in loaded["d"].keys():
        d[key] = loaded["d"][key]

    if args.log_dir:
        d["TEST_LOG_DIR"] = args.log_dir
    else:
        d["TEST_LOG_DIR"] = os.path.abspath(os.path.dirname(__file__))
    if args.deploy_dir:
        d["DEPLOY_DIR"] = args.deploy_dir
    else:
        if not os.path.isdir(d["DEPLOY_DIR"]):
            print("WARNING: The path to DEPLOY_DIR does not exist: %s" % d["DEPLOY_DIR"])

    extract_sdk(d)

    target = FakeTarget(d)
    for key in loaded["target"].keys():
        setattr(target, key, loaded["target"][key])

    target.exportStart()
    tc = ExportTestContext(d, target, True)
    tc.loadTests()
    tc.runTests()

    return 0

def extract_sdk(d):
    """
    Extract SDK if needed
    """

    export_dir = os.path.dirname(os.path.realpath(__file__))
    tools_dir = d.getVar("TEST_EXPORT_SDK_DIR", True)
    tarball_name = "%s.sh" % d.getVar("TEST_EXPORT_SDK_NAME", True)
    tarball_path = os.path.join(export_dir, tools_dir, tarball_name)
    extract_path = os.path.join(export_dir, "sysroot")
    if os.path.isfile(tarball_path):
        print ("Found SDK tarball %s. Extracting..." % tarball_path)
        result = runCmd("%s -y -d %s" % (tarball_path, extract_path))
        for f in os.listdir(extract_path):
            if f.startswith("environment-setup"):
                print("Setting up SDK environment...")
                env_file = os.path.join(extract_path, f)
                update_env(env_file)

def update_env(env_file):
    """
    Source a file and update environment
    """

    cmd = ". %s; env -0" % env_file
    result = runCmd(cmd)

    for line in result.output.split("\0"):
        (key, _, value) = line.partition("=")
        os.environ[key] = value

if __name__ == "__main__":
    try:
        ret = main()
    except Exception:
        ret = 1
        import traceback
        traceback.print_exc()
    sys.exit(ret)