aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilo Casagrande <milo.casagrande@linaro.org>2015-03-06 16:41:18 +0100
committerMilo Casagrande <milo.casagrande@linaro.org>2015-03-06 16:41:18 +0100
commit7e5d4a29da65b9bda84ec249db82a8053547ba02 (patch)
treec74c662af634de287922c58eb11af91f97cbf52f
parent02cca3c56a9e7d4d84f9be190efe499587ee843b (diff)
Complete test suite handler.
* More work is still necessary to implement the test sets and test cases import logic. * Add tests.
-rw-r--r--app/handlers/common.py14
-rw-r--r--app/handlers/test_suite.py139
-rw-r--r--app/handlers/tests/test_test_suite_handler.py300
3 files changed, 440 insertions, 13 deletions
diff --git a/app/handlers/common.py b/app/handlers/common.py
index 05f6834..c5972ed 100644
--- a/app/handlers/common.py
+++ b/app/handlers/common.py
@@ -363,6 +363,20 @@ TEST_SUITE_VALID_KEYS = {
models.VERSION_KEY
]
},
+ "PUT": [
+ models.ARCHITECTURE_KEY,
+ models.BOARD_INSTANCE_KEY,
+ models.BOARD_KEY,
+ models.BOOT_ID_KEY,
+ models.DEFCONFIG_FULL_KEY,
+ models.DEFCONFIG_ID_KEY,
+ models.DEFCONFIG_KEY,
+ models.JOB_ID_KEY,
+ models.JOB_KEY,
+ models.KERNEL_KEY,
+ models.METADATA_KEY,
+ models.NAME_KEY
+ ],
"GET": [
models.ARCHITECTURE_KEY,
models.BOARD_INSTANCE_KEY,
diff --git a/app/handlers/test_suite.py b/app/handlers/test_suite.py
index c7ce574..1813c96 100644
--- a/app/handlers/test_suite.py
+++ b/app/handlers/test_suite.py
@@ -13,6 +13,11 @@
"""The RequestHandler for /test/suite URLs."""
+try:
+ import simplejson as json
+except ImportError:
+ import json
+
import bson
import datetime
import types
@@ -23,9 +28,12 @@ import handlers.response as hresponse
import models
import models.test_suite as mtsuite
import utils.db
+import utils.validator as validator
+# pylint: disable=too-many-public-methods
class TestSuiteHandler(hbase.BaseHandler):
+ """The test suite request handler."""
def __init__(self, application, request, **kwargs):
super(TestSuiteHandler, self).__init__(application, request, **kwargs)
@@ -71,17 +79,144 @@ class TestSuiteHandler(hbase.BaseHandler):
response.messages = (
"Associated test sets will be parsed and imported")
# TODO: import async the test sets.
- pass
if all([test_case, isinstance(test_case, types.ListType)]):
response.status_code = 202
response.messages = (
"Associated test cases will be parsed and imported")
# TODO: import async the test cases.
- pass
else:
response.status_code = 500
response.reason = (
"Error saving test set '%s'" % test_suite.name)
return response
+
+ def execute_put(self, *args, **kwargs):
+ """Execute the PUT pre-operations."""
+ response = None
+
+ if self.validate_req_token("PUT"):
+ if kwargs and kwargs.get("id", None):
+ valid_request = self._valid_post_request()
+
+ if valid_request == 200:
+ try:
+ json_obj = json.loads(self.request.body.decode("utf8"))
+
+ valid_json, j_reason = validator.is_valid_json(
+ json_obj, self._valid_keys("PUT")
+ )
+ if valid_json:
+ kwargs["json_obj"] = json_obj
+ kwargs["db_options"] = self.settings["dboptions"]
+ kwargs["reason"] = j_reason
+ response = self._put(*args, **kwargs)
+ else:
+ response = hresponse.HandlerResponse(400)
+ if j_reason:
+ response.reason = (
+ "Provided JSON is not valid: %s" % j_reason
+ )
+ else:
+ response.reason = "Provided JSON is not valid"
+ response.result = None
+ except ValueError, ex:
+ self.log.exception(ex)
+ error = "No JSON data found in the PUT request"
+ self.log.error(error)
+ response = hresponse.HandlerResponse(422)
+ response.reason = error
+ response.result = None
+ else:
+ response = hresponse.HandlerResponse(valid_request)
+ response.reason = (
+ "%s: %s" %
+ (
+ self._get_status_message(valid_request),
+ "Use %s as the content type" % self.content_type
+ )
+ )
+ response.result = None
+ else:
+ response = hresponse.HandlerResponse(400)
+ response.reason = "No ID specified"
+ else:
+ response = hresponse.HandlerResponse(403)
+ response.reason = hcommon.NOT_VALID_TOKEN
+
+ return response
+
+ def _put(self, *args, **kwargs):
+ response = hresponse.HandlerResponse()
+ update_doc = kwargs.get("json_obj")
+ doc_id = kwargs.get("id")
+
+ try:
+ suite_id = bson.objectid.ObjectId(doc_id)
+ if utils.db.find_one2(self.collection, suite_id):
+ update_val = utils.db.update(
+ self.collection, suite_id, update_doc)
+
+ if update_val == 200:
+ response.reason = "Resource '%s' updated" % doc_id
+ else:
+ response.status_code = update_val
+ response.reason = "Error updating resource '%s'" % doc_id
+ else:
+ response.status_code = 404
+ response.reason = self._get_status_message(404)
+ except bson.errors.InvalidId, ex:
+ self.log.exception(ex)
+ self.log.error("Invalid ID specified: %s", doc_id)
+ response.status_code = 400
+ response.reason = "Wrong ID specified"
+ return response
+
+ def _delete(self, doc_id):
+ response = hresponse.HandlerResponse()
+ response.result = None
+
+ try:
+ suite_id = bson.objectid.ObjectId(doc_id)
+ if utils.db.find_one2(self.collection, suite_id):
+ response.status_code = utils.db.delete(
+ self.collection, suite_id)
+
+ if response.status_code == 200:
+ response.reason = "Resource '%s' deleted" % doc_id
+
+ test_set_canc = utils.db.delete(
+ self.db[models.TEST_SET_COLLECTION],
+ {models.TEST_SUITE_ID_KEY: {"$in": [suite_id]}}
+ )
+
+ test_case_canc = utils.db.delete(
+ self.db[models.TEST_CASE_COLLECTION],
+ {models.TEST_SUITE_ID_KEY: {"$in": [suite_id]}}
+ )
+
+ if test_case_canc != 200:
+ response.errors = (
+ "Error deleting test cases with "
+ "test_suite_id '%s'" %
+ doc_id
+ )
+ if test_set_canc != 200:
+ response.errors = (
+ "Error deleting test sets with "
+ "test_suite_id '%s'" %
+ doc_id
+ )
+ else:
+ response.reason = "Error deleting resource '%s'" % doc_id
+ else:
+ response.status_code = 404
+ response.reason = self._get_status_message(404)
+ except bson.errors.InvalidId, ex:
+ self.log.exception(ex)
+ self.log.error("Invalid ID specified: %s", doc_id)
+ response.status_code = 400
+ response.reason = "Wrong ID specified"
+
+ return response
diff --git a/app/handlers/tests/test_test_suite_handler.py b/app/handlers/tests/test_test_suite_handler.py
index b26da19..0117d55 100644
--- a/app/handlers/tests/test_test_suite_handler.py
+++ b/app/handlers/tests/test_test_suite_handler.py
@@ -138,8 +138,7 @@ class TestTestSuiteHandler(
headers = {"Authorization": "foo", "Content-Type": "application/json"}
response = self.fetch(
- "/test/suite", method="POST", body="", headers=headers
- )
+ "/test/suite", method="POST", body="", headers=headers)
self.assertEqual(response.code, 422)
self.assertEqual(
@@ -149,8 +148,7 @@ class TestTestSuiteHandler(
headers = {"Authorization": "foo"}
response = self.fetch(
- "/test/suite", method="POST", body="", headers=headers
- )
+ "/test/suite", method="POST", body="", headers=headers)
self.assertEqual(response.code, 415)
self.assertEqual(
@@ -162,8 +160,7 @@ class TestTestSuiteHandler(
body = json.dumps(dict(foo="foo", bar="bar"))
response = self.fetch(
- "/test/suite", method="POST", body=body, headers=headers
- )
+ "/test/suite", method="POST", body=body, headers=headers)
self.assertEqual(response.code, 400)
self.assertEqual(
@@ -172,10 +169,77 @@ class TestTestSuiteHandler(
@mock.patch("utils.db.save")
def test_post_correct(self, mock_save):
mock_save.return_value = (201, "test-suite-id")
- headers = {
- "Authorization": "foo",
- "Content-Type": "application/json",
- }
+ headers = {"Authorization": "foo", "Content-Type": "application/json"}
+
+ body = json.dumps(
+ dict(
+ name="test",
+ lab_name="lab_name", version="1.0", defconfig_id="defconfig")
+ )
+
+ response = self.fetch(
+ "/test/suite", method="POST", headers=headers, body=body
+ )
+
+ self.assertEqual(response.code, 201)
+ self.assertEqual(
+ response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)
+
+ def test_post_correct_with_id(self):
+ headers = {"Authorization": "foo", "Content-Type": "application/json"}
+ body = json.dumps(
+ dict(
+ name="suite",
+ version="1.0", lab_name="lab", defconfig_id="defconfig")
+ )
+
+ response = self.fetch(
+ "/test/suite/fake-id", method="POST", headers=headers, body=body)
+
+ self.assertEqual(response.code, 400)
+ self.assertEqual(
+ response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)
+
+ def test_post_correct_with_test_set(self):
+ headers = {"Authorization": "foo", "Content-Type": "application/json"}
+ body = json.dumps(
+ dict(
+ name="suite",
+ version="1.0",
+ lab_name="lab",
+ defconfig_id="defconfig", test_set=[{"foo": "bar"}]
+ )
+ )
+
+ response = self.fetch(
+ "/test/suite", method="POST", headers=headers, body=body)
+
+ self.assertEqual(response.code, 202)
+ self.assertEqual(
+ response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)
+
+ def test_post_correct_with_test_case(self):
+ headers = {"Authorization": "foo", "Content-Type": "application/json"}
+ body = json.dumps(
+ dict(
+ name="suite",
+ version="1.0",
+ lab_name="lab",
+ defconfig_id="defconfig", test_case=[{"foo": "bar"}]
+ )
+ )
+
+ response = self.fetch(
+ "/test/suite", method="POST", headers=headers, body=body)
+
+ self.assertEqual(response.code, 202)
+ self.assertEqual(
+ response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)
+
+ @mock.patch("utils.db.save")
+ def test_post_correct_with_error(self, mock_save):
+ mock_save.return_value = (500, None)
+ headers = {"Authorization": "foo", "Content-Type": "application/json"}
body = json.dumps(
dict(
@@ -187,6 +251,220 @@ class TestTestSuiteHandler(
"/test/suite", method="POST", headers=headers, body=body
)
- self.assertEqual(response.code, 201)
+ self.assertEqual(response.code, 500)
+ self.assertEqual(
+ response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)
+
+ def test_put_no_token(self):
+ response = self.fetch("/test/suite/id", method="PUT", body="")
+
+ self.assertEqual(response.code, 403)
+ self.assertEqual(
+ response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)
+
+ def test_put_wrong_token(self):
+ headers = {"Authorization": "foo", "Content-Type": "application/json"}
+ self.validate_token.return_value = False
+
+ response = self.fetch(
+ "/test/suite/id", method="PUT", headers=headers, body=""
+ )
+
+ self.assertEqual(response.code, 403)
+ self.assertEqual(
+ response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)
+
+ def test_put_wrong_content_type(self):
+ headers = {"Authorization": "foo"}
+
+ response = self.fetch(
+ "/test/suite/id", method="PUT", body="", headers=headers)
+
+ self.assertEqual(response.code, 415)
+ self.assertEqual(
+ response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)
+
+ def test_put_no_id(self):
+ headers = {"Authorization": "foo", "Content-Type": "application/json"}
+
+ response = self.fetch(
+ "/test/suite/", method="PUT", headers=headers, body=""
+ )
+
+ self.assertEqual(response.code, 400)
+ self.assertEqual(
+ response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)
+
+ def test_put_no_valid_json(self):
+ headers = {"Authorization": "foo", "Content-Type": "application/json"}
+
+ body = json.dumps(dict(foo="foo", bar="bar"))
+
+ response = self.fetch(
+ "/test/suite/id", method="PUT", body=body, headers=headers
+ )
+
+ self.assertEqual(response.code, 400)
+ self.assertEqual(
+ response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)
+
+ def test_put_no_json_data(self):
+ headers = {"Authorization": "foo", "Content-Type": "application/json"}
+
+ response = self.fetch(
+ "/test/suite/id", method="PUT", body="", headers=headers
+ )
+
+ self.assertEqual(response.code, 422)
+ self.assertEqual(
+ response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)
+
+ def test_put_no_valid_id(self):
+ headers = {"Authorization": "foo", "Content-Type": "application/json"}
+
+ body = json.dumps(dict(job="job", kernel="kernel"))
+
+ response = self.fetch(
+ "/test/suite/wrong-id", method="PUT", body=body, headers=headers
+ )
+
+ self.assertEqual(response.code, 400)
+ self.assertEqual(
+ response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)
+
+ @mock.patch("utils.db.find_one2")
+ @mock.patch("bson.objectid.ObjectId")
+ def test_put_id_not_found(self, mock_id, mock_find):
+ mock_id.return_value = "fake-id"
+ mock_find.return_value = None
+ headers = {"Authorization": "foo", "Content-Type": "application/json"}
+
+ body = json.dumps(dict(job="job", kernel="kernel"))
+
+ response = self.fetch(
+ "/test/suite/wrong-id", method="PUT", body=body, headers=headers
+ )
+
+ self.assertEqual(response.code, 404)
+ self.assertEqual(
+ response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)
+
+ @mock.patch("utils.db.update")
+ @mock.patch("utils.db.find_one2")
+ @mock.patch("bson.objectid.ObjectId")
+ def test_put_valid_no_error(self, mock_id, mock_find, mock_update):
+ mock_id.return_value = "fake-id"
+ mock_find.return_value = {"_id": "fake-id", "job": "bar"}
+ mock_update.return_value = 200
+ headers = {"Authorization": "foo", "Content-Type": "application/json"}
+
+ body = json.dumps(dict(job="job", kernel="kernel"))
+
+ response = self.fetch(
+ "/test/suite/fake-id", method="PUT", body=body, headers=headers)
+
+ self.assertEqual(response.code, 200)
+ self.assertEqual(
+ response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)
+
+ @mock.patch("utils.db.update")
+ @mock.patch("utils.db.find_one2")
+ @mock.patch("bson.objectid.ObjectId")
+ def test_put_valid_with_error(self, mock_id, mock_find, mock_update):
+ mock_id.return_value = "fake-id"
+ mock_find.return_value = {"_id": "fake-id", "job": "bar"}
+ mock_update.return_value = 500
+ headers = {"Authorization": "foo", "Content-Type": "application/json"}
+
+ body = json.dumps(dict(job="job", kernel="kernel"))
+
+ response = self.fetch(
+ "/test/suite/fake-id", method="PUT", body=body, headers=headers)
+
+ self.assertEqual(response.code, 500)
+ self.assertEqual(
+ response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)
+
+ def test_delete_no_token(self):
+ response = self.fetch("/test/suite/id", method="DELETE")
+
+ self.assertEqual(response.code, 403)
+ self.assertEqual(
+ response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)
+
+ def test_delete_wrong_token(self):
+ headers = {"Authorization": "foo"}
+ self.validate_token.return_value = False
+
+ response = self.fetch(
+ "/test/suite/id", method="DELETE", headers=headers)
+
+ self.assertEqual(response.code, 403)
+ self.assertEqual(
+ response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)
+
+ def test_delete_no_id(self):
+ headers = {"Authorization": "foo"}
+
+ response = self.fetch(
+ "/test/suite/", method="DELETE", headers=headers)
+
+ self.assertEqual(response.code, 400)
+ self.assertEqual(
+ response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)
+
+ def test_delete_wrong_id(self):
+ headers = {"Authorization": "foo"}
+
+ response = self.fetch(
+ "/test/suite/wrong-id", method="DELETE", headers=headers)
+
+ self.assertEqual(response.code, 400)
+ self.assertEqual(
+ response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)
+
+ @mock.patch("utils.db.find_one2")
+ @mock.patch("bson.objectid.ObjectId")
+ def test_delete_correct_not_found(self, mock_id, mock_find):
+ mock_id.return_value = "fake-id"
+ mock_find.return_value = None
+ headers = {"Authorization": "foo"}
+
+ response = self.fetch(
+ "/test/suite/fake-id", method="DELETE", headers=headers)
+
+ self.assertEqual(response.code, 404)
+ self.assertEqual(
+ response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)
+
+ @mock.patch("utils.db.delete")
+ @mock.patch("utils.db.find_one2")
+ @mock.patch("bson.objectid.ObjectId")
+ def test_delete_correct_with_error(self, mock_id, mock_find, mock_delete):
+ mock_id.return_value = "fake-id"
+ mock_find.return_value = {"_id": "fake-id"}
+ mock_delete.return_value = 500
+ headers = {"Authorization": "foo"}
+
+ response = self.fetch(
+ "/test/suite/fake-id", method="DELETE", headers=headers)
+
+ self.assertEqual(response.code, 500)
+ self.assertEqual(
+ response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)
+
+ @mock.patch("utils.db.delete")
+ @mock.patch("utils.db.find_one2")
+ @mock.patch("bson.objectid.ObjectId")
+ def test_delete_correct(self, mock_id, mock_find, mock_delete):
+ mock_id.return_value = "fake-id"
+ mock_find.return_value = {"_id": "fake-id"}
+ mock_delete.side_effect = [200, 500, 500]
+ headers = {"Authorization": "foo"}
+
+ response = self.fetch(
+ "/test/suite/fake-id", method="DELETE", headers=headers)
+
+ self.assertEqual(response.code, 200)
self.assertEqual(
response.headers["Content-Type"], DEFAULT_CONTENT_TYPE)