aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilo Casagrande <milo.casagrande@linaro.org>2015-03-10 18:25:03 +0100
committerMilo Casagrande <milo.casagrande@linaro.org>2015-03-10 18:25:03 +0100
commit39268db9cbeba8e62b216aaaeca298298601fedf (patch)
treecce61cc04309fb226bb5551895cb4338f2db4d06
parentfabd850da1f2f8100d8533d5d96c2c39555937ac (diff)
downloadkernel-ci-backend-test-schema.tar.gz
First draft of test cases/sets parsing/import.test-schema
-rw-r--r--app/tests/__init__.py1
-rw-r--r--app/utils/tests/test_tests_import.py195
-rw-r--r--app/utils/tests_import.py141
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