#!/usr/bin/env python
|
|
# Copyright 2016 gRPC authors.
|
#
|
# 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 os
|
import sys
|
import unittest
|
import re
|
|
# hack import paths to pick up extra code
|
sys.path.insert(0, os.path.abspath('tools/run_tests/'))
|
from run_tests_matrix import _create_test_jobs, _create_portability_test_jobs
|
import python_utils.filter_pull_request_tests as filter_pull_request_tests
|
|
_LIST_OF_LANGUAGE_LABELS = [
|
'c', 'c++', 'csharp', 'grpc-node', 'objc', 'php', 'php7', 'python', 'ruby'
|
]
|
_LIST_OF_PLATFORM_LABELS = ['linux', 'macos', 'windows']
|
|
|
class TestFilteringTest(unittest.TestCase):
|
|
def generate_all_tests(self):
|
all_jobs = _create_test_jobs() + _create_portability_test_jobs()
|
self.assertIsNotNone(all_jobs)
|
return all_jobs
|
|
def test_filtering(self, changed_files=[], labels=_LIST_OF_LANGUAGE_LABELS):
|
"""
|
Default args should filter no tests because changed_files is empty and
|
default labels should be able to match all jobs
|
:param changed_files: mock list of changed_files from pull request
|
:param labels: list of job labels that should be skipped
|
"""
|
all_jobs = self.generate_all_tests()
|
|
# Replacing _get_changed_files function to allow specifying changed files in filter_tests function
|
def _get_changed_files(foo):
|
return changed_files
|
|
filter_pull_request_tests._get_changed_files = _get_changed_files
|
print()
|
filtered_jobs = filter_pull_request_tests.filter_tests(all_jobs, "test")
|
|
# Make sure sanity tests aren't being filtered out
|
sanity_tests_in_all_jobs = 0
|
sanity_tests_in_filtered_jobs = 0
|
for job in all_jobs:
|
if "sanity" in job.labels:
|
sanity_tests_in_all_jobs += 1
|
all_jobs = [job for job in all_jobs if "sanity" not in job.labels]
|
for job in filtered_jobs:
|
if "sanity" in job.labels:
|
sanity_tests_in_filtered_jobs += 1
|
filtered_jobs = [
|
job for job in filtered_jobs if "sanity" not in job.labels
|
]
|
self.assertEquals(sanity_tests_in_all_jobs,
|
sanity_tests_in_filtered_jobs)
|
|
for label in labels:
|
for job in filtered_jobs:
|
self.assertNotIn(label, job.labels)
|
|
jobs_matching_labels = 0
|
for label in labels:
|
for job in all_jobs:
|
if (label in job.labels):
|
jobs_matching_labels += 1
|
self.assertEquals(
|
len(filtered_jobs),
|
len(all_jobs) - jobs_matching_labels)
|
|
def test_individual_language_filters(self):
|
# Changing unlisted file should trigger all languages
|
self.test_filtering(['ffffoo/bar.baz'], [_LIST_OF_LANGUAGE_LABELS])
|
# Changing core should trigger all tests
|
self.test_filtering(['src/core/foo.bar'], [_LIST_OF_LANGUAGE_LABELS])
|
# Testing individual languages
|
self.test_filtering(['test/core/foo.bar'], [
|
label for label in _LIST_OF_LANGUAGE_LABELS
|
if label not in filter_pull_request_tests._CORE_TEST_SUITE.labels +
|
filter_pull_request_tests._CPP_TEST_SUITE.labels
|
])
|
self.test_filtering(['src/cpp/foo.bar'], [
|
label for label in _LIST_OF_LANGUAGE_LABELS
|
if label not in filter_pull_request_tests._CPP_TEST_SUITE.labels
|
])
|
self.test_filtering(['src/csharp/foo.bar'], [
|
label for label in _LIST_OF_LANGUAGE_LABELS
|
if label not in filter_pull_request_tests._CSHARP_TEST_SUITE.labels
|
])
|
self.test_filtering(['src/objective-c/foo.bar'], [
|
label for label in _LIST_OF_LANGUAGE_LABELS
|
if label not in filter_pull_request_tests._OBJC_TEST_SUITE.labels
|
])
|
self.test_filtering(['src/php/foo.bar'], [
|
label for label in _LIST_OF_LANGUAGE_LABELS
|
if label not in filter_pull_request_tests._PHP_TEST_SUITE.labels
|
])
|
self.test_filtering(['src/python/foo.bar'], [
|
label for label in _LIST_OF_LANGUAGE_LABELS
|
if label not in filter_pull_request_tests._PYTHON_TEST_SUITE.labels
|
])
|
self.test_filtering(['src/ruby/foo.bar'], [
|
label for label in _LIST_OF_LANGUAGE_LABELS
|
if label not in filter_pull_request_tests._RUBY_TEST_SUITE.labels
|
])
|
|
def test_combined_language_filters(self):
|
self.test_filtering(['src/cpp/foo.bar', 'test/core/foo.bar'], [
|
label for label in _LIST_OF_LANGUAGE_LABELS
|
if label not in filter_pull_request_tests._CPP_TEST_SUITE.labels and
|
label not in filter_pull_request_tests._CORE_TEST_SUITE.labels
|
])
|
self.test_filtering(['src/cpp/foo.bar', "src/csharp/foo.bar"], [
|
label for label in _LIST_OF_LANGUAGE_LABELS
|
if label not in filter_pull_request_tests._CPP_TEST_SUITE.labels and
|
label not in filter_pull_request_tests._CSHARP_TEST_SUITE.labels
|
])
|
self.test_filtering([
|
'src/objective-c/foo.bar', 'src/php/foo.bar', "src/python/foo.bar",
|
"src/ruby/foo.bar"
|
], [
|
label for label in _LIST_OF_LANGUAGE_LABELS
|
if label not in filter_pull_request_tests._OBJC_TEST_SUITE.labels
|
and label not in filter_pull_request_tests._PHP_TEST_SUITE.labels
|
and label not in filter_pull_request_tests._PYTHON_TEST_SUITE.labels
|
and label not in filter_pull_request_tests._RUBY_TEST_SUITE.labels
|
])
|
|
def test_platform_filter(self):
|
self.test_filtering(['vsprojects/foo.bar'], [
|
label for label in _LIST_OF_PLATFORM_LABELS
|
if label not in filter_pull_request_tests._WINDOWS_TEST_SUITE.labels
|
])
|
|
def test_whitelist(self):
|
whitelist = filter_pull_request_tests._WHITELIST_DICT
|
files_that_should_trigger_all_tests = [
|
'src/core/foo.bar', 'some_file_not_on_the_white_list', 'BUILD',
|
'etc/roots.pem', 'Makefile', 'tools/foo'
|
]
|
for key in whitelist.keys():
|
for file_name in files_that_should_trigger_all_tests:
|
self.assertFalse(re.match(key, file_name))
|
|
|
if __name__ == '__main__':
|
unittest.main(verbosity=2)
|