diff --git a/elastic_recheck/cmd/uncategorized_fails.py b/elastic_recheck/cmd/uncategorized_fails.py index 694abecb..b62a4346 100755 --- a/elastic_recheck/cmd/uncategorized_fails.py +++ b/elastic_recheck/cmd/uncategorized_fails.py @@ -27,6 +27,20 @@ import elastic_recheck.elasticRecheck as er import elastic_recheck.query_builder as qb import elastic_recheck.results as er_results +# Not all teams actively used elastic recheck for categorizing their +# work, so to keep the uncategorized page more meaningful, we exclude +# jobs from teams that don't use this toolchain. +EXCLUDED_JOBS = ( + # Docs team + "api-site", + "operations-guide", + "openstack-manuals", + # Ansible + "ansible" +) + +EXCLUDED_JOBS_REGEX = re.compile('(' + '|'.join(EXCLUDED_JOBS) + ')') + def get_options(): parser = argparse.ArgumentParser( @@ -65,6 +79,10 @@ def all_fails(classifier): facets.detect_facets(results, ["build_uuid"]) for build in facets: for result in facets[build]: + # If the job is on the exclude list, skip + if re.search(EXCLUDED_JOBS_REGEX, result.build_name): + continue + # not perfect, but basically an attempt to show the integrated # gate. Would be nice if there was a zuul attr for this in es. if re.search("(^openstack/|devstack|grenade)", result.project): diff --git a/elastic_recheck/tests/unit/cmd/__init__.py b/elastic_recheck/tests/unit/cmd/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/elastic_recheck/tests/unit/cmd/test_uncategorized_fails.py b/elastic_recheck/tests/unit/cmd/test_uncategorized_fails.py new file mode 100644 index 00000000..2a595417 --- /dev/null +++ b/elastic_recheck/tests/unit/cmd/test_uncategorized_fails.py @@ -0,0 +1,58 @@ +# Copyright 2015 IBM Corp. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import uuid + +import mock +import testtools + +from elastic_recheck.cmd import uncategorized_fails as fails + + +class TestUncategorizedFails(testtools.TestCase): + """Tests the uncategorized fails command module""" + + def test_all_fails(self): + # Tests that we properly filter out results using our blacklist regex. + + # The list of results would really be Hit objects but the attr stuff + # in those is tricky so let's just be lazy and use mock. + results = [ + # should be excluded + mock.MagicMock(build_uuid=str(uuid.uuid4()), + build_name='gate-api-site-tox-checklinks', + project='openstack/api-site', + timestamp='2015-09-25T17:55:09.372Z', + log_url='http://logs.openstack.org/1/console.html'), + # should be excluded + mock.MagicMock(build_uuid=str(uuid.uuid4()), + build_name='gate-openstack-ansible-dsvm-commit', + project='openstack/openstack-ansible', + timestamp='2015-09-25T17:55:09.372Z', + log_url='http://logs.openstack.org/2/console.html'), + # should be included + mock.MagicMock(build_uuid=str(uuid.uuid4()), + build_name='gate-tempest-dsvm-full', + project='openstack/cinder', + timestamp='2015-09-25T17:55:09.372Z', + log_url='http://logs.openstack.org/3/console.html'), + ] + classifier = mock.MagicMock() + query_mock = mock.Mock(return_value=results) + classifier.hits_by_query = query_mock + all_fails = fails.all_fails(classifier) + # assert that we only have the single result + self.assertThat(all_fails, + testtools.matchers.HasLength(1)) + self.assertIn('gate-tempest-dsvm-full', all_fails.keys()[0])