mirror of
https://git.yoctoproject.org/poky
synced 2026-05-09 17:39:31 +00:00
70cc20daef
Event objects are represented by base64-encoded strings in the event file and can't be loaded by existing eventreplay code. Fixed the code of loading events from file by decoding base64 strings into the binary form and loading them with pickle.load. [YOCTO #9585] (Bitbake rev: a55c280c167f84caed6518119246e5a55f56cfd4) Signed-off-by: Ed Bartosh <ed.bartosh@linux.intel.com> Signed-off-by: Elliot Smith <elliot.smith@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
185 lines
6.3 KiB
Python
Executable File
185 lines
6.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# ex:ts=4:sw=4:sts=4:et
|
|
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
|
|
#
|
|
# Copyright (C) 2014 Alex Damian
|
|
#
|
|
# This file re-uses code spread throughout other Bitbake source files.
|
|
# As such, all other copyrights belong to their own right holders.
|
|
#
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License version 2 as
|
|
# published by the Free Software Foundation.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along
|
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
|
|
# This command takes a filename as a single parameter. The filename is read
|
|
# as a build eventlog, and the ToasterUI is used to process events in the file
|
|
# and log data in the database
|
|
|
|
from __future__ import print_function
|
|
import os
|
|
import sys, logging
|
|
import codecs
|
|
|
|
# mangle syspath to allow easy import of modules
|
|
sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
|
|
'lib'))
|
|
|
|
|
|
import bb.cooker
|
|
from bb.ui import toasterui
|
|
import sys
|
|
import logging
|
|
|
|
import json, pickle
|
|
|
|
|
|
class FileReadEventsServerConnection():
|
|
""" Emulates a connection to a bitbake server that feeds
|
|
events coming actually read from a saved log file.
|
|
"""
|
|
|
|
class MockConnection():
|
|
""" fill-in for the proxy to the server. we just return generic data
|
|
"""
|
|
def __init__(self, sc):
|
|
self._sc = sc
|
|
self.eventmask = []
|
|
|
|
def runCommand(self, commandArray):
|
|
""" emulates running a command on the server; only read-only commands are accepted """
|
|
command_name = commandArray[0]
|
|
|
|
if command_name == "getVariable":
|
|
if commandArray[1] in self._sc._variables:
|
|
return (self._sc._variables[commandArray[1]]['v'], None)
|
|
return (None, "Missing variable")
|
|
|
|
elif command_name == "getAllKeysWithFlags":
|
|
dump = {}
|
|
flaglist = commandArray[1]
|
|
for k in self._sc._variables.keys():
|
|
try:
|
|
if not k.startswith("__"):
|
|
v = self._sc._variables[k]['v']
|
|
dump[k] = {
|
|
'v' : v ,
|
|
'history' : self._sc._variables[k]['history'],
|
|
}
|
|
for d in flaglist:
|
|
dump[k][d] = self._sc._variables[k][d]
|
|
except Exception as e:
|
|
print(e)
|
|
return (dump, None)
|
|
|
|
elif command_name == 'setEventMask':
|
|
self.eventmask = commandArray[-1]
|
|
return True, None
|
|
|
|
else:
|
|
raise Exception("Command %s not implemented" % commandArray[0])
|
|
|
|
def terminateServer(self):
|
|
""" do not do anything """
|
|
pass
|
|
|
|
def getEventHandle(self):
|
|
pass
|
|
|
|
|
|
class EventReader():
|
|
def __init__(self, sc):
|
|
self._sc = sc
|
|
self.firstraise = 0
|
|
|
|
def _create_event(self, line):
|
|
def _import_class(name):
|
|
assert len(name) > 0
|
|
assert "." in name, name
|
|
|
|
components = name.strip().split(".")
|
|
modulename = ".".join(components[:-1])
|
|
moduleklass = components[-1]
|
|
|
|
module = __import__(modulename, fromlist=[str(moduleklass)])
|
|
return getattr(module, moduleklass)
|
|
|
|
# we build a toaster event out of current event log line
|
|
try:
|
|
event_data = json.loads(line.strip())
|
|
event_class = _import_class(event_data['class'])
|
|
event_str = event_data['vars'].encode('utf-8')
|
|
event_object = pickle.loads(codecs.decode(event_str, 'base64'))
|
|
except ValueError as e:
|
|
print("Failed loading ", line)
|
|
raise e
|
|
|
|
if not isinstance(event_object, event_class):
|
|
raise Exception("Error loading objects %s class %s ", event_object, event_class)
|
|
|
|
return event_object
|
|
|
|
def waitEvent(self, timeout):
|
|
|
|
nextline = self._sc._eventfile.readline()
|
|
if len(nextline) == 0:
|
|
# the build data ended, while toasterui still waits for events.
|
|
# this happens when the server was abruptly stopped, so we simulate this
|
|
self.firstraise += 1
|
|
if self.firstraise == 1:
|
|
raise KeyboardInterrupt()
|
|
else:
|
|
return None
|
|
else:
|
|
self._sc.lineno += 1
|
|
return self._create_event(nextline)
|
|
|
|
|
|
def _readVariables(self, variableline):
|
|
self._variables = json.loads(variableline.strip())['allvariables']
|
|
|
|
|
|
def __init__(self, file_name):
|
|
self.connection = FileReadEventsServerConnection.MockConnection(self)
|
|
self._eventfile = open(file_name, "r")
|
|
|
|
# we expect to have the variable dump at the start of the file
|
|
self.lineno = 1
|
|
self._readVariables(self._eventfile.readline())
|
|
|
|
self.events = FileReadEventsServerConnection.EventReader(self)
|
|
|
|
|
|
|
|
|
|
|
|
class MockConfigParameters():
|
|
""" stand-in for cookerdata.ConfigParameters; as we don't really config a cooker, this
|
|
serves just to supply needed interfaces for the toaster ui to work """
|
|
def __init__(self):
|
|
self.observe_only = True # we can only read files
|
|
|
|
|
|
# run toaster ui on our mock bitbake class
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) < 2:
|
|
print("Usage: %s event.log " % sys.argv[0])
|
|
sys.exit(1)
|
|
|
|
file_name = sys.argv[-1]
|
|
mock_connection = FileReadEventsServerConnection(file_name)
|
|
configParams = MockConfigParameters()
|
|
|
|
# run the main program and set exit code to the returned value
|
|
sys.exit(toasterui.main(mock_connection.connection, mock_connection.events, configParams))
|