xref: /OK3568_Linux_fs/yocto/poky/bitbake/bin/toaster-eventreplay (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#!/usr/bin/env python3
2*4882a593Smuzhiyun#
3*4882a593Smuzhiyun# Copyright (C) 2014        Alex Damian
4*4882a593Smuzhiyun#
5*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0-only
6*4882a593Smuzhiyun#
7*4882a593Smuzhiyun# This file re-uses code spread throughout other Bitbake source files.
8*4882a593Smuzhiyun# As such, all other copyrights belong to their own right holders.
9*4882a593Smuzhiyun#
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun"""
12*4882a593SmuzhiyunThis command takes a filename as a single parameter. The filename is read
13*4882a593Smuzhiyunas a build eventlog, and the ToasterUI is used to process events in the file
14*4882a593Smuzhiyunand log data in the database
15*4882a593Smuzhiyun"""
16*4882a593Smuzhiyun
17*4882a593Smuzhiyunimport os
18*4882a593Smuzhiyunimport sys
19*4882a593Smuzhiyunimport json
20*4882a593Smuzhiyunimport pickle
21*4882a593Smuzhiyunimport codecs
22*4882a593Smuzhiyunimport warnings
23*4882a593Smuzhiyunwarnings.simplefilter("default")
24*4882a593Smuzhiyun
25*4882a593Smuzhiyunfrom collections import namedtuple
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun# mangle syspath to allow easy import of modules
28*4882a593Smuzhiyunfrom os.path import join, dirname, abspath
29*4882a593Smuzhiyunsys.path.insert(0, join(dirname(dirname(abspath(__file__))), 'lib'))
30*4882a593Smuzhiyun
31*4882a593Smuzhiyunimport bb.cooker
32*4882a593Smuzhiyunfrom bb.ui import toasterui
33*4882a593Smuzhiyun
34*4882a593Smuzhiyunclass EventPlayer:
35*4882a593Smuzhiyun    """Emulate a connection to a bitbake server."""
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun    def __init__(self, eventfile, variables):
38*4882a593Smuzhiyun        self.eventfile = eventfile
39*4882a593Smuzhiyun        self.variables = variables
40*4882a593Smuzhiyun        self.eventmask = []
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun    def waitEvent(self, _timeout):
43*4882a593Smuzhiyun        """Read event from the file."""
44*4882a593Smuzhiyun        line = self.eventfile.readline().strip()
45*4882a593Smuzhiyun        if not line:
46*4882a593Smuzhiyun            return
47*4882a593Smuzhiyun        try:
48*4882a593Smuzhiyun            event_str = json.loads(line)['vars'].encode('utf-8')
49*4882a593Smuzhiyun            event = pickle.loads(codecs.decode(event_str, 'base64'))
50*4882a593Smuzhiyun            event_name = "%s.%s" % (event.__module__, event.__class__.__name__)
51*4882a593Smuzhiyun            if event_name not in self.eventmask:
52*4882a593Smuzhiyun                return
53*4882a593Smuzhiyun            return event
54*4882a593Smuzhiyun        except ValueError as err:
55*4882a593Smuzhiyun            print("Failed loading ", line)
56*4882a593Smuzhiyun            raise err
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun    def runCommand(self, command_line):
59*4882a593Smuzhiyun        """Emulate running a command on the server."""
60*4882a593Smuzhiyun        name = command_line[0]
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun        if name == "getVariable":
63*4882a593Smuzhiyun            var_name = command_line[1]
64*4882a593Smuzhiyun            variable = self.variables.get(var_name)
65*4882a593Smuzhiyun            if variable:
66*4882a593Smuzhiyun                return variable['v'], None
67*4882a593Smuzhiyun            return None, "Missing variable %s" % var_name
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun        elif name == "getAllKeysWithFlags":
70*4882a593Smuzhiyun            dump = {}
71*4882a593Smuzhiyun            flaglist = command_line[1]
72*4882a593Smuzhiyun            for key, val in self.variables.items():
73*4882a593Smuzhiyun                try:
74*4882a593Smuzhiyun                    if not key.startswith("__"):
75*4882a593Smuzhiyun                        dump[key] = {
76*4882a593Smuzhiyun                            'v': val['v'],
77*4882a593Smuzhiyun                            'history' : val['history'],
78*4882a593Smuzhiyun                        }
79*4882a593Smuzhiyun                        for flag in flaglist:
80*4882a593Smuzhiyun                            dump[key][flag] = val[flag]
81*4882a593Smuzhiyun                except Exception as err:
82*4882a593Smuzhiyun                    print(err)
83*4882a593Smuzhiyun            return (dump, None)
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun        elif name == 'setEventMask':
86*4882a593Smuzhiyun            self.eventmask = command_line[-1]
87*4882a593Smuzhiyun            return True, None
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun        else:
90*4882a593Smuzhiyun            raise Exception("Command %s not implemented" % command_line[0])
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun    def getEventHandle(self):
93*4882a593Smuzhiyun        """
94*4882a593Smuzhiyun        This method is called by toasterui.
95*4882a593Smuzhiyun        The return value is passed to self.runCommand but not used there.
96*4882a593Smuzhiyun        """
97*4882a593Smuzhiyun        pass
98*4882a593Smuzhiyun
99*4882a593Smuzhiyundef main(argv):
100*4882a593Smuzhiyun    with open(argv[-1]) as eventfile:
101*4882a593Smuzhiyun        # load variables from the first line
102*4882a593Smuzhiyun        variables = json.loads(eventfile.readline().strip())['allvariables']
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun        params = namedtuple('ConfigParams', ['observe_only'])(True)
105*4882a593Smuzhiyun        player = EventPlayer(eventfile, variables)
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun        return toasterui.main(player, player, params)
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun# run toaster ui on our mock bitbake class
110*4882a593Smuzhiyunif __name__ == "__main__":
111*4882a593Smuzhiyun    if len(sys.argv) != 2:
112*4882a593Smuzhiyun        print("Usage: %s <event file>" % os.path.basename(sys.argv[0]))
113*4882a593Smuzhiyun        sys.exit(1)
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun    sys.exit(main(sys.argv))
116