X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=test%2Fpy%2Fu_boot_utils.py;h=bb31e57b279993e3de4055bee6d0ff6a2a8d1dd0;hb=d99894dd3a713ea6226ac39a7e332b55cf8aca49;hp=2ba4baed07eb87fa2eb0822cab75a5051b42e580;hpb=c98b171e1098f94b2ff7720c45a25a602882f876;p=u-boot diff --git a/test/py/u_boot_utils.py b/test/py/u_boot_utils.py index 2ba4baed07..bb31e57b27 100644 --- a/test/py/u_boot_utils.py +++ b/test/py/u_boot_utils.py @@ -1,16 +1,16 @@ -# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. -# # SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. # Utility code shared across multiple tests. import hashlib +import inspect import os import os.path import pytest import sys import time -import pytest +import re def md5sum_data(data): """Calculate the MD5 hash of some data. @@ -237,3 +237,98 @@ def find_ram_base(u_boot_console): raise Exception('Failed to find RAM bank start in `bdinfo`') return ram_base + +class PersistentFileHelperCtxMgr(object): + """A context manager for Python's "with" statement, which ensures that any + generated file is deleted (and hence regenerated) if its mtime is older + than the mtime of the Python module which generated it, and gets an mtime + newer than the mtime of the Python module which generated after it is + generated. Objects of this type should be created by factory function + persistent_file_helper rather than directly.""" + + def __init__(self, log, filename): + """Initialize a new object. + + Args: + log: The Logfile object to log to. + filename: The filename of the generated file. + + Returns: + Nothing. + """ + + self.log = log + self.filename = filename + + def __enter__(self): + frame = inspect.stack()[1] + module = inspect.getmodule(frame[0]) + self.module_filename = module.__file__ + self.module_timestamp = os.path.getmtime(self.module_filename) + + if os.path.exists(self.filename): + filename_timestamp = os.path.getmtime(self.filename) + if filename_timestamp < self.module_timestamp: + self.log.action('Removing stale generated file ' + + self.filename) + os.unlink(self.filename) + + def __exit__(self, extype, value, traceback): + if extype: + try: + os.path.unlink(self.filename) + except: + pass + return + logged = False + for i in range(20): + filename_timestamp = os.path.getmtime(self.filename) + if filename_timestamp > self.module_timestamp: + break + if not logged: + self.log.action( + 'Waiting for generated file timestamp to increase') + logged = True + os.utime(self.filename) + time.sleep(0.1) + +def persistent_file_helper(u_boot_log, filename): + """Manage the timestamps and regeneration of a persistent generated + file. This function creates a context manager for Python's "with" + statement + + Usage: + with persistent_file_helper(u_boot_console.log, filename): + code to generate the file, if it's missing. + + Args: + u_boot_log: u_boot_console.log. + filename: The filename of the generated file. + + Returns: + A context manager object. + """ + + return PersistentFileHelperCtxMgr(u_boot_log, filename) + +def crc32(u_boot_console, address, count): + """Helper function used to compute the CRC32 value of a section of RAM. + + Args: + u_boot_console: A U-Boot console connection. + address: Address where data starts. + count: Amount of data to use for calculation. + + Returns: + CRC32 value + """ + + bcfg = u_boot_console.config.buildconfig + has_cmd_crc32 = bcfg.get('config_cmd_crc32', 'n') == 'y' + assert has_cmd_crc32, 'Cannot compute crc32 without CONFIG_CMD_CRC32.' + output = u_boot_console.run_command('crc32 %08x %x' % (address, count)) + + m = re.search('==> ([0-9a-fA-F]{8})$', output) + assert m, 'CRC32 operation failed.' + + return m.group(1)