[autotest] Make _ControlFileRetriever class

This class will contain all of the logic for getting and parsing
control files.

BUG=chromium:672348
TEST=None

Change-Id: I24bc89193a271e9e631c7376f47ec06aaee1d2a2
Reviewed-on: https://chromium-review.googlesource.com/452676
Commit-Ready: Allen Li <ayatane@chromium.org>
Tested-by: Allen Li <ayatane@chromium.org>
Reviewed-by: Aviv Keshet <akeshet@chromium.org>
diff --git a/server/cros/dynamic_suite/suite.py b/server/cros/dynamic_suite/suite.py
index afa46bb..e283d8c 100644
--- a/server/cros/dynamic_suite/suite.py
+++ b/server/cros/dynamic_suite/suite.py
@@ -462,70 +462,78 @@
         return keyvals
 
 
-def _find_test_control_data_for_suite(
-        cf_getter, suite_name='',
-        forgiving_parser=True, run_prod_code=False,
-        test_args=None):
+class _ControlFileRetriever(object):
+    """Retrieves control files.
+
+    This returns control data instances, unlike control file getters
+    which simply return the control file text contents.
     """
-    Function to scan through all tests and find all tests.
 
-    When this method is called with a file system ControlFileGetter, or
-    enable_controls_in_batch is set as false, this function will looks at
-    control files returned by cf_getter.get_control_file_list() for tests.
 
-    If cf_getter is a File system ControlFileGetter, it performs a full
-    parse of the root directory associated with the getter. This is the
-    case when it's invoked from suite_preprocessor.
+    def find_test_control_data_for_suite(
+            self, cf_getter, suite_name='',
+            forgiving_parser=True, run_prod_code=False,
+            test_args=None):
+        """
+        Function to scan through all tests and find all tests.
 
-    If cf_getter is a devserver getter it looks up the suite_name in a
-    suite to control file map generated at build time, and parses the
-    relevant control files alone. This lookup happens on the devserver,
-    so as far as this method is concerned, both cases are equivalent. If
-    enable_controls_in_batch is switched on, this function will call
-    cf_getter.get_suite_info() to get a dict of control files and contents
-    in batch.
+        When this method is called with a file system ControlFileGetter, or
+        enable_controls_in_batch is set as false, this function will looks at
+        control files returned by cf_getter.get_control_file_list() for tests.
 
-    @param cf_getter: a control_file_getter.ControlFileGetter used to list
-           and fetch the content of control files
-    @param suite_name: If specified, this method will attempt to restrain
-                       the search space to just this suite's control files.
-    @param forgiving_parser: If False, will raise ControlVariableExceptions
-                             if any are encountered when parsing control
-                             files. Note that this can raise an exception
-                             for syntax errors in unrelated files, because
-                             we parse them before applying the predicate.
-    @param run_prod_code: If true, the suite will run the test code that
-                          lives in prod aka the test code currently on the
-                          lab servers by disabling SSP for the discovered
-                          tests.
-    @param test_args: A dict of args to be seeded in test control file under
-                      the name |args_dict|.
+        If cf_getter is a File system ControlFileGetter, it performs a full
+        parse of the root directory associated with the getter. This is the
+        case when it's invoked from suite_preprocessor.
 
-    @raises ControlVariableException: If forgiving_parser is False and there
-                                      is a syntax error in a control file.
+        If cf_getter is a devserver getter it looks up the suite_name in a
+        suite to control file map generated at build time, and parses the
+        relevant control files alone. This lookup happens on the devserver,
+        so as far as this method is concerned, both cases are equivalent. If
+        enable_controls_in_batch is switched on, this function will call
+        cf_getter.get_suite_info() to get a dict of control files and contents
+        in batch.
 
-    @returns a dictionary of ControlData objects that based on given
-             parameters.
-    """
-    if _should_batch_with(cf_getter):
-        suite_info = cf_getter.get_suite_info(suite_name=suite_name)
-        files = suite_info.keys()
-    else:
-        files = cf_getter.get_control_file_list(suite_name=suite_name)
+        @param cf_getter: a control_file_getter.ControlFileGetter used to list
+               and fetch the content of control files
+        @param suite_name: If specified, this method will attempt to restrain
+                           the search space to just this suite's control files.
+        @param forgiving_parser: If False, will raise ControlVariableExceptions
+                                 if any are encountered when parsing control
+                                 files. Note that this can raise an exception
+                                 for syntax errors in unrelated files, because
+                                 we parse them before applying the predicate.
+        @param run_prod_code: If true, the suite will run the test code that
+                              lives in prod aka the test code currently on the
+                              lab servers by disabling SSP for the discovered
+                              tests.
+        @param test_args: A dict of args to be seeded in test control file under
+                          the name |args_dict|.
 
-    matcher = re.compile(r'[^/]+/(deps|profilers)/.+')
-    filtered_files = (path for path in files if not matcher.match(path))
-    if _should_batch_with(cf_getter):
-        control_file_texts = _batch_get_control_file_texts(
-                suite_info, filtered_files)
-    else:
-        control_file_texts = _get_control_file_texts(
-                cf_getter, filtered_files)
-    return _parse_control_file_texts(
-            control_file_texts=control_file_texts,
-            forgiving_parser=forgiving_parser,
-            run_prod_code=run_prod_code,
-            test_args=test_args)
+        @raises ControlVariableException: If forgiving_parser is False and there
+                                          is a syntax error in a control file.
+
+        @returns a dictionary of ControlData objects that based on given
+                 parameters.
+        """
+        if _should_batch_with(cf_getter):
+            suite_info = cf_getter.get_suite_info(suite_name=suite_name)
+            files = suite_info.keys()
+        else:
+            files = cf_getter.get_control_file_list(suite_name=suite_name)
+
+        matcher = re.compile(r'[^/]+/(deps|profilers)/.+')
+        filtered_files = (path for path in files if not matcher.match(path))
+        if _should_batch_with(cf_getter):
+            control_file_texts = _batch_get_control_file_texts(
+                    suite_info, filtered_files)
+        else:
+            control_file_texts = _get_control_file_texts(
+                    cf_getter, filtered_files)
+        return _parse_control_file_texts(
+                control_file_texts=control_file_texts,
+                forgiving_parser=forgiving_parser,
+                run_prod_code=run_prod_code,
+                test_args=test_args)
 
 
 def _parse_control_file_texts(control_file_texts,
@@ -846,7 +854,7 @@
             on the TIME setting in control file, slowest test comes first.
     """
     logging.debug('Getting control file list for suite: %s', suite_name)
-    tests = _find_test_control_data_for_suite(
+    tests = _ControlFileRetriever().find_test_control_data_for_suite(
             cf_getter, suite_name, forgiving_parser,
             run_prod_code=run_prod_code, test_args=test_args)
     if not add_experimental:
@@ -883,7 +891,7 @@
             match ratio.
     """
     logging.debug('Getting control file list for suite: %s', suite_name)
-    tests = _find_test_control_data_for_suite(
+    tests = _ControlFileRetriever().find_test_control_data_for_suite(
             cf_getter, suite_name, forgiving_parser=True)
     logging.debug('Parsed %s control files.', len(tests))
     similarities = {}