aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilo Casagrande <milo.casagrande@linaro.org>2015-02-02 16:31:44 +0100
committerMilo Casagrande <milo.casagrande@linaro.org>2015-02-02 16:31:44 +0100
commitf2e649f52d5374c979f8513aa2e13b0a48d29dd2 (patch)
tree0afbae9221bf0d29f8cd13d85faa424898c34ab2
parent10e54d90e5cf73f7c6da25f12685c035dc94d471 (diff)
Implement defconfig compared bisection.
Change-Id: Ia4582849b2f84e1904cd9a05503e3c16ca17a895
-rw-r--r--app/utils/bisect/defconfig.py152
1 files changed, 136 insertions, 16 deletions
diff --git a/app/utils/bisect/defconfig.py b/app/utils/bisect/defconfig.py
index fd113b0..4707ffa 100644
--- a/app/utils/bisect/defconfig.py
+++ b/app/utils/bisect/defconfig.py
@@ -50,6 +50,8 @@ DEFCONFIG_SORT = [(models.CREATED_KEY, pymongo.DESCENDING)]
# pylint: disable=too-many-locals
+# pylint: disable=too-many-branches
+# pylint: disable=too-many-statements
def execute_defconfig_bisection(doc_id, db_options, fields=None):
"""Calculate bisect data for the provided defconfig report.
@@ -91,6 +93,8 @@ def execute_defconfig_bisection(doc_id, db_options, fields=None):
bisect_doc.job_id = start_doc_get(models.JOB_ID_KEY, None)
bisect_doc.defconfig_id = start_doc_get(models.ID_KEY)
bisect_doc.defconfig = start_doc_get(models.DEFCONFIG_KEY, None)
+ bisect_doc.defconfig_full = start_doc_get(
+ models.DEFCONFIG_FULL_KEY, None)
bisect_doc.created_on = datetime.datetime.now(tz=bson.tz_util.utc)
bisect_doc.bad_commit_date = start_doc_get(models.CREATED_KEY)
bisect_doc.bad_commit = start_doc_get(models.GIT_COMMIT_KEY)
@@ -135,18 +139,9 @@ def execute_defconfig_bisection(doc_id, db_options, fields=None):
# the valid dates.
passed_build = None
if passed_builds.count() > 0:
- passed_build = passed_builds[0]
-
- if passed_build.get(models.STATUS_KEY) != models.PASS_STATUS:
- utils.LOG.warn(
- "First result found is not a passed build for '%s'",
- obj_id
- )
- for doc in passed_builds:
- if doc.get(models.STATUS_KEY) == models.PASS_STATUS:
- passed_build = doc
- break
+ passed_build = _search_passed_doc(passed_builds)
+ if passed_build is not None:
spec[models.CREATED_KEY] = {
"$gte": passed_build.get(models.CREATED_KEY),
"$lt": start_doc_get(models.CREATED_KEY)
@@ -191,13 +186,138 @@ def execute_defconfig_bisection(doc_id, db_options, fields=None):
# Store everything in the bisect data.
bisect_doc.bisect_data = all_valid_docs
+ bcommon.save_bisect_doc(database, bisect_doc, doc_id)
+
+ bisect_doc = bcommon.update_doc_fields(bisect_doc, fields)
+ result = [
+ json.loads(
+ json.dumps(
+ bisect_doc,
+ default=bson.json_util.default,
+ ensure_ascii=False,
+ separators=(",", ":")
+ )
+ )
+ ]
+ else:
+ code = 404
+ result = None
+
+ return code, result
+
+
+def _search_passed_doc(passed_builds):
+ """Search for a document with PASS status.
+
+ :param passed_builds: The list or an iterator of docs to parse.
+ :return A doc with PASS status or None.
+ """
+ passed_build = passed_builds[0]
+
+ if passed_build.get(models.STATUS_KEY) != models.PASS_STATUS:
+ passed_build = None
+ for doc in passed_builds:
+ if doc.get(models.STATUS_KEY) == models.PASS_STATUS:
+ passed_build = doc
+ break
+
+ return passed_build
+
+
+# pylint: disable=invalid-name
+def execute_defconfig_bisection_compared_to(
+ doc_id, compare_to, db_options, fields=None):
+ """Execute a bisect for one tree compared to another one.
+
+ :param doc_id: The ID of the defconfig report we want compared.
+ :type doc_id: string
+ :param compare_to: The tree name to compare against.
+ :type compare_to: string
+ :param db_options: The options for the database connection.
+ :type db_options: dictionary
+ :param fields: A `fields` data structure with the fields to return or
+ exclude. Default to None.
+ :type fields: list or dict
+ :return A numeric value for the result status and a list dictionaries.
+ """
+ database = utils.db.get_db_connection(db_options)
+ result = []
+ code = 200
+
+ obj_id = bson.objectid.ObjectId(doc_id)
+ start_doc = utils.db.find_one2(
+ database[models.DEFCONFIG_COLLECTION],
+ obj_id,
+ fields=DEFCONFIG_SEARCH_FIELDS
+ )
+
+ if all([start_doc, isinstance(start_doc, types.DictionaryType)]):
+ start_doc_get = start_doc.get
+
+ if start_doc_get(models.STATUS_KEY) == models.PASS_STATUS:
+ code = 400
+ result = None
+ else:
+ # TODO: we need to know the baseline tree commit in order not to
+ # search too much in the past.
+ end_date, limit = bcommon.search_previous_bisect(
+ database,
+ {models.DEFCONFIG_ID_KEY: obj_id},
+ models.CREATED_KEY
+ )
+
+ job = start_doc_get(models.JOB_KEY)
+ defconfig = start_doc_get(models.DEFCONFIG_KEY)
+ defconfig_full = start_doc_get(
+ models.DEFCONFIG_FULL_KEY) or defconfig
+ created_on = start_doc_get(models.CREATED_KEY)
+ arch = start_doc_get(
+ models.ARCHITECTURE_KEY) or models.ARM_ARCHITECTURE_KEY
+
+ bisect_doc = mbisect.DefconfigBisectDocument(obj_id)
+ bisect_doc.compare_to = compare_to
+ bisect_doc.version = "1.0"
+ bisect_doc.defconfig = defconfig
+ bisect_doc.defconfig_full = defconfig_full
+ bisect_doc.job = job
+ bisect_doc.job_id = start_doc_get(models.JOB_ID_KEY, None)
+ bisect_doc.defconfig_id = start_doc_get(
+ models.DEFCONFIG_ID_KEY, None)
+ bisect_doc.boot_id = obj_id
+ bisect_doc.created_on = datetime.datetime.now(tz=bson.tz_util.utc)
+ bisect_doc.arch = arch
- return_code, saved_id = utils.db.save(
- database, bisect_doc, manipulate=True)
- if return_code == 201:
- bisect_doc.id = saved_id
+ if end_date:
+ date_range = {
+ "$lt": created_on,
+ "$gte": end_date
+ }
else:
- utils.LOG.error("Error saving bisect data %s", doc_id)
+ date_range = {"$lt": created_on}
+
+ spec = {
+ models.DEFCONFIG_KEY: defconfig,
+ models.DEFCONFIG_FULL_KEY: defconfig_full,
+ models.JOB_KEY: compare_to,
+ models.ARCHITECTURE_KEY: arch,
+ models.CREATED_KEY: date_range
+ }
+
+ prev_docs = utils.db.find(
+ database[models.DEFCONFIG_COLLECTION],
+ limit,
+ 0,
+ spec=spec,
+ fields=DEFCONFIG_SEARCH_FIELDS,
+ sort=DEFCONFIG_SORT)
+
+ all_valid_docs = []
+ if prev_docs:
+ all_valid_docs.extend(prev_docs)
+
+ # Store everything in the bisect data.
+ bisect_doc.bisect_data = all_valid_docs
+ bcommon.save_bisect_doc(database, bisect_doc, doc_id)
bisect_doc = bcommon.update_doc_fields(bisect_doc, fields)
result = [