1
0
mirror of https://github.com/ARM-software/devlib.git synced 2025-01-31 02:00:45 +00:00

target: read_tree_values: handle multiline values

Extend Target.read_tree_values() to handle notes that contain line
breaks in their values. Underlying this method, is a call to

	grep -r '' /tree/root/

When files under that location contain multiple lines, grep will output
each line prefixed with the path; e.g. a file "test" with the contents
"one\n\ntwo\n" will be output by grep as:

	/tree/root/test: one
	/tree/root/test:
	/tree/root/test: two

Previous implementation of read_tree_values() was assuming one value per
line, and that the paths were unique. Since it wasn't checking for
duplicate paths, it would simply override the earlier entries resulting
with the value of "two" for test.

This change ensure that such multiline values are now handled correctly,
and the entire value is preserved.

To keep compatibility with existing uses of read_tree_values(), the
trailing new lines are stripped.
This commit is contained in:
Sergei Trofimov 2018-08-23 09:57:56 +01:00 committed by setrofim
parent 8cd1470bb8
commit 61208ce2e0
2 changed files with 38 additions and 3 deletions

View File

@ -24,7 +24,7 @@ import tarfile
import tempfile import tempfile
import threading import threading
import xml.dom.minidom import xml.dom.minidom
from collections import namedtuple from collections import namedtuple, defaultdict
from devlib.host import LocalConnection, PACKAGE_BIN_DIRECTORY from devlib.host import LocalConnection, PACKAGE_BIN_DIRECTORY
from devlib.module import get_module from devlib.module import get_module
@ -676,12 +676,15 @@ class Target(object):
command = 'read_tree_values {} {}'.format(path, depth) command = 'read_tree_values {} {}'.format(path, depth)
output = self._execute_util(command, as_root=self.is_rooted, output = self._execute_util(command, as_root=self.is_rooted,
check_exit_code=check_exit_code) check_exit_code=check_exit_code)
result = {}
accumulator = defaultdict(list)
for entry in output.strip().split('\n'): for entry in output.strip().split('\n'):
if ':' not in entry: if ':' not in entry:
continue continue
path, value = entry.strip().split(':', 1) path, value = entry.strip().split(':', 1)
result[path] = value accumulator[path].append(value)
result = {k: '\n'.join(v).strip() for k, v in accumulator.items()}
return result return result
def read_tree_values(self, path, depth=1, dictcls=dict, check_exit_code=True): def read_tree_values(self, path, depth=1, dictcls=dict, check_exit_code=True):

32
tests/test_target.py Normal file
View File

@ -0,0 +1,32 @@
import os
import shutil
import tempfile
from unittest import TestCase
from devlib import LocalLinuxTarget
class TestReadTreeValues(TestCase):
def test_read_multiline_values(self):
data = {
'test1': '1',
'test2': '2\n\n',
'test3': '3\n\n4\n\n',
}
tempdir = tempfile.mkdtemp(prefix='devlib-test-')
for key, value in data.items():
path = os.path.join(tempdir, key)
with open(path, 'w') as wfh:
wfh.write(value)
t = LocalLinuxTarget(connection_settings={'unrooted': True})
raw_result = t.read_tree_values_flat(tempdir)
result = {os.path.basename(k): v for k, v in raw_result.items()}
shutil.rmtree(tempdir)
self.assertEqual({k: v.strip()
for k, v in data.items()},
result)