We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
yaml.load_all is unsafe with default loader
tests/mobly/output_test.py::OutputTest::test_teardown_class_output
  T:\src\github\mobly\tests\mobly\output_test.py:258: YAMLLoadWarning: 
    *** Calling yaml.load_all() without Loader=... is deprecated.
    *** The default Loader is unsafe.
    *** Please read https://msg.pyyaml.org/load for full details.
    for entry in yaml.load_all(f):

tests/mobly/records_test.py::RecordsTest::test_summary_user_data
  T:\src\github\mobly\tests\mobly\records_test.py:401: YAMLLoadWarning: 
    *** Calling yaml.load_all() without Loader=... is deprecated.
    *** The default Loader is unsafe.
    *** Please read https://msg.pyyaml.org/load for full details.
    for c in yaml.load_all(f):

tests/mobly/records_test.py::RecordsTest::test_summary_write_dump
  T:\src\github\mobly\tests\mobly\records_test.py:364: YAMLLoadWarning: 
    *** Calling yaml.load() without Loader=... is deprecated.
    *** The default Loader is unsafe.
    *** Please read https://msg.pyyaml.org/load for full details.
    content = yaml.load(f)

tests/mobly/records_test.py::RecordsTest::test_summary_write_dump_with_unicode
  T:\src\github\mobly\tests\mobly\records_test.py:383: YAMLLoadWarning: 
    *** Calling yaml.load() without Loader=... is deprecated.
    *** The default Loader is unsafe.
    *** Please read https://msg.pyyaml.org/load for full details.
    content = yaml.load(f)

tests/mobly/test_runner_test.py::TestRunnerTest::test_summary_file_entries
  T:\src\github\mobly\tests\mobly\test_runner_test.py:135: YAMLLoadWarning: 
    *** Calling yaml.load_all() without Loader=... is deprecated.
    *** The default Loader is unsafe.
    *** Please read https://msg.pyyaml.org/load for full details.
    summary_entries = list(yaml.load_all(f))


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mobly/config_parser.py`
Content:
```
1 # Copyright 2016 Google Inc.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 from builtins import str
16 
17 import copy
18 import io
19 import pprint
20 import os
21 import yaml
22 
23 from mobly import keys
24 from mobly import utils
25 
26 # An environment variable defining the base location for Mobly logs.
27 ENV_MOBLY_LOGPATH = 'MOBLY_LOGPATH'
28 _DEFAULT_LOG_PATH = '/tmp/logs/mobly/'
29 
30 
31 class MoblyConfigError(Exception):
32     """Raised when there is a problem in test configuration file."""
33 
34 
35 def _validate_test_config(test_config):
36     """Validates the raw configuration loaded from the config file.
37 
38     Making sure the required key 'TestBeds' is present.
39     """
40     required_key = keys.Config.key_testbed.value
41     if required_key not in test_config:
42         raise MoblyConfigError(
43             'Required key %s missing in test config.' % required_key)
44 
45 
46 def _validate_testbed_name(name):
47     """Validates the name of a test bed.
48 
49     Since test bed names are used as part of the test run id, it needs to meet
50     certain requirements.
51 
52     Args:
53         name: The test bed's name specified in config file.
54 
55     Raises:
56         MoblyConfigError: The name does not meet any criteria.
57     """
58     if not name:
59         raise MoblyConfigError("Test bed names can't be empty.")
60     name = str(name)
61     for char in name:
62         if char not in utils.valid_filename_chars:
63             raise MoblyConfigError(
64                 'Char "%s" is not allowed in test bed names.' % char)
65 
66 
67 def _validate_testbed_configs(testbed_configs):
68     """Validates the testbed configurations.
69 
70     Args:
71         testbed_configs: A list of testbed configuration dicts.
72 
73     Raises:
74         MoblyConfigError: Some parts of the configuration is invalid.
75     """
76     seen_names = set()
77     # Cross checks testbed configs for resource conflicts.
78     for config in testbed_configs:
79         # Check for conflicts between multiple concurrent testbed configs.
80         # No need to call it if there's only one testbed config.
81         name = config[keys.Config.key_testbed_name.value]
82         _validate_testbed_name(name)
83         # Test bed names should be unique.
84         if name in seen_names:
85             raise MoblyConfigError('Duplicate testbed name %s found.' % name)
86         seen_names.add(name)
87 
88 
89 def load_test_config_file(test_config_path, tb_filters=None):
90     """Processes the test configuration file provied by user.
91 
92     Loads the configuration file into a dict, unpacks each testbed
93     config into its own dict, and validate the configuration in the
94     process.
95 
96     Args:
97         test_config_path: Path to the test configuration file.
98         tb_filters: A subset of test bed names to be pulled from the config
99             file. If None, then all test beds will be selected.
100 
101     Returns:
102         A list of test configuration dicts to be passed to
103         test_runner.TestRunner.
104     """
105     configs = _load_config_file(test_config_path)
106     if tb_filters:
107         tbs = []
108         for tb in configs[keys.Config.key_testbed.value]:
109             if tb[keys.Config.key_testbed_name.value] in tb_filters:
110                 tbs.append(tb)
111         if len(tbs) != len(tb_filters):
112             raise MoblyConfigError(
113                 'Expect to find %d test bed configs, found %d. Check if'
114                 ' you have the correct test bed names.' % (len(tb_filters),
115                                                            len(tbs)))
116         configs[keys.Config.key_testbed.value] = tbs
117     mobly_params = configs.get(keys.Config.key_mobly_params.value, {})
118     # Decide log path.
119     log_path = mobly_params.get(keys.Config.key_log_path.value,
120                                 _DEFAULT_LOG_PATH)
121     if ENV_MOBLY_LOGPATH in os.environ:
122         log_path = os.environ[ENV_MOBLY_LOGPATH]
123     log_path = utils.abs_path(log_path)
124     # Validate configs
125     _validate_test_config(configs)
126     _validate_testbed_configs(configs[keys.Config.key_testbed.value])
127     # Transform config dict from user-facing key mapping to internal config object.
128     test_configs = []
129     for original_bed_config in configs[keys.Config.key_testbed.value]:
130         test_run_config = TestRunConfig()
131         test_run_config.test_bed_name = original_bed_config[
132             keys.Config.key_testbed_name.value]
133         test_run_config.log_path = log_path
134         test_run_config.controller_configs = original_bed_config.get(
135             keys.Config.key_testbed_controllers.value, {})
136         test_run_config.user_params = original_bed_config.get(
137             keys.Config.key_testbed_test_params.value, {})
138         test_configs.append(test_run_config)
139     return test_configs
140 
141 
142 def _load_config_file(path):
143     """Loads a test config file.
144 
145     The test config file has to be in YAML format.
146 
147     Args:
148         path: A string that is the full path to the config file, including the
149             file name.
150 
151     Returns:
152         A dict that represents info in the config file.
153     """
154     with io.open(utils.abs_path(path), 'r', encoding='utf-8') as f:
155         conf = yaml.load(f)
156         return conf
157 
158 
159 class TestRunConfig(object):
160     """The data class that holds all the information needed for a test run.
161 
162     Attributes:
163         log_path: string, specifies the root directory for all logs written by
164             a test run.
165         test_bed_name: string, the name of the test bed used by a test run.
166         controller_configs: dict, configs used for instantiating controller
167             objects.
168         user_params: dict, all the parameters to be consumed by the test logic.
169         summary_writer: records.TestSummaryWriter, used to write elements to
170             the test result summary file.
171         test_class_name_suffix: string, suffix to append to the class name for
172                 reporting. This is used for differentiating the same class
173                 executed with different parameters in a suite.
174     """
175 
176     def __init__(self):
177         self.log_path = None
178         self.test_bed_name = None
179         self.controller_configs = None
180         self.user_params = None
181         self.summary_writer = None
182         self.test_class_name_suffix = None
183 
184     def copy(self):
185         """Returns a deep copy of the current config.
186         """
187         return copy.deepcopy(self)
188 
189     def __str__(self):
190         content = dict(self.__dict__)
191         content.pop('summary_writer')
192         return pprint.pformat(content)
193
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/mobly/config_parser.py b/mobly/config_parser.py
--- a/mobly/config_parser.py
+++ b/mobly/config_parser.py
@@ -152,7 +152,7 @@
         A dict that represents info in the config file.
     """
     with io.open(utils.abs_path(path), 'r', encoding='utf-8') as f:
-        conf = yaml.load(f)
+        conf = yaml.safe_load(f)
         return conf

{"golden_diff": "diff --git a/mobly/config_parser.py b/mobly/config_parser.py\n--- a/mobly/config_parser.py\n+++ b/mobly/config_parser.py\n@@ -152,7 +152,7 @@\n         A dict that represents info in the config file.\n     \"\"\"\n     with io.open(utils.abs_path(path), 'r', encoding='utf-8') as f:\n-        conf = yaml.load(f)\n+        conf = yaml.safe_load(f)\n         return conf\n", "issue": "yaml.load_all is unsafe with default loader\ntests/mobly/output_test.py::OutputTest::test_teardown_class_output\r\n  T:\\src\\github\\mobly\\tests\\mobly\\output_test.py:258: YAMLLoadWarning: \r\n    *** Calling yaml.load_all() without Loader=... is deprecated.\r\n    *** The default Loader is unsafe.\r\n    *** Please read https://msg.pyyaml.org/load for full details.\r\n    for entry in yaml.load_all(f):\r\n\r\ntests/mobly/records_test.py::RecordsTest::test_summary_user_data\r\n  T:\\src\\github\\mobly\\tests\\mobly\\records_test.py:401: YAMLLoadWarning: \r\n    *** Calling yaml.load_all() without Loader=... is deprecated.\r\n    *** The default Loader is unsafe.\r\n    *** Please read https://msg.pyyaml.org/load for full details.\r\n    for c in yaml.load_all(f):\r\n\r\ntests/mobly/records_test.py::RecordsTest::test_summary_write_dump\r\n  T:\\src\\github\\mobly\\tests\\mobly\\records_test.py:364: YAMLLoadWarning: \r\n    *** Calling yaml.load() without Loader=... is deprecated.\r\n    *** The default Loader is unsafe.\r\n    *** Please read https://msg.pyyaml.org/load for full details.\r\n    content = yaml.load(f)\r\n\r\ntests/mobly/records_test.py::RecordsTest::test_summary_write_dump_with_unicode\r\n  T:\\src\\github\\mobly\\tests\\mobly\\records_test.py:383: YAMLLoadWarning: \r\n    *** Calling yaml.load() without Loader=... is deprecated.\r\n    *** The default Loader is unsafe.\r\n    *** Please read https://msg.pyyaml.org/load for full details.\r\n    content = yaml.load(f)\r\n\r\ntests/mobly/test_runner_test.py::TestRunnerTest::test_summary_file_entries\r\n  T:\\src\\github\\mobly\\tests\\mobly\\test_runner_test.py:135: YAMLLoadWarning: \r\n    *** Calling yaml.load_all() without Loader=... is deprecated.\r\n    *** The default Loader is unsafe.\r\n    *** Please read https://msg.pyyaml.org/load for full details.\r\n    summary_entries = list(yaml.load_all(f))\r\n\n", "before_files": [{"content": "# Copyright 2016 Google Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom builtins import str\n\nimport copy\nimport io\nimport pprint\nimport os\nimport yaml\n\nfrom mobly import keys\nfrom mobly import utils\n\n# An environment variable defining the base location for Mobly logs.\nENV_MOBLY_LOGPATH = 'MOBLY_LOGPATH'\n_DEFAULT_LOG_PATH = '/tmp/logs/mobly/'\n\n\nclass MoblyConfigError(Exception):\n    \"\"\"Raised when there is a problem in test configuration file.\"\"\"\n\n\ndef _validate_test_config(test_config):\n    \"\"\"Validates the raw configuration loaded from the config file.\n\n    Making sure the required key 'TestBeds' is present.\n    \"\"\"\n    required_key = keys.Config.key_testbed.value\n    if required_key not in test_config:\n        raise MoblyConfigError(\n            'Required key %s missing in test config.' % required_key)\n\n\ndef _validate_testbed_name(name):\n    \"\"\"Validates the name of a test bed.\n\n    Since test bed names are used as part of the test run id, it needs to meet\n    certain requirements.\n\n    Args:\n        name: The test bed's name specified in config file.\n\n    Raises:\n        MoblyConfigError: The name does not meet any criteria.\n    \"\"\"\n    if not name:\n        raise MoblyConfigError(\"Test bed names can't be empty.\")\n    name = str(name)\n    for char in name:\n        if char not in utils.valid_filename_chars:\n            raise MoblyConfigError(\n                'Char \"%s\" is not allowed in test bed names.' % char)\n\n\ndef _validate_testbed_configs(testbed_configs):\n    \"\"\"Validates the testbed configurations.\n\n    Args:\n        testbed_configs: A list of testbed configuration dicts.\n\n    Raises:\n        MoblyConfigError: Some parts of the configuration is invalid.\n    \"\"\"\n    seen_names = set()\n    # Cross checks testbed configs for resource conflicts.\n    for config in testbed_configs:\n        # Check for conflicts between multiple concurrent testbed configs.\n        # No need to call it if there's only one testbed config.\n        name = config[keys.Config.key_testbed_name.value]\n        _validate_testbed_name(name)\n        # Test bed names should be unique.\n        if name in seen_names:\n            raise MoblyConfigError('Duplicate testbed name %s found.' % name)\n        seen_names.add(name)\n\n\ndef load_test_config_file(test_config_path, tb_filters=None):\n    \"\"\"Processes the test configuration file provied by user.\n\n    Loads the configuration file into a dict, unpacks each testbed\n    config into its own dict, and validate the configuration in the\n    process.\n\n    Args:\n        test_config_path: Path to the test configuration file.\n        tb_filters: A subset of test bed names to be pulled from the config\n            file. If None, then all test beds will be selected.\n\n    Returns:\n        A list of test configuration dicts to be passed to\n        test_runner.TestRunner.\n    \"\"\"\n    configs = _load_config_file(test_config_path)\n    if tb_filters:\n        tbs = []\n        for tb in configs[keys.Config.key_testbed.value]:\n            if tb[keys.Config.key_testbed_name.value] in tb_filters:\n                tbs.append(tb)\n        if len(tbs) != len(tb_filters):\n            raise MoblyConfigError(\n                'Expect to find %d test bed configs, found %d. Check if'\n                ' you have the correct test bed names.' % (len(tb_filters),\n                                                           len(tbs)))\n        configs[keys.Config.key_testbed.value] = tbs\n    mobly_params = configs.get(keys.Config.key_mobly_params.value, {})\n    # Decide log path.\n    log_path = mobly_params.get(keys.Config.key_log_path.value,\n                                _DEFAULT_LOG_PATH)\n    if ENV_MOBLY_LOGPATH in os.environ:\n        log_path = os.environ[ENV_MOBLY_LOGPATH]\n    log_path = utils.abs_path(log_path)\n    # Validate configs\n    _validate_test_config(configs)\n    _validate_testbed_configs(configs[keys.Config.key_testbed.value])\n    # Transform config dict from user-facing key mapping to internal config object.\n    test_configs = []\n    for original_bed_config in configs[keys.Config.key_testbed.value]:\n        test_run_config = TestRunConfig()\n        test_run_config.test_bed_name = original_bed_config[\n            keys.Config.key_testbed_name.value]\n        test_run_config.log_path = log_path\n        test_run_config.controller_configs = original_bed_config.get(\n            keys.Config.key_testbed_controllers.value, {})\n        test_run_config.user_params = original_bed_config.get(\n            keys.Config.key_testbed_test_params.value, {})\n        test_configs.append(test_run_config)\n    return test_configs\n\n\ndef _load_config_file(path):\n    \"\"\"Loads a test config file.\n\n    The test config file has to be in YAML format.\n\n    Args:\n        path: A string that is the full path to the config file, including the\n            file name.\n\n    Returns:\n        A dict that represents info in the config file.\n    \"\"\"\n    with io.open(utils.abs_path(path), 'r', encoding='utf-8') as f:\n        conf = yaml.load(f)\n        return conf\n\n\nclass TestRunConfig(object):\n    \"\"\"The data class that holds all the information needed for a test run.\n\n    Attributes:\n        log_path: string, specifies the root directory for all logs written by\n            a test run.\n        test_bed_name: string, the name of the test bed used by a test run.\n        controller_configs: dict, configs used for instantiating controller\n            objects.\n        user_params: dict, all the parameters to be consumed by the test logic.\n        summary_writer: records.TestSummaryWriter, used to write elements to\n            the test result summary file.\n        test_class_name_suffix: string, suffix to append to the class name for\n                reporting. This is used for differentiating the same class\n                executed with different parameters in a suite.\n    \"\"\"\n\n    def __init__(self):\n        self.log_path = None\n        self.test_bed_name = None\n        self.controller_configs = None\n        self.user_params = None\n        self.summary_writer = None\n        self.test_class_name_suffix = None\n\n    def copy(self):\n        \"\"\"Returns a deep copy of the current config.\n        \"\"\"\n        return copy.deepcopy(self)\n\n    def __str__(self):\n        content = dict(self.__dict__)\n        content.pop('summary_writer')\n        return pprint.pformat(content)\n", "path": "mobly/config_parser.py"}], "after_files": [{"content": "# Copyright 2016 Google Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom builtins import str\n\nimport copy\nimport io\nimport pprint\nimport os\nimport yaml\n\nfrom mobly import keys\nfrom mobly import utils\n\n# An environment variable defining the base location for Mobly logs.\nENV_MOBLY_LOGPATH = 'MOBLY_LOGPATH'\n_DEFAULT_LOG_PATH = '/tmp/logs/mobly/'\n\n\nclass MoblyConfigError(Exception):\n    \"\"\"Raised when there is a problem in test configuration file.\"\"\"\n\n\ndef _validate_test_config(test_config):\n    \"\"\"Validates the raw configuration loaded from the config file.\n\n    Making sure the required key 'TestBeds' is present.\n    \"\"\"\n    required_key = keys.Config.key_testbed.value\n    if required_key not in test_config:\n        raise MoblyConfigError(\n            'Required key %s missing in test config.' % required_key)\n\n\ndef _validate_testbed_name(name):\n    \"\"\"Validates the name of a test bed.\n\n    Since test bed names are used as part of the test run id, it needs to meet\n    certain requirements.\n\n    Args:\n        name: The test bed's name specified in config file.\n\n    Raises:\n        MoblyConfigError: The name does not meet any criteria.\n    \"\"\"\n    if not name:\n        raise MoblyConfigError(\"Test bed names can't be empty.\")\n    name = str(name)\n    for char in name:\n        if char not in utils.valid_filename_chars:\n            raise MoblyConfigError(\n                'Char \"%s\" is not allowed in test bed names.' % char)\n\n\ndef _validate_testbed_configs(testbed_configs):\n    \"\"\"Validates the testbed configurations.\n\n    Args:\n        testbed_configs: A list of testbed configuration dicts.\n\n    Raises:\n        MoblyConfigError: Some parts of the configuration is invalid.\n    \"\"\"\n    seen_names = set()\n    # Cross checks testbed configs for resource conflicts.\n    for config in testbed_configs:\n        # Check for conflicts between multiple concurrent testbed configs.\n        # No need to call it if there's only one testbed config.\n        name = config[keys.Config.key_testbed_name.value]\n        _validate_testbed_name(name)\n        # Test bed names should be unique.\n        if name in seen_names:\n            raise MoblyConfigError('Duplicate testbed name %s found.' % name)\n        seen_names.add(name)\n\n\ndef load_test_config_file(test_config_path, tb_filters=None):\n    \"\"\"Processes the test configuration file provied by user.\n\n    Loads the configuration file into a dict, unpacks each testbed\n    config into its own dict, and validate the configuration in the\n    process.\n\n    Args:\n        test_config_path: Path to the test configuration file.\n        tb_filters: A subset of test bed names to be pulled from the config\n            file. If None, then all test beds will be selected.\n\n    Returns:\n        A list of test configuration dicts to be passed to\n        test_runner.TestRunner.\n    \"\"\"\n    configs = _load_config_file(test_config_path)\n    if tb_filters:\n        tbs = []\n        for tb in configs[keys.Config.key_testbed.value]:\n            if tb[keys.Config.key_testbed_name.value] in tb_filters:\n                tbs.append(tb)\n        if len(tbs) != len(tb_filters):\n            raise MoblyConfigError(\n                'Expect to find %d test bed configs, found %d. Check if'\n                ' you have the correct test bed names.' % (len(tb_filters),\n                                                           len(tbs)))\n        configs[keys.Config.key_testbed.value] = tbs\n    mobly_params = configs.get(keys.Config.key_mobly_params.value, {})\n    # Decide log path.\n    log_path = mobly_params.get(keys.Config.key_log_path.value,\n                                _DEFAULT_LOG_PATH)\n    if ENV_MOBLY_LOGPATH in os.environ:\n        log_path = os.environ[ENV_MOBLY_LOGPATH]\n    log_path = utils.abs_path(log_path)\n    # Validate configs\n    _validate_test_config(configs)\n    _validate_testbed_configs(configs[keys.Config.key_testbed.value])\n    # Transform config dict from user-facing key mapping to internal config object.\n    test_configs = []\n    for original_bed_config in configs[keys.Config.key_testbed.value]:\n        test_run_config = TestRunConfig()\n        test_run_config.test_bed_name = original_bed_config[\n            keys.Config.key_testbed_name.value]\n        test_run_config.log_path = log_path\n        test_run_config.controller_configs = original_bed_config.get(\n            keys.Config.key_testbed_controllers.value, {})\n        test_run_config.user_params = original_bed_config.get(\n            keys.Config.key_testbed_test_params.value, {})\n        test_configs.append(test_run_config)\n    return test_configs\n\n\ndef _load_config_file(path):\n    \"\"\"Loads a test config file.\n\n    The test config file has to be in YAML format.\n\n    Args:\n        path: A string that is the full path to the config file, including the\n            file name.\n\n    Returns:\n        A dict that represents info in the config file.\n    \"\"\"\n    with io.open(utils.abs_path(path), 'r', encoding='utf-8') as f:\n        conf = yaml.safe_load(f)\n        return conf\n\n\nclass TestRunConfig(object):\n    \"\"\"The data class that holds all the information needed for a test run.\n\n    Attributes:\n        log_path: string, specifies the root directory for all logs written by\n            a test run.\n        test_bed_name: string, the name of the test bed used by a test run.\n        controller_configs: dict, configs used for instantiating controller\n            objects.\n        user_params: dict, all the parameters to be consumed by the test logic.\n        summary_writer: records.TestSummaryWriter, used to write elements to\n            the test result summary file.\n        test_class_name_suffix: string, suffix to append to the class name for\n                reporting. This is used for differentiating the same class\n                executed with different parameters in a suite.\n    \"\"\"\n\n    def __init__(self):\n        self.log_path = None\n        self.test_bed_name = None\n        self.controller_configs = None\n        self.user_params = None\n        self.summary_writer = None\n        self.test_class_name_suffix = None\n\n    def copy(self):\n        \"\"\"Returns a deep copy of the current config.\n        \"\"\"\n        return copy.deepcopy(self)\n\n    def __str__(self):\n        content = dict(self.__dict__)\n        content.pop('summary_writer')\n        return pprint.pformat(content)\n", "path": "mobly/config_parser.py"}]}