blob: 86ddf8ffc382ece90e3f92f3e3a364fdc735de8f [file] [log] [blame]
#-------------------------------------------------------------------------------
# Copyright (c) 2020, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
#-------------------------------------------------------------------------------
from irq_test_abstract_debugger import Location
import logging
import json
def create_locations_from_file(breakpoints_file_name):
"""Internal function to create Location objects of a breakpoints data file
"""
# Read in the points to break at
logging.info("Reading breakpoints file '%s'", breakpoints_file_name)
breakpoints_file = open(breakpoints_file_name)
breakpoints = json.load(breakpoints_file)
logging.debug("breakpoints: %s", str(breakpoints))
#TODO: go over the breakpoints and try to set them as a sanity check
locations = {}
for loc_name in breakpoints['breakpoints']:
bkpt = breakpoints['breakpoints'][loc_name]
offset = 0
if 'file' in bkpt:
filename = bkpt['file']
else:
filename = None
if 'symbol' in bkpt:
symbol = bkpt['symbol']
if 'offset' in bkpt:
offset = bkpt['offset']
else:
offset = 0
else:
if 'offset' in bkpt:
logging.error("In location %s offset is included without a"
" symbol")
exit(2)
symbol = None
if 'line' in bkpt:
line = bkpt['line']
try:
int(line)
except ValueError:
logging.error("In location %s line is not a valid int",
loc_name)
exit(2)
else:
line = None
if symbol:
if line or filename:
logging.error("In location %s nor filename nor line should"
"be present when symbol is present", loc_name)
exit(2)
if (not line and filename) or (line and not filename):
logging.error("In location %s line and filename have to be "
"present the same time", loc_name)
exit(2)
if (not symbol) and (not filename):
logging.error("In location %s no symbol nor code location is "
"specified at all", loc_name)
exit(2)
loc = Location(symbol=symbol, offset=offset, filename=filename, line=line)
locations[loc_name] = loc
return locations
class TestExecutor(object):
""" This class implements the test logic.
It reads the input files, and executes the steps of the testcase. It receives an
AbstractDebugger instance on creation. The test execution is implemented in the
execute function.
"""
def __init__(self, debugger):
self.debugger = debugger
def execute(self, irqs_filename, breakpoints_filename, testcase_filename):
""" Execute a testcase
Execute the testcase defined in 'testcase_filename', using the IRQs and
breakpoints defined in irqs_filename and breakpoints_filename.
"""
# Read in the list of IRQs
logging.info("Reading irqs file '%s'", irqs_filename)
irqs_file = open(irqs_filename)
irqs = json.load(irqs_file)
logging.debug("irqs: %s", str(irqs))
# read in the test sequence
logging.info("Reading test sequence file '%s'", testcase_filename)
test_file = open(testcase_filename)
test = json.load(test_file)
logging.debug("testcase: %s", str(test))
# TODO: crosscheck the tests file against the breakpoints and the irq's
# available
locations = create_locations_from_file(breakpoints_filename)
self.debugger.clear_breakpoints()
# execute the test
steps = test['steps']
for i, step in enumerate(steps):
logging.info("---- Step %d ----", i)
continue_execution = False
if 'wait_for' in step:
bp_name = step['wait_for']
self.debugger.set_breakpoint(bp_name, locations[bp_name])
next_to_break_at = bp_name
continue_execution = True
elif 'expect' in step:
bp_name = step['expect']
self.debugger.set_breakpoint(bp_name, locations[bp_name])
next_to_break_at = bp_name
# Find the next wait_for in the test sequence, and set a
# breakpoint for that as well. So that it can be detected if an
# expected breakpoint is missed.
wait_for_found = False
ii = i+1
while ii < len(steps) and not wait_for_found:
next_step = steps[ii]
if 'wait_for' in next_step:
next_bp_name = next_step['wait_for']
self.debugger.set_breakpoint(next_bp_name,
locations[next_bp_name])
wait_for_found = True
ii += 1
continue_execution = True
if 'trigger' in step:
irqs_dict = irqs['irqs']
irq = irqs_dict[step['trigger']]
line_nu = irq['line_num']
self.debugger.trigger_interrupt(line_nu)
if continue_execution:
self.debugger.continue_execution()
triggered_breakpoint = self.debugger.get_triggered_breakpoint()
if triggered_breakpoint is None:
logging.error("No breakpoint was hit?????")
exit(0)
if triggered_breakpoint != next_to_break_at:
logging.error("execution stopped at '%s' instead of '%s'",
triggered_breakpoint, next_to_break_at)
exit(0)
else:
logging.error("execution stopped as no breakpoint is set")
exit(1)
self.debugger.clear_breakpoints()
logging.info("All the steps in the test file are executed successfully"
" with the expected result.")