Repository: locustio/locust

Issue:
Add --config parameter
<!-- 
If you have a general question about how to use Locust, please check Stack Overflow first https://stackoverflow.com/questions/tagged/locust

You can also ask new questions on SO, https://stackoverflow.com/questions/ask just remember to tag your question with "locust".
-->

### Is your feature request related to a problem? Please describe.
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
I would like to be able to have multiple config files stored in version control for different purposes (eg one that uses step-mode and one that doesn't).

### Describe the solution you'd like
<!-- A clear and concise description of what you want to happen -->
`ConfigArgParse` makes it easy to add this capability. I think it could be done with a single line in `parse_options`:
`parser.add_argument('--config', is_config_file_arg=True, help='config file path')`

### Describe alternatives you've considered
<!-- A clear and concise description of any alternative solutions or features you've considered -->
Current workaround is to keep multiple sets of configurations in `locust.conf`, with the active one uncommented.



Discussion:
Sounds good to me! Please make a PR!

Resolving patch:
diff --git a/locust/argument_parser.py b/locust/argument_parser.py
--- a/locust/argument_parser.py
+++ b/locust/argument_parser.py
@@ -76,6 +76,8 @@ def get_empty_argument_parser(add_help=True, default_config_files=DEFAULT_CONFIG
         help="Python module file to import, e.g. '../other.py'. Default: locustfile",
         env_var="LOCUST_LOCUSTFILE",
     )
+    parser.add_argument('--config', is_config_file_arg=True, help='Config file path')
+
     return parser
 
 


Test patch:
diff --git a/locust/test/test_main.py b/locust/test/test_main.py
--- a/locust/test/test_main.py
+++ b/locust/test/test_main.py
@@ -77,6 +77,40 @@ def test_create_environment(self):
         self.assertEqual(None, env.host)
         self.assertFalse(env.reset_stats)
 
+    def test_specify_config_file(self):
+        with temporary_file(textwrap.dedent("""
+            host = localhost  # With "="
+            u 100             # Short form
+            hatch-rate 5      # long form
+            headless          # boolean
+        """), suffix=".conf") as conf_file_path:
+            options = parse_options(args=[
+                "--config", conf_file_path,
+            ])
+            self.assertEqual(conf_file_path, options.config)
+            self.assertEqual("localhost", options.host)
+            self.assertEqual(100, options.num_users)
+            self.assertEqual(5, options.hatch_rate)
+            self.assertTrue(options.headless)
+
+    def test_command_line_arguments_override_config_file(self):
+        with temporary_file("host=from_file", suffix=".conf") as conf_file_path:
+            options = parse_options(args=[
+                "--config", conf_file_path,
+                "--host", "from_args",
+            ])
+            self.assertEqual("from_args", options.host)
+
+    def test_locustfile_can_be_set_in_config_file(self):
+        with temporary_file(
+            "locustfile my_locust_file.py",
+            suffix=".conf",
+        ) as conf_file_path:
+            options = parse_options(args=[
+                "--config", conf_file_path,
+            ])
+            self.assertEqual("my_locust_file.py", options.locustfile)
+
 
 class LocustProcessIntegrationTest(TestCase):
     def setUp(self):