From 3c7c8bb039219b7f61ae57e33e7d71abb8080722 Mon Sep 17 00:00:00 2001 From: Jeffrey Thiessen Date: Wed, 8 Jun 2022 12:36:40 -0500 Subject: [PATCH] improve boolean evaluation from config files and added/improved test cases --- CHANGELOG.md | 5 ++ iridauploader/config/config.py | 23 +++++++- iridauploader/tests/config/test_config.conf | 1 + iridauploader/tests/config/test_config.py | 57 ++++++++++++++++++- .../tests/config/test_config_case_error.conf | 8 +++ .../tests/config/test_config_case_false.conf | 8 +++ .../tests/config/test_config_case_true.conf | 8 +++ 7 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 iridauploader/tests/config/test_config_case_error.conf create mode 100644 iridauploader/tests/config/test_config_case_false.conf create mode 100644 iridauploader/tests/config/test_config_case_true.conf diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f99dd0d..8b8a0ce6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ Changes ======= +Beta 0.8.2 +--------- +Bug Fixes: +* config file now evaluates any capitalization of True/False and displays errors to the user if unable to parse. + Beta 0.8.1 --------- Bug Fixes: diff --git a/iridauploader/config/config.py b/iridauploader/config/config.py index ab81c6f5..4b3a4d24 100644 --- a/iridauploader/config/config.py +++ b/iridauploader/config/config.py @@ -254,7 +254,7 @@ def read_config_option(key, expected_type=None, default_value=None): if type(res) is bool: return res elif type(res) is str: - return eval(res) + return _eval_boolean(res, key) else: raise NameError except (ValueError, NameError, NoOptionError): @@ -264,6 +264,27 @@ def read_config_option(key, expected_type=None, default_value=None): raise +def _eval_boolean(string, field): + """ + Converts string to bool value, accepts any case permutation. + If non true/false is given, displays error to user and raises to exit + :param string: string to evaluate as a boolean + :param field: config field the key originated from for logging and error message + :return: Boolean + """ + caps = string.upper() + if caps == "TRUE": + logging.debug("Evaluated as True") + return True + elif caps == "FALSE": + logging.debug("Evaluated as False") + return False + else: + error_msg = "Config file field '{}' expected 'True' or 'False' but instead got '{}'".format(field, string) + logging.error(error_msg) + raise NameError(error_msg) + + def _update_config_option(field_name, field_value): """ Sets an option in the config parser (Does not write to file) diff --git a/iridauploader/tests/config/test_config.conf b/iridauploader/tests/config/test_config.conf index f46d6374..29da92e1 100644 --- a/iridauploader/tests/config/test_config.conf +++ b/iridauploader/tests/config/test_config.conf @@ -5,3 +5,4 @@ username = admin password = password1 base_url = http://localhost:8080/irida-latest/api/ parser = miseq +readonly = False diff --git a/iridauploader/tests/config/test_config.py b/iridauploader/tests/config/test_config.py index ef2e744c..3ce83b25 100644 --- a/iridauploader/tests/config/test_config.py +++ b/iridauploader/tests/config/test_config.py @@ -104,7 +104,7 @@ def test_dont_create_new_file_if_override_file_exists(self, mock_path_exists, mo def test_read_config_option(self): """ - Test writing to config file, make sure writen values are written correctly + Test reading from well-defined config file :return: """ # set up config @@ -119,6 +119,61 @@ def test_read_config_option(self): self.assertEqual(config.read_config_option('parser'), 'miseq') self.assertEqual(config.read_config_option('readonly', bool), False) + def test_read_config_option_case_false(self): + """ + Test reading from well-defined config file with all lowercase boolean (false) + :return: + """ + # set up config + config.set_config_file(os.path.join(path_to_module, "test_config_case_false.conf")) + config.setup() + # Test that all the parameters loaded from file are correct + self.assertEqual(config.read_config_option('client_id'), 'uploader') + self.assertEqual(config.read_config_option('client_secret'), 'secret') + self.assertEqual(config.read_config_option('username'), 'admin') + self.assertEqual(config.read_config_option('password'), 'password1') + self.assertEqual(config.read_config_option('base_url'), 'http://localhost:8080/irida-latest/api/') + self.assertEqual(config.read_config_option('parser'), 'miseq') + self.assertEqual(config.read_config_option('readonly', bool), False) + + def test_read_config_option_case_true(self): + """ + Test reading from well-defined config file with strange casing boolean (tRuE) + :return: + """ + # set up config + config.set_config_file(os.path.join(path_to_module, "test_config_case_true.conf")) + config.setup() + # Test that all the parameters loaded from file are correct + self.assertEqual(config.read_config_option('client_id'), 'uploader') + self.assertEqual(config.read_config_option('client_secret'), 'secret') + self.assertEqual(config.read_config_option('username'), 'admin') + self.assertEqual(config.read_config_option('password'), 'password1') + self.assertEqual(config.read_config_option('base_url'), 'http://localhost:8080/irida-latest/api/') + self.assertEqual(config.read_config_option('parser'), 'miseq') + self.assertEqual(config.read_config_option('readonly', bool), True) + + def test_read_config_option_case_error(self): + """ + Test reading from ill-defined config file with a non-boolean entry + :return: + """ + # set up config + config.set_config_file(os.path.join(path_to_module, "test_config_case_error.conf")) + config.setup() + # Test that all the parameters loaded from file are correct + self.assertEqual(config.read_config_option('client_id'), 'uploader') + self.assertEqual(config.read_config_option('client_secret'), 'secret') + self.assertEqual(config.read_config_option('username'), 'admin') + self.assertEqual(config.read_config_option('password'), 'password1') + self.assertEqual(config.read_config_option('base_url'), 'http://localhost:8080/irida-latest/api/') + self.assertEqual(config.read_config_option('parser'), 'miseq') + with self.assertRaises(NameError) as context: + self.assertEqual(config.read_config_option('readonly', bool), False) + self.assertTrue( + "Config file field 'readonly' expected 'True' or 'False' but instead got 'this_is_not_a_bool'" in + str(context.exception)) + def test_set_config_options(self): """ Test writing to config file, make sure writen values are written correctly diff --git a/iridauploader/tests/config/test_config_case_error.conf b/iridauploader/tests/config/test_config_case_error.conf new file mode 100644 index 00000000..201e061f --- /dev/null +++ b/iridauploader/tests/config/test_config_case_error.conf @@ -0,0 +1,8 @@ +[Settings] +client_id = uploader +client_secret = secret +username = admin +password = password1 +base_url = http://localhost:8080/irida-latest/api/ +parser = miseq +readonly = this_is_not_a_bool diff --git a/iridauploader/tests/config/test_config_case_false.conf b/iridauploader/tests/config/test_config_case_false.conf new file mode 100644 index 00000000..efaf80b6 --- /dev/null +++ b/iridauploader/tests/config/test_config_case_false.conf @@ -0,0 +1,8 @@ +[Settings] +client_id = uploader +client_secret = secret +username = admin +password = password1 +base_url = http://localhost:8080/irida-latest/api/ +parser = miseq +readonly = false diff --git a/iridauploader/tests/config/test_config_case_true.conf b/iridauploader/tests/config/test_config_case_true.conf new file mode 100644 index 00000000..9d28ea4c --- /dev/null +++ b/iridauploader/tests/config/test_config_case_true.conf @@ -0,0 +1,8 @@ +[Settings] +client_id = uploader +client_secret = secret +username = admin +password = password1 +base_url = http://localhost:8080/irida-latest/api/ +parser = miseq +readonly = tRuE