mirror of
https://github.com/ARM-software/devlib.git
synced 2025-02-07 05:30:44 +00:00
Target: add read_tree_values and read_tree_values_flat
Add two new methods to target that allow querying values of all sysfs nodes in a sub-directory structure all at once. The difference is that read_tree_values_flat returns a flat dict of path->value mappings; read_tree_values returns a nested dict structure that mimics the scanned sub-directories tree.
This commit is contained in:
parent
92fb54d57b
commit
181bc180c4
@ -195,6 +195,22 @@ cgroups_freezer_set_state() {
|
|||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Misc
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
read_tree_values() {
|
||||||
|
PATH=$1
|
||||||
|
MAXDEPTH=$2
|
||||||
|
|
||||||
|
PATHS=$($BUSYBOX find $PATH -follow -maxdepth $MAXDEPTH)
|
||||||
|
if [ ${#PATHS[@]} -eq 0 ]; then
|
||||||
|
echo "ERROR: '$1' does not exist"
|
||||||
|
else
|
||||||
|
$BUSYBOX grep -s '' $PATHS
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Main Function Dispatcher
|
# Main Function Dispatcher
|
||||||
################################################################################
|
################################################################################
|
||||||
@ -236,6 +252,9 @@ cgroups_freezer_set_state)
|
|||||||
ftrace_get_function_stats)
|
ftrace_get_function_stats)
|
||||||
ftrace_get_function_stats
|
ftrace_get_function_stats
|
||||||
;;
|
;;
|
||||||
|
read_tree_values)
|
||||||
|
read_tree_values $*
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Command [$CMD] not supported"
|
echo "Command [$CMD] not supported"
|
||||||
exit -1
|
exit -1
|
||||||
|
@ -614,6 +614,20 @@ class Target(object):
|
|||||||
timeout = duration + 10
|
timeout = duration + 10
|
||||||
self.execute('sleep {}'.format(duration), timeout=timeout)
|
self.execute('sleep {}'.format(duration), timeout=timeout)
|
||||||
|
|
||||||
|
def read_tree_values_flat(self, path, depth=1, check_exit_code=True):
|
||||||
|
command = 'read_tree_values {} {}'.format(path, depth)
|
||||||
|
output = self._execute_util(command, as_root=self.is_rooted,
|
||||||
|
check_exit_code=check_exit_code)
|
||||||
|
result = {}
|
||||||
|
for entry in output.strip().split('\n'):
|
||||||
|
path, value = entry.strip().split(':', 1)
|
||||||
|
result[path] = value
|
||||||
|
return result
|
||||||
|
|
||||||
|
def read_tree_values(self, path, depth=1, dictcls=dict, check_exit_code=True):
|
||||||
|
value_map = self.read_tree_values_flat(path, depth, check_exit_code)
|
||||||
|
return _build_path_tree(value_map, path, self.path.sep, dictcls)
|
||||||
|
|
||||||
# internal methods
|
# internal methods
|
||||||
|
|
||||||
def _setup_shutils(self):
|
def _setup_shutils(self):
|
||||||
@ -1558,3 +1572,32 @@ def _get_part_name(section):
|
|||||||
if name is None:
|
if name is None:
|
||||||
name = '{}/{}/{}'.format(implementer, part, variant)
|
name = '{}/{}/{}'.format(implementer, part, variant)
|
||||||
return name
|
return name
|
||||||
|
|
||||||
|
|
||||||
|
def _build_path_tree(path_map, basepath, sep=os.path.sep, dictcls=dict):
|
||||||
|
"""
|
||||||
|
Convert a flat mapping of paths to values into a nested structure of
|
||||||
|
dict-line object (``dict``'s by default), mirroring the directory hierarchy
|
||||||
|
represented by the paths relative to ``basepath``.
|
||||||
|
|
||||||
|
"""
|
||||||
|
def process_node(node, path, value):
|
||||||
|
parts = path.split(sep, 1)
|
||||||
|
if len(parts) == 1: # leaf
|
||||||
|
node[parts[0]] = value
|
||||||
|
else: # branch
|
||||||
|
if parts[0] not in node:
|
||||||
|
node[parts[0]] = dictcls()
|
||||||
|
process_node(node[parts[0]], parts[1], value)
|
||||||
|
|
||||||
|
relpath_map = {os.path.relpath(p, basepath): v
|
||||||
|
for p, v in path_map.iteritems()}
|
||||||
|
|
||||||
|
if len(relpath_map) == 1 and relpath_map.keys()[0] == '.':
|
||||||
|
result = relpath_map.values()[0]
|
||||||
|
else:
|
||||||
|
result = dictcls()
|
||||||
|
for path, value in relpath_map.iteritems():
|
||||||
|
process_node(result, path, value)
|
||||||
|
|
||||||
|
return result
|
||||||
|
@ -327,6 +327,32 @@ Target
|
|||||||
some sysfs entries silently failing to set the written value without
|
some sysfs entries silently failing to set the written value without
|
||||||
returning an error code.
|
returning an error code.
|
||||||
|
|
||||||
|
.. method:: Target.read_tree_values(path, depth=1, dictcls=dict):
|
||||||
|
|
||||||
|
Read values of all sysfs (or similar) file nodes under ``path``, traversing
|
||||||
|
up to the maximum depth ``depth``.
|
||||||
|
|
||||||
|
Returns a nested structure of dict-like objects (``dict``\ s by default) that
|
||||||
|
follows the structure of the scanned sub-directory tree. The top-level entry
|
||||||
|
has a single item who's key is ``path``. If ``path`` points to a single file,
|
||||||
|
the value of the entry is the value ready from that file node. Otherwise, the
|
||||||
|
value is a dict-line object with a key for every entry under ``path``
|
||||||
|
mapping onto its value or further dict-like objects as appropriate.
|
||||||
|
|
||||||
|
:param path: sysfs path to scan
|
||||||
|
:param depth: maximum depth to descend
|
||||||
|
:param dictcls: a dict-like type to be used for each level of the hierarchy.
|
||||||
|
|
||||||
|
.. method:: Target.read_tree_values_flat(path, depth=1):
|
||||||
|
|
||||||
|
Read values of all sysfs (or similar) file nodes under ``path``, traversing
|
||||||
|
up to the maximum depth ``depth``.
|
||||||
|
|
||||||
|
Returns a dict mapping paths of file nodes to corresponding values.
|
||||||
|
|
||||||
|
:param path: sysfs path to scan
|
||||||
|
:param depth: maximum depth to descend
|
||||||
|
|
||||||
.. method:: Target.reset()
|
.. method:: Target.reset()
|
||||||
|
|
||||||
Soft reset the target. Typically, this means executing ``reboot`` on the
|
Soft reset the target. Typically, this means executing ``reboot`` on the
|
||||||
|
Loading…
x
Reference in New Issue
Block a user