summaryrefslogtreecommitdiff
path: root/buildscripts/feature_flag_tags_check.py
blob: fe3bed82cb121e6907718c453dc3b4f752559f63 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/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 argparse
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 REQUIRES_FCV_TAG_LATEST
from buildscripts.resmokelib.utils import jscomment


def _run_git_cmd(cmd_args, cwd=None, silent=True):
    """Run git command."""
    run_args = {}
    if cwd:
        run_args["cwd"] = cwd
    if silent:
        run_args["stdout"] = subprocess.DEVNULL
        run_args["stderr"] = subprocess.DEVNULL
    subprocess.run(["git"] + cmd_args, **run_args, check=False)


def get_tests_with_feature_flag_tags(feature_flags, ent_path):
    """Get the list of tests with feature flag tag."""
    selector_config = {
        "roots": ["jstests/**/*.js", f"{ent_path}/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_LATEST not in test_tags:
                found_tests.append(test)
    return found_tests


def main(diff_file, ent_path):
    """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:
        print(
            "No feature flags were enabled by default in this patch/commit; skipping feature flag checks"
        )
        sys.exit(0)

    tests_with_feature_flag_tag = get_tests_with_feature_flag_tags(enabled_feature_flags, ent_path)

    _run_git_cmd(["apply", diff_file])
    _run_git_cmd(["apply", diff_file], cwd=ent_path)
    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_LATEST}` tag:\n" +
              "\n".join(tests_missing_fcv_tag))
        sys.exit(1)
    sys.exit(0)


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--diff-file-name", type=str,
                        help="Name of the file containing the git diff")
    parser.add_argument("--enterprise-path", type=str, help="Path to the enterprise module")
    args = parser.parse_args()
    main(args.diff_file_name, args.enterprise_path)