From 6c74d1b83224a5be8ce73a13ed9b4cc8f8d6723a Mon Sep 17 00:00:00 2001
From: Walter Lozano <walter.lozano@collabora.com>
Date: Tue, 28 Jul 2020 19:06:23 -0300
Subject: [PATCH] dtoc: add coverage test for unicode error

Add an additional test to dtoc in order improve the coverage,
specifically to take into account the case of unicode error when
scanning drivers.

Signed-off-by: Walter Lozano <walter.lozano@collabora.com>
---
 tools/dtoc/dtb_platdata.py            | 18 +++++++++++++++---
 tools/dtoc/dtoc_test_scan_drivers.cxx |  1 +
 tools/dtoc/test_dtoc.py               | 26 ++++++++++++++++++++++++++
 3 files changed, 42 insertions(+), 3 deletions(-)
 create mode 100644 tools/dtoc/dtoc_test_scan_drivers.cxx

diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index 8ba8f16369..8fdf49f809 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -154,8 +154,10 @@ class DtbPlatdata(object):
                 U_BOOT_DRIVER_ALIAS(driver_alias, driver_name)
             value: Driver name declared with U_BOOT_DRIVER(driver_name)
         _links: List of links to be included in dm_populate_phandle_data()
+        _drivers_additional: List of additional drivers to use during scanning
     """
-    def __init__(self, dtb_fname, include_disabled, warning_disabled):
+    def __init__(self, dtb_fname, include_disabled, warning_disabled,
+                 drivers_additional=[]):
         self._fdt = None
         self._dtb_fname = dtb_fname
         self._valid_nodes = None
@@ -167,6 +169,7 @@ class DtbPlatdata(object):
         self._drivers = []
         self._driver_aliases = {}
         self._links = []
+        self._drivers_additional = drivers_additional
 
     def get_normalized_compat_name(self, node):
         """Get a node's normalized compat name
@@ -343,6 +346,14 @@ class DtbPlatdata(object):
                     continue
                 self.scan_driver(dirpath + '/' + fn)
 
+        for fn in self._drivers_additional:
+            if not isinstance(fn, str) or len(fn) == 0:
+                continue
+            if fn[0] == '/':
+                self.scan_driver(fn)
+            else:
+                self.scan_driver(basedir + '/' + fn)
+
     def scan_dtb(self):
         """Scan the device tree to obtain a tree of nodes and properties
 
@@ -668,7 +679,8 @@ class DtbPlatdata(object):
 
         self.out(''.join(self.get_buf()))
 
-def run_steps(args, dtb_file, include_disabled, output, warning_disabled=False):
+def run_steps(args, dtb_file, include_disabled, output, warning_disabled=False,
+              drivers_additional=[]):
     """Run all the steps of the dtoc tool
 
     Args:
@@ -680,7 +692,7 @@ def run_steps(args, dtb_file, include_disabled, output, warning_disabled=False):
     if not args:
         raise ValueError('Please specify a command: struct, platdata')
 
-    plat = DtbPlatdata(dtb_file, include_disabled, warning_disabled)
+    plat = DtbPlatdata(dtb_file, include_disabled, warning_disabled, drivers_additional)
     plat.scan_drivers()
     plat.scan_dtb()
     plat.scan_tree()
diff --git a/tools/dtoc/dtoc_test_scan_drivers.cxx b/tools/dtoc/dtoc_test_scan_drivers.cxx
new file mode 100644
index 0000000000..557c692ba2
--- /dev/null
+++ b/tools/dtoc/dtoc_test_scan_drivers.cxx
@@ -0,0 +1 @@
+U_BOOT_DRIVER_ALIAS(sandbox_gpio, sandbox_gpio_alias2)
diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py
index 08b02d4843..a351bd7728 100755
--- a/tools/dtoc/test_dtoc.py
+++ b/tools/dtoc/test_dtoc.py
@@ -13,6 +13,7 @@ import collections
 import os
 import struct
 import sys
+import tempfile
 import unittest
 
 from dtoc import dtb_platdata
@@ -863,3 +864,28 @@ U_BOOT_DEVICE(spl_test2) = {
             self.run_test(['invalid-cmd'], dtb_file, output)
         self.assertIn("Unknown command 'invalid-cmd': (use: struct, platdata)",
                       str(e.exception))
+
+    def testScanDrivers(self):
+        """Test running dtoc with additional drivers to scan"""
+        dtb_file = get_dtb_file('dtoc_test_simple.dts')
+        output = tools.GetOutputFilename('output')
+        with test_util.capture_sys_output() as (stdout, stderr):
+            dtb_platdata.run_steps(['struct'], dtb_file, False, output, True,
+                               [None, '', 'tools/dtoc/dtoc_test_scan_drivers.cxx'])
+
+    def testUnicodeError(self):
+        """Test running dtoc with an invalid unicode file
+
+        To be able to perform this test without adding a weird text file which
+        would produce issues when using checkpatch.pl or patman, generate the
+        file at runtime and then process it.
+        """
+        dtb_file = get_dtb_file('dtoc_test_simple.dts')
+        output = tools.GetOutputFilename('output')
+        driver_fn = '/tmp/' + next(tempfile._get_candidate_names())
+        with open(driver_fn, 'wb+') as df:
+            df.write(b'\x81')
+
+        with test_util.capture_sys_output() as (stdout, stderr):
+            dtb_platdata.run_steps(['struct'], dtb_file, False, output, True,
+                               [driver_fn])
-- 
2.39.5