mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-30 08:07:59 +00:00
test/py: use " for docstrings
Python's coding style docs indicate to use " not ' for docstrings. test/py has other violations of the coding style docs, since the docs specify a stranger style than I would expect, but nobody has complained about those yet:-) Signed-off-by: Stephen Warren <swarren@nvidia.com> Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
56382a81f3
commit
e8debf394f
19 changed files with 245 additions and 245 deletions
|
@ -29,7 +29,7 @@ log = None
|
||||||
console = None
|
console = None
|
||||||
|
|
||||||
def mkdir_p(path):
|
def mkdir_p(path):
|
||||||
'''Create a directory path.
|
"""Create a directory path.
|
||||||
|
|
||||||
This includes creating any intermediate/parent directories. Any errors
|
This includes creating any intermediate/parent directories. Any errors
|
||||||
caused due to already extant directories are ignored.
|
caused due to already extant directories are ignored.
|
||||||
|
@ -39,7 +39,7 @@ def mkdir_p(path):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
os.makedirs(path)
|
os.makedirs(path)
|
||||||
|
@ -50,14 +50,14 @@ def mkdir_p(path):
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def pytest_addoption(parser):
|
def pytest_addoption(parser):
|
||||||
'''pytest hook: Add custom command-line options to the cmdline parser.
|
"""pytest hook: Add custom command-line options to the cmdline parser.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
parser: The pytest command-line parser.
|
parser: The pytest command-line parser.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
parser.addoption('--build-dir', default=None,
|
parser.addoption('--build-dir', default=None,
|
||||||
help='U-Boot build directory (O=)')
|
help='U-Boot build directory (O=)')
|
||||||
|
@ -73,14 +73,14 @@ def pytest_addoption(parser):
|
||||||
help='Compile U-Boot before running tests')
|
help='Compile U-Boot before running tests')
|
||||||
|
|
||||||
def pytest_configure(config):
|
def pytest_configure(config):
|
||||||
'''pytest hook: Perform custom initialization at startup time.
|
"""pytest hook: Perform custom initialization at startup time.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
config: The pytest configuration.
|
config: The pytest configuration.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
global log
|
global log
|
||||||
global console
|
global console
|
||||||
|
@ -190,7 +190,7 @@ def pytest_configure(config):
|
||||||
console = u_boot_console_exec_attach.ConsoleExecAttach(log, ubconfig)
|
console = u_boot_console_exec_attach.ConsoleExecAttach(log, ubconfig)
|
||||||
|
|
||||||
def pytest_generate_tests(metafunc):
|
def pytest_generate_tests(metafunc):
|
||||||
'''pytest hook: parameterize test functions based on custom rules.
|
"""pytest hook: parameterize test functions based on custom rules.
|
||||||
|
|
||||||
If a test function takes parameter(s) (fixture names) of the form brd__xxx
|
If a test function takes parameter(s) (fixture names) of the form brd__xxx
|
||||||
or env__xxx, the brd and env configuration dictionaries are consulted to
|
or env__xxx, the brd and env configuration dictionaries are consulted to
|
||||||
|
@ -202,7 +202,7 @@ def pytest_generate_tests(metafunc):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
subconfigs = {
|
subconfigs = {
|
||||||
'brd': console.config.brd,
|
'brd': console.config.brd,
|
||||||
|
@ -229,14 +229,14 @@ def pytest_generate_tests(metafunc):
|
||||||
|
|
||||||
@pytest.fixture(scope='function')
|
@pytest.fixture(scope='function')
|
||||||
def u_boot_console(request):
|
def u_boot_console(request):
|
||||||
'''Generate the value of a test's u_boot_console fixture.
|
"""Generate the value of a test's u_boot_console fixture.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
request: The pytest request.
|
request: The pytest request.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The fixture value.
|
The fixture value.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
console.ensure_spawned()
|
console.ensure_spawned()
|
||||||
return console
|
return console
|
||||||
|
@ -247,7 +247,7 @@ tests_skipped = set()
|
||||||
tests_passed = set()
|
tests_passed = set()
|
||||||
|
|
||||||
def pytest_itemcollected(item):
|
def pytest_itemcollected(item):
|
||||||
'''pytest hook: Called once for each test found during collection.
|
"""pytest hook: Called once for each test found during collection.
|
||||||
|
|
||||||
This enables our custom result analysis code to see the list of all tests
|
This enables our custom result analysis code to see the list of all tests
|
||||||
that should eventually be run.
|
that should eventually be run.
|
||||||
|
@ -257,12 +257,12 @@ def pytest_itemcollected(item):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
tests_not_run.add(item.name)
|
tests_not_run.add(item.name)
|
||||||
|
|
||||||
def cleanup():
|
def cleanup():
|
||||||
'''Clean up all global state.
|
"""Clean up all global state.
|
||||||
|
|
||||||
Executed (via atexit) once the entire test process is complete. This
|
Executed (via atexit) once the entire test process is complete. This
|
||||||
includes logging the status of all tests, and the identity of any failed
|
includes logging the status of all tests, and the identity of any failed
|
||||||
|
@ -273,7 +273,7 @@ def cleanup():
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
if console:
|
if console:
|
||||||
console.close()
|
console.close()
|
||||||
|
@ -295,7 +295,7 @@ def cleanup():
|
||||||
atexit.register(cleanup)
|
atexit.register(cleanup)
|
||||||
|
|
||||||
def setup_boardspec(item):
|
def setup_boardspec(item):
|
||||||
'''Process any 'boardspec' marker for a test.
|
"""Process any 'boardspec' marker for a test.
|
||||||
|
|
||||||
Such a marker lists the set of board types that a test does/doesn't
|
Such a marker lists the set of board types that a test does/doesn't
|
||||||
support. If tests are being executed on an unsupported board, the test is
|
support. If tests are being executed on an unsupported board, the test is
|
||||||
|
@ -306,7 +306,7 @@ def setup_boardspec(item):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
mark = item.get_marker('boardspec')
|
mark = item.get_marker('boardspec')
|
||||||
if not mark:
|
if not mark:
|
||||||
|
@ -323,7 +323,7 @@ def setup_boardspec(item):
|
||||||
pytest.skip('board not supported')
|
pytest.skip('board not supported')
|
||||||
|
|
||||||
def setup_buildconfigspec(item):
|
def setup_buildconfigspec(item):
|
||||||
'''Process any 'buildconfigspec' marker for a test.
|
"""Process any 'buildconfigspec' marker for a test.
|
||||||
|
|
||||||
Such a marker lists some U-Boot configuration feature that the test
|
Such a marker lists some U-Boot configuration feature that the test
|
||||||
requires. If tests are being executed on an U-Boot build that doesn't
|
requires. If tests are being executed on an U-Boot build that doesn't
|
||||||
|
@ -334,7 +334,7 @@ def setup_buildconfigspec(item):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
mark = item.get_marker('buildconfigspec')
|
mark = item.get_marker('buildconfigspec')
|
||||||
if not mark:
|
if not mark:
|
||||||
|
@ -344,7 +344,7 @@ def setup_buildconfigspec(item):
|
||||||
pytest.skip('.config feature not enabled')
|
pytest.skip('.config feature not enabled')
|
||||||
|
|
||||||
def pytest_runtest_setup(item):
|
def pytest_runtest_setup(item):
|
||||||
'''pytest hook: Configure (set up) a test item.
|
"""pytest hook: Configure (set up) a test item.
|
||||||
|
|
||||||
Called once for each test to perform any custom configuration. This hook
|
Called once for each test to perform any custom configuration. This hook
|
||||||
is used to skip the test if certain conditions apply.
|
is used to skip the test if certain conditions apply.
|
||||||
|
@ -354,14 +354,14 @@ def pytest_runtest_setup(item):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
log.start_section(item.name)
|
log.start_section(item.name)
|
||||||
setup_boardspec(item)
|
setup_boardspec(item)
|
||||||
setup_buildconfigspec(item)
|
setup_buildconfigspec(item)
|
||||||
|
|
||||||
def pytest_runtest_protocol(item, nextitem):
|
def pytest_runtest_protocol(item, nextitem):
|
||||||
'''pytest hook: Called to execute a test.
|
"""pytest hook: Called to execute a test.
|
||||||
|
|
||||||
This hook wraps the standard pytest runtestprotocol() function in order
|
This hook wraps the standard pytest runtestprotocol() function in order
|
||||||
to acquire visibility into, and record, each test function's result.
|
to acquire visibility into, and record, each test function's result.
|
||||||
|
@ -372,7 +372,7 @@ def pytest_runtest_protocol(item, nextitem):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A list of pytest reports (test result data).
|
A list of pytest reports (test result data).
|
||||||
'''
|
"""
|
||||||
|
|
||||||
reports = runtestprotocol(item, nextitem=nextitem)
|
reports = runtestprotocol(item, nextitem=nextitem)
|
||||||
failed = None
|
failed = None
|
||||||
|
|
|
@ -14,12 +14,12 @@ import subprocess
|
||||||
mod_dir = os.path.dirname(os.path.abspath(__file__))
|
mod_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
class LogfileStream(object):
|
class LogfileStream(object):
|
||||||
'''A file-like object used to write a single logical stream of data into
|
"""A file-like object used to write a single logical stream of data into
|
||||||
a multiplexed log file. Objects of this type should be created by factory
|
a multiplexed log file. Objects of this type should be created by factory
|
||||||
functions in the Logfile class rather than directly.'''
|
functions in the Logfile class rather than directly."""
|
||||||
|
|
||||||
def __init__(self, logfile, name, chained_file):
|
def __init__(self, logfile, name, chained_file):
|
||||||
'''Initialize a new object.
|
"""Initialize a new object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
logfile: The Logfile object to log to.
|
logfile: The Logfile object to log to.
|
||||||
|
@ -29,26 +29,26 @@ class LogfileStream(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self.logfile = logfile
|
self.logfile = logfile
|
||||||
self.name = name
|
self.name = name
|
||||||
self.chained_file = chained_file
|
self.chained_file = chained_file
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
'''Dummy function so that this class is "file-like".
|
"""Dummy function so that this class is "file-like".
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
None.
|
None.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def write(self, data, implicit=False):
|
def write(self, data, implicit=False):
|
||||||
'''Write data to the log stream.
|
"""Write data to the log stream.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
data: The data to write tot he file.
|
data: The data to write tot he file.
|
||||||
|
@ -60,33 +60,33 @@ class LogfileStream(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self.logfile.write(self, data, implicit)
|
self.logfile.write(self, data, implicit)
|
||||||
if self.chained_file:
|
if self.chained_file:
|
||||||
self.chained_file.write(data)
|
self.chained_file.write(data)
|
||||||
|
|
||||||
def flush(self):
|
def flush(self):
|
||||||
'''Flush the log stream, to ensure correct log interleaving.
|
"""Flush the log stream, to ensure correct log interleaving.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
None.
|
None.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self.logfile.flush()
|
self.logfile.flush()
|
||||||
if self.chained_file:
|
if self.chained_file:
|
||||||
self.chained_file.flush()
|
self.chained_file.flush()
|
||||||
|
|
||||||
class RunAndLog(object):
|
class RunAndLog(object):
|
||||||
'''A utility object used to execute sub-processes and log their output to
|
"""A utility object used to execute sub-processes and log their output to
|
||||||
a multiplexed log file. Objects of this type should be created by factory
|
a multiplexed log file. Objects of this type should be created by factory
|
||||||
functions in the Logfile class rather than directly.'''
|
functions in the Logfile class rather than directly."""
|
||||||
|
|
||||||
def __init__(self, logfile, name, chained_file):
|
def __init__(self, logfile, name, chained_file):
|
||||||
'''Initialize a new object.
|
"""Initialize a new object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
logfile: The Logfile object to log to.
|
logfile: The Logfile object to log to.
|
||||||
|
@ -96,18 +96,18 @@ class RunAndLog(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self.logfile = logfile
|
self.logfile = logfile
|
||||||
self.name = name
|
self.name = name
|
||||||
self.chained_file = chained_file
|
self.chained_file = chained_file
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
'''Clean up any resources managed by this object.'''
|
"""Clean up any resources managed by this object."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def run(self, cmd, cwd=None, ignore_errors=False):
|
def run(self, cmd, cwd=None, ignore_errors=False):
|
||||||
'''Run a command as a sub-process, and log the results.
|
"""Run a command as a sub-process, and log the results.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
cmd: The command to execute.
|
cmd: The command to execute.
|
||||||
|
@ -120,7 +120,7 @@ class RunAndLog(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
msg = "+" + " ".join(cmd) + "\n"
|
msg = "+" + " ".join(cmd) + "\n"
|
||||||
if self.chained_file:
|
if self.chained_file:
|
||||||
|
@ -163,13 +163,13 @@ class RunAndLog(object):
|
||||||
raise exception
|
raise exception
|
||||||
|
|
||||||
class SectionCtxMgr(object):
|
class SectionCtxMgr(object):
|
||||||
'''A context manager for Python's "with" statement, which allows a certain
|
"""A context manager for Python's "with" statement, which allows a certain
|
||||||
portion of test code to be logged to a separate section of the log file.
|
portion of test code to be logged to a separate section of the log file.
|
||||||
Objects of this type should be created by factory functions in the Logfile
|
Objects of this type should be created by factory functions in the Logfile
|
||||||
class rather than directly.'''
|
class rather than directly."""
|
||||||
|
|
||||||
def __init__(self, log, marker):
|
def __init__(self, log, marker):
|
||||||
'''Initialize a new object.
|
"""Initialize a new object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
log: The Logfile object to log to.
|
log: The Logfile object to log to.
|
||||||
|
@ -177,7 +177,7 @@ class SectionCtxMgr(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self.log = log
|
self.log = log
|
||||||
self.marker = marker
|
self.marker = marker
|
||||||
|
@ -189,18 +189,18 @@ class SectionCtxMgr(object):
|
||||||
self.log.end_section(self.marker)
|
self.log.end_section(self.marker)
|
||||||
|
|
||||||
class Logfile(object):
|
class Logfile(object):
|
||||||
'''Generates an HTML-formatted log file containing multiple streams of
|
"""Generates an HTML-formatted log file containing multiple streams of
|
||||||
data, each represented in a well-delineated/-structured fashion.'''
|
data, each represented in a well-delineated/-structured fashion."""
|
||||||
|
|
||||||
def __init__(self, fn):
|
def __init__(self, fn):
|
||||||
'''Initialize a new object.
|
"""Initialize a new object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
fn: The filename to write to.
|
fn: The filename to write to.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self.f = open(fn, "wt")
|
self.f = open(fn, "wt")
|
||||||
self.last_stream = None
|
self.last_stream = None
|
||||||
|
@ -217,7 +217,7 @@ class Logfile(object):
|
||||||
""")
|
""")
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
'''Close the log file.
|
"""Close the log file.
|
||||||
|
|
||||||
After calling this function, no more data may be written to the log.
|
After calling this function, no more data may be written to the log.
|
||||||
|
|
||||||
|
@ -226,7 +226,7 @@ class Logfile(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self.f.write("""\
|
self.f.write("""\
|
||||||
</tt>
|
</tt>
|
||||||
|
@ -241,7 +241,7 @@ class Logfile(object):
|
||||||
"".join(chr(c) for c in range(127, 256)))
|
"".join(chr(c) for c in range(127, 256)))
|
||||||
|
|
||||||
def _escape(self, data):
|
def _escape(self, data):
|
||||||
'''Render data format suitable for inclusion in an HTML document.
|
"""Render data format suitable for inclusion in an HTML document.
|
||||||
|
|
||||||
This includes HTML-escaping certain characters, and translating
|
This includes HTML-escaping certain characters, and translating
|
||||||
control characters to a hexadecimal representation.
|
control characters to a hexadecimal representation.
|
||||||
|
@ -251,7 +251,7 @@ class Logfile(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
An escaped version of the data.
|
An escaped version of the data.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
data = data.replace(chr(13), "")
|
data = data.replace(chr(13), "")
|
||||||
data = "".join((c in self._nonprint) and ("%%%02x" % ord(c)) or
|
data = "".join((c in self._nonprint) and ("%%%02x" % ord(c)) or
|
||||||
|
@ -260,14 +260,14 @@ class Logfile(object):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def _terminate_stream(self):
|
def _terminate_stream(self):
|
||||||
'''Write HTML to the log file to terminate the current stream's data.
|
"""Write HTML to the log file to terminate the current stream's data.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
None.
|
None.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self.cur_evt += 1
|
self.cur_evt += 1
|
||||||
if not self.last_stream:
|
if not self.last_stream:
|
||||||
|
@ -280,7 +280,7 @@ class Logfile(object):
|
||||||
self.last_stream = None
|
self.last_stream = None
|
||||||
|
|
||||||
def _note(self, note_type, msg):
|
def _note(self, note_type, msg):
|
||||||
'''Write a note or one-off message to the log file.
|
"""Write a note or one-off message to the log file.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
note_type: The type of note. This must be a value supported by the
|
note_type: The type of note. This must be a value supported by the
|
||||||
|
@ -289,7 +289,7 @@ class Logfile(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self._terminate_stream()
|
self._terminate_stream()
|
||||||
self.f.write("<div class=\"" + note_type + "\">\n<pre>")
|
self.f.write("<div class=\"" + note_type + "\">\n<pre>")
|
||||||
|
@ -297,14 +297,14 @@ class Logfile(object):
|
||||||
self.f.write("\n</pre></div>\n")
|
self.f.write("\n</pre></div>\n")
|
||||||
|
|
||||||
def start_section(self, marker):
|
def start_section(self, marker):
|
||||||
'''Begin a new nested section in the log file.
|
"""Begin a new nested section in the log file.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
marker: The name of the section that is starting.
|
marker: The name of the section that is starting.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self._terminate_stream()
|
self._terminate_stream()
|
||||||
self.blocks.append(marker)
|
self.blocks.append(marker)
|
||||||
|
@ -314,7 +314,7 @@ class Logfile(object):
|
||||||
"\">Section: " + blk_path + "</div>\n")
|
"\">Section: " + blk_path + "</div>\n")
|
||||||
|
|
||||||
def end_section(self, marker):
|
def end_section(self, marker):
|
||||||
'''Terminate the current nested section in the log file.
|
"""Terminate the current nested section in the log file.
|
||||||
|
|
||||||
This function validates proper nesting of start_section() and
|
This function validates proper nesting of start_section() and
|
||||||
end_section() calls. If a mismatch is found, an exception is raised.
|
end_section() calls. If a mismatch is found, an exception is raised.
|
||||||
|
@ -324,7 +324,7 @@ class Logfile(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
if (not self.blocks) or (marker != self.blocks[-1]):
|
if (not self.blocks) or (marker != self.blocks[-1]):
|
||||||
raise Exception("Block nesting mismatch: \"%s\" \"%s\"" %
|
raise Exception("Block nesting mismatch: \"%s\" \"%s\"" %
|
||||||
|
@ -337,7 +337,7 @@ class Logfile(object):
|
||||||
self.blocks.pop()
|
self.blocks.pop()
|
||||||
|
|
||||||
def section(self, marker):
|
def section(self, marker):
|
||||||
'''Create a temporary section in the log file.
|
"""Create a temporary section in the log file.
|
||||||
|
|
||||||
This function creates a context manager for Python's "with" statement,
|
This function creates a context manager for Python's "with" statement,
|
||||||
which allows a certain portion of test code to be logged to a separate
|
which allows a certain portion of test code to be logged to a separate
|
||||||
|
@ -352,96 +352,96 @@ class Logfile(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A context manager object.
|
A context manager object.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
return SectionCtxMgr(self, marker)
|
return SectionCtxMgr(self, marker)
|
||||||
|
|
||||||
def error(self, msg):
|
def error(self, msg):
|
||||||
'''Write an error note to the log file.
|
"""Write an error note to the log file.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
msg: A message describing the error.
|
msg: A message describing the error.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self._note("error", msg)
|
self._note("error", msg)
|
||||||
|
|
||||||
def warning(self, msg):
|
def warning(self, msg):
|
||||||
'''Write an warning note to the log file.
|
"""Write an warning note to the log file.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
msg: A message describing the warning.
|
msg: A message describing the warning.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self._note("warning", msg)
|
self._note("warning", msg)
|
||||||
|
|
||||||
def info(self, msg):
|
def info(self, msg):
|
||||||
'''Write an informational note to the log file.
|
"""Write an informational note to the log file.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
msg: An informational message.
|
msg: An informational message.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self._note("info", msg)
|
self._note("info", msg)
|
||||||
|
|
||||||
def action(self, msg):
|
def action(self, msg):
|
||||||
'''Write an action note to the log file.
|
"""Write an action note to the log file.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
msg: A message describing the action that is being logged.
|
msg: A message describing the action that is being logged.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self._note("action", msg)
|
self._note("action", msg)
|
||||||
|
|
||||||
def status_pass(self, msg):
|
def status_pass(self, msg):
|
||||||
'''Write a note to the log file describing test(s) which passed.
|
"""Write a note to the log file describing test(s) which passed.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
msg: A message describing passed test(s).
|
msg: A message describing passed test(s).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self._note("status-pass", msg)
|
self._note("status-pass", msg)
|
||||||
|
|
||||||
def status_skipped(self, msg):
|
def status_skipped(self, msg):
|
||||||
'''Write a note to the log file describing skipped test(s).
|
"""Write a note to the log file describing skipped test(s).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
msg: A message describing passed test(s).
|
msg: A message describing passed test(s).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self._note("status-skipped", msg)
|
self._note("status-skipped", msg)
|
||||||
|
|
||||||
def status_fail(self, msg):
|
def status_fail(self, msg):
|
||||||
'''Write a note to the log file describing failed test(s).
|
"""Write a note to the log file describing failed test(s).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
msg: A message describing passed test(s).
|
msg: A message describing passed test(s).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self._note("status-fail", msg)
|
self._note("status-fail", msg)
|
||||||
|
|
||||||
def get_stream(self, name, chained_file=None):
|
def get_stream(self, name, chained_file=None):
|
||||||
'''Create an object to log a single stream's data into the log file.
|
"""Create an object to log a single stream's data into the log file.
|
||||||
|
|
||||||
This creates a "file-like" object that can be written to in order to
|
This creates a "file-like" object that can be written to in order to
|
||||||
write a single stream's data to the log file. The implementation will
|
write a single stream's data to the log file. The implementation will
|
||||||
|
@ -456,12 +456,12 @@ class Logfile(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A file-like object.
|
A file-like object.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
return LogfileStream(self, name, chained_file)
|
return LogfileStream(self, name, chained_file)
|
||||||
|
|
||||||
def get_runner(self, name, chained_file=None):
|
def get_runner(self, name, chained_file=None):
|
||||||
'''Create an object that executes processes and logs their output.
|
"""Create an object that executes processes and logs their output.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
name: The name of this sub-process.
|
name: The name of this sub-process.
|
||||||
|
@ -470,12 +470,12 @@ class Logfile(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A RunAndLog object.
|
A RunAndLog object.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
return RunAndLog(self, name, chained_file)
|
return RunAndLog(self, name, chained_file)
|
||||||
|
|
||||||
def write(self, stream, data, implicit=False):
|
def write(self, stream, data, implicit=False):
|
||||||
'''Write stream data into the log file.
|
"""Write stream data into the log file.
|
||||||
|
|
||||||
This function should only be used by instances of LogfileStream or
|
This function should only be used by instances of LogfileStream or
|
||||||
RunAndLog.
|
RunAndLog.
|
||||||
|
@ -491,7 +491,7 @@ class Logfile(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
if stream != self.last_stream:
|
if stream != self.last_stream:
|
||||||
self._terminate_stream()
|
self._terminate_stream()
|
||||||
|
@ -507,13 +507,13 @@ class Logfile(object):
|
||||||
self.last_stream = stream
|
self.last_stream = stream
|
||||||
|
|
||||||
def flush(self):
|
def flush(self):
|
||||||
'''Flush the log stream, to ensure correct log interleaving.
|
"""Flush the log stream, to ensure correct log interleaving.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
None.
|
None.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self.f.flush()
|
self.f.flush()
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
# command prompt.
|
# command prompt.
|
||||||
|
|
||||||
def test_version(u_boot_console):
|
def test_version(u_boot_console):
|
||||||
'''Test that the "version" command prints the U-Boot version.'''
|
"""Test that the "version" command prints the U-Boot version."""
|
||||||
|
|
||||||
# "version" prints the U-Boot sign-on message. This is usually considered
|
# "version" prints the U-Boot sign-on message. This is usually considered
|
||||||
# an error, so that any unexpected reboot causes an error. Here, this
|
# an error, so that any unexpected reboot causes an error. Here, this
|
||||||
|
|
|
@ -12,7 +12,7 @@ import os.path
|
||||||
import pytest
|
import pytest
|
||||||
import u_boot_utils
|
import u_boot_utils
|
||||||
|
|
||||||
'''
|
"""
|
||||||
Note: This test relies on:
|
Note: This test relies on:
|
||||||
|
|
||||||
a) boardenv_* to contain configuration values to define which USB ports are
|
a) boardenv_* to contain configuration values to define which USB ports are
|
||||||
|
@ -44,7 +44,7 @@ ACTION=="add", SUBSYSTEM=="block", SUBSYSTEMS=="usb", KERNELS=="3-13", MODE:="66
|
||||||
(You may wish to change the group ID instead of setting the permissions wide
|
(You may wish to change the group ID instead of setting the permissions wide
|
||||||
open. All that matters is that the user ID running the test can access the
|
open. All that matters is that the user ID running the test can access the
|
||||||
device.)
|
device.)
|
||||||
'''
|
"""
|
||||||
|
|
||||||
# The set of file sizes to test. These values trigger various edge-cases such
|
# The set of file sizes to test. These values trigger various edge-cases such
|
||||||
# as one less than, equal to, and one greater than typical USB max packet
|
# as one less than, equal to, and one greater than typical USB max packet
|
||||||
|
@ -71,7 +71,7 @@ first_usb_dev_port = None
|
||||||
|
|
||||||
@pytest.mark.buildconfigspec('cmd_dfu')
|
@pytest.mark.buildconfigspec('cmd_dfu')
|
||||||
def test_dfu(u_boot_console, env__usb_dev_port, env__dfu_config):
|
def test_dfu(u_boot_console, env__usb_dev_port, env__dfu_config):
|
||||||
'''Test the "dfu" command; the host system must be able to enumerate a USB
|
"""Test the "dfu" command; the host system must be able to enumerate a USB
|
||||||
device when "dfu" is running, various DFU transfers are tested, and the
|
device when "dfu" is running, various DFU transfers are tested, and the
|
||||||
USB device must disappear when "dfu" is aborted.
|
USB device must disappear when "dfu" is aborted.
|
||||||
|
|
||||||
|
@ -86,10 +86,10 @@ def test_dfu(u_boot_console, env__usb_dev_port, env__dfu_config):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
def start_dfu():
|
def start_dfu():
|
||||||
'''Start U-Boot's dfu shell command.
|
"""Start U-Boot's dfu shell command.
|
||||||
|
|
||||||
This also waits for the host-side USB enumeration process to complete.
|
This also waits for the host-side USB enumeration process to complete.
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ def test_dfu(u_boot_console, env__usb_dev_port, env__dfu_config):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
fh = u_boot_utils.attempt_to_open_file(
|
fh = u_boot_utils.attempt_to_open_file(
|
||||||
env__usb_dev_port['host_usb_dev_node'])
|
env__usb_dev_port['host_usb_dev_node'])
|
||||||
|
@ -120,7 +120,7 @@ def test_dfu(u_boot_console, env__usb_dev_port, env__dfu_config):
|
||||||
fh.close()
|
fh.close()
|
||||||
|
|
||||||
def stop_dfu(ignore_errors):
|
def stop_dfu(ignore_errors):
|
||||||
'''Stop U-Boot's dfu shell command from executing.
|
"""Stop U-Boot's dfu shell command from executing.
|
||||||
|
|
||||||
This also waits for the host-side USB de-enumeration process to
|
This also waits for the host-side USB de-enumeration process to
|
||||||
complete.
|
complete.
|
||||||
|
@ -133,7 +133,7 @@ def test_dfu(u_boot_console, env__usb_dev_port, env__dfu_config):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
u_boot_console.log.action(
|
u_boot_console.log.action(
|
||||||
|
@ -148,7 +148,7 @@ def test_dfu(u_boot_console, env__usb_dev_port, env__dfu_config):
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def run_dfu_util(alt_setting, fn, up_dn_load_arg):
|
def run_dfu_util(alt_setting, fn, up_dn_load_arg):
|
||||||
'''Invoke dfu-util on the host.
|
"""Invoke dfu-util on the host.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
alt_setting: The DFU "alternate setting" identifier to interact
|
alt_setting: The DFU "alternate setting" identifier to interact
|
||||||
|
@ -159,7 +159,7 @@ def test_dfu(u_boot_console, env__usb_dev_port, env__dfu_config):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
cmd = ['dfu-util', '-a', str(alt_setting), up_dn_load_arg, fn]
|
cmd = ['dfu-util', '-a', str(alt_setting), up_dn_load_arg, fn]
|
||||||
if 'host_usb_port_path' in env__usb_dev_port:
|
if 'host_usb_port_path' in env__usb_dev_port:
|
||||||
|
@ -168,7 +168,7 @@ def test_dfu(u_boot_console, env__usb_dev_port, env__dfu_config):
|
||||||
u_boot_console.wait_for('Ctrl+C to exit ...')
|
u_boot_console.wait_for('Ctrl+C to exit ...')
|
||||||
|
|
||||||
def dfu_write(alt_setting, fn):
|
def dfu_write(alt_setting, fn):
|
||||||
'''Write a file to the target board using DFU.
|
"""Write a file to the target board using DFU.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
alt_setting: The DFU "alternate setting" identifier to interact
|
alt_setting: The DFU "alternate setting" identifier to interact
|
||||||
|
@ -177,12 +177,12 @@ def test_dfu(u_boot_console, env__usb_dev_port, env__dfu_config):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
run_dfu_util(alt_setting, fn, '-D')
|
run_dfu_util(alt_setting, fn, '-D')
|
||||||
|
|
||||||
def dfu_read(alt_setting, fn):
|
def dfu_read(alt_setting, fn):
|
||||||
'''Read a file from the target board using DFU.
|
"""Read a file from the target board using DFU.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
alt_setting: The DFU "alternate setting" identifier to interact
|
alt_setting: The DFU "alternate setting" identifier to interact
|
||||||
|
@ -191,7 +191,7 @@ def test_dfu(u_boot_console, env__usb_dev_port, env__dfu_config):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
# dfu-util fails reads/uploads if the host file already exists
|
# dfu-util fails reads/uploads if the host file already exists
|
||||||
if os.path.exists(fn):
|
if os.path.exists(fn):
|
||||||
|
@ -199,7 +199,7 @@ def test_dfu(u_boot_console, env__usb_dev_port, env__dfu_config):
|
||||||
run_dfu_util(alt_setting, fn, '-U')
|
run_dfu_util(alt_setting, fn, '-U')
|
||||||
|
|
||||||
def dfu_write_read_check(size):
|
def dfu_write_read_check(size):
|
||||||
'''Test DFU transfers of a specific size of data
|
"""Test DFU transfers of a specific size of data
|
||||||
|
|
||||||
This function first writes data to the board then reads it back and
|
This function first writes data to the board then reads it back and
|
||||||
compares the written and read back data. Measures are taken to avoid
|
compares the written and read back data. Measures are taken to avoid
|
||||||
|
@ -210,7 +210,7 @@ def test_dfu(u_boot_console, env__usb_dev_port, env__dfu_config):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
test_f = u_boot_utils.PersistentRandomFile(u_boot_console,
|
test_f = u_boot_utils.PersistentRandomFile(u_boot_console,
|
||||||
'dfu_%d.bin' % size, size)
|
'dfu_%d.bin' % size, size)
|
||||||
|
|
|
@ -10,34 +10,34 @@ import pytest
|
||||||
# FIXME: This might be useful for other tests;
|
# FIXME: This might be useful for other tests;
|
||||||
# perhaps refactor it into ConsoleBase or some other state object?
|
# perhaps refactor it into ConsoleBase or some other state object?
|
||||||
class StateTestEnv(object):
|
class StateTestEnv(object):
|
||||||
'''Container that represents the state of all U-Boot environment variables.
|
"""Container that represents the state of all U-Boot environment variables.
|
||||||
This enables quick determination of existant/non-existant variable
|
This enables quick determination of existant/non-existant variable
|
||||||
names.
|
names.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
def __init__(self, u_boot_console):
|
def __init__(self, u_boot_console):
|
||||||
'''Initialize a new StateTestEnv object.
|
"""Initialize a new StateTestEnv object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
u_boot_console: A U-Boot console.
|
u_boot_console: A U-Boot console.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self.u_boot_console = u_boot_console
|
self.u_boot_console = u_boot_console
|
||||||
self.get_env()
|
self.get_env()
|
||||||
self.set_var = self.get_non_existent_var()
|
self.set_var = self.get_non_existent_var()
|
||||||
|
|
||||||
def get_env(self):
|
def get_env(self):
|
||||||
'''Read all current environment variables from U-Boot.
|
"""Read all current environment variables from U-Boot.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
None.
|
None.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
response = self.u_boot_console.run_command('printenv')
|
response = self.u_boot_console.run_command('printenv')
|
||||||
self.env = {}
|
self.env = {}
|
||||||
|
@ -48,27 +48,27 @@ class StateTestEnv(object):
|
||||||
self.env[var] = value
|
self.env[var] = value
|
||||||
|
|
||||||
def get_existent_var(self):
|
def get_existent_var(self):
|
||||||
'''Return the name of an environment variable that exists.
|
"""Return the name of an environment variable that exists.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
None.
|
None.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The name of an environment variable.
|
The name of an environment variable.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
for var in self.env:
|
for var in self.env:
|
||||||
return var
|
return var
|
||||||
|
|
||||||
def get_non_existent_var(self):
|
def get_non_existent_var(self):
|
||||||
'''Return the name of an environment variable that does not exist.
|
"""Return the name of an environment variable that does not exist.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
None.
|
None.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The name of an environment variable.
|
The name of an environment variable.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
n = 0
|
n = 0
|
||||||
while True:
|
while True:
|
||||||
|
@ -80,7 +80,7 @@ class StateTestEnv(object):
|
||||||
ste = None
|
ste = None
|
||||||
@pytest.fixture(scope='function')
|
@pytest.fixture(scope='function')
|
||||||
def state_test_env(u_boot_console):
|
def state_test_env(u_boot_console):
|
||||||
'''pytest fixture to provide a StateTestEnv object to tests.'''
|
"""pytest fixture to provide a StateTestEnv object to tests."""
|
||||||
|
|
||||||
global ste
|
global ste
|
||||||
if not ste:
|
if not ste:
|
||||||
|
@ -88,7 +88,7 @@ def state_test_env(u_boot_console):
|
||||||
return ste
|
return ste
|
||||||
|
|
||||||
def unset_var(state_test_env, var):
|
def unset_var(state_test_env, var):
|
||||||
'''Unset an environment variable.
|
"""Unset an environment variable.
|
||||||
|
|
||||||
This both executes a U-Boot shell command and updates a StateTestEnv
|
This both executes a U-Boot shell command and updates a StateTestEnv
|
||||||
object.
|
object.
|
||||||
|
@ -99,14 +99,14 @@ def unset_var(state_test_env, var):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
state_test_env.u_boot_console.run_command('setenv %s' % var)
|
state_test_env.u_boot_console.run_command('setenv %s' % var)
|
||||||
if var in state_test_env.env:
|
if var in state_test_env.env:
|
||||||
del state_test_env.env[var]
|
del state_test_env.env[var]
|
||||||
|
|
||||||
def set_var(state_test_env, var, value):
|
def set_var(state_test_env, var, value):
|
||||||
'''Set an environment variable.
|
"""Set an environment variable.
|
||||||
|
|
||||||
This both executes a U-Boot shell command and updates a StateTestEnv
|
This both executes a U-Boot shell command and updates a StateTestEnv
|
||||||
object.
|
object.
|
||||||
|
@ -118,26 +118,26 @@ def set_var(state_test_env, var, value):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
state_test_env.u_boot_console.run_command('setenv %s "%s"' % (var, value))
|
state_test_env.u_boot_console.run_command('setenv %s "%s"' % (var, value))
|
||||||
state_test_env.env[var] = value
|
state_test_env.env[var] = value
|
||||||
|
|
||||||
def validate_empty(state_test_env, var):
|
def validate_empty(state_test_env, var):
|
||||||
'''Validate that a variable is not set, using U-Boot shell commands.
|
"""Validate that a variable is not set, using U-Boot shell commands.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
var: The variable name to test.
|
var: The variable name to test.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
response = state_test_env.u_boot_console.run_command('echo $%s' % var)
|
response = state_test_env.u_boot_console.run_command('echo $%s' % var)
|
||||||
assert response == ''
|
assert response == ''
|
||||||
|
|
||||||
def validate_set(state_test_env, var, value):
|
def validate_set(state_test_env, var, value):
|
||||||
'''Validate that a variable is set, using U-Boot shell commands.
|
"""Validate that a variable is set, using U-Boot shell commands.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
var: The variable name to test.
|
var: The variable name to test.
|
||||||
|
@ -145,7 +145,7 @@ def validate_set(state_test_env, var, value):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
# echo does not preserve leading, internal, or trailing whitespace in the
|
# echo does not preserve leading, internal, or trailing whitespace in the
|
||||||
# value. printenv does, and hence allows more complete testing.
|
# value. printenv does, and hence allows more complete testing.
|
||||||
|
@ -153,20 +153,20 @@ def validate_set(state_test_env, var, value):
|
||||||
assert response == ('%s=%s' % (var, value))
|
assert response == ('%s=%s' % (var, value))
|
||||||
|
|
||||||
def test_env_echo_exists(state_test_env):
|
def test_env_echo_exists(state_test_env):
|
||||||
'''Test echoing a variable that exists.'''
|
"""Test echoing a variable that exists."""
|
||||||
|
|
||||||
var = state_test_env.get_existent_var()
|
var = state_test_env.get_existent_var()
|
||||||
value = state_test_env.env[var]
|
value = state_test_env.env[var]
|
||||||
validate_set(state_test_env, var, value)
|
validate_set(state_test_env, var, value)
|
||||||
|
|
||||||
def test_env_echo_non_existent(state_test_env):
|
def test_env_echo_non_existent(state_test_env):
|
||||||
'''Test echoing a variable that doesn't exist.'''
|
"""Test echoing a variable that doesn't exist."""
|
||||||
|
|
||||||
var = state_test_env.set_var
|
var = state_test_env.set_var
|
||||||
validate_empty(state_test_env, var)
|
validate_empty(state_test_env, var)
|
||||||
|
|
||||||
def test_env_printenv_non_existent(state_test_env):
|
def test_env_printenv_non_existent(state_test_env):
|
||||||
'''Test printenv error message for non-existant variables.'''
|
"""Test printenv error message for non-existant variables."""
|
||||||
|
|
||||||
var = state_test_env.set_var
|
var = state_test_env.set_var
|
||||||
c = state_test_env.u_boot_console
|
c = state_test_env.u_boot_console
|
||||||
|
@ -175,14 +175,14 @@ def test_env_printenv_non_existent(state_test_env):
|
||||||
assert(response == '## Error: "%s" not defined' % var)
|
assert(response == '## Error: "%s" not defined' % var)
|
||||||
|
|
||||||
def test_env_unset_non_existent(state_test_env):
|
def test_env_unset_non_existent(state_test_env):
|
||||||
'''Test unsetting a nonexistent variable.'''
|
"""Test unsetting a nonexistent variable."""
|
||||||
|
|
||||||
var = state_test_env.get_non_existent_var()
|
var = state_test_env.get_non_existent_var()
|
||||||
unset_var(state_test_env, var)
|
unset_var(state_test_env, var)
|
||||||
validate_empty(state_test_env, var)
|
validate_empty(state_test_env, var)
|
||||||
|
|
||||||
def test_env_set_non_existent(state_test_env):
|
def test_env_set_non_existent(state_test_env):
|
||||||
'''Test set a non-existant variable.'''
|
"""Test set a non-existant variable."""
|
||||||
|
|
||||||
var = state_test_env.set_var
|
var = state_test_env.set_var
|
||||||
value = 'foo'
|
value = 'foo'
|
||||||
|
@ -190,7 +190,7 @@ def test_env_set_non_existent(state_test_env):
|
||||||
validate_set(state_test_env, var, value)
|
validate_set(state_test_env, var, value)
|
||||||
|
|
||||||
def test_env_set_existing(state_test_env):
|
def test_env_set_existing(state_test_env):
|
||||||
'''Test setting an existant variable.'''
|
"""Test setting an existant variable."""
|
||||||
|
|
||||||
var = state_test_env.set_var
|
var = state_test_env.set_var
|
||||||
value = 'bar'
|
value = 'bar'
|
||||||
|
@ -198,14 +198,14 @@ def test_env_set_existing(state_test_env):
|
||||||
validate_set(state_test_env, var, value)
|
validate_set(state_test_env, var, value)
|
||||||
|
|
||||||
def test_env_unset_existing(state_test_env):
|
def test_env_unset_existing(state_test_env):
|
||||||
'''Test unsetting a variable.'''
|
"""Test unsetting a variable."""
|
||||||
|
|
||||||
var = state_test_env.set_var
|
var = state_test_env.set_var
|
||||||
unset_var(state_test_env, var)
|
unset_var(state_test_env, var)
|
||||||
validate_empty(state_test_env, var)
|
validate_empty(state_test_env, var)
|
||||||
|
|
||||||
def test_env_expansion_spaces(state_test_env):
|
def test_env_expansion_spaces(state_test_env):
|
||||||
'''Test expanding a variable that contains a space in its value.'''
|
"""Test expanding a variable that contains a space in its value."""
|
||||||
|
|
||||||
var_space = None
|
var_space = None
|
||||||
var_test = None
|
var_test = None
|
||||||
|
|
|
@ -4,6 +4,6 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
def test_help(u_boot_console):
|
def test_help(u_boot_console):
|
||||||
'''Test that the "help" command can be executed.'''
|
"""Test that the "help" command can be executed."""
|
||||||
|
|
||||||
u_boot_console.run_command('help')
|
u_boot_console.run_command('help')
|
||||||
|
|
|
@ -95,7 +95,7 @@ subtests = (
|
||||||
)
|
)
|
||||||
|
|
||||||
def exec_hush_if(u_boot_console, expr, result):
|
def exec_hush_if(u_boot_console, expr, result):
|
||||||
'''Execute a shell "if" command, and validate its result.'''
|
"""Execute a shell "if" command, and validate its result."""
|
||||||
|
|
||||||
cmd = 'if ' + expr + '; then echo true; else echo false; fi'
|
cmd = 'if ' + expr + '; then echo true; else echo false; fi'
|
||||||
response = u_boot_console.run_command(cmd)
|
response = u_boot_console.run_command(cmd)
|
||||||
|
@ -103,7 +103,7 @@ def exec_hush_if(u_boot_console, expr, result):
|
||||||
|
|
||||||
@pytest.mark.buildconfigspec('sys_hush_parser')
|
@pytest.mark.buildconfigspec('sys_hush_parser')
|
||||||
def test_hush_if_test_setup(u_boot_console):
|
def test_hush_if_test_setup(u_boot_console):
|
||||||
'''Set up environment variables used during the "if" tests.'''
|
"""Set up environment variables used during the "if" tests."""
|
||||||
|
|
||||||
u_boot_console.run_command('setenv ut_var_nonexistent')
|
u_boot_console.run_command('setenv ut_var_nonexistent')
|
||||||
u_boot_console.run_command('setenv ut_var_exists 1')
|
u_boot_console.run_command('setenv ut_var_exists 1')
|
||||||
|
@ -111,13 +111,13 @@ def test_hush_if_test_setup(u_boot_console):
|
||||||
@pytest.mark.buildconfigspec('sys_hush_parser')
|
@pytest.mark.buildconfigspec('sys_hush_parser')
|
||||||
@pytest.mark.parametrize('expr,result', subtests)
|
@pytest.mark.parametrize('expr,result', subtests)
|
||||||
def test_hush_if_test(u_boot_console, expr, result):
|
def test_hush_if_test(u_boot_console, expr, result):
|
||||||
'''Test a single "if test" condition.'''
|
"""Test a single "if test" condition."""
|
||||||
|
|
||||||
exec_hush_if(u_boot_console, expr, result)
|
exec_hush_if(u_boot_console, expr, result)
|
||||||
|
|
||||||
@pytest.mark.buildconfigspec('sys_hush_parser')
|
@pytest.mark.buildconfigspec('sys_hush_parser')
|
||||||
def test_hush_if_test_teardown(u_boot_console):
|
def test_hush_if_test_teardown(u_boot_console):
|
||||||
'''Clean up environment variables used during the "if" tests.'''
|
"""Clean up environment variables used during the "if" tests."""
|
||||||
|
|
||||||
u_boot_console.run_command('setenv ut_var_exists')
|
u_boot_console.run_command('setenv ut_var_exists')
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ def test_hush_if_test_teardown(u_boot_console):
|
||||||
# Of those, only UMS currently allows file removal though.
|
# Of those, only UMS currently allows file removal though.
|
||||||
@pytest.mark.boardspec('sandbox')
|
@pytest.mark.boardspec('sandbox')
|
||||||
def test_hush_if_test_host_file_exists(u_boot_console):
|
def test_hush_if_test_host_file_exists(u_boot_console):
|
||||||
'''Test the "if test -e" shell command.'''
|
"""Test the "if test -e" shell command."""
|
||||||
|
|
||||||
test_file = u_boot_console.config.result_dir + \
|
test_file = u_boot_console.config.result_dir + \
|
||||||
'/creating_this_file_breaks_u_boot_tests'
|
'/creating_this_file_breaks_u_boot_tests'
|
||||||
|
|
|
@ -8,8 +8,8 @@ import u_boot_utils
|
||||||
|
|
||||||
@pytest.mark.buildconfigspec('cmd_memory')
|
@pytest.mark.buildconfigspec('cmd_memory')
|
||||||
def test_md(u_boot_console):
|
def test_md(u_boot_console):
|
||||||
'''Test that md reads memory as expected, and that memory can be modified
|
"""Test that md reads memory as expected, and that memory can be modified
|
||||||
using the mw command.'''
|
using the mw command."""
|
||||||
|
|
||||||
ram_base = u_boot_utils.find_ram_base(u_boot_console)
|
ram_base = u_boot_utils.find_ram_base(u_boot_console)
|
||||||
addr = '%08x' % ram_base
|
addr = '%08x' % ram_base
|
||||||
|
@ -24,8 +24,8 @@ def test_md(u_boot_console):
|
||||||
|
|
||||||
@pytest.mark.buildconfigspec('cmd_memory')
|
@pytest.mark.buildconfigspec('cmd_memory')
|
||||||
def test_md_repeat(u_boot_console):
|
def test_md_repeat(u_boot_console):
|
||||||
'''Test command repeat (via executing an empty command) operates correctly
|
"""Test command repeat (via executing an empty command) operates correctly
|
||||||
for "md"; the command must repeat and dump an incrementing address.'''
|
for "md"; the command must repeat and dump an incrementing address."""
|
||||||
|
|
||||||
ram_base = u_boot_utils.find_ram_base(u_boot_console)
|
ram_base = u_boot_utils.find_ram_base(u_boot_console)
|
||||||
addr_base = '%08x' % ram_base
|
addr_base = '%08x' % ram_base
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
import pytest
|
import pytest
|
||||||
import u_boot_utils
|
import u_boot_utils
|
||||||
|
|
||||||
'''
|
"""
|
||||||
Note: This test relies on boardenv_* containing configuration values to define
|
Note: This test relies on boardenv_* containing configuration values to define
|
||||||
which the network environment available for testing. Without this, this test
|
which the network environment available for testing. Without this, this test
|
||||||
will be automatically skipped.
|
will be automatically skipped.
|
||||||
|
@ -46,16 +46,16 @@ env__net_tftp_readable_file = {
|
||||||
"size": 5058624,
|
"size": 5058624,
|
||||||
"crc32": "c2244b26",
|
"crc32": "c2244b26",
|
||||||
}
|
}
|
||||||
'''
|
"""
|
||||||
|
|
||||||
net_set_up = False
|
net_set_up = False
|
||||||
|
|
||||||
def test_net_pre_commands(u_boot_console):
|
def test_net_pre_commands(u_boot_console):
|
||||||
'''Execute any commands required to enable network hardware.
|
"""Execute any commands required to enable network hardware.
|
||||||
|
|
||||||
These commands are provided by the boardenv_* file; see the comment at the
|
These commands are provided by the boardenv_* file; see the comment at the
|
||||||
beginning of this file.
|
beginning of this file.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
init_usb = u_boot_console.config.env.get('env__net_uses_usb', False)
|
init_usb = u_boot_console.config.env.get('env__net_uses_usb', False)
|
||||||
if init_usb:
|
if init_usb:
|
||||||
|
@ -67,11 +67,11 @@ def test_net_pre_commands(u_boot_console):
|
||||||
|
|
||||||
@pytest.mark.buildconfigspec('cmd_dhcp')
|
@pytest.mark.buildconfigspec('cmd_dhcp')
|
||||||
def test_net_dhcp(u_boot_console):
|
def test_net_dhcp(u_boot_console):
|
||||||
'''Test the dhcp command.
|
"""Test the dhcp command.
|
||||||
|
|
||||||
The boardenv_* file may be used to enable/disable this test; see the
|
The boardenv_* file may be used to enable/disable this test; see the
|
||||||
comment at the beginning of this file.
|
comment at the beginning of this file.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
test_dhcp = u_boot_console.config.env.get('env__net_dhcp_server', False)
|
test_dhcp = u_boot_console.config.env.get('env__net_dhcp_server', False)
|
||||||
if not test_dhcp:
|
if not test_dhcp:
|
||||||
|
@ -86,11 +86,11 @@ def test_net_dhcp(u_boot_console):
|
||||||
|
|
||||||
@pytest.mark.buildconfigspec('net')
|
@pytest.mark.buildconfigspec('net')
|
||||||
def test_net_setup_static(u_boot_console):
|
def test_net_setup_static(u_boot_console):
|
||||||
'''Set up a static IP configuration.
|
"""Set up a static IP configuration.
|
||||||
|
|
||||||
The configuration is provided by the boardenv_* file; see the comment at
|
The configuration is provided by the boardenv_* file; see the comment at
|
||||||
the beginning of this file.
|
the beginning of this file.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
env_vars = u_boot_console.config.env.get('env__net_static_env_vars', None)
|
env_vars = u_boot_console.config.env.get('env__net_static_env_vars', None)
|
||||||
if not env_vars:
|
if not env_vars:
|
||||||
|
@ -104,12 +104,12 @@ def test_net_setup_static(u_boot_console):
|
||||||
|
|
||||||
@pytest.mark.buildconfigspec('cmd_ping')
|
@pytest.mark.buildconfigspec('cmd_ping')
|
||||||
def test_net_ping(u_boot_console):
|
def test_net_ping(u_boot_console):
|
||||||
'''Test the ping command.
|
"""Test the ping command.
|
||||||
|
|
||||||
The $serverip (as set up by either test_net_dhcp or test_net_setup_static)
|
The $serverip (as set up by either test_net_dhcp or test_net_setup_static)
|
||||||
is pinged. The test validates that the host is alive, as reported by the
|
is pinged. The test validates that the host is alive, as reported by the
|
||||||
ping command's output.
|
ping command's output.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
if not net_set_up:
|
if not net_set_up:
|
||||||
pytest.skip("Network not initialized")
|
pytest.skip("Network not initialized")
|
||||||
|
@ -119,14 +119,14 @@ def test_net_ping(u_boot_console):
|
||||||
|
|
||||||
@pytest.mark.buildconfigspec('cmd_net')
|
@pytest.mark.buildconfigspec('cmd_net')
|
||||||
def test_net_tftpboot(u_boot_console):
|
def test_net_tftpboot(u_boot_console):
|
||||||
'''Test the tftpboot command.
|
"""Test the tftpboot command.
|
||||||
|
|
||||||
A file is downloaded from the TFTP server, its size and optionally its
|
A file is downloaded from the TFTP server, its size and optionally its
|
||||||
CRC32 are validated.
|
CRC32 are validated.
|
||||||
|
|
||||||
The details of the file to download are provided by the boardenv_* file;
|
The details of the file to download are provided by the boardenv_* file;
|
||||||
see the comment at the beginning of this file.
|
see the comment at the beginning of this file.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
if not net_set_up:
|
if not net_set_up:
|
||||||
pytest.skip("Network not initialized")
|
pytest.skip("Network not initialized")
|
||||||
|
|
|
@ -9,14 +9,14 @@ import signal
|
||||||
@pytest.mark.boardspec('sandbox')
|
@pytest.mark.boardspec('sandbox')
|
||||||
@pytest.mark.buildconfigspec('reset')
|
@pytest.mark.buildconfigspec('reset')
|
||||||
def test_reset(u_boot_console):
|
def test_reset(u_boot_console):
|
||||||
'''Test that the "reset" command exits sandbox process.'''
|
"""Test that the "reset" command exits sandbox process."""
|
||||||
|
|
||||||
u_boot_console.run_command('reset', wait_for_prompt=False)
|
u_boot_console.run_command('reset', wait_for_prompt=False)
|
||||||
assert(u_boot_console.validate_exited())
|
assert(u_boot_console.validate_exited())
|
||||||
|
|
||||||
@pytest.mark.boardspec('sandbox')
|
@pytest.mark.boardspec('sandbox')
|
||||||
def test_ctrl_c(u_boot_console):
|
def test_ctrl_c(u_boot_console):
|
||||||
'''Test that sending SIGINT to sandbox causes it to exit.'''
|
"""Test that sending SIGINT to sandbox causes it to exit."""
|
||||||
|
|
||||||
u_boot_console.kill(signal.SIGINT)
|
u_boot_console.kill(signal.SIGINT)
|
||||||
assert(u_boot_console.validate_exited())
|
assert(u_boot_console.validate_exited())
|
||||||
|
|
|
@ -5,13 +5,13 @@
|
||||||
# Test basic shell functionality, such as commands separate by semi-colons.
|
# Test basic shell functionality, such as commands separate by semi-colons.
|
||||||
|
|
||||||
def test_shell_execute(u_boot_console):
|
def test_shell_execute(u_boot_console):
|
||||||
'''Test any shell command.'''
|
"""Test any shell command."""
|
||||||
|
|
||||||
response = u_boot_console.run_command('echo hello')
|
response = u_boot_console.run_command('echo hello')
|
||||||
assert response.strip() == 'hello'
|
assert response.strip() == 'hello'
|
||||||
|
|
||||||
def test_shell_semicolon_two(u_boot_console):
|
def test_shell_semicolon_two(u_boot_console):
|
||||||
'''Test two shell commands separate by a semi-colon.'''
|
"""Test two shell commands separate by a semi-colon."""
|
||||||
|
|
||||||
cmd = 'echo hello; echo world'
|
cmd = 'echo hello; echo world'
|
||||||
response = u_boot_console.run_command(cmd)
|
response = u_boot_console.run_command(cmd)
|
||||||
|
@ -19,8 +19,8 @@ def test_shell_semicolon_two(u_boot_console):
|
||||||
assert response.index('hello') < response.index('world')
|
assert response.index('hello') < response.index('world')
|
||||||
|
|
||||||
def test_shell_semicolon_three(u_boot_console):
|
def test_shell_semicolon_three(u_boot_console):
|
||||||
'''Test three shell commands separate by a semi-colon, with variable
|
"""Test three shell commands separate by a semi-colon, with variable
|
||||||
expansion dependencies between them.'''
|
expansion dependencies between them."""
|
||||||
|
|
||||||
cmd = 'setenv list 1; setenv list ${list}2; setenv list ${list}3; ' + \
|
cmd = 'setenv list 1; setenv list ${list}2; setenv list ${list}3; ' + \
|
||||||
'echo ${list}'
|
'echo ${list}'
|
||||||
|
@ -29,7 +29,7 @@ def test_shell_semicolon_three(u_boot_console):
|
||||||
u_boot_console.run_command('setenv list')
|
u_boot_console.run_command('setenv list')
|
||||||
|
|
||||||
def test_shell_run(u_boot_console):
|
def test_shell_run(u_boot_console):
|
||||||
'''Test the "run" shell command.'''
|
"""Test the "run" shell command."""
|
||||||
|
|
||||||
u_boot_console.run_command('setenv foo \"setenv monty 1; setenv python 2\"')
|
u_boot_console.run_command('setenv foo \"setenv monty 1; setenv python 2\"')
|
||||||
u_boot_console.run_command('run foo')
|
u_boot_console.run_command('run foo')
|
||||||
|
|
|
@ -6,8 +6,8 @@ import pytest
|
||||||
import time
|
import time
|
||||||
|
|
||||||
def test_sleep(u_boot_console):
|
def test_sleep(u_boot_console):
|
||||||
'''Test the sleep command, and validate that it sleeps for approximately
|
"""Test the sleep command, and validate that it sleeps for approximately
|
||||||
the correct amount of time.'''
|
the correct amount of time."""
|
||||||
|
|
||||||
# 3s isn't too long, but is enough to cross a few second boundaries.
|
# 3s isn't too long, but is enough to cross a few second boundaries.
|
||||||
sleep_time = 3
|
sleep_time = 3
|
||||||
|
|
|
@ -14,7 +14,7 @@ import re
|
||||||
import time
|
import time
|
||||||
import u_boot_utils
|
import u_boot_utils
|
||||||
|
|
||||||
'''
|
"""
|
||||||
Note: This test relies on:
|
Note: This test relies on:
|
||||||
|
|
||||||
a) boardenv_* to contain configuration values to define which USB ports are
|
a) boardenv_* to contain configuration values to define which USB ports are
|
||||||
|
@ -69,11 +69,11 @@ root permissions. For example:
|
||||||
|
|
||||||
This entry is only needed if any block_devs above contain a
|
This entry is only needed if any block_devs above contain a
|
||||||
writable_fs_partition value.
|
writable_fs_partition value.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
@pytest.mark.buildconfigspec('cmd_usb_mass_storage')
|
@pytest.mark.buildconfigspec('cmd_usb_mass_storage')
|
||||||
def test_ums(u_boot_console, env__usb_dev_port, env__block_devs):
|
def test_ums(u_boot_console, env__usb_dev_port, env__block_devs):
|
||||||
'''Test the "ums" command; the host system must be able to enumerate a UMS
|
"""Test the "ums" command; the host system must be able to enumerate a UMS
|
||||||
device when "ums" is running, block and optionally file I/O are tested,
|
device when "ums" is running, block and optionally file I/O are tested,
|
||||||
and this device must disappear when "ums" is aborted.
|
and this device must disappear when "ums" is aborted.
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ def test_ums(u_boot_console, env__usb_dev_port, env__block_devs):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
have_writable_fs_partition = 'writable_fs_partition' in env__block_devs[0]
|
have_writable_fs_partition = 'writable_fs_partition' in env__block_devs[0]
|
||||||
if not have_writable_fs_partition:
|
if not have_writable_fs_partition:
|
||||||
|
@ -120,7 +120,7 @@ def test_ums(u_boot_console, env__usb_dev_port, env__block_devs):
|
||||||
mounted_test_fn = mount_point + '/' + mount_subdir + test_f.fn
|
mounted_test_fn = mount_point + '/' + mount_subdir + test_f.fn
|
||||||
|
|
||||||
def start_ums():
|
def start_ums():
|
||||||
'''Start U-Boot's ums shell command.
|
"""Start U-Boot's ums shell command.
|
||||||
|
|
||||||
This also waits for the host-side USB enumeration process to complete.
|
This also waits for the host-side USB enumeration process to complete.
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ def test_ums(u_boot_console, env__usb_dev_port, env__block_devs):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
u_boot_console.log.action(
|
u_boot_console.log.action(
|
||||||
'Starting long-running U-Boot ums shell command')
|
'Starting long-running U-Boot ums shell command')
|
||||||
|
@ -142,21 +142,21 @@ def test_ums(u_boot_console, env__usb_dev_port, env__block_devs):
|
||||||
fh.close()
|
fh.close()
|
||||||
|
|
||||||
def mount():
|
def mount():
|
||||||
'''Mount the block device that U-Boot exports.
|
"""Mount the block device that U-Boot exports.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
None.
|
None.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
u_boot_console.log.action('Mounting exported UMS device')
|
u_boot_console.log.action('Mounting exported UMS device')
|
||||||
cmd = ('/bin/mount', host_ums_part_node)
|
cmd = ('/bin/mount', host_ums_part_node)
|
||||||
u_boot_utils.run_and_log(u_boot_console, cmd)
|
u_boot_utils.run_and_log(u_boot_console, cmd)
|
||||||
|
|
||||||
def umount(ignore_errors):
|
def umount(ignore_errors):
|
||||||
'''Unmount the block device that U-Boot exports.
|
"""Unmount the block device that U-Boot exports.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
ignore_errors: Ignore any errors. This is useful if an error has
|
ignore_errors: Ignore any errors. This is useful if an error has
|
||||||
|
@ -166,14 +166,14 @@ def test_ums(u_boot_console, env__usb_dev_port, env__block_devs):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
u_boot_console.log.action('Unmounting UMS device')
|
u_boot_console.log.action('Unmounting UMS device')
|
||||||
cmd = ('/bin/umount', host_ums_part_node)
|
cmd = ('/bin/umount', host_ums_part_node)
|
||||||
u_boot_utils.run_and_log(u_boot_console, cmd, ignore_errors)
|
u_boot_utils.run_and_log(u_boot_console, cmd, ignore_errors)
|
||||||
|
|
||||||
def stop_ums(ignore_errors):
|
def stop_ums(ignore_errors):
|
||||||
'''Stop U-Boot's ums shell command from executing.
|
"""Stop U-Boot's ums shell command from executing.
|
||||||
|
|
||||||
This also waits for the host-side USB de-enumeration process to
|
This also waits for the host-side USB de-enumeration process to
|
||||||
complete.
|
complete.
|
||||||
|
@ -186,7 +186,7 @@ def test_ums(u_boot_console, env__usb_dev_port, env__block_devs):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
u_boot_console.log.action(
|
u_boot_console.log.action(
|
||||||
'Stopping long-running U-Boot ums shell command')
|
'Stopping long-running U-Boot ums shell command')
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
def test_unknown_command(u_boot_console):
|
def test_unknown_command(u_boot_console):
|
||||||
'''Test that executing an unknown command causes U-Boot to print an
|
"""Test that executing an unknown command causes U-Boot to print an
|
||||||
error.'''
|
error."""
|
||||||
|
|
||||||
# The "unknown command" error is actively expected here,
|
# The "unknown command" error is actively expected here,
|
||||||
# so error detection for it is disabled.
|
# so error detection for it is disabled.
|
||||||
|
|
|
@ -24,12 +24,12 @@ pattern_unknown_command = re.compile('Unknown command \'.*\' - try \'help\'')
|
||||||
pattern_error_notification = re.compile('## Error: ')
|
pattern_error_notification = re.compile('## Error: ')
|
||||||
|
|
||||||
class ConsoleDisableCheck(object):
|
class ConsoleDisableCheck(object):
|
||||||
'''Context manager (for Python's with statement) that temporarily disables
|
"""Context manager (for Python's with statement) that temporarily disables
|
||||||
the specified console output error check. This is useful when deliberately
|
the specified console output error check. This is useful when deliberately
|
||||||
executing a command that is known to trigger one of the error checks, in
|
executing a command that is known to trigger one of the error checks, in
|
||||||
order to test that the error condition is actually raised. This class is
|
order to test that the error condition is actually raised. This class is
|
||||||
used internally by ConsoleBase::disable_check(); it is not intended for
|
used internally by ConsoleBase::disable_check(); it is not intended for
|
||||||
direct usage.'''
|
direct usage."""
|
||||||
|
|
||||||
def __init__(self, console, check_type):
|
def __init__(self, console, check_type):
|
||||||
self.console = console
|
self.console = console
|
||||||
|
@ -42,13 +42,13 @@ class ConsoleDisableCheck(object):
|
||||||
self.console.disable_check_count[self.check_type] -= 1
|
self.console.disable_check_count[self.check_type] -= 1
|
||||||
|
|
||||||
class ConsoleBase(object):
|
class ConsoleBase(object):
|
||||||
'''The interface through which test functions interact with the U-Boot
|
"""The interface through which test functions interact with the U-Boot
|
||||||
console. This primarily involves executing shell commands, capturing their
|
console. This primarily involves executing shell commands, capturing their
|
||||||
results, and checking for common error conditions. Some common utilities
|
results, and checking for common error conditions. Some common utilities
|
||||||
are also provided too.'''
|
are also provided too."""
|
||||||
|
|
||||||
def __init__(self, log, config, max_fifo_fill):
|
def __init__(self, log, config, max_fifo_fill):
|
||||||
'''Initialize a U-Boot console connection.
|
"""Initialize a U-Boot console connection.
|
||||||
|
|
||||||
Can only usefully be called by sub-classes.
|
Can only usefully be called by sub-classes.
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ class ConsoleBase(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self.log = log
|
self.log = log
|
||||||
self.config = config
|
self.config = config
|
||||||
|
@ -88,7 +88,7 @@ class ConsoleBase(object):
|
||||||
self.at_prompt_logevt = None
|
self.at_prompt_logevt = None
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
'''Terminate the connection to the U-Boot console.
|
"""Terminate the connection to the U-Boot console.
|
||||||
|
|
||||||
This function is only useful once all interaction with U-Boot is
|
This function is only useful once all interaction with U-Boot is
|
||||||
complete. Once this function is called, data cannot be sent to or
|
complete. Once this function is called, data cannot be sent to or
|
||||||
|
@ -99,7 +99,7 @@ class ConsoleBase(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
if self.p:
|
if self.p:
|
||||||
self.p.close()
|
self.p.close()
|
||||||
|
@ -107,7 +107,7 @@ class ConsoleBase(object):
|
||||||
|
|
||||||
def run_command(self, cmd, wait_for_echo=True, send_nl=True,
|
def run_command(self, cmd, wait_for_echo=True, send_nl=True,
|
||||||
wait_for_prompt=True):
|
wait_for_prompt=True):
|
||||||
'''Execute a command via the U-Boot console.
|
"""Execute a command via the U-Boot console.
|
||||||
|
|
||||||
The command is always sent to U-Boot.
|
The command is always sent to U-Boot.
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ class ConsoleBase(object):
|
||||||
The output from U-Boot during command execution. In other
|
The output from U-Boot during command execution. In other
|
||||||
words, the text U-Boot emitted between the point it echod the
|
words, the text U-Boot emitted between the point it echod the
|
||||||
command string and emitted the subsequent command prompts.
|
command string and emitted the subsequent command prompts.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
if self.at_prompt and \
|
if self.at_prompt and \
|
||||||
self.at_prompt_logevt != self.logstream.logfile.cur_evt:
|
self.at_prompt_logevt != self.logstream.logfile.cur_evt:
|
||||||
|
@ -198,7 +198,7 @@ class ConsoleBase(object):
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def ctrlc(self):
|
def ctrlc(self):
|
||||||
'''Send a CTRL-C character to U-Boot.
|
"""Send a CTRL-C character to U-Boot.
|
||||||
|
|
||||||
This is useful in order to stop execution of long-running synchronous
|
This is useful in order to stop execution of long-running synchronous
|
||||||
commands such as "ums".
|
commands such as "ums".
|
||||||
|
@ -208,13 +208,13 @@ class ConsoleBase(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self.log.action('Sending Ctrl-C')
|
self.log.action('Sending Ctrl-C')
|
||||||
self.run_command(chr(3), wait_for_echo=False, send_nl=False)
|
self.run_command(chr(3), wait_for_echo=False, send_nl=False)
|
||||||
|
|
||||||
def wait_for(self, text):
|
def wait_for(self, text):
|
||||||
'''Wait for a pattern to be emitted by U-Boot.
|
"""Wait for a pattern to be emitted by U-Boot.
|
||||||
|
|
||||||
This is useful when a long-running command such as "dfu" is executing,
|
This is useful when a long-running command such as "dfu" is executing,
|
||||||
and it periodically emits some text that should show up at a specific
|
and it periodically emits some text that should show up at a specific
|
||||||
|
@ -226,14 +226,14 @@ class ConsoleBase(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
if type(text) == type(''):
|
if type(text) == type(''):
|
||||||
text = re.escape(text)
|
text = re.escape(text)
|
||||||
self.p.expect([text])
|
self.p.expect([text])
|
||||||
|
|
||||||
def drain_console(self):
|
def drain_console(self):
|
||||||
'''Read from and log the U-Boot console for a short time.
|
"""Read from and log the U-Boot console for a short time.
|
||||||
|
|
||||||
U-Boot's console output is only logged when the test code actively
|
U-Boot's console output is only logged when the test code actively
|
||||||
waits for U-Boot to emit specific data. There are cases where tests
|
waits for U-Boot to emit specific data. There are cases where tests
|
||||||
|
@ -248,7 +248,7 @@ class ConsoleBase(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
# If we are already not connected to U-Boot, there's nothing to drain.
|
# If we are already not connected to U-Boot, there's nothing to drain.
|
||||||
# This should only happen when a previous call to run_command() or
|
# This should only happen when a previous call to run_command() or
|
||||||
|
@ -270,7 +270,7 @@ class ConsoleBase(object):
|
||||||
self.p.timeout = orig_timeout
|
self.p.timeout = orig_timeout
|
||||||
|
|
||||||
def ensure_spawned(self):
|
def ensure_spawned(self):
|
||||||
'''Ensure a connection to a correctly running U-Boot instance.
|
"""Ensure a connection to a correctly running U-Boot instance.
|
||||||
|
|
||||||
This may require spawning a new Sandbox process or resetting target
|
This may require spawning a new Sandbox process or resetting target
|
||||||
hardware, as defined by the implementation sub-class.
|
hardware, as defined by the implementation sub-class.
|
||||||
|
@ -282,7 +282,7 @@ class ConsoleBase(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
if self.p:
|
if self.p:
|
||||||
return
|
return
|
||||||
|
@ -320,7 +320,7 @@ class ConsoleBase(object):
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def cleanup_spawn(self):
|
def cleanup_spawn(self):
|
||||||
'''Shut down all interaction with the U-Boot instance.
|
"""Shut down all interaction with the U-Boot instance.
|
||||||
|
|
||||||
This is used when an error is detected prior to re-establishing a
|
This is used when an error is detected prior to re-establishing a
|
||||||
connection with a fresh U-Boot instance.
|
connection with a fresh U-Boot instance.
|
||||||
|
@ -332,7 +332,7 @@ class ConsoleBase(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if self.p:
|
if self.p:
|
||||||
|
@ -342,7 +342,7 @@ class ConsoleBase(object):
|
||||||
self.p = None
|
self.p = None
|
||||||
|
|
||||||
def validate_version_string_in_text(self, text):
|
def validate_version_string_in_text(self, text):
|
||||||
'''Assert that a command's output includes the U-Boot signon message.
|
"""Assert that a command's output includes the U-Boot signon message.
|
||||||
|
|
||||||
This is primarily useful for validating the "version" command without
|
This is primarily useful for validating the "version" command without
|
||||||
duplicating the signon text regex in a test function.
|
duplicating the signon text regex in a test function.
|
||||||
|
@ -352,12 +352,12 @@ class ConsoleBase(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing. An exception is raised if the validation fails.
|
Nothing. An exception is raised if the validation fails.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
assert(self.u_boot_version_string in text)
|
assert(self.u_boot_version_string in text)
|
||||||
|
|
||||||
def disable_check(self, check_type):
|
def disable_check(self, check_type):
|
||||||
'''Temporarily disable an error check of U-Boot's output.
|
"""Temporarily disable an error check of U-Boot's output.
|
||||||
|
|
||||||
Create a new context manager (for use with the "with" statement) which
|
Create a new context manager (for use with the "with" statement) which
|
||||||
temporarily disables a particular console output error check.
|
temporarily disables a particular console output error check.
|
||||||
|
@ -368,6 +368,6 @@ class ConsoleBase(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A context manager object.
|
A context manager object.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
return ConsoleDisableCheck(self, check_type)
|
return ConsoleDisableCheck(self, check_type)
|
||||||
|
|
|
@ -11,15 +11,15 @@ from u_boot_spawn import Spawn
|
||||||
from u_boot_console_base import ConsoleBase
|
from u_boot_console_base import ConsoleBase
|
||||||
|
|
||||||
class ConsoleExecAttach(ConsoleBase):
|
class ConsoleExecAttach(ConsoleBase):
|
||||||
'''Represents a physical connection to a U-Boot console, typically via a
|
"""Represents a physical connection to a U-Boot console, typically via a
|
||||||
serial port. This implementation executes a sub-process to attach to the
|
serial port. This implementation executes a sub-process to attach to the
|
||||||
console, expecting that the stdin/out of the sub-process will be forwarded
|
console, expecting that the stdin/out of the sub-process will be forwarded
|
||||||
to/from the physical hardware. This approach isolates the test infra-
|
to/from the physical hardware. This approach isolates the test infra-
|
||||||
structure from the user-/installation-specific details of how to
|
structure from the user-/installation-specific details of how to
|
||||||
communicate with, and the identity of, serial ports etc.'''
|
communicate with, and the identity of, serial ports etc."""
|
||||||
|
|
||||||
def __init__(self, log, config):
|
def __init__(self, log, config):
|
||||||
'''Initialize a U-Boot console connection.
|
"""Initialize a U-Boot console connection.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
log: A multiplexed_log.Logfile instance.
|
log: A multiplexed_log.Logfile instance.
|
||||||
|
@ -27,7 +27,7 @@ class ConsoleExecAttach(ConsoleBase):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
# The max_fifo_fill value might need tweaking per-board/-SoC?
|
# The max_fifo_fill value might need tweaking per-board/-SoC?
|
||||||
# 1 would be safe anywhere, but is very slow (a pexpect issue?).
|
# 1 would be safe anywhere, but is very slow (a pexpect issue?).
|
||||||
|
@ -42,7 +42,7 @@ class ConsoleExecAttach(ConsoleBase):
|
||||||
runner.close()
|
runner.close()
|
||||||
|
|
||||||
def get_spawn(self):
|
def get_spawn(self):
|
||||||
'''Connect to a fresh U-Boot instance.
|
"""Connect to a fresh U-Boot instance.
|
||||||
|
|
||||||
The target board is reset, so that U-Boot begins running from scratch.
|
The target board is reset, so that U-Boot begins running from scratch.
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ class ConsoleExecAttach(ConsoleBase):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A u_boot_spawn.Spawn object that is attached to U-Boot.
|
A u_boot_spawn.Spawn object that is attached to U-Boot.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
args = [self.config.board_type, self.config.board_identity]
|
args = [self.config.board_type, self.config.board_identity]
|
||||||
s = Spawn(['u-boot-test-console'] + args)
|
s = Spawn(['u-boot-test-console'] + args)
|
||||||
|
|
|
@ -10,11 +10,11 @@ from u_boot_spawn import Spawn
|
||||||
from u_boot_console_base import ConsoleBase
|
from u_boot_console_base import ConsoleBase
|
||||||
|
|
||||||
class ConsoleSandbox(ConsoleBase):
|
class ConsoleSandbox(ConsoleBase):
|
||||||
'''Represents a connection to a sandbox U-Boot console, executed as a sub-
|
"""Represents a connection to a sandbox U-Boot console, executed as a sub-
|
||||||
process.'''
|
process."""
|
||||||
|
|
||||||
def __init__(self, log, config):
|
def __init__(self, log, config):
|
||||||
'''Initialize a U-Boot console connection.
|
"""Initialize a U-Boot console connection.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
log: A multiplexed_log.Logfile instance.
|
log: A multiplexed_log.Logfile instance.
|
||||||
|
@ -22,12 +22,12 @@ class ConsoleSandbox(ConsoleBase):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
super(ConsoleSandbox, self).__init__(log, config, max_fifo_fill=1024)
|
super(ConsoleSandbox, self).__init__(log, config, max_fifo_fill=1024)
|
||||||
|
|
||||||
def get_spawn(self):
|
def get_spawn(self):
|
||||||
'''Connect to a fresh U-Boot instance.
|
"""Connect to a fresh U-Boot instance.
|
||||||
|
|
||||||
A new sandbox process is created, so that U-Boot begins running from
|
A new sandbox process is created, so that U-Boot begins running from
|
||||||
scratch.
|
scratch.
|
||||||
|
@ -37,25 +37,25 @@ class ConsoleSandbox(ConsoleBase):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A u_boot_spawn.Spawn object that is attached to U-Boot.
|
A u_boot_spawn.Spawn object that is attached to U-Boot.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
return Spawn([self.config.build_dir + '/u-boot'])
|
return Spawn([self.config.build_dir + '/u-boot'])
|
||||||
|
|
||||||
def kill(self, sig):
|
def kill(self, sig):
|
||||||
'''Send a specific Unix signal to the sandbox process.
|
"""Send a specific Unix signal to the sandbox process.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
sig: The Unix signal to send to the process.
|
sig: The Unix signal to send to the process.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self.log.action('kill %d' % sig)
|
self.log.action('kill %d' % sig)
|
||||||
self.p.kill(sig)
|
self.p.kill(sig)
|
||||||
|
|
||||||
def validate_exited(self):
|
def validate_exited(self):
|
||||||
'''Determine whether the sandbox process has exited.
|
"""Determine whether the sandbox process has exited.
|
||||||
|
|
||||||
If required, this function waits a reasonable time for the process to
|
If required, this function waits a reasonable time for the process to
|
||||||
exit.
|
exit.
|
||||||
|
@ -65,7 +65,7 @@ class ConsoleSandbox(ConsoleBase):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Boolean indicating whether the process has exited.
|
Boolean indicating whether the process has exited.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
p = self.p
|
p = self.p
|
||||||
self.p = None
|
self.p = None
|
||||||
|
|
|
@ -12,23 +12,23 @@ import select
|
||||||
import time
|
import time
|
||||||
|
|
||||||
class Timeout(Exception):
|
class Timeout(Exception):
|
||||||
'''An exception sub-class that indicates that a timeout occurred.'''
|
"""An exception sub-class that indicates that a timeout occurred."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Spawn(object):
|
class Spawn(object):
|
||||||
'''Represents the stdio of a freshly created sub-process. Commands may be
|
"""Represents the stdio of a freshly created sub-process. Commands may be
|
||||||
sent to the process, and responses waited for.
|
sent to the process, and responses waited for.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
def __init__(self, args):
|
def __init__(self, args):
|
||||||
'''Spawn (fork/exec) the sub-process.
|
"""Spawn (fork/exec) the sub-process.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
args: array of processs arguments. argv[0] is the command to execute.
|
args: array of processs arguments. argv[0] is the command to execute.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self.waited = False
|
self.waited = False
|
||||||
self.buf = ''
|
self.buf = ''
|
||||||
|
@ -56,26 +56,26 @@ class Spawn(object):
|
||||||
self.poll.register(self.fd, select.POLLIN | select.POLLPRI | select.POLLERR | select.POLLHUP | select.POLLNVAL)
|
self.poll.register(self.fd, select.POLLIN | select.POLLPRI | select.POLLERR | select.POLLHUP | select.POLLNVAL)
|
||||||
|
|
||||||
def kill(self, sig):
|
def kill(self, sig):
|
||||||
'''Send unix signal "sig" to the child process.
|
"""Send unix signal "sig" to the child process.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
sig: The signal number to send.
|
sig: The signal number to send.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
os.kill(self.pid, sig)
|
os.kill(self.pid, sig)
|
||||||
|
|
||||||
def isalive(self):
|
def isalive(self):
|
||||||
'''Determine whether the child process is still running.
|
"""Determine whether the child process is still running.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
None.
|
None.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Boolean indicating whether process is alive.
|
Boolean indicating whether process is alive.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
if self.waited:
|
if self.waited:
|
||||||
return False
|
return False
|
||||||
|
@ -88,19 +88,19 @@ class Spawn(object):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def send(self, data):
|
def send(self, data):
|
||||||
'''Send data to the sub-process's stdin.
|
"""Send data to the sub-process's stdin.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
data: The data to send to the process.
|
data: The data to send to the process.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
os.write(self.fd, data)
|
os.write(self.fd, data)
|
||||||
|
|
||||||
def expect(self, patterns):
|
def expect(self, patterns):
|
||||||
'''Wait for the sub-process to emit specific data.
|
"""Wait for the sub-process to emit specific data.
|
||||||
|
|
||||||
This function waits for the process to emit one pattern from the
|
This function waits for the process to emit one pattern from the
|
||||||
supplied list of patterns, or for a timeout to occur.
|
supplied list of patterns, or for a timeout to occur.
|
||||||
|
@ -116,7 +116,7 @@ class Spawn(object):
|
||||||
Notable exceptions:
|
Notable exceptions:
|
||||||
Timeout, if the process did not emit any of the patterns within
|
Timeout, if the process did not emit any of the patterns within
|
||||||
the expected time.
|
the expected time.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
for pi in xrange(len(patterns)):
|
for pi in xrange(len(patterns)):
|
||||||
if type(patterns[pi]) == type(''):
|
if type(patterns[pi]) == type(''):
|
||||||
|
@ -161,7 +161,7 @@ class Spawn(object):
|
||||||
self.logfile_read.flush()
|
self.logfile_read.flush()
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
'''Close the stdio connection to the sub-process.
|
"""Close the stdio connection to the sub-process.
|
||||||
|
|
||||||
This also waits a reasonable time for the sub-process to stop running.
|
This also waits a reasonable time for the sub-process to stop running.
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ class Spawn(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
os.close(self.fd)
|
os.close(self.fd)
|
||||||
for i in xrange(100):
|
for i in xrange(100):
|
||||||
|
|
|
@ -11,21 +11,21 @@ import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
def md5sum_data(data):
|
def md5sum_data(data):
|
||||||
'''Calculate the MD5 hash of some data.
|
"""Calculate the MD5 hash of some data.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
data: The data to hash.
|
data: The data to hash.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The hash of the data, as a binary string.
|
The hash of the data, as a binary string.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
h = hashlib.md5()
|
h = hashlib.md5()
|
||||||
h.update(data)
|
h.update(data)
|
||||||
return h.digest()
|
return h.digest()
|
||||||
|
|
||||||
def md5sum_file(fn, max_length=None):
|
def md5sum_file(fn, max_length=None):
|
||||||
'''Calculate the MD5 hash of the contents of a file.
|
"""Calculate the MD5 hash of the contents of a file.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
fn: The filename of the file to hash.
|
fn: The filename of the file to hash.
|
||||||
|
@ -35,7 +35,7 @@ def md5sum_file(fn, max_length=None):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The hash of the file content, as a binary string.
|
The hash of the file content, as a binary string.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
with open(fn, 'rb') as fh:
|
with open(fn, 'rb') as fh:
|
||||||
if max_length:
|
if max_length:
|
||||||
|
@ -46,11 +46,11 @@ def md5sum_file(fn, max_length=None):
|
||||||
return md5sum_data(data)
|
return md5sum_data(data)
|
||||||
|
|
||||||
class PersistentRandomFile(object):
|
class PersistentRandomFile(object):
|
||||||
'''Generate and store information about a persistent file containing
|
"""Generate and store information about a persistent file containing
|
||||||
random data.'''
|
random data."""
|
||||||
|
|
||||||
def __init__(self, u_boot_console, fn, size):
|
def __init__(self, u_boot_console, fn, size):
|
||||||
'''Create or process the persistent file.
|
"""Create or process the persistent file.
|
||||||
|
|
||||||
If the file does not exist, it is generated.
|
If the file does not exist, it is generated.
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ class PersistentRandomFile(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
self.fn = fn
|
self.fn = fn
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ class PersistentRandomFile(object):
|
||||||
self.content_hash = md5sum_data(data)
|
self.content_hash = md5sum_data(data)
|
||||||
|
|
||||||
def attempt_to_open_file(fn):
|
def attempt_to_open_file(fn):
|
||||||
'''Attempt to open a file, without throwing exceptions.
|
"""Attempt to open a file, without throwing exceptions.
|
||||||
|
|
||||||
Any errors (exceptions) that occur during the attempt to open the file
|
Any errors (exceptions) that occur during the attempt to open the file
|
||||||
are ignored. This is useful in order to test whether a file (in
|
are ignored. This is useful in order to test whether a file (in
|
||||||
|
@ -98,7 +98,7 @@ def attempt_to_open_file(fn):
|
||||||
Returns:
|
Returns:
|
||||||
An open file handle to the file, or None if the file could not be
|
An open file handle to the file, or None if the file could not be
|
||||||
opened.
|
opened.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return open(fn, 'rb')
|
return open(fn, 'rb')
|
||||||
|
@ -106,7 +106,7 @@ def attempt_to_open_file(fn):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def wait_until_open_succeeds(fn):
|
def wait_until_open_succeeds(fn):
|
||||||
'''Poll until a file can be opened, or a timeout occurs.
|
"""Poll until a file can be opened, or a timeout occurs.
|
||||||
|
|
||||||
Continually attempt to open a file, and return when this succeeds, or
|
Continually attempt to open a file, and return when this succeeds, or
|
||||||
raise an exception after a timeout.
|
raise an exception after a timeout.
|
||||||
|
@ -116,7 +116,7 @@ def wait_until_open_succeeds(fn):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
An open file handle to the file.
|
An open file handle to the file.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
for i in xrange(100):
|
for i in xrange(100):
|
||||||
fh = attempt_to_open_file(fn)
|
fh = attempt_to_open_file(fn)
|
||||||
|
@ -126,7 +126,7 @@ def wait_until_open_succeeds(fn):
|
||||||
raise Exception('File could not be opened')
|
raise Exception('File could not be opened')
|
||||||
|
|
||||||
def wait_until_file_open_fails(fn, ignore_errors):
|
def wait_until_file_open_fails(fn, ignore_errors):
|
||||||
'''Poll until a file cannot be opened, or a timeout occurs.
|
"""Poll until a file cannot be opened, or a timeout occurs.
|
||||||
|
|
||||||
Continually attempt to open a file, and return when this fails, or
|
Continually attempt to open a file, and return when this fails, or
|
||||||
raise an exception after a timeout.
|
raise an exception after a timeout.
|
||||||
|
@ -139,7 +139,7 @@ def wait_until_file_open_fails(fn, ignore_errors):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
for i in xrange(100):
|
for i in xrange(100):
|
||||||
fh = attempt_to_open_file(fn)
|
fh = attempt_to_open_file(fn)
|
||||||
|
@ -152,7 +152,7 @@ def wait_until_file_open_fails(fn, ignore_errors):
|
||||||
raise Exception('File can still be opened')
|
raise Exception('File can still be opened')
|
||||||
|
|
||||||
def run_and_log(u_boot_console, cmd, ignore_errors=False):
|
def run_and_log(u_boot_console, cmd, ignore_errors=False):
|
||||||
'''Run a command and log its output.
|
"""Run a command and log its output.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
u_boot_console: A console connection to U-Boot.
|
u_boot_console: A console connection to U-Boot.
|
||||||
|
@ -164,7 +164,7 @@ def run_and_log(u_boot_console, cmd, ignore_errors=False):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Nothing.
|
Nothing.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
runner = u_boot_console.log.get_runner(cmd[0], sys.stdout)
|
runner = u_boot_console.log.get_runner(cmd[0], sys.stdout)
|
||||||
runner.run(cmd, ignore_errors=ignore_errors)
|
runner.run(cmd, ignore_errors=ignore_errors)
|
||||||
|
@ -172,7 +172,7 @@ def run_and_log(u_boot_console, cmd, ignore_errors=False):
|
||||||
|
|
||||||
ram_base = None
|
ram_base = None
|
||||||
def find_ram_base(u_boot_console):
|
def find_ram_base(u_boot_console):
|
||||||
'''Find the running U-Boot's RAM location.
|
"""Find the running U-Boot's RAM location.
|
||||||
|
|
||||||
Probe the running U-Boot to determine the address of the first bank
|
Probe the running U-Boot to determine the address of the first bank
|
||||||
of RAM. This is useful for tests that test reading/writing RAM, or
|
of RAM. This is useful for tests that test reading/writing RAM, or
|
||||||
|
@ -186,7 +186,7 @@ def find_ram_base(u_boot_console):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The address of U-Boot's first RAM bank, as an integer.
|
The address of U-Boot's first RAM bank, as an integer.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
global ram_base
|
global ram_base
|
||||||
if u_boot_console.config.buildconfig.get('config_cmd_bdi', 'n') != 'y':
|
if u_boot_console.config.buildconfig.get('config_cmd_bdi', 'n') != 'y':
|
||||||
|
|
Loading…
Add table
Reference in a new issue