diff --git a/grimoire_elk/enriched/bugzilla.py b/grimoire_elk/enriched/bugzilla.py index 8bcbaf085..30aaa4b1f 100644 --- a/grimoire_elk/enriched/bugzilla.py +++ b/grimoire_elk/enriched/bugzilla.py @@ -204,6 +204,9 @@ def get_rich_item(self, item): get_time_diff_days(eitem['creation_date'], eitem['delta_ts']) eitem['timeopen_days'] = \ get_time_diff_days(eitem['creation_date'], datetime_utcnow().replace(tzinfo=None)) + eitem['time_to_first_attention'] = \ + get_time_diff_days(eitem['creation_date'], + self.get_time_to_first_attention(issue)) if self.sortinghat: eitem.update(self.get_item_sh(item, self.roles)) @@ -216,3 +219,29 @@ def get_rich_item(self, item): self.add_repository_labels(eitem) self.add_metadata_filter_raw(eitem) return eitem + + def get_time_to_first_attention(self, item): + """Set the time to first attention. + + This date is defined as the first date at which a comment by someone + other than the user who created the issue. + """ + if 'long_desc' not in item: + return None + + comment_dates = [] + reporter = item['reporter'][0]['__text__'] + + # First comment is the description of the issue + # Real comments start at the second position (index 1) + for comment in item['long_desc'][1:]: + user = comment['who'][0]['__text__'] + if user == reporter: + continue + dt = str_to_datetime(comment['bug_when'][0]['__text__']).replace(tzinfo=None) + comment_dates.append(dt) + + if comment_dates: + return min(comment_dates) + else: + return None diff --git a/schema/bugzilla.csv b/schema/bugzilla.csv index 187ee6b63..e9a8a52ad 100644 --- a/schema/bugzilla.csv +++ b/schema/bugzilla.csv @@ -110,6 +110,7 @@ severity,keyword status,keyword tag,keyword timeopen_days,float +time_to_first_attention,float url,keyword uuid,keyword whiteboard,keyword diff --git a/tests/data/bugzilla.json b/tests/data/bugzilla.json index 68612bbf3..387d2a0e3 100644 --- a/tests/data/bugzilla.json +++ b/tests/data/bugzilla.json @@ -181,8 +181,8 @@ ], "reporter": [ { - "__text__": "rocapal@example.org", - "name": "Roberto Calvo" + "__text__": "sduenas@example.org", + "name": "Santiago Due\u00f1as" } ], "reporter_accessible": [ @@ -507,8 +507,8 @@ ], "reporter": [ { - "__text__": "rocapal@example.org", - "name": "Roberto Calvo" + "__text__": "sduenas@example.org", + "name": "Santiago Due\u00f1as" } ], "reporter_accessible": [ @@ -668,8 +668,8 @@ ], "who": [ { - "__text__": "sduenas@example.org", - "name": "Santiago Due\u00f1as" + "__text__": "dizquierdo@example.org", + "name": "Daniel Izquierdo Cortazar" } ] } @@ -1026,8 +1026,8 @@ ], "reporter": [ { - "__text__": "rocapal@example.com", - "name": "Roberto Calvo" + "__text__": "sduenas@example.org", + "name": "Santiago Due\u00f1as" } ], "reporter_accessible": [ @@ -1251,8 +1251,8 @@ ], "reporter": [ { - "__text__": "rocapal@example.org", - "name": "Roberto Calvo" + "__text__": "sduenas@example.org", + "name": "Santiago Due\u00f1as" } ], "reporter_accessible": [ @@ -1446,8 +1446,8 @@ ], "reporter": [ { - "__text__": "dizquierdo@example.org", - "name": "Daniel Izquierdo Cortazar" + "__text__": "sduenas@example.org", + "name": "Santiago Due\u00f1as" } ], "reporter_accessible": [ @@ -1661,7 +1661,7 @@ ], "creation_ts": [ { - "__text__": "2015-05-23 06:06:06 +0200" + "__text__": "2013-06-25 11:49:36 +0200" } ], "delta_ts": [ @@ -1720,7 +1720,7 @@ ], "bug_when": [ { - "__text__": "2013-06-25 11:55:46 +0200" + "__text__": "2013-07-01 12:00:00 +0200" } ], "commentid": [ @@ -1740,6 +1740,96 @@ "name": "Santiago Due\u00f1as" } ] + }, + { + "__text__": "\n ", + "attachid": [ + { + "__text__": "172" + } + ], + "bug_when": [ + { + "__text__": "2014-06-25 11:55:46 +0200" + } + ], + "commentid": [ + { + "__text__": "1086" + } + ], + "isprivate": "0", + "thetext": [ + { + "__text__": "This patch is great" + } + ], + "who": [ + { + "__text__": "lcanas@example.org", + "name": "Luis Ca\u00f1as" + } + ] + }, + { + "__text__": "\n ", + "attachid": [ + { + "__text__": "172" + } + ], + "bug_when": [ + { + "__text__": "2014-06-25 11:55:46 +0200" + } + ], + "commentid": [ + { + "__text__": "1086" + } + ], + "isprivate": "0", + "thetext": [ + { + "__text__": "Thanks!" + } + ], + "who": [ + { + "__text__": "sduenas@example.org", + "name": "Santiago Due\u00f1as" + } + ] + }, + { + "__text__": "\n ", + "attachid": [ + { + "__text__": "172" + } + ], + "bug_when": [ + { + "__text__": "2014-08-01 11:55:46 +0200" + } + ], + "commentid": [ + { + "__text__": "1086" + } + ], + "isprivate": "0", + "thetext": [ + { + "__text__": "Applied" + } + ], + "who": [ + { + "__text__": "sduenas@example.org", + "name": "Santiago Due\u00f1as" + } + ] } ], "op_sys": [ @@ -1770,8 +1860,8 @@ ], "reporter": [ { - "__text__": "carlosgc@example.com", - "name": "Carlos Garcia Campos" + "__text__": "sduenas@example.org", + "name": "Santiago Due\u00f1as" } ], "reporter_accessible": [ diff --git a/tests/test_bugzilla.py b/tests/test_bugzilla.py index aaa0afd8e..ef5e3b345 100644 --- a/tests/test_bugzilla.py +++ b/tests/test_bugzilla.py @@ -93,6 +93,18 @@ def test_enrich_keywords(self): eitem = enrich_backend.get_rich_item(item) self.assertEqual(eitem['keywords'], []) + def test_time_to_first_attention(self): + """Test whether time_to_first_attention is calculated""" + + self._test_raw_to_enrich() + enrich_backend = self.connectors[self.connector][2]() + + expected = [None, None, None, None, None, None, 365] + + for index in range(0, len(self.items)): + eitem = enrich_backend.get_rich_item(self.items[index]) + self.assertEqual(eitem['time_to_first_attention'], expected[index]) + def test_raw_to_enrich_sorting_hat(self): """Test enrich with SortingHat"""