test_lists: Create test_list_common.py for test list constants.

Move some test list constants, such as file paths, to a separate file,
so that we don't need to import manager.py just to get these variables.

BUG=chromium:910037, chromium:899136
TEST=make test

Change-Id: Ife293743b539a45bf50a5d3a43a83b2ee1228718
Reviewed-on: https://chromium-review.googlesource.com/1560950
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: Cheng-Han Yang <chenghan@chromium.org>
Reviewed-by: Yong Hong <yhong@google.com>
diff --git a/py/test/test_lists/manager.py b/py/test/test_lists/manager.py
index 224e0f3..8aaa587 100644
--- a/py/test/test_lists/manager.py
+++ b/py/test/test_lists/manager.py
@@ -10,9 +10,9 @@
 import zipimport
 
 import factory_common  # pylint: disable=unused-import
-from cros.factory.test.env import paths
 from cros.factory.test.test_lists import checker as checker_module
 from cros.factory.test.test_lists import test_list as test_list_module
+from cros.factory.test.test_lists import test_list_common
 from cros.factory.utils import config_utils
 from cros.factory.utils import file_utils
 from cros.factory.utils import json_utils
@@ -20,36 +20,9 @@
 from cros.factory.utils import type_utils
 
 
-# Directory for test lists.
-TEST_LISTS_RELPATH = os.path.join('py', 'test', 'test_lists')
-TEST_LISTS_PATH = os.path.join(paths.FACTORY_DIR, TEST_LISTS_RELPATH)
-
-# File identifying the active test list.
-ACTIVE_TEST_LIST_CONFIG_NAME = 'active_test_list'
-ACTIVE_TEST_LIST_CONFIG_ID_KEY = 'id'
-
-# The active test list ID is the most important factory data that we
-# can't afford it to disappear unexpectedly.  Therefore, instead of
-# saving it as a runtime configuration, we would rather saving it as
-# a buildtime configuration manually.
-ACTIVE_TEST_LIST_CONFIG_RELPATH = os.path.join(
-    TEST_LISTS_RELPATH,
-    ACTIVE_TEST_LIST_CONFIG_NAME + config_utils.CONFIG_FILE_EXT)
-ACTIVE_TEST_LIST_CONFIG_PATH = os.path.join(
-    paths.FACTORY_DIR, ACTIVE_TEST_LIST_CONFIG_RELPATH)
-
-# Test list constants config
-CONSTANTS_CONFIG_NAME = 'test_list_constants'
-CONSTANTS_KEY = 'constants'
-
 # Default test list.
 DEFAULT_TEST_LIST_ID = 'main'
 
-# All test lists must have name: <id>.test_list.json
-CONFIG_SUFFIX = '.test_list'
-
-TEST_LIST_SCHEMA_NAME = 'test_list'
-
 
 class TestListConfig(object):
   """A loaded test list config.
@@ -124,13 +97,14 @@
     # manager in factory par. The default_config_dirs config_utils.LoadConfig
     # will find should be the same one we compute here, however, we also need
     # this path to check file state, so let's figure out the path by ourselves.
-    self.config_dir = config_dir or TEST_LISTS_PATH
+    self.config_dir = config_dir or test_list_common.TEST_LISTS_PATH
 
   @type_utils.LazyProperty
   def test_list_constants(self):
     constants = {}
     try:
-      constants = config_utils.LoadConfig(CONSTANTS_CONFIG_NAME)
+      constants = config_utils.LoadConfig(
+          test_list_common.TEST_LIST_CONSTANTS_CONFIG_NAME)
     except config_utils.ConfigNotFoundError:
       logging.info('No test list constants config found')
     except Exception as e:
@@ -143,11 +117,11 @@
     Returns:
       :rtype: TestListConfig
     """
-    config_name = self._GetConfigName(test_list_id)
+    config_name = test_list_common.GetTestListConfigName(test_list_id)
     try:
       loaded_config = config_utils.LoadConfig(
           config_name=config_name,
-          schema_name=TEST_LIST_SCHEMA_NAME,
+          schema_name=test_list_common.TEST_LIST_SCHEMA_NAME,
           validate_schema=True,
           default_config_dirs=self.config_dir,
           allow_inherit=allow_inherit,
@@ -157,7 +131,8 @@
       raise
 
     # Override constants from py/config if it exists
-    loaded_config.get(CONSTANTS_KEY, {}).update(self.test_list_constants)
+    loaded_config.get(test_list_common.TEST_LIST_CONSTANTS_KEY, {}).update(
+        self.test_list_constants)
 
     loaded_config = TestListConfig(
         resolved_config=loaded_config,
@@ -166,15 +141,13 @@
 
     return loaded_config
 
-  def _GetConfigName(self, test_list_id):
-    """Returns the test list config file corresponding to `test_list_id`."""
-    return test_list_id + CONFIG_SUFFIX
-
   def FindTestLists(self):
     """Returns a dict which maps the id to the file path of each test list."""
     globbed_configs = config_utils.GlobConfig(
-        '*' + CONFIG_SUFFIX, default_config_dirs=self.config_dir)
-    return [name[:-len(CONFIG_SUFFIX)] for name in globbed_configs]
+        test_list_common.GetTestListConfigName('*'),
+        default_config_dirs=self.config_dir)
+    return [name[:-len(test_list_common.TEST_LIST_CONFIG_SUFFIX)]
+            for name in globbed_configs]
 
 
 class Manager(object):
@@ -267,9 +240,10 @@
     """
     try:
       config_data = config_utils.LoadConfig(
-          config_name=ACTIVE_TEST_LIST_CONFIG_NAME,
-          default_config_dirs=os.path.dirname(ACTIVE_TEST_LIST_CONFIG_PATH))
-      return config_data[ACTIVE_TEST_LIST_CONFIG_ID_KEY]
+          config_name=test_list_common.ACTIVE_TEST_LIST_CONFIG_NAME,
+          default_config_dirs=os.path.dirname(
+              test_list_common.ACTIVE_TEST_LIST_CONFIG_PATH))
+      return config_data[test_list_common.ACTIVE_TEST_LIST_CONFIG_ID_KEY]
 
     except config_utils.ConfigNotFoundError:
       logging.info('No active test list configuration is found, '
@@ -289,8 +263,8 @@
 
     for test_list_id in [model_main, 'main', 'generic_main']:
       if os.path.exists(os.path.join(
-          TEST_LISTS_PATH,
-          test_list_id + CONFIG_SUFFIX + config_utils.CONFIG_FILE_EXT)):
+          test_list_common.TEST_LISTS_PATH,
+          test_list_common.GetTestListConfigFile(test_list_id))):
         return test_list_id
     return DEFAULT_TEST_LIST_ID
 
@@ -301,10 +275,11 @@
     This writes the name of the new active test list to the build time config
     file.
     """
-    config_data = json_utils.DumpStr({ACTIVE_TEST_LIST_CONFIG_ID_KEY: new_id},
-                                     pretty=True)
+    config_data = json_utils.DumpStr(
+        test_list_common.GenerateActiveTestListConfig(new_id), pretty=True)
 
-    with file_utils.AtomicWrite(ACTIVE_TEST_LIST_CONFIG_PATH) as f:
+    with file_utils.AtomicWrite(
+        test_list_common.ACTIVE_TEST_LIST_CONFIG_PATH) as f:
       f.write(config_data)
 
 
diff --git a/py/test/test_lists/manager_unittest.py b/py/test/test_lists/manager_unittest.py
index c591615..d93a05b 100755
--- a/py/test/test_lists/manager_unittest.py
+++ b/py/test/test_lists/manager_unittest.py
@@ -17,6 +17,7 @@
 from cros.factory.test import device_data
 from cros.factory.test import state
 from cros.factory.test.test_lists import manager
+from cros.factory.test.test_lists import test_list_common
 from cros.factory.utils import config_utils
 
 
@@ -273,7 +274,8 @@
 
   def _GetTestListConfigPath(self, test_list_id):
     return os.path.join(
-        self.temp_dir, test_list_id + manager.CONFIG_SUFFIX + '.json')
+        self.temp_dir,
+        test_list_common.GetTestListConfigFile(test_list_id))
 
 
 if __name__ == '__main__':
diff --git a/py/test/test_lists/test_list_common.py b/py/test/test_lists/test_list_common.py
new file mode 100644
index 0000000..7a3f873
--- /dev/null
+++ b/py/test/test_lists/test_list_common.py
@@ -0,0 +1,53 @@
+# Copyright 2019 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import os
+
+import factory_common  # pylint: disable=unused-import
+from cros.factory.test.env import paths
+from cros.factory.utils import config_utils
+
+
+# Directory for test lists.
+TEST_LISTS_RELPATH = os.path.join('py', 'test', 'test_lists')
+TEST_LISTS_PATH = os.path.join(paths.FACTORY_DIR, TEST_LISTS_RELPATH)
+
+# All test lists must have name: <id>.test_list.json.
+TEST_LIST_CONFIG_SUFFIX = '.test_list'
+
+# Test list schema.
+TEST_LIST_SCHEMA_NAME = 'test_list'
+
+# File identifying the active test list.
+ACTIVE_TEST_LIST_CONFIG_NAME = 'active_test_list'
+ACTIVE_TEST_LIST_CONFIG_ID_KEY = 'id'
+
+# The active test list ID is the most important factory data that we
+# can't afford it to disappear unexpectedly.  Therefore, instead of
+# saving it as a runtime configuration, we would rather saving it as
+# a buildtime configuration manually.
+ACTIVE_TEST_LIST_CONFIG_RELPATH = os.path.join(
+    TEST_LISTS_RELPATH,
+    ACTIVE_TEST_LIST_CONFIG_NAME + config_utils.CONFIG_FILE_EXT)
+ACTIVE_TEST_LIST_CONFIG_PATH = os.path.join(
+    paths.FACTORY_DIR, ACTIVE_TEST_LIST_CONFIG_RELPATH)
+
+# Test list constants config.
+TEST_LIST_CONSTANTS_CONFIG_NAME = 'test_list_constants'
+TEST_LIST_CONSTANTS_KEY = 'constants'
+
+
+def GetTestListConfigName(test_list_id):
+  """Returns the test list config name corresponding to `test_list_id`."""
+  return test_list_id + TEST_LIST_CONFIG_SUFFIX
+
+
+def GetTestListConfigFile(test_list_id):
+  """Returns the test list config file corresponding to `test_list_id`."""
+  return test_list_id + TEST_LIST_CONFIG_SUFFIX + config_utils.CONFIG_FILE_EXT
+
+
+def GenerateActiveTestListConfig(active_test_list):
+  """Returns a dictionary for active test list."""
+  return {ACTIVE_TEST_LIST_CONFIG_ID_KEY: active_test_list}
diff --git a/py/test_list_editor/backend/rpc.py b/py/test_list_editor/backend/rpc.py
index afe1654..a4a2ca5 100644
--- a/py/test_list_editor/backend/rpc.py
+++ b/py/test_list_editor/backend/rpc.py
@@ -10,9 +10,8 @@
 
 import factory_common  # pylint: disable=unused-import
 from cros.factory.test import i18n
-from cros.factory.test.test_lists import manager
+from cros.factory.test.test_lists import test_list_common
 from cros.factory.test.utils import pytest_utils
-from cros.factory.utils import config_utils
 from cros.factory.utils import file_utils
 from cros.factory.utils import type_utils
 
@@ -69,11 +68,11 @@
     dirs = []
     files = {}
     for dirname, dirpath in self.dirs:
-      test_list_dir = os.path.join(dirpath, manager.TEST_LISTS_RELPATH)
+      test_list_dir = os.path.join(dirpath, test_list_common.TEST_LISTS_RELPATH)
       filelist = []
       filepaths = glob.glob(os.path.join(
           test_list_dir,
-          '*' + manager.CONFIG_SUFFIX + config_utils.CONFIG_FILE_EXT))
+          test_list_common.GetTestListConfigFile('*')))
       for filepath in filepaths:
         basename = os.path.basename(filepath)
         if basename in files:
@@ -97,12 +96,12 @@
     """
 
     def IsForbidden(path):
-      if not path.endswith(
-          manager.CONFIG_SUFFIX + config_utils.CONFIG_FILE_EXT):
+      if not path.endswith(test_list_common.GetTestListConfigFile('')):
         return True
       path_dir = os.path.dirname(path)
       for unused_dirname, dirpath in self.dirs:
-        if path_dir == os.path.join(dirpath, manager.TEST_LISTS_RELPATH):
+        if path_dir == os.path.join(dirpath,
+                                    test_list_common.TEST_LISTS_RELPATH):
           return False
       return True
 
diff --git a/py/test_list_editor/backend/rpc_unittest.py b/py/test_list_editor/backend/rpc_unittest.py
index 9d31136..8dee6c3 100755
--- a/py/test_list_editor/backend/rpc_unittest.py
+++ b/py/test_list_editor/backend/rpc_unittest.py
@@ -12,7 +12,7 @@
 
 import factory_common  # pylint: disable=unused-import
 from cros.factory.test.env import paths
-from cros.factory.test.test_lists import manager
+from cros.factory.test.test_lists import test_list_common
 from cros.factory.test_list_editor.backend import rpc
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import file_utils
@@ -42,7 +42,7 @@
 
   def testSaveFiles(self):
     with file_utils.TempDirectory() as tmp_dir:
-      test_list_dir = os.path.join(tmp_dir, manager.TEST_LISTS_RELPATH)
+      test_list_dir = os.path.join(tmp_dir, test_list_common.TEST_LISTS_RELPATH)
       os.makedirs(test_list_dir)
       rpc_obj = rpc.RPC([('', tmp_dir)])
       content = 'hello, world'
diff --git a/py/test_list_editor/backend/test_list_editor.py b/py/test_list_editor/backend/test_list_editor.py
index 8651d88..70000a2 100755
--- a/py/test_list_editor/backend/test_list_editor.py
+++ b/py/test_list_editor/backend/test_list_editor.py
@@ -15,7 +15,7 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.test.env import paths
 from cros.factory.test.i18n import translation
-from cros.factory.test.test_lists import manager
+from cros.factory.test.test_lists import test_list_common
 from cros.factory.test_list_editor.backend import common
 from cros.factory.test_list_editor.backend import rpc
 from cros.factory.utils import sys_utils
@@ -78,7 +78,7 @@
     return
 
   base_dir = os.path.join(private_overlay_dir, common.PRIVATE_FACTORY_RELPATH)
-  test_list_dir = os.path.join(base_dir, manager.TEST_LISTS_RELPATH)
+  test_list_dir = os.path.join(base_dir, test_list_common.TEST_LISTS_RELPATH)
   if not os.path.isdir(test_list_dir):
     raise RuntimeError('Directory %r not found.' % test_list_dir)
   dirs.append((os.path.basename(private_overlay_dir).split('-')[1], base_dir))
diff --git a/py/toolkit/installer.py b/py/toolkit/installer.py
index 437b7e9..fd77a99 100755
--- a/py/toolkit/installer.py
+++ b/py/toolkit/installer.py
@@ -24,7 +24,7 @@
 
 import factory_common  # pylint: disable=unused-import
 from cros.factory.test.env import paths
-from cros.factory.test.test_lists import manager
+from cros.factory.test.test_lists import test_list_common
 from cros.factory.tools import install_symlinks
 from cros.factory.utils import file_utils
 from cros.factory.utils import json_utils
@@ -201,8 +201,10 @@
     """Set the active test list for Goofy."""
     if self._active_test_list is not None:
       path = os.path.join(self._usr_local_dest, 'factory',
-                          manager.ACTIVE_TEST_LIST_CONFIG_RELPATH)
-      json_utils.DumpFile(path, {'id': self._active_test_list})
+                          test_list_common.ACTIVE_TEST_LIST_CONFIG_RELPATH)
+      json_utils.DumpFile(
+          path,
+          test_list_common.GenerateActiveTestListConfig(self._active_test_list))
 
   def _EnableApp(self, app, enabled):
     """Enable / disable @app.