1 # Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
3 # SPDX-License-Identifier: GPL-2.0
5 # Utility code shared across multiple tests.
14 def md5sum_data(data):
15 """Calculate the MD5 hash of some data.
18 data: The data to hash.
21 The hash of the data, as a binary string.
28 def md5sum_file(fn, max_length=None):
29 """Calculate the MD5 hash of the contents of a file.
32 fn: The filename of the file to hash.
33 max_length: The number of bytes to hash. If the file has more
34 bytes than this, they will be ignored. If None or omitted, the
35 entire file will be hashed.
38 The hash of the file content, as a binary string.
41 with open(fn, 'rb') as fh:
46 data = fh.read(*params)
47 return md5sum_data(data)
49 class PersistentRandomFile(object):
50 """Generate and store information about a persistent file containing
53 def __init__(self, u_boot_console, fn, size):
54 """Create or process the persistent file.
56 If the file does not exist, it is generated.
58 If the file does exist, its content is hashed for later comparison.
60 These files are always located in the "persistent data directory" of
64 u_boot_console: A console connection to U-Boot.
65 fn: The filename (without path) to create.
66 size: The desired size of the file in bytes.
74 self.abs_fn = u_boot_console.config.persistent_data_dir + '/' + fn
76 if os.path.exists(self.abs_fn):
77 u_boot_console.log.action('Persistent data file ' + self.abs_fn +
79 self.content_hash = md5sum_file(self.abs_fn)
81 u_boot_console.log.action('Generating ' + self.abs_fn +
82 ' (random, persistent, %d bytes)' % size)
83 data = os.urandom(size)
84 with open(self.abs_fn, 'wb') as fh:
86 self.content_hash = md5sum_data(data)
88 def attempt_to_open_file(fn):
89 """Attempt to open a file, without throwing exceptions.
91 Any errors (exceptions) that occur during the attempt to open the file
92 are ignored. This is useful in order to test whether a file (in
93 particular, a device node) exists and can be successfully opened, in order
94 to poll for e.g. USB enumeration completion.
97 fn: The filename to attempt to open.
100 An open file handle to the file, or None if the file could not be
105 return open(fn, 'rb')
109 def wait_until_open_succeeds(fn):
110 """Poll until a file can be opened, or a timeout occurs.
112 Continually attempt to open a file, and return when this succeeds, or
113 raise an exception after a timeout.
116 fn: The filename to attempt to open.
119 An open file handle to the file.
122 for i in xrange(100):
123 fh = attempt_to_open_file(fn)
127 raise Exception('File could not be opened')
129 def wait_until_file_open_fails(fn, ignore_errors):
130 """Poll until a file cannot be opened, or a timeout occurs.
132 Continually attempt to open a file, and return when this fails, or
133 raise an exception after a timeout.
136 fn: The filename to attempt to open.
137 ignore_errors: Indicate whether to ignore timeout errors. If True, the
138 function will simply return if a timeout occurs, otherwise an
139 exception will be raised.
145 for i in xrange(100):
146 fh = attempt_to_open_file(fn)
153 raise Exception('File can still be opened')
155 def run_and_log(u_boot_console, cmd, ignore_errors=False):
156 """Run a command and log its output.
159 u_boot_console: A console connection to U-Boot.
160 cmd: The command to run, as an array of argv[].
161 ignore_errors: Indicate whether to ignore errors. If True, the function
162 will simply return if the command cannot be executed or exits with
163 an error code, otherwise an exception will be raised if such
170 runner = u_boot_console.log.get_runner(cmd[0], sys.stdout)
171 runner.run(cmd, ignore_errors=ignore_errors)
175 def find_ram_base(u_boot_console):
176 """Find the running U-Boot's RAM location.
178 Probe the running U-Boot to determine the address of the first bank
179 of RAM. This is useful for tests that test reading/writing RAM, or
180 load/save files that aren't associated with some standard address
181 typically represented in an environment variable such as
182 ${kernel_addr_r}. The value is cached so that it only needs to be
186 u_boot_console: A console connection to U-Boot.
189 The address of U-Boot's first RAM bank, as an integer.
193 if u_boot_console.config.buildconfig.get('config_cmd_bdi', 'n') != 'y':
194 pytest.skip('bdinfo command not supported')
196 pytest.skip('Previously failed to find RAM bank start')
197 if ram_base is not None:
200 with u_boot_console.log.section('find_ram_base'):
201 response = u_boot_console.run_command('bdinfo')
202 for l in response.split('\n'):
204 ram_base = int(l.split('=')[1].strip(), 16)
208 raise Exception('Failed to find RAM bank start in `bdinfo`')