summaryrefslogtreecommitdiff
path: root/buildscripts/antithesis_suite.py
blob: 8397a992ee72309a92a55149c7bc5d69351400f6 (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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/usr/bin/env python3
"""Command line utility for generating suites for targeting antithesis."""

import os.path
import sys
import pathlib

import click
import yaml

# 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__))))

SUITE_BLACKLIST = [
    "CheckReplDBHash",
    "CheckReplOplogs",
    "CleanEveryN",
    "ContinuousStepdown",
    "ValidateCollections",
    "CheckOrphansDeleted",
]


def _sanitize_hooks(hooks):
    if len(hooks) == 0:
        return hooks
    # it's either a list of strings, or a list of dicts, each with key 'class'
    if isinstance(hooks[0], str):
        return list(filter(lambda x: x not in SUITE_BLACKLIST, hooks))
    elif isinstance(hooks[0], dict):
        return list(filter(lambda x: x['class'] not in SUITE_BLACKLIST, hooks))
    else:
        raise RuntimeError('Unknown structure in hook. File a TIG ticket.')


def _sanitize_test_data(test_data):
    if test_data.get("useStepdownPermittedFile", None):
        test_data["useStepdownPermittedFile"] = False
    return test_data


_SUITES_PATH = os.path.join("buildscripts", "resmokeconfig", "suites")


@click.group()
def cli():
    """CLI Entry point."""
    pass


def _generate(suite_name: str) -> None:
    with open(os.path.join(_SUITES_PATH, "{}.yml".format(suite_name))) as fstream:
        suite = yaml.safe_load(fstream)

    try:
        suite["archive"]["hooks"] = _sanitize_hooks(suite["archive"]["hooks"])
    except KeyError:
        # pass, don't care
        pass
    except TypeError:
        pass

    try:
        suite["executor"]["archive"]["hooks"] = _sanitize_hooks(
            suite["executor"]["archive"]["hooks"])
    except KeyError:
        # pass, don't care
        pass
    except TypeError:
        pass

    try:
        suite["executor"]["hooks"] = _sanitize_hooks(suite["executor"]["hooks"])
    except KeyError:
        # pass, don't care
        pass
    except TypeError:
        pass

    try:
        suite["executor"]["config"]["shell_options"]["global_vars"][
            "TestData"] = _sanitize_test_data(
                suite["executor"]["config"]["shell_options"]["global_vars"]["TestData"])
    except KeyError:
        # pass, don't care
        pass
    except TypeError:
        pass

    try:
        suite["executor"]["config"]["shell_options"]["eval"] += "jsTestLog = Function.prototype;"
    except KeyError:
        # pass, don't care
        pass
    except TypeError:
        pass

    out = yaml.dump(suite)
    with open(os.path.join(_SUITES_PATH, "antithesis_{}.yml".format(suite_name)), "w") as fstream:
        fstream.write(
            "# this file was generated by buildscripts/antithesis_suite.py generate {}\n".format(
                suite_name))
        fstream.write("# Do not modify by hand\n")
        fstream.write(out)


@cli.command()
@click.argument('suite_name')
def generate(suite_name: str) -> None:
    """Generate a single suite."""
    _generate(suite_name)


@cli.command('generate-all')
def generate_all():
    """Generate all suites."""
    for path in os.listdir(_SUITES_PATH):
        if os.path.isfile(os.path.join(_SUITES_PATH, path)):
            suite = path.split(".")[0]
            _generate(suite)


if __name__ == "__main__":
    cli()