diff options
author | Mikhail Shchatko <mikhail.shchatko@mongodb.com> | 2021-07-15 13:14:05 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-07-23 07:30:05 +0000 |
commit | fcdbc97ec75cad751764c43343e018d0ffd3f642 (patch) | |
tree | 902bf711dc6e14bc887e8aadb76e708ced0b703c /buildscripts | |
parent | 00840fd3470baa28ff6ed6a50b8b59327e6bac45 (diff) | |
download | mongo-fcdbc97ec75cad751764c43343e018d0ffd3f642.tar.gz |
SERVER-55858 Enforce transition to requires-fcv after feature flag is changed from disabled to enabled by default
Diffstat (limited to 'buildscripts')
-rwxr-xr-x | buildscripts/feature_flag_tags_check.py | 86 | ||||
-rw-r--r-- | buildscripts/resmokelib/selector.py | 2 | ||||
-rw-r--r-- | buildscripts/tests/test_feature_flag_tags_check.py | 36 |
3 files changed, 124 insertions, 0 deletions
diff --git a/buildscripts/feature_flag_tags_check.py b/buildscripts/feature_flag_tags_check.py new file mode 100755 index 00000000000..6142e658eab --- /dev/null +++ b/buildscripts/feature_flag_tags_check.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 +"""Feature flag tags check. + +Check that on changing feature flag from disabled to enabled by default in all js tests that +had that feature flag in tags there is a tag that requires the latest FCV. +""" + +import os +import subprocess +import sys + +# Get relative imports to work when the package is not installed on the PYTHONPATH. +if __name__ == "__main__" and __package__ is None: + sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +# pylint: disable=wrong-import-position +from buildscripts.resmokelib import selector +from buildscripts.resmokelib.multiversionconstants import LATEST_FCV +from buildscripts.resmokelib.utils import jscomment + +REQUIRES_FCV_TAG = f"requires_fcv_{LATEST_FCV}".replace(".", "") +ENTERPRISE_DIR = "src/mongo/db/modules/enterprise" + + +def _run_git_stash_cmd(args, cwd=None): + """Run git stash command.""" + git_cmd = ["git", "stash"] + args + proc = subprocess.Popen(git_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=cwd) + proc.communicate() + + +def _git_stash(args): + """Run git stash command in he current and enterprise directory.""" + _run_git_stash_cmd(args) + if os.path.isdir(ENTERPRISE_DIR): + _run_git_stash_cmd(args, cwd=ENTERPRISE_DIR) + + +def get_tests_with_feature_flag_tags(feature_flags): + """Get the list of tests with feature flag tag.""" + selector_config = { + "roots": ["jstests/**/*.js", f"{ENTERPRISE_DIR}/jstests/**/*.js"], + "include_with_any_tags": feature_flags, + } + tests, _ = selector.filter_tests("js_test", selector_config) + return tests + + +def get_tests_missing_fcv_tag(tests): + """Get the list of tests missing requires FCV tag.""" + found_tests = [] + for test in tests: + try: + test_tags = jscomment.get_tags(test) + except FileNotFoundError: + continue + else: + if REQUIRES_FCV_TAG not in test_tags: + found_tests.append(test) + return found_tests + + +def main(): + """Run the main function.""" + with open("base_all_feature_flags.txt", "r") as fh: + base_feature_flags = fh.read().split() + with open("patch_all_feature_flags.txt", "r") as fh: + patch_feature_flags = fh.read().split() + enabled_feature_flags = [flag for flag in base_feature_flags if flag not in patch_feature_flags] + + if not enabled_feature_flags: + sys.exit(0) + + _git_stash(["--", "jstests"]) + tests_with_feature_flag_tag = get_tests_with_feature_flag_tags(enabled_feature_flags) + _git_stash(["pop"]) + tests_missing_fcv_tag = get_tests_missing_fcv_tag(tests_with_feature_flag_tag) + + if tests_missing_fcv_tag: + print(f"Found tests missing `{REQUIRES_FCV_TAG}` tag:\n" + "\n".join(tests_missing_fcv_tag)) + sys.exit(1) + sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/buildscripts/resmokelib/selector.py b/buildscripts/resmokelib/selector.py index 53ea29bf766..8ce2f3a8761 100644 --- a/buildscripts/resmokelib/selector.py +++ b/buildscripts/resmokelib/selector.py @@ -123,6 +123,8 @@ class TestFileExplorer(object): if tagged_tests is None: tagged_tests = collections.defaultdict(list) + if tag_files is None: + tag_files = [] for tag_file in tag_files: if tag_file and os.path.exists(tag_file): tags_conf = _tags.TagsConfig.from_file(tag_file) diff --git a/buildscripts/tests/test_feature_flag_tags_check.py b/buildscripts/tests/test_feature_flag_tags_check.py new file mode 100644 index 00000000000..292ed05a1d6 --- /dev/null +++ b/buildscripts/tests/test_feature_flag_tags_check.py @@ -0,0 +1,36 @@ +"""Unit tests for feature_flag_tags_check.py.""" +# pylint: disable=missing-docstring +import unittest +from unittest.mock import patch + +from buildscripts import feature_flag_tags_check + + +class TestFindTestsInGitDiff(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.requires_fcv_tag = "requires_fcv_50" + cls.original_requires_fcv_tag = feature_flag_tags_check.REQUIRES_FCV_TAG + feature_flag_tags_check.REQUIRES_FCV_TAG = cls.requires_fcv_tag + + @classmethod + def tearDownClass(cls): + feature_flag_tags_check.REQUIRES_FCV_TAG = cls.original_requires_fcv_tag + + def test_get_tests_missing_fcv_tag_no_tag(self): + tests = ["dummy_jstest_file.js"] + with patch.object(feature_flag_tags_check.jscomment, "get_tags", return_value=[]): + result = feature_flag_tags_check.get_tests_missing_fcv_tag(tests) + self.assertCountEqual(tests, result) + + def test_get_tests_missing_fcv_tag_have_tag(self): + tests = ["dummy_jstest_file.js"] + with patch.object(feature_flag_tags_check.jscomment, "get_tags", + return_value=[self.requires_fcv_tag]): + result = feature_flag_tags_check.get_tests_missing_fcv_tag(tests) + self.assertCountEqual([], result) + + def test_get_tests_missing_fcv_tag_test_file_deleted(self): + tests = ["some/non/existent/jstest_file.js"] + result = feature_flag_tags_check.get_tests_missing_fcv_tag(tests) + self.assertCountEqual([], result) |