[Autotest][PY3] Update suite_common to not crash autotest in py3.

If a control file is not python3 compatible, it will cause autotest as a whole
to crash (even if the control file is not the test being run) when being run
in python3. This workaround will instead just omit non-valid control files
(in python3 only).

This also has the somewhat un-intended, but useful, benefit of bad control
files can't bring down non-related tests.

BUG=chromium:990593
TEST=dummy_pass in python 2 and 3. utils_unittest

Change-Id: I33e39a3a6f159514f299e5e782707929f903ad1b
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/autotest/+/2574788
Tested-by: Derek Beckett <dbeckett@chromium.org>
Auto-Submit: Derek Beckett <dbeckett@chromium.org>
Reviewed-by: Gregory Nisbet <gregorynisbet@google.com>
Commit-Queue: Derek Beckett <dbeckett@chromium.org>
diff --git a/server/cros/dynamic_suite/suite_common.py b/server/cros/dynamic_suite/suite_common.py
index 0cd6718..b98a6f3 100644
--- a/server/cros/dynamic_suite/suite_common.py
+++ b/server/cros/dynamic_suite/suite_common.py
@@ -329,18 +329,39 @@
         # path, text, forgiving_error configuration, and test arguments.
         paths, texts = list(zip(*control_file_texts_all))
         worker_data = list(zip(paths, texts, [forgiving_error] * len(paths),
-                          [test_args] * len(paths)))
+                           [test_args] * len(paths)))
         pool = multiprocessing.Pool(processes=get_process_limit())
-        result_list = pool.map(parse_cf_text_process, worker_data)
+        raw_result_list = pool.map(parse_cf_text_process, worker_data)
         pool.close()
         pool.join()
 
-        # Convert [(path, test), ...] to {path: test, ...}
+        result_list = _current_py_compatible_files(raw_result_list)
         tests = dict(result_list)
 
     return tests
 
 
+def _current_py_compatible_files(control_files):
+    """Given a list of control_files, return a list of compatible files.
+
+    Remove blanks/ctrl files with errors (aka not python3 when running
+    python3 compatible) items so the dict conversion doesn't fail.
+
+    @return: List of control files filtered down to those who are compatible
+             with the current running version of python
+    """
+    result_list = []
+    for item in control_files:
+        if item:
+            result_list.append(item)
+        elif six.PY2:
+            # Only raise the error in python 2 environments, for now. See
+            # crbug.com/990593
+            raise error.ControlFileMalformed(
+                "Blank or invalid control file. See log for details.")
+    return result_list
+
+
 def retrieve_control_data_for_test(cf_getter, test_name):
     """Retrieve a test's control file.