mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-24 00:17:37 +01:00
855dfadef0
GitOrigin-RevId: e793d662774ccd3ab6c3f356c2287cf1f7ff9805
765 lines
29 KiB
Python
Executable File
765 lines
29 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Compares IDL server parameters and configs between MongoDB server versions.
|
|
|
|
The comparison is computed by scanning though `base_version_dirs` and `incremented_version_dirs` looking for all configs and setParameters in each tree.
|
|
It then compares these looking for additions, removals, and deltas. Finally it outputs a summary to the console.
|
|
|
|
This comparison does not currently support nested properties is as it does only simple string comparison on key:property pairs - see build_diff_fn as a means of extending the comparison capability in the future.
|
|
"""
|
|
|
|
import argparse
|
|
import io
|
|
import os
|
|
import pprint
|
|
import unittest
|
|
from enum import Enum
|
|
|
|
import yaml
|
|
|
|
_COMPARE_FIELDS_SERVER_PARAMETERS = ["default", "set_at", "validator", "test_only"]
|
|
_COMPARE_FIELDS_CONFIGS = ["arg_vartype", "requires", "hidden", "redact"]
|
|
|
|
|
|
class ComparisonType(str, Enum):
|
|
CONFIGS = "configs"
|
|
SERVER_PARAMETERS = "server_parameters"
|
|
|
|
|
|
class PropertyDiff:
|
|
def __init__(self, base, inc):
|
|
self.base = base
|
|
self.inc = inc
|
|
|
|
|
|
class PropertiesDiffs:
|
|
def __init__(self, removed, added, modified):
|
|
self.removed = removed
|
|
self.added = added
|
|
self.modified = modified
|
|
|
|
|
|
def build_diff_fn(compare_fields: list) -> callable:
|
|
def diff_fn(prop_base: dict, prop_inc: dict) -> dict:
|
|
change_diffs = {}
|
|
for field in compare_fields:
|
|
if prop_base.get(field) != prop_inc.get(field):
|
|
change_diffs[field] = PropertyDiff(
|
|
str(prop_base.get(field, "")), str(prop_inc.get(field, ""))
|
|
)
|
|
return change_diffs
|
|
|
|
return diff_fn
|
|
|
|
|
|
class BuildBasePropertiesForComparisonHandler:
|
|
"""Interprets an .idl file representing a "base" version of configuration for comparison.
|
|
|
|
As a base version, no comparison is required, only to build a list of configurations for
|
|
future comparison.
|
|
"""
|
|
|
|
def __init__(self, handler_type: ComparisonType):
|
|
self.handler_type = handler_type
|
|
self.properties = {}
|
|
|
|
def handle(self, yaml_obj: dict, yaml_file_name: str) -> None:
|
|
yaml_props = yaml_obj.get(self.handler_type)
|
|
|
|
if yaml_props is not None:
|
|
for prop, val in yaml_props.items():
|
|
self.properties[prop, yaml_file_name] = val
|
|
|
|
|
|
class ComputeDiffsFromIncrementedVersionHandler:
|
|
"""Interprets an .idl file representing an "incremented" version containing changes from a "base" version.
|
|
|
|
This handler performs comparison between the "incremented" state and a base state, and thus
|
|
requires knowledge of a base dictionary of properties (base_properties) to execute.
|
|
"""
|
|
|
|
def __init__(self, handler_type: ComparisonType, base_properties: dict, calc_diff_fn: callable):
|
|
self.calc_diff = calc_diff_fn
|
|
self.handler_type = handler_type
|
|
self.properties_diff = PropertiesDiffs(base_properties, {}, {})
|
|
|
|
def _compare_and_partition(self, yaml_props: dict, yaml_file_name: str) -> None:
|
|
for yaml_key, yaml_val in yaml_props.items():
|
|
compare_key = (yaml_key, yaml_file_name)
|
|
|
|
# If the yaml file property does not exist in "removed" base version properties,
|
|
# it must have been added in the incremented version
|
|
if compare_key not in self.properties_diff.removed:
|
|
self.properties_diff.added[compare_key] = yaml_val
|
|
continue
|
|
|
|
# Otherwise, we can remove it from 'removed' since it exists in both
|
|
# version properties, and check if there is a diff
|
|
# This will leave properties_diff.removed containing only entries that were
|
|
# present in the base version properties, but not in the incremented version properties,
|
|
# which means they were removed in the incremented version
|
|
in_both_prop = self.properties_diff.removed.pop(compare_key)
|
|
changed_properties = self.calc_diff(in_both_prop, yaml_val)
|
|
|
|
if len(changed_properties) > 0:
|
|
self.properties_diff.modified[compare_key] = changed_properties
|
|
|
|
def handle(self, yaml_obj: dict, yaml_file_name: str) -> None:
|
|
yaml_props = yaml_obj.get(self.handler_type.value)
|
|
if yaml_props is not None:
|
|
self._compare_and_partition(yaml_props, yaml_file_name)
|
|
|
|
|
|
def load_yaml(dirs: list, exclusions: list, idl_yaml_handlers: list) -> None:
|
|
"""Walks each path from top to bottom, applying each handler in idl_yaml_handlers to any .idl files encountered.
|
|
|
|
If a directory encountered contains any string in exclusions, it is skipped and will not
|
|
be included in the walk.
|
|
"""
|
|
for directory in dirs:
|
|
for dirpath, dirnames, filenames in os.walk(directory):
|
|
for dirname in dirnames:
|
|
for exclusion in exclusions:
|
|
if exclusion in dirpath + os.path.sep + dirname:
|
|
dirnames.remove(dirname)
|
|
break
|
|
|
|
for name in filenames:
|
|
if not name.endswith(".idl"):
|
|
continue
|
|
|
|
with io.open(os.path.join(dirpath, name), "r", encoding="utf-8") as idl_yaml_stream:
|
|
idl_yaml = yaml.safe_load(idl_yaml_stream)
|
|
for handler in idl_yaml_handlers:
|
|
handler.handle(idl_yaml, name)
|
|
|
|
|
|
def get_properties_diffs(
|
|
mode: ComparisonType, base_version_dirs: list, inc_version_dirs: list, exclude: list
|
|
) -> PropertiesDiffs:
|
|
"""Returns a PropertiesDiffs object containing the changes between properties in base_version_dirs and inc_version_dirs."""
|
|
|
|
compare_fields = []
|
|
if mode == ComparisonType.SERVER_PARAMETERS:
|
|
compare_fields = _COMPARE_FIELDS_SERVER_PARAMETERS
|
|
elif mode == ComparisonType.CONFIGS:
|
|
compare_fields = _COMPARE_FIELDS_CONFIGS
|
|
else:
|
|
raise Exception(f"Unknown option {mode}")
|
|
|
|
diff_fn = build_diff_fn(compare_fields)
|
|
|
|
base_handler = BuildBasePropertiesForComparisonHandler(mode)
|
|
load_yaml(base_version_dirs, exclude, [base_handler])
|
|
|
|
increment_handler = ComputeDiffsFromIncrementedVersionHandler(
|
|
mode, base_handler.properties, diff_fn
|
|
)
|
|
load_yaml(inc_version_dirs, exclude, [increment_handler])
|
|
|
|
return increment_handler.properties_diff
|
|
|
|
|
|
def output_diffs(mode: ComparisonType, diff: PropertiesDiffs) -> None:
|
|
pp = pprint.PrettyPrinter()
|
|
|
|
mode_format = ""
|
|
if mode == ComparisonType.CONFIGS:
|
|
mode_format = "config"
|
|
elif mode == ComparisonType.SERVER_PARAMETERS:
|
|
mode_format = "server parameter"
|
|
else:
|
|
raise Exception(f"Unknown option {mode}")
|
|
|
|
for sp, val in diff.added.items():
|
|
if not val.get("test_only"):
|
|
print(f"Added {mode_format} {str(sp)}")
|
|
pp.pprint(val)
|
|
print()
|
|
|
|
for sp, val in diff.removed.items():
|
|
if not val.get("test_only"):
|
|
print(f"Removed {mode_format} {str(sp)}")
|
|
pp.pprint(val)
|
|
print()
|
|
|
|
for sp, val in diff.modified.items():
|
|
if not val.get("test_only"):
|
|
print(f"Modified {mode_format} {str(sp)}")
|
|
for property_name, delta in val.items():
|
|
print(f"<{property_name}> changed from [{delta.base}] to [{delta.inc}]")
|
|
print()
|
|
|
|
|
|
def main():
|
|
arg_parser = argparse.ArgumentParser(prog="Core Server IDL Parameter/Config Diff")
|
|
|
|
arg_parser.add_argument(
|
|
"mode", choices=[ComparisonType.SERVER_PARAMETERS.value, ComparisonType.CONFIGS.value]
|
|
)
|
|
arg_parser.add_argument(
|
|
"-b",
|
|
"--base_version_dirs",
|
|
help="A colon-separated list of paths to the base version for comparison",
|
|
required=True,
|
|
)
|
|
|
|
arg_parser.add_argument(
|
|
"-i",
|
|
"--incremented_version_dirs",
|
|
help="A colon-separated list of paths to the incremented version for comparison",
|
|
required=True,
|
|
)
|
|
arg_parser.add_argument(
|
|
"-e",
|
|
"--exclude_dirs",
|
|
help="A colon-separated list of directory path strings to exclude from comparison, "
|
|
+ "e.g. a path /foo/bar/dir will be excluded by an argument of any of foo/bar/dir, bar/dir,"
|
|
+ "foo, or bar, or dir ",
|
|
required=False,
|
|
)
|
|
|
|
args = arg_parser.parse_args()
|
|
|
|
incremented_version_dirs = str.split(args.incremented_version_dirs, ":")
|
|
base_version_dirs = str.split(args.base_version_dirs, ":")
|
|
exclude = set(args.exclude_dirs.split(":")) if args.exclude_dirs else set()
|
|
mode = ComparisonType(args.mode)
|
|
|
|
diffs = get_properties_diffs(mode, base_version_dirs, incremented_version_dirs, exclude)
|
|
output_diffs(mode, diffs)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|
|
|
|
#########################################################################################
|
|
# python3 -m unittest buildscripts/config_diff.py
|
|
#########################################################################################
|
|
class TestBuildBasePropertiesForComparisonHandler(unittest.TestCase):
|
|
def test_yaml_obj_filters_comparison_types_correctly(self):
|
|
filename = "test.yml"
|
|
document = """
|
|
global:
|
|
cpp_namespace: "mongo"
|
|
|
|
server_parameters:
|
|
changeStreamOptions:
|
|
description: "Cluster server parameter for change stream options"
|
|
set_at: cluster
|
|
omit_in_ftdc: false
|
|
cpp_class:
|
|
name: ChangeStreamOptionsParameter
|
|
override_set: true
|
|
override_validate: true
|
|
|
|
configs:
|
|
"net.compression.compressors":
|
|
description: 'Comma-separated list of compressors to use for network messages'
|
|
source: [ cli, ini, yaml ]
|
|
arg_vartype: String
|
|
short_name: networkMessageCompressors
|
|
default: 'snappy,zstd,zlib'
|
|
"""
|
|
yaml_obj = yaml.load(document, Loader=yaml.FullLoader)
|
|
|
|
fixture = BuildBasePropertiesForComparisonHandler(ComparisonType.SERVER_PARAMETERS)
|
|
fixture.handle(yaml_obj, filename)
|
|
|
|
# should filter out configs, but parse server parameters
|
|
self.assertIsNone(fixture.properties.get(("net.compression.compressors", filename)))
|
|
self.assertIsNotNone(fixture.properties[("changeStreamOptions", filename)])
|
|
|
|
fixture = BuildBasePropertiesForComparisonHandler(ComparisonType.CONFIGS)
|
|
fixture.handle(yaml_obj, filename)
|
|
|
|
# should filter out server parameters, but parse configs
|
|
self.assertIsNone(fixture.properties.get(("changeStreamOptions", filename)))
|
|
self.assertIsNotNone(fixture.properties.get(("net.compression.compressors", filename)))
|
|
|
|
def test_empty_yaml_obj_does_nothing(self):
|
|
filename = "test.yml"
|
|
document = """
|
|
global:
|
|
cpp_namespace: "mongo"
|
|
"""
|
|
|
|
yaml_obj = yaml.load(document, Loader=yaml.FullLoader)
|
|
|
|
fixture = BuildBasePropertiesForComparisonHandler(ComparisonType.SERVER_PARAMETERS)
|
|
fixture.handle(yaml_obj, filename)
|
|
self.assertTrue(len(fixture.properties) == 0)
|
|
|
|
fixture = BuildBasePropertiesForComparisonHandler(ComparisonType.CONFIGS)
|
|
fixture.handle(yaml_obj, filename)
|
|
self.assertTrue(len(fixture.properties) == 0)
|
|
|
|
|
|
class TestComputeDiffsFromIncrementedVersionHandler(unittest.TestCase):
|
|
def setUp(self):
|
|
self.parameter_diff_function = build_diff_fn(_COMPARE_FIELDS_SERVER_PARAMETERS)
|
|
self.config_diff_function = build_diff_fn(_COMPARE_FIELDS_CONFIGS)
|
|
|
|
def test_yaml_obj_filtered_correctly(self):
|
|
filename = "inc.yml"
|
|
document = """
|
|
server_parameters:
|
|
testOptions:
|
|
description: "Cluster server parameter for change stream options"
|
|
set_at: cluster
|
|
omit_in_ftdc: false
|
|
cpp_class:
|
|
name: ChangeStreamOptionsParameter
|
|
override_set: true
|
|
override_validate: true
|
|
helloMorld:
|
|
description: "yep"
|
|
set_at: allthetime
|
|
cpp_class:
|
|
name: ChangeStreamOptionsParameter
|
|
override_set: true
|
|
override_validate: true
|
|
|
|
configs:
|
|
"asdf":
|
|
description: 'Comma-separated list of compressors to use for network messages'
|
|
source: [ cli, ini, yaml ]
|
|
arg_vartype: String
|
|
short_name: networkMessageCompressors
|
|
default: 'snappy,zstd,zlib'
|
|
"qwer":
|
|
description: 'ok'
|
|
source: [ cli, yaml ]
|
|
arg_vartype: String
|
|
short_name: networkMessageCompressors
|
|
default: 'zlib'
|
|
"""
|
|
|
|
inc_yaml_obj = yaml.load(document, Loader=yaml.FullLoader)
|
|
|
|
inc_fixture = ComputeDiffsFromIncrementedVersionHandler(
|
|
ComparisonType.CONFIGS, {}, self.config_diff_function
|
|
)
|
|
inc_fixture.handle(inc_yaml_obj, filename)
|
|
|
|
properties_diffs = inc_fixture.properties_diff
|
|
self.assertIsNotNone(properties_diffs.added.get(("asdf", filename)))
|
|
self.assertIsNotNone(properties_diffs.added.get(("qwer", filename)))
|
|
|
|
self.assertIsNone(properties_diffs.added.get(("testOptions", filename)))
|
|
self.assertIsNone(properties_diffs.added.get(("helloMorld", filename)))
|
|
|
|
inc_fixture = ComputeDiffsFromIncrementedVersionHandler(
|
|
ComparisonType.SERVER_PARAMETERS, {}, self.parameter_diff_function
|
|
)
|
|
inc_fixture.handle(inc_yaml_obj, filename)
|
|
|
|
properties_diffs = inc_fixture.properties_diff
|
|
|
|
self.assertIsNone(properties_diffs.added.get(("asdf", filename)))
|
|
self.assertIsNone(properties_diffs.added.get(("qwer", filename)))
|
|
|
|
self.assertIsNotNone(properties_diffs.added.get(("testOptions", filename)))
|
|
self.assertIsNotNone(properties_diffs.added.get(("helloMorld", filename)))
|
|
|
|
def test_added_works_correctly(self):
|
|
filename = "test.yaml"
|
|
document = """
|
|
server_parameters:
|
|
testOptions:
|
|
description: "Cluster server parameter for change stream options"
|
|
set_at: cluster
|
|
omit_in_ftdc: false
|
|
cpp_class:
|
|
name: ChangeStreamOptionsParameter
|
|
override_set: true
|
|
override_validate: true
|
|
|
|
configs:
|
|
"asdf":
|
|
description: 'Comma-separated list of compressors to use for network messages'
|
|
source: [ cli, ini, yaml ]
|
|
arg_vartype: String
|
|
short_name: networkMessageCompressors
|
|
default: 'snappy,zstd,zlib'
|
|
"""
|
|
|
|
inc_yaml_obj = yaml.load(document, Loader=yaml.FullLoader)
|
|
|
|
inc_fixture = ComputeDiffsFromIncrementedVersionHandler(
|
|
ComparisonType.CONFIGS, {}, self.config_diff_function
|
|
)
|
|
inc_fixture.handle(inc_yaml_obj, filename)
|
|
|
|
properties_diffs = inc_fixture.properties_diff
|
|
|
|
self.assertIsNotNone(properties_diffs.added.get(("asdf", filename)))
|
|
self.assertTrue(len(properties_diffs.added) == 1)
|
|
self.assertTrue(len(properties_diffs.removed) == 0)
|
|
self.assertTrue(len(properties_diffs.modified) == 0)
|
|
|
|
inc_fixture = ComputeDiffsFromIncrementedVersionHandler(
|
|
ComparisonType.SERVER_PARAMETERS, {}, self.parameter_diff_function
|
|
)
|
|
inc_fixture.handle(inc_yaml_obj, filename)
|
|
|
|
properties_diffs = inc_fixture.properties_diff
|
|
self.assertTrue(len(properties_diffs.added) == 1)
|
|
self.assertIsNotNone(properties_diffs.added.get(("testOptions", filename)))
|
|
self.assertTrue(len(properties_diffs.removed) == 0)
|
|
self.assertTrue(len(properties_diffs.modified) == 0)
|
|
|
|
def test_removed_works_correctly(self):
|
|
filename = "test.yaml"
|
|
document = """
|
|
server_parameters:
|
|
configs:
|
|
"""
|
|
|
|
def get_base_data():
|
|
return {("ok", "test.yaml"): {"yes": "no"}, ("also_ok", "blah.yaml"): {"no": "yes"}}
|
|
|
|
inc_yaml_obj = yaml.load(document, Loader=yaml.FullLoader)
|
|
|
|
inc_fixture = ComputeDiffsFromIncrementedVersionHandler(
|
|
ComparisonType.CONFIGS, get_base_data(), self.config_diff_function
|
|
)
|
|
inc_fixture.handle(inc_yaml_obj, filename)
|
|
|
|
properties_diffs = inc_fixture.properties_diff
|
|
|
|
self.assertIsNotNone(properties_diffs.removed.get(("ok", filename)))
|
|
self.assertIsNotNone(properties_diffs.removed.get(("also_ok", "blah.yaml")))
|
|
|
|
self.assertTrue(len(properties_diffs.removed) == 2)
|
|
self.assertTrue(len(properties_diffs.added) == 0)
|
|
self.assertTrue(len(properties_diffs.modified) == 0)
|
|
|
|
inc_fixture = ComputeDiffsFromIncrementedVersionHandler(
|
|
ComparisonType.SERVER_PARAMETERS, get_base_data(), self.parameter_diff_function
|
|
)
|
|
inc_fixture.handle(inc_yaml_obj, filename)
|
|
|
|
properties_diffs = inc_fixture.properties_diff
|
|
|
|
self.assertIsNotNone(properties_diffs.removed.get(("ok", filename)))
|
|
self.assertIsNotNone(properties_diffs.removed.get(("also_ok", "blah.yaml")))
|
|
|
|
self.assertTrue(len(properties_diffs.removed) == 2)
|
|
self.assertTrue(len(properties_diffs.added) == 0)
|
|
self.assertTrue(len(properties_diffs.modified) == 0)
|
|
|
|
def test_empty_modified_works_correctly(self):
|
|
filename = "test.yaml"
|
|
document = """
|
|
server_parameters:
|
|
testOptions:
|
|
description: "Cluster server parameter for change stream options"
|
|
set_at: cluster
|
|
omit_in_ftdc: false
|
|
cpp_class:
|
|
name: ChangeStreamOptionsParameter
|
|
override_set: true
|
|
override_validate: true
|
|
|
|
testParameter:
|
|
description: "Some parameter"
|
|
set_at: cluster
|
|
omit_in_ftdc: false
|
|
cpp_class:
|
|
name: ChangeStreamOptionsParameter
|
|
override_set: true
|
|
override_validate: true
|
|
|
|
configs:
|
|
"asdf":
|
|
description: 'Comma-separated list of compressors to use for network messages'
|
|
source: [ cli, ini, yaml ]
|
|
arg_vartype: String
|
|
short_name: networkMessageCompressors
|
|
default: 'snappy,zstd,zlib'
|
|
|
|
"zxcv":
|
|
description: 'Comma-separated list of compressors to use for network messages'
|
|
source: [ cli, ini, yaml ]
|
|
arg_vartype: String
|
|
short_name: networkMessageCompressors
|
|
default: 'snappy,zstd,zlib'
|
|
"""
|
|
inc_yaml_obj = yaml.load(document, Loader=yaml.FullLoader)
|
|
|
|
inc_fixture = ComputeDiffsFromIncrementedVersionHandler(
|
|
ComparisonType.CONFIGS, {}, build_diff_fn(["default"])
|
|
)
|
|
inc_fixture.handle(inc_yaml_obj, filename)
|
|
|
|
properties_diffs = inc_fixture.properties_diff
|
|
|
|
self.assertIsNotNone(properties_diffs.added.get(("asdf", filename)))
|
|
self.assertTrue(len(properties_diffs.removed) == 0)
|
|
self.assertTrue(len(properties_diffs.modified) == 0)
|
|
|
|
inc_fixture = ComputeDiffsFromIncrementedVersionHandler(
|
|
ComparisonType.SERVER_PARAMETERS, {}, build_diff_fn(["set_at"])
|
|
)
|
|
inc_fixture.handle(inc_yaml_obj, filename)
|
|
|
|
properties_diffs = inc_fixture.properties_diff
|
|
|
|
self.assertIsNotNone(properties_diffs.added.get(("testOptions", filename)))
|
|
self.assertTrue(len(properties_diffs.removed) == 0)
|
|
self.assertTrue(len(properties_diffs.modified) == 0)
|
|
|
|
def test_not_modified_between_yamls_reports_correctly(self):
|
|
filename = "test.yaml"
|
|
document = """
|
|
server_parameters:
|
|
testOptions:
|
|
description: "Cluster server parameter for change stream options"
|
|
set_at: cluster
|
|
omit_in_ftdc: false
|
|
cpp_class:
|
|
name: ChangeStreamOptionsParameter
|
|
override_set: true
|
|
override_validate: true
|
|
|
|
testParameter:
|
|
description: "Some parameter"
|
|
set_at: cluster
|
|
omit_in_ftdc: false
|
|
cpp_class:
|
|
name: ChangeStreamOptionsParameter
|
|
override_set: true
|
|
override_validate: true
|
|
|
|
configs:
|
|
"asdf":
|
|
description: 'Comma-separated list of compressors to use for network messages'
|
|
source: [ cli, ini, yaml ]
|
|
arg_vartype: String
|
|
short_name: networkMessageCompressors
|
|
default: 'snappy,zstd,zlib'
|
|
|
|
"zxcv":
|
|
description: 'Comma-separated list of compressors to use for network messages'
|
|
source: [ cli, ini, yaml ]
|
|
arg_vartype: String
|
|
short_name: networkMessageCompressors
|
|
default: 'snappy,zstd,zlib'
|
|
"""
|
|
|
|
document_inc = document
|
|
|
|
document_yaml = yaml.load(document, Loader=yaml.FullLoader)
|
|
document_inc_yaml = yaml.load(document_inc, Loader=yaml.FullLoader)
|
|
|
|
diff_fn = build_diff_fn(_COMPARE_FIELDS_CONFIGS)
|
|
|
|
config_base_properties_handler = BuildBasePropertiesForComparisonHandler(
|
|
ComparisonType.CONFIGS
|
|
)
|
|
config_base_properties_handler.handle(document_yaml, filename)
|
|
|
|
config_inc_properties_handler = ComputeDiffsFromIncrementedVersionHandler(
|
|
ComparisonType.CONFIGS, config_base_properties_handler.properties, diff_fn
|
|
)
|
|
config_inc_properties_handler.handle(document_inc_yaml, filename)
|
|
|
|
property_diff = config_inc_properties_handler.properties_diff
|
|
|
|
self.assertEqual(0, len(property_diff.modified))
|
|
|
|
diff_fn = build_diff_fn(_COMPARE_FIELDS_SERVER_PARAMETERS)
|
|
|
|
sp_base_properties_handler = BuildBasePropertiesForComparisonHandler(
|
|
ComparisonType.SERVER_PARAMETERS
|
|
)
|
|
sp_base_properties_handler.handle(document_yaml, filename)
|
|
|
|
sp_inc_properties_handler = ComputeDiffsFromIncrementedVersionHandler(
|
|
ComparisonType.SERVER_PARAMETERS, sp_base_properties_handler.properties, diff_fn
|
|
)
|
|
sp_inc_properties_handler.handle(document_inc_yaml, filename)
|
|
|
|
property_diff = sp_inc_properties_handler.properties_diff
|
|
|
|
self.assertEqual(0, len(property_diff.modified))
|
|
|
|
def test_modified_between_yamls_reports_correctly(self):
|
|
filename = "test.yaml"
|
|
document = """
|
|
server_parameters:
|
|
testOptions:
|
|
description: "Cluster server parameter for change stream options"
|
|
set_at: cluster
|
|
omit_in_ftdc: false
|
|
cpp_class:
|
|
name: ChangeStreamOptionsParameter
|
|
override_set: true
|
|
override_validate: true
|
|
|
|
testParameter:
|
|
description: "Some parameter"
|
|
set_at: cluster
|
|
omit_in_ftdc: false
|
|
cpp_class:
|
|
name: ChangeStreamOptionsParameter
|
|
override_set: true
|
|
override_validate: true
|
|
|
|
configs:
|
|
"asdf":
|
|
description: 'Comma-separated list of compressors to use for network messages'
|
|
source: [ cli, ini, yaml ]
|
|
arg_vartype: String
|
|
short_name: networkMessageCompressors
|
|
default: 'snappy,zstd,zlib'
|
|
|
|
"zxcv":
|
|
description: 'Comma-separated list of compressors to use for network messages'
|
|
source: [ cli, ini, yaml ]
|
|
arg_vartype: String
|
|
short_name: networkMessageCompressors
|
|
default: 'snappy,zstd,zlib'
|
|
"""
|
|
|
|
document_inc = """
|
|
server_parameters:
|
|
testOptions:
|
|
description: "Cluster server parameter for change stream options"
|
|
set_at: runtime
|
|
cpp_class:
|
|
name: ChangeStreamOptionsParameter
|
|
override_set: true
|
|
override_validate: true
|
|
|
|
testParameter:
|
|
description: "Some parameter"
|
|
set_at: cluster
|
|
omit_in_ftdc: false
|
|
cpp_class:
|
|
name: ChangeStreamOptionsParameter
|
|
override_set: true
|
|
override_validate: true
|
|
|
|
configs:
|
|
"asdf":
|
|
description: 'Comma-separated list of compressors to use for network messages'
|
|
source: [ cli, ini, yaml ]
|
|
arg_vartype: int
|
|
short_name: networkMessageCompressors
|
|
default: 'snappy,zstd,zlib'
|
|
|
|
"zxcv":
|
|
description: 'Comma-separated list of compressors to use for network messages'
|
|
source: [ cli, ini, yaml ]
|
|
arg_vartype: String
|
|
short_name: networkMessageCompressors
|
|
default: 'snappy,zstd,zlib'
|
|
"""
|
|
|
|
document_yaml = yaml.load(document, Loader=yaml.FullLoader)
|
|
document_inc_yaml = yaml.load(document_inc, Loader=yaml.FullLoader)
|
|
|
|
diff_fn = build_diff_fn(_COMPARE_FIELDS_CONFIGS)
|
|
|
|
config_base_properties_handler = BuildBasePropertiesForComparisonHandler(
|
|
ComparisonType.CONFIGS
|
|
)
|
|
config_base_properties_handler.handle(document_yaml, filename)
|
|
|
|
config_inc_properties_handler = ComputeDiffsFromIncrementedVersionHandler(
|
|
ComparisonType.CONFIGS, config_base_properties_handler.properties, diff_fn
|
|
)
|
|
config_inc_properties_handler.handle(document_inc_yaml, filename)
|
|
|
|
property_diff = config_inc_properties_handler.properties_diff
|
|
|
|
self.assertEqual(
|
|
property_diff.modified.get(("asdf", filename)).get("arg_vartype").base, "String"
|
|
)
|
|
self.assertEqual(
|
|
property_diff.modified.get(("asdf", filename)).get("arg_vartype").inc, "int"
|
|
)
|
|
self.assertIsNone(property_diff.modified.get(("zxcv", filename)))
|
|
|
|
diff_fn = build_diff_fn(_COMPARE_FIELDS_SERVER_PARAMETERS)
|
|
|
|
sp_base_properties_handler = BuildBasePropertiesForComparisonHandler(
|
|
ComparisonType.SERVER_PARAMETERS
|
|
)
|
|
sp_base_properties_handler.handle(document_yaml, filename)
|
|
|
|
sp_inc_properties_handler = ComputeDiffsFromIncrementedVersionHandler(
|
|
ComparisonType.SERVER_PARAMETERS, sp_base_properties_handler.properties, diff_fn
|
|
)
|
|
sp_inc_properties_handler.handle(document_inc_yaml, filename)
|
|
|
|
property_diff = sp_inc_properties_handler.properties_diff
|
|
|
|
self.assertEqual(
|
|
property_diff.modified.get(("testOptions", filename)).get("set_at").base, "cluster"
|
|
)
|
|
self.assertEqual(
|
|
property_diff.modified.get(("testOptions", filename)).get("set_at").inc, "runtime"
|
|
)
|
|
self.assertIsNone(property_diff.modified.get(("testParameter", filename)))
|
|
|
|
|
|
class TestPropertiesDiffFunction(unittest.TestCase):
|
|
def test_empty_returns_empty(self):
|
|
fn = build_diff_fn([])
|
|
diffs = fn({"same": "different"}, {"same": "different"})
|
|
self.assertTrue(len(diffs) == 0)
|
|
|
|
def test_return_one_diff(self):
|
|
fn = build_diff_fn(["same"])
|
|
diffs = fn({"same": "dofferent"}, {"same": "different"})
|
|
self.assertTrue(len(diffs) == 1)
|
|
self.assertTrue(diffs["same"].base == "dofferent")
|
|
self.assertTrue(diffs["same"].inc == "different")
|
|
|
|
def test_return_two_diffs(self):
|
|
fn = build_diff_fn(["same", "a"])
|
|
diffs = fn({"same": "dofferent", "a": "1"}, {"same": "different", "a": "2"})
|
|
self.assertTrue(len(diffs) == 2)
|
|
self.assertTrue(diffs["same"].base == "dofferent")
|
|
self.assertTrue(diffs["same"].inc == "different")
|
|
self.assertTrue(diffs["a"].base == "1")
|
|
self.assertTrue(diffs["a"].inc == "2")
|
|
|
|
def test_only_base_returns_diff(self):
|
|
fn = build_diff_fn(["a"])
|
|
diffs = fn({"a": "1"}, {})
|
|
self.assertTrue(len(diffs) == 1)
|
|
self.assertTrue(diffs["a"].base == "1")
|
|
self.assertTrue(diffs["a"].inc == "")
|
|
|
|
def test_only_inc_returns_diff(self):
|
|
fn = build_diff_fn(["a"])
|
|
diffs = fn({}, {"a": "1"})
|
|
self.assertTrue(len(diffs) == 1)
|
|
self.assertTrue(diffs["a"].inc == "1")
|
|
self.assertTrue(diffs["a"].base == "")
|
|
|
|
def test_nonincluided_field_is_not_diff(self):
|
|
fn = build_diff_fn(["b"])
|
|
diffs = fn({}, {"a": "1"})
|
|
self.assertTrue(len(diffs) == 0)
|
|
|
|
def test_base_version_nexist_added_none(self):
|
|
fn = build_diff_fn(["a"])
|
|
diffs = fn({}, {"a": "None"})
|
|
self.assertTrue(diffs["a"].inc == "None")
|
|
self.assertTrue(diffs["a"].base == "")
|
|
self.assertTrue(len(diffs) == 1)
|
|
|
|
|
|
class TestCLIFunctions(unittest.TestCase):
|
|
def test_unknown_comparison_type_throws(self):
|
|
with self.assertRaises(Exception):
|
|
output_diffs(None, PropertiesDiffs({}, {}, {}))
|
|
|
|
with self.assertRaises(Exception):
|
|
get_properties_diffs(None, [], [], [])
|