diff options
author | Milo Casagrande <milo.casagrande@linaro.org> | 2015-03-10 18:25:03 +0100 |
---|---|---|
committer | Milo Casagrande <milo.casagrande@linaro.org> | 2015-03-10 18:25:03 +0100 |
commit | 39268db9cbeba8e62b216aaaeca298298601fedf (patch) | |
tree | cce61cc04309fb226bb5551895cb4338f2db4d06 | |
parent | fabd850da1f2f8100d8533d5d96c2c39555937ac (diff) |
First draft of test cases/sets parsing/import.test-schema
-rw-r--r-- | app/tests/__init__.py | 1 | ||||
-rw-r--r-- | app/utils/tests/test_tests_import.py | 195 | ||||
-rw-r--r-- | app/utils/tests_import.py | 141 |
3 files changed, 337 insertions, 0 deletions
diff --git a/app/tests/__init__.py b/app/tests/__init__.py index 90ca52b..fc187aa 100644 --- a/app/tests/__init__.py +++ b/app/tests/__init__.py @@ -53,6 +53,7 @@ def test_modules(): "utils.tests.test_base", "utils.tests.test_bootimport", "utils.tests.test_docimport", + "utils.tests.test_tests_import", "utils.tests.test_validator" ] diff --git a/app/utils/tests/test_tests_import.py b/app/utils/tests/test_tests_import.py new file mode 100644 index 0000000..87329dc --- /dev/null +++ b/app/utils/tests/test_tests_import.py @@ -0,0 +1,195 @@ +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import logging +import mongomock +import unittest +import mock + +import utils.tests_import as tests_import + + +class TestTestsImport(unittest.TestCase): + + def setUp(self): + logging.disable(logging.CRITICAL) + self.db = mongomock.Database(mongomock.Connection(), 'kernel-ci') + + def tearDown(self): + logging.disable(logging.NOTSET) + + @mock.patch("utils.db.get_db_connection") + def test_import_multi_test_cases_empty(self, mock_db): + mock_db.return_value = self.db + + case_list = [] + test_suite_id = "test-suite-id" + kwargs = { + "test_set_id": "test-set-id" + } + + results = tests_import.import_multi_test_case( + case_list, test_suite_id, {}, **kwargs) + + self.assertDictEqual({}, results) + + @mock.patch("utils.db.save") + @mock.patch("utils.db.get_db_connection") + def test_import_multi_test_cases_simple(self, mock_db, mock_save): + mock_db.return_value = self.db + mock_save.return_value = (201, "id") + + case_list = [ + {"name": "test-case", "version": "1.0"} + ] + test_suite_id = "test-suite-id" + kwargs = { + "test_set_id": "test-set-id" + } + + results = tests_import.import_multi_test_case( + case_list, test_suite_id, {}, **kwargs) + + self.assertDictEqual({}, results) + + @mock.patch("utils.db.save") + @mock.patch("utils.db.get_db_connection") + def test_import_multi_test_cases_complex(self, mock_db, mock_save): + mock_db.return_value = self.db + mock_save.return_value = (201, "id") + + case_list = [ + {"name": "test-case0", "version": "1.0", "parameters": {"a": 1}}, + {"name": "test-case1", "version": "1.0", "parameters": {"a": 2}}, + {"name": "test-case2", "version": "1.0", "parameters": {"a": 3}} + ] + test_suite_id = "test-suite-id" + kwargs = { + "test_set_id": "test-set-id" + } + + results = tests_import.import_multi_test_case( + case_list, test_suite_id, {}, **kwargs) + + self.assertDictEqual({}, results) + + @mock.patch("utils.db.save") + @mock.patch("utils.db.get_db_connection") + def test_import_multi_test_cases_with_save_error(self, mock_db, mock_save): + mock_db.return_value = self.db + mock_save.return_value = (500, None) + + case_list = [ + {"name": "test-case0", "version": "1.0", "parameters": {"a": 1}} + ] + test_suite_id = "test-suite-id" + kwargs = { + "test_set_id": "test-set-id" + } + + results = tests_import.import_multi_test_case( + case_list, test_suite_id, {}, **kwargs) + + self.assertListEqual([500], results.keys()) + + @mock.patch("utils.db.save") + @mock.patch("utils.db.get_db_connection") + def test_import_multi_test_cases_with_multi_save_error( + self, mock_db, mock_save): + mock_db.return_value = self.db + mock_save.return_value = (500, None) + + case_list = [ + {"name": "test-case0", "version": "1.0", "parameters": {"a": 1}}, + {"name": "test-case1", "version": "1.0", "parameters": {"a": 2}} + ] + test_suite_id = "test-suite-id" + kwargs = { + "test_set_id": "test-set-id" + } + + results = tests_import.import_multi_test_case( + case_list, test_suite_id, {}, **kwargs) + + self.assertListEqual([500], results.keys()) + self.assertEqual(2, len(results[500])) + + @mock.patch("utils.db.save") + @mock.patch("utils.db.get_db_connection") + def test_import_multi_test_cases_with_multi_save_error_complex( + self, mock_db, mock_save): + mock_db.return_value = self.db + mock_save.side_effect = [ + (500, None), (201, "id"), (201, "id"), (500, None)] + + case_list = [ + {"name": "test-case0", "version": "1.0", "parameters": {"a": 1}}, + {"name": "test-case1", "version": "1.0", "parameters": {"a": 2}}, + {"name": "test-case2", "version": "1.0", "parameters": {"a": 3}}, + {"name": "test-case3", "version": "1.0", "parameters": {"a": 4}} + ] + test_suite_id = "test-suite-id" + kwargs = { + "test_set_id": "test-set-id" + } + + results = tests_import.import_multi_test_case( + case_list, test_suite_id, {}, **kwargs) + + self.assertListEqual([500], results.keys()) + self.assertEqual(2, len(results[500])) + + @mock.patch("utils.db.get_db_connection") + def test_import_multi_test_cases_with_non_dictionary(self, mock_db): + mock_db.return_value = self.db + + case_list = [["foo"]] + test_suite_id = "test-suite-id" + kwargs = { + "test_set_id": "test-set-id" + } + + results = tests_import.import_multi_test_case( + case_list, test_suite_id, {}, **kwargs) + + self.assertListEqual([400], results.keys()) + + @mock.patch("utils.db.get_db_connection") + def test_import_multi_test_cases_missing_mandatory_keys(self, mock_db): + mock_db.return_value = self.db + + case_list = [{"parameters": {"a": 1}}] + test_suite_id = "test-suite-id" + kwargs = { + "test_set_id": "test-set-id" + } + + results = tests_import.import_multi_test_case( + case_list, test_suite_id, {}, **kwargs) + + self.assertListEqual([400], results.keys()) + + @mock.patch("utils.db.get_db_connection") + def test_import_multi_test_cases_wrong_key(self, mock_db): + mock_db.return_value = self.db + + case_list = [{"name": "case", "version": "1.0", "parameters": ["a"]}] + test_suite_id = "test-suite-id" + kwargs = { + "test_set_id": "test-set-id" + } + + results = tests_import.import_multi_test_case( + case_list, test_suite_id, {}, **kwargs) + + self.assertListEqual([400], results.keys()) diff --git a/app/utils/tests_import.py b/app/utils/tests_import.py new file mode 100644 index 0000000..9ec3d9f --- /dev/null +++ b/app/utils/tests_import.py @@ -0,0 +1,141 @@ +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +"""All the necessary functions to import test sets and test cases.""" + +import types + +import models +import models.test_case as mtcase +import utils +import utils.db + + +def import_multi_test_set(set_list, test_suite_id, **kwargs): + pass + + +def import_test_set(set_list, test_suite_id, **kwargs): + pass + + +def import_multi_test_case(case_list, test_suite_id, db_options, **kwargs): + """Import all the test cases provided. + + Additional named arguments passed might be (with the exact following + names): + * test_set_id + * defconfig_id + * job_id + * job + * kernel + * defconfig + * defconfig_full + * lab_name + * board + * board_instance + + :param case_list: The list with the test cases to import. + :type case_list: list + :param test_suite_id: The ID of the test suite these test cases belong to. + :param test_suite_id: string + :return A dictionary with keys the error codes and value a list of error + messages, or an empty dictionary if no errors. + """ + utils.LOG.info("Importing test cases for test suite '%s'", test_suite_id) + + database = utils.db.get_db_connection(db_options) + err_results = {} + res_keys = err_results.viewkeys() + + def _add_err_msg(err_code, err_msg): + if err_code != 200: + if err_code in res_keys: + err_results[err_code].append(err_msg) + else: + err_results[err_code] = [] + err_results[err_code].append(err_msg) + + def _yield_test_cases_import(): + for test_case in case_list: + yield import_test_case( + test_case, test_suite_id, database, **kwargs) + + [ + _add_err_msg(ret_val, err_msg) + for ret_val, err_msg in _yield_test_cases_import() + ] + + return err_results + + +def import_test_case(json_case, test_suite_id, database, **kwargs): + """Parse and save a test case. + + Additional named arguments passed might be (with the exact following + names): + * test_set_id + * defconfig_id + * job_id + * job + * kernel + * defconfig + * defconfig_full + * lab_name + * board + * board_instance + + :param json_case: The JSON data structure of the test case to import. + :type json_case: dict + :param test_suite_id: The ID of the test suite these test cases belong to. + :type test_suite_id: string + :return 200 if OK, 500 in case of errors, and None or an error message. + """ + ret_val = 400 + error = None + + if isinstance(json_case, types.DictionaryType): + # Inject the test_suite_id value into the data structure. + json_case[models.TEST_SUITE_ID_KEY] = test_suite_id + + try: + test_name = json_case.get(models.NAME_KEY) + test_case = mtcase.TestCaseDocument.from_json(json_case) + + if test_case: + k_get = kwargs.get + + test_case.test_suite_id = test_suite_id + test_case.test_set_id = k_get(models.TEST_SET_ID_KEY, None) + + utils.LOG.info("Saving test case '%s'", test_name) + save_val, doc_id = utils.db.save( + database, test_case, manipulate=False) + + if save_val == 201: + ret_val = 200 + else: + ret_val = 500 + error = "Error saving test case '%s'" % test_name + utils.LOG.error(error) + else: + error = "Missing mandatory key in JSON object" + except ValueError, ex: + error = ( + "Error parsing test case '%s': %s" % (test_name, ex.message)) + utils.LOG.exception(ex) + utils.LOG.error(error) + else: + error = "Test case is not a JSON object" + + return ret_val, error |