summaryrefslogtreecommitdiff
path: root/buildscripts
diff options
context:
space:
mode:
Diffstat (limited to 'buildscripts')
-rw-r--r--buildscripts/idl/idl_check_compatibility.py389
-rw-r--r--buildscripts/idl/tests/compatibility_test_fail/new/compatibility_test_fail_new.idl314
-rw-r--r--buildscripts/idl/tests/compatibility_test_fail/old/compatibility_test_fail_old.idl311
-rw-r--r--buildscripts/idl/tests/compatibility_test_pass/new/compatibility_test_pass_new.idl102
-rw-r--r--buildscripts/idl/tests/compatibility_test_pass/old/compatibility_test_pass_old.idl85
-rw-r--r--buildscripts/idl/tests/test_compatibility.py182
6 files changed, 1241 insertions, 142 deletions
diff --git a/buildscripts/idl/idl_check_compatibility.py b/buildscripts/idl/idl_check_compatibility.py
index eb807eb0dd9..f57cf0663e9 100644
--- a/buildscripts/idl/idl_check_compatibility.py
+++ b/buildscripts/idl/idl_check_compatibility.py
@@ -39,6 +39,7 @@ directories containing the old IDL files from previous releases.
import argparse
import os
import sys
+from dataclasses import dataclass
from typing import Dict, List, Optional, Tuple, Union
from idl import parser, syntax, errors, common
@@ -65,6 +66,15 @@ ALLOW_ANY_TYPE_LIST: List[str] = [
"replyFieldCppTypeNotEqual-reply-cppTypeNotEqualReplyField",
"commandCppTypeNotEqual",
"commandParameterCppTypeNotEqual-param-cppTypeNotEqualParam",
+ "newlyAddedReplyFieldTypeBsonAnyAllowed-reply-newlyAddedBsonSerializationTypeAnyReplyField",
+ "replyFieldTypeBsonAnyWithVariantUnstable-reply-bsonSerializationTypeWithVariantAnyUnstableReplyField",
+ "newlyAddedParamBsonAnyAllowList-param-newlyAddedBsonAnyAllowListParam",
+ "newlyAddedTypeFieldBsonAnyAllowList",
+ "parameterFieldTypeBsonAnyWithVariantUnstable-param-bsonSerializationTypeAnyStructField",
+ "commandTypeBsonAnyWithVariantUnstable",
+ "commandParameterCppTypeNotEqualUnstable-param-cppTypeNotEqualParam",
+ "replyFieldCppTypeNotEqualUnstable-reply-cppTypeNotEqualReplyUnstableField",
+ "commandCppTypeNotEqualUnstable",
# TODO (SERVER-54956): Decide what to do with commands: (create, createIndexes).
'create-param-backwards',
@@ -130,6 +140,26 @@ ALLOW_ANY_TYPE_LIST: List[str] = [
SKIPPED_FILES = ["unittest.idl"]
+@dataclass
+class FieldCompatibility:
+ """Information about a Field to check compatibility."""
+
+ field_type: syntax.Type
+ idl_file: syntax.IDLParsedSpec
+ idl_file_path: str
+ unstable: bool
+
+
+@dataclass
+class FieldCompatibilityPair:
+ """Information about an old and new Field pair to check compatibility."""
+
+ old: FieldCompatibility
+ new: FieldCompatibility
+ cmd_name: str
+ field_name: str
+
+
def get_new_commands(
ctxt: IDLCompatibilityContext, new_idl_dir: str, import_directories: List[str]
) -> Tuple[Dict[str, syntax.Command], Dict[str, syntax.IDLParsedSpec], Dict[str, str]]:
@@ -206,28 +236,37 @@ def check_superset(ctxt: IDLCompatibilityContext, cmd_name: str, type_name: str,
param_name, is_command_parameter)
-def check_reply_field_type_recursive(
- ctxt: IDLCompatibilityContext, old_field_type: syntax.Type,
- new_field_type: Optional[Union[syntax.Enum, syntax.Struct, syntax.Type]], cmd_name: str,
- field_name: str, old_idl_file: syntax.IDLParsedSpec, new_idl_file: syntax.IDLParsedSpec,
- old_idl_file_path: str, new_idl_file_path: str) -> None:
- # pylint: disable=too-many-arguments,too-many-branches
+def check_reply_field_type_recursive(ctxt: IDLCompatibilityContext,
+ field_pair: FieldCompatibilityPair) -> None:
+ # pylint: disable=too-many-branches
"""Check compatibility between old and new reply field type if old field type is a syntax.Type instance."""
+ old_field = field_pair.old
+ new_field = field_pair.new
+ old_field_type = old_field.field_type
+ new_field_type = new_field.field_type
+ cmd_name = field_pair.cmd_name
+ field_name = field_pair.field_name
+
+ # If the old field is unstable, we only add errors related to the use of 'any' as the
+ # bson_serialization_type. For all other errors, we check that the old field is stable
+ # before adding an error.
if not isinstance(new_field_type, syntax.Type):
- ctxt.add_new_reply_field_type_enum_or_struct_error(
- cmd_name, field_name, new_field_type.name, old_field_type.name, new_idl_file_path)
+ if not old_field.unstable:
+ ctxt.add_new_reply_field_type_enum_or_struct_error(
+ cmd_name, field_name, new_field_type.name, old_field_type.name,
+ new_field.idl_file_path)
return
# If bson_serialization_type switches from 'any' to non-any type.
if "any" in old_field_type.bson_serialization_type and "any" not in new_field_type.bson_serialization_type:
ctxt.add_old_reply_field_bson_any_error(cmd_name, field_name, old_field_type.name,
- old_idl_file_path)
+ old_field.idl_file_path)
return
# If bson_serialization_type switches from non-any to 'any' type.
if "any" not in old_field_type.bson_serialization_type and "any" in new_field_type.bson_serialization_type:
ctxt.add_new_reply_field_bson_any_error(cmd_name, field_name, old_field_type.name,
- new_idl_file_path)
+ new_field.idl_file_path)
return
allow_name: str = cmd_name + "-reply-" + field_name
@@ -235,13 +274,13 @@ def check_reply_field_type_recursive(
if "any" in old_field_type.bson_serialization_type:
# If 'any' is not explicitly allowed as the bson_serialization_type.
if allow_name not in ALLOW_ANY_TYPE_LIST:
- ctxt.add_reply_field_bson_any_not_allowed_error(cmd_name, field_name,
- old_field_type.name, old_idl_file_path)
+ ctxt.add_reply_field_bson_any_not_allowed_error(
+ cmd_name, field_name, old_field_type.name, old_field.idl_file_path)
return
if old_field_type.cpp_type != new_field_type.cpp_type:
ctxt.add_reply_field_cpp_type_not_equal_error(cmd_name, field_name, new_field_type.name,
- new_idl_file_path)
+ new_field.idl_file_path)
if isinstance(old_field_type, syntax.VariantType):
# If the new type is not variant just check the single type.
@@ -254,87 +293,95 @@ def check_reply_field_type_recursive(
for old_variant_type in old_variant_types:
if old_variant_type.name == new_variant_type.name:
# Check that the old and new version of each variant type is also compatible.
- check_reply_field_type(ctxt, old_variant_type, new_variant_type, cmd_name,
- field_name, old_idl_file, new_idl_file,
- old_idl_file_path, new_idl_file_path)
+ old = FieldCompatibility(old_variant_type, old_field.idl_file,
+ old_field.idl_file_path, old_field.unstable)
+ new = FieldCompatibility(new_variant_type, new_field.idl_file,
+ new_field.idl_file_path, new_field.unstable)
+ check_reply_field_type(ctxt,
+ FieldCompatibilityPair(old, new, cmd_name, field_name))
break
else:
# new_variant_type was not found in old_variant_types.
- ctxt.add_new_reply_field_variant_type_not_subset_error(
- cmd_name, field_name, new_variant_type.name, new_idl_file_path)
+ if not old_field.unstable:
+ ctxt.add_new_reply_field_variant_type_not_subset_error(
+ cmd_name, field_name, new_variant_type.name, new_field.idl_file_path)
# If new type is variant and has a struct as a variant type, compare old and new variant_struct_type.
# Since enums can't be part of variant types, we don't explicitly check for enums.
if isinstance(new_field_type,
syntax.VariantType) and new_field_type.variant_struct_type is not None:
- if old_field_type.variant_struct_type is None:
+ if old_field_type.variant_struct_type is None and not old_field.unstable:
ctxt.add_new_reply_field_variant_type_not_subset_error(
cmd_name, field_name, new_field_type.variant_struct_type.name,
- new_idl_file_path)
+ new_field.idl_file_path)
else:
check_reply_fields(ctxt, old_field_type.variant_struct_type,
- new_field_type.variant_struct_type, cmd_name, old_idl_file,
- new_idl_file, old_idl_file_path, new_idl_file_path)
+ new_field_type.variant_struct_type, cmd_name, old_field.idl_file,
+ new_field.idl_file, old_field.idl_file_path,
+ new_field.idl_file_path)
- else:
+ elif not old_field.unstable:
if isinstance(new_field_type, syntax.VariantType):
ctxt.add_new_reply_field_variant_type_error(cmd_name, field_name, old_field_type.name,
- new_idl_file_path)
+ new_field.idl_file_path)
else:
check_subset(ctxt, cmd_name, field_name, new_field_type.name,
new_field_type.bson_serialization_type,
- old_field_type.bson_serialization_type, new_idl_file_path)
+ old_field_type.bson_serialization_type, new_field.idl_file_path)
-def check_reply_field_type(ctxt: IDLCompatibilityContext,
- old_field_type: Optional[Union[syntax.Enum, syntax.Struct, syntax.Type]],
- new_field_type: Optional[Union[syntax.Enum, syntax.Struct, syntax.Type]],
- cmd_name: str, field_name: str, old_idl_file: syntax.IDLParsedSpec,
- new_idl_file: syntax.IDLParsedSpec, old_idl_file_path: str,
- new_idl_file_path: str):
+def check_reply_field_type(ctxt: IDLCompatibilityContext, field_pair: FieldCompatibilityPair):
"""Check compatibility between old and new reply field type."""
- # pylint: disable=too-many-arguments,too-many-branches
- if check_array_type(ctxt, "reply_field", old_field_type, new_field_type, cmd_name, 'type',
- old_idl_file_path, new_idl_file_path):
- old_field_type = old_field_type.element_type
- new_field_type = new_field_type.element_type
-
+ # pylint: disable=too-many-branches
+ old_field = field_pair.old
+ new_field = field_pair.new
+ if check_array_type(ctxt, "reply_field", old_field.field_type, new_field.field_type,
+ field_pair.cmd_name, 'type', old_field.idl_file_path,
+ new_field.idl_file_path, old_field.unstable):
+ old_field.field_type = old_field.field_type.element_type
+ new_field.field_type = new_field.field_type.element_type
+
+ old_field_type = old_field.field_type
+ new_field_type = new_field.field_type
+ cmd_name = field_pair.cmd_name
+ field_name = field_pair.field_name
if old_field_type is None:
- ctxt.add_reply_field_type_invalid_error(cmd_name, field_name, old_idl_file_path)
+ ctxt.add_reply_field_type_invalid_error(cmd_name, field_name, old_field.idl_file_path)
ctxt.errors.dump_errors()
sys.exit(1)
if new_field_type is None:
- ctxt.add_reply_field_type_invalid_error(cmd_name, field_name, new_idl_file_path)
+ ctxt.add_reply_field_type_invalid_error(cmd_name, field_name, new_field.idl_file_path)
ctxt.errors.dump_errors()
sys.exit(1)
if isinstance(old_field_type, syntax.Type):
- check_reply_field_type_recursive(ctxt, old_field_type, new_field_type, cmd_name, field_name,
- old_idl_file, new_idl_file, old_idl_file_path,
- new_idl_file_path)
+ check_reply_field_type_recursive(ctxt, field_pair)
- elif isinstance(old_field_type, syntax.Enum):
+ elif isinstance(old_field_type, syntax.Enum) and not old_field.unstable:
if isinstance(new_field_type, syntax.Enum):
check_subset(ctxt, cmd_name, field_name, new_field_type.name, new_field_type.values,
- old_field_type.values, new_idl_file_path)
+ old_field_type.values, new_field.idl_file_path)
else:
ctxt.add_new_reply_field_type_not_enum_error(cmd_name, field_name, new_field_type.name,
- old_field_type.name, new_idl_file_path)
+ old_field_type.name,
+ new_field.idl_file_path)
elif isinstance(old_field_type, syntax.Struct):
if isinstance(new_field_type, syntax.Struct):
- check_reply_fields(ctxt, old_field_type, new_field_type, cmd_name, old_idl_file,
- new_idl_file, old_idl_file_path, new_idl_file_path)
+ check_reply_fields(ctxt, old_field_type, new_field_type, cmd_name, old_field.idl_file,
+ new_field.idl_file, old_field.idl_file_path, new_field.idl_file_path)
else:
- ctxt.add_new_reply_field_type_not_struct_error(
- cmd_name, field_name, new_field_type.name, old_field_type.name, new_idl_file_path)
+ if not old_field.unstable:
+ ctxt.add_new_reply_field_type_not_struct_error(
+ cmd_name, field_name, new_field_type.name, old_field_type.name,
+ new_field.idl_file_path)
def check_array_type(ctxt: IDLCompatibilityContext, symbol: str,
old_type: Optional[Union[syntax.Enum, syntax.Struct, syntax.Type]],
new_type: Optional[Union[syntax.Enum, syntax.Struct, syntax.Type]],
cmd_name: str, symbol_name: str, old_idl_file_path: str,
- new_idl_file_path: str) -> bool:
+ new_idl_file_path: str, old_field_unstable: bool) -> bool:
"""Check compatibility between old and new ArrayTypes."""
# pylint: disable=too-many-arguments,too-many-branches
old_is_array = isinstance(old_type, syntax.ArrayType)
@@ -342,7 +389,7 @@ def check_array_type(ctxt: IDLCompatibilityContext, symbol: str,
if not old_is_array and not new_is_array:
return False
- if not old_is_array or not new_is_array:
+ if (not old_is_array or not new_is_array) and not old_field_unstable:
ctxt.add_type_not_array_error(symbol, cmd_name, symbol_name, new_type.name, old_type.name,
new_idl_file_path if old_is_array else old_idl_file_path)
ctxt.errors.dump_errors()
@@ -357,25 +404,32 @@ def check_reply_field(ctxt: IDLCompatibilityContext, old_field: syntax.Field,
new_idl_file_path: str):
"""Check compatibility between old and new reply field."""
# pylint: disable=too-many-arguments
- if new_field.unstable:
- ctxt.add_new_reply_field_unstable_error(cmd_name, new_field.name, new_idl_file_path)
- if new_field.optional and not old_field.optional:
- ctxt.add_new_reply_field_optional_error(cmd_name, new_field.name, new_idl_file_path)
-
- if new_field.validator:
- if old_field.validator:
- if new_field.validator != old_field.validator:
- ctxt.add_reply_field_validators_not_equal_error(cmd_name, new_field.name,
- new_idl_file_path)
- else:
- ctxt.add_reply_field_contains_validator_error(cmd_name, new_field.name,
- new_idl_file_path)
+ if not old_field.unstable:
+ if new_field.unstable:
+ ctxt.add_new_reply_field_unstable_error(cmd_name, new_field.name, new_idl_file_path)
+ if new_field.optional and not old_field.optional:
+ ctxt.add_new_reply_field_optional_error(cmd_name, new_field.name, new_idl_file_path)
+
+ if new_field.validator:
+ if old_field.validator:
+ if new_field.validator != old_field.validator:
+ ctxt.add_reply_field_validators_not_equal_error(cmd_name, new_field.name,
+ new_idl_file_path)
+ else:
+ ctxt.add_reply_field_contains_validator_error(cmd_name, new_field.name,
+ new_idl_file_path)
old_field_type = get_field_type(old_field, old_idl_file, old_idl_file_path)
new_field_type = get_field_type(new_field, new_idl_file, new_idl_file_path)
- check_reply_field_type(ctxt, old_field_type, new_field_type, cmd_name, old_field.name,
- old_idl_file, new_idl_file, old_idl_file_path, new_idl_file_path)
+ old_field_compatibility = FieldCompatibility(old_field_type, old_idl_file, old_idl_file_path,
+ old_field.unstable)
+ new_field_compatibility = FieldCompatibility(new_field_type, new_idl_file, new_idl_file_path,
+ new_field.unstable)
+ field_pair = FieldCompatibilityPair(old_field_compatibility, new_field_compatibility, cmd_name,
+ old_field.name)
+
+ check_reply_field_type(ctxt, field_pair)
def check_reply_fields(ctxt: IDLCompatibilityContext, old_reply: syntax.Struct,
@@ -385,9 +439,6 @@ def check_reply_fields(ctxt: IDLCompatibilityContext, old_reply: syntax.Struct,
"""Check compatibility between old and new reply fields."""
# pylint: disable=too-many-arguments
for old_field in old_reply.fields or []:
- if old_field.unstable:
- continue
-
new_field_exists = False
for new_field in new_reply.fields or []:
if new_field.name == old_field.name:
@@ -397,40 +448,68 @@ def check_reply_fields(ctxt: IDLCompatibilityContext, old_reply: syntax.Struct,
break
- if not new_field_exists:
+ if not new_field_exists and not old_field.unstable:
ctxt.add_new_reply_field_missing_error(cmd_name, old_field.name, old_idl_file_path)
+ # Check that newly added fields do not have an unallowed use of 'any' as the bson_serialization_type.
+ for new_field in new_reply.fields or []:
+ newly_added = True
+ for old_field in old_reply.fields or []:
+ if new_field.name == old_field.name:
+ newly_added = False
-def check_param_or_command_type_recursive(
- ctxt: IDLCompatibilityContext,
- old_type: Optional[Union[syntax.Enum, syntax.Struct, syntax.Type]],
- new_type: Optional[Union[syntax.Enum, syntax.Struct, syntax.Type]], cmd_name: str,
- old_idl_file: syntax.IDLParsedSpec, new_idl_file: syntax.IDLParsedSpec,
- old_idl_file_path: str, new_idl_file_path: str, param_name: Optional[str],
- is_command_parameter: bool):
- # pylint: disable=too-many-arguments,too-many-branches
+ if newly_added:
+ allow_name: str = cmd_name + "-reply-" + new_field.name
+
+ new_field_type = get_field_type(new_field, new_idl_file, new_idl_file_path)
+ if isinstance(new_field_type,
+ syntax.Type) and "any" in new_field_type.bson_serialization_type:
+ # If 'any' is not explicitly allowed as the bson_serialization_type.
+ if allow_name not in ALLOW_ANY_TYPE_LIST:
+ ctxt.add_reply_field_bson_any_not_allowed_error(
+ cmd_name, new_field.name, new_field_type.name, new_idl_file_path)
+
+
+def check_param_or_command_type_recursive(ctxt: IDLCompatibilityContext,
+ field_pair: FieldCompatibilityPair,
+ is_command_parameter: bool):
+ # pylint: disable=too-many-branches,too-many-locals
"""
Check compatibility between old and new command or param type recursively.
If the old type is a syntax.Type instance, check the compatibility between the old and new
command type or parameter type recursively.
"""
+ old_field = field_pair.old
+ new_field = field_pair.new
+ old_type = old_field.field_type
+ new_type = new_field.field_type
+ cmd_name = field_pair.cmd_name
+ param_name = field_pair.field_name
+
+ # If the old field is unstable, we only add errors related to the use of 'any' as the
+ # bson_serialization_type. For all other errors, we check that the old field is stable
+ # before adding an error.
+
if not isinstance(new_type, syntax.Type):
- ctxt.add_new_command_or_param_type_enum_or_struct_error(cmd_name, new_type.name,
- old_type.name, new_idl_file_path,
- param_name, is_command_parameter)
+ if not old_field.unstable:
+ ctxt.add_new_command_or_param_type_enum_or_struct_error(
+ cmd_name, new_type.name, old_type.name, new_field.idl_file_path, param_name,
+ is_command_parameter)
return
+ if old_type.bson_serialization_type is None or new_type.bson_serialization_type is None:
+ print("here")
# If bson_serialization_type switches from 'any' to non-any type.
if "any" in old_type.bson_serialization_type and "any" not in new_type.bson_serialization_type:
ctxt.add_old_command_or_param_type_bson_any_error(
- cmd_name, old_type.name, old_idl_file_path, param_name, is_command_parameter)
+ cmd_name, old_type.name, old_field.idl_file_path, param_name, is_command_parameter)
return
# If bson_serialization_type switches from non-any to 'any' type.
if "any" not in old_type.bson_serialization_type and "any" in new_type.bson_serialization_type:
ctxt.add_new_command_or_param_type_bson_any_error(
- cmd_name, new_type.name, new_idl_file_path, param_name, is_command_parameter)
+ cmd_name, new_type.name, new_field.idl_file_path, param_name, is_command_parameter)
return
allow_name: str = cmd_name + "-param-" + param_name if is_command_parameter else cmd_name
@@ -439,17 +518,19 @@ def check_param_or_command_type_recursive(
# If 'any' is not explicitly allowed as the bson_serialization_type.
if allow_name not in ALLOW_ANY_TYPE_LIST:
ctxt.add_command_or_param_type_bson_any_not_allowed_error(
- cmd_name, old_type.name, old_idl_file_path, param_name, is_command_parameter)
+ cmd_name, old_type.name, old_field.idl_file_path, param_name, is_command_parameter)
return
if old_type.cpp_type != new_type.cpp_type:
ctxt.add_command_or_param_cpp_type_not_equal_error(
- cmd_name, new_type.name, new_idl_file_path, param_name, is_command_parameter)
+ cmd_name, new_type.name, new_field.idl_file_path, param_name, is_command_parameter)
if isinstance(old_type, syntax.VariantType):
if not isinstance(new_type, syntax.VariantType):
- ctxt.add_new_command_or_param_type_not_variant_type_error(
- cmd_name, new_type.name, new_idl_file_path, param_name, is_command_parameter)
+ if not old_field.unstable:
+ ctxt.add_new_command_or_param_type_not_variant_type_error(
+ cmd_name, new_type.name, new_field.idl_file_path, param_name,
+ is_command_parameter)
else:
new_variant_types = new_type.variant_types
old_variant_types = old_type.variant_types
@@ -459,16 +540,20 @@ def check_param_or_command_type_recursive(
for new_variant_type in new_variant_types:
if old_variant_type.name == new_variant_type.name:
# Check that the old and new version of each variant type is also compatible.
- check_param_or_command_type(ctxt, old_variant_type, new_variant_type,
- cmd_name, old_idl_file, new_idl_file,
- old_idl_file_path, new_idl_file_path,
- param_name, is_command_parameter)
+ old = FieldCompatibility(old_variant_type, old_field.idl_file,
+ old_field.idl_file_path, old_field.unstable)
+ new = FieldCompatibility(new_variant_type, new_field.idl_file,
+ new_field.idl_file_path, new_field.unstable)
+ check_param_or_command_type(
+ ctxt, FieldCompatibilityPair(old, new, cmd_name, param_name),
+ is_command_parameter)
break
else:
- # old_variant_type was not found in new_variant_types.
- ctxt.add_new_command_or_param_variant_type_not_superset_error(
- cmd_name, old_variant_type.name, new_idl_file_path, param_name,
- is_command_parameter)
+ if not old_field.unstable:
+ # old_variant_type was not found in new_variant_types.
+ ctxt.add_new_command_or_param_variant_type_not_superset_error(
+ cmd_name, old_variant_type.name, new_field.idl_file_path, param_name,
+ is_command_parameter)
# If old and new types both have a struct as a variant type, compare old and new variant_struct_type.
# Since enums can't be part of variant types, we don't explicitly check for enums.
@@ -476,71 +561,72 @@ def check_param_or_command_type_recursive(
if new_type.variant_struct_type is not None:
check_command_params_or_type_struct_fields(
ctxt, old_type.variant_struct_type, new_type.variant_struct_type, cmd_name,
- old_idl_file, new_idl_file, old_idl_file_path, new_idl_file_path,
- is_command_parameter)
+ old_field.idl_file, new_field.idl_file, old_field.idl_file_path,
+ new_field.idl_file_path, is_command_parameter)
# If old type has a variant struct type and new type does not have a variant struct type.
- else:
+ elif not old_field.unstable:
ctxt.add_new_command_or_param_variant_type_not_superset_error(
- cmd_name, old_type.variant_struct_type.name, new_idl_file_path, param_name,
- is_command_parameter)
+ cmd_name, old_type.variant_struct_type.name, new_field.idl_file_path,
+ param_name, is_command_parameter)
- else:
+ elif not old_field.unstable:
check_superset(ctxt, cmd_name, new_type.name, new_type.bson_serialization_type,
- old_type.bson_serialization_type, new_idl_file_path, param_name,
+ old_type.bson_serialization_type, new_field.idl_file_path, param_name,
is_command_parameter)
-def check_param_or_command_type(ctxt: IDLCompatibilityContext,
- old_type: Optional[Union[syntax.Enum, syntax.Struct, syntax.Type]],
- new_type: Optional[Union[syntax.Enum, syntax.Struct, syntax.Type]],
- cmd_name: str, old_idl_file: syntax.IDLParsedSpec,
- new_idl_file: syntax.IDLParsedSpec, old_idl_file_path: str,
- new_idl_file_path: str, param_name: Optional[str],
+def check_param_or_command_type(ctxt: IDLCompatibilityContext, field_pair: FieldCompatibilityPair,
is_command_parameter: bool):
"""Check compatibility between old and new command parameter type or command type."""
- # pylint: disable=too-many-arguments,too-many-branches
+ # pylint: disable=too-many-branches
+ old_field = field_pair.old
+ new_field = field_pair.new
if check_array_type(ctxt, "command_parameter" if is_command_parameter else "command_namespace",
- old_type, new_type, cmd_name,
- param_name if is_command_parameter else "type", old_idl_file_path,
- new_idl_file_path):
- old_type = old_type.element_type
- new_type = new_type.element_type
-
+ old_field.field_type, new_field.field_type, field_pair.cmd_name,
+ field_pair.field_name if is_command_parameter else "type",
+ old_field.idl_file_path, new_field.idl_file_path, old_field.unstable):
+ old_field.field_type = old_field.field_type.element_type
+ new_field.field_type = new_field.field_type.element_type
+
+ old_type = old_field.field_type
+ new_type = new_field.field_type
if old_type is None:
- ctxt.add_command_or_param_type_invalid_error(cmd_name, old_idl_file_path, param_name,
- is_command_parameter)
+ ctxt.add_command_or_param_type_invalid_error(field_pair.cmd_name, old_field.idl_file_path,
+ field_pair.field_name, is_command_parameter)
ctxt.errors.dump_errors()
sys.exit(1)
if new_type is None:
- ctxt.add_command_or_param_type_invalid_error(cmd_name, new_idl_file_path, param_name,
- is_command_parameter)
+ ctxt.add_command_or_param_type_invalid_error(field_pair.cmd_name, new_field.idl_file_path,
+ field_pair.field_name, is_command_parameter)
ctxt.errors.dump_errors()
sys.exit(1)
if isinstance(old_type, syntax.Type):
- check_param_or_command_type_recursive(ctxt, old_type, new_type, cmd_name, old_idl_file,
- new_idl_file, old_idl_file_path, new_idl_file_path,
- param_name, is_command_parameter)
+ check_param_or_command_type_recursive(ctxt, field_pair, is_command_parameter)
- elif isinstance(old_type, syntax.Enum):
+ # Only add type errors if the old field is stable.
+ elif isinstance(old_type, syntax.Enum) and not old_field.unstable:
if isinstance(new_type, syntax.Enum):
- check_superset(ctxt, cmd_name, new_type.name, new_type.values, old_type.values,
- new_idl_file_path, param_name, is_command_parameter)
+ check_superset(ctxt, field_pair.cmd_name, new_type.name, new_type.values,
+ old_type.values, new_field.idl_file_path, field_pair.field_name,
+ is_command_parameter)
else:
- ctxt.add_new_command_or_param_type_not_enum_error(cmd_name, new_type.name,
- old_type.name, new_idl_file_path,
- param_name, is_command_parameter)
+ ctxt.add_new_command_or_param_type_not_enum_error(
+ field_pair.cmd_name, new_type.name, old_type.name, new_field.idl_file_path,
+ field_pair.field_name, is_command_parameter)
elif isinstance(old_type, syntax.Struct):
if isinstance(new_type, syntax.Struct):
check_command_params_or_type_struct_fields(
- ctxt, old_type, new_type, cmd_name, old_idl_file, new_idl_file, old_idl_file_path,
- new_idl_file_path, is_command_parameter)
+ ctxt, old_type, new_type, field_pair.cmd_name, old_field.idl_file,
+ new_field.idl_file, old_field.idl_file_path, new_field.idl_file_path,
+ is_command_parameter)
else:
- ctxt.add_new_command_or_param_type_not_struct_error(cmd_name, new_type.name,
- old_type.name, new_idl_file_path,
- param_name, is_command_parameter)
+ if not old_field.unstable:
+ ctxt.add_new_command_or_param_type_not_struct_error(
+ field_pair.cmd_name, new_type.name, old_type.name, new_field.idl_file_path,
+ field_pair.field_name, is_command_parameter)
def check_param_or_type_validator(ctxt: IDLCompatibilityContext, old_field: syntax.Field,
@@ -596,6 +682,18 @@ def check_command_params_or_type_struct_fields(
ctxt.add_new_param_or_command_type_field_added_required_error(
cmd_name, new_field.name, new_idl_file_path, new_struct.name, is_command_parameter)
+ # Check that a new field does not have an unallowed use of 'any' as the bson_serialization_type.
+ if newly_added:
+ allow_name: str = cmd_name + "-param-" + new_field.name if is_command_parameter else cmd_name
+ new_field_type = get_field_type(new_field, new_idl_file, new_idl_file_path)
+ if isinstance(new_field_type,
+ syntax.Type) and "any" in new_field_type.bson_serialization_type:
+ # If 'any' is not explicitly allowed as the bson_serialization_type.
+ if allow_name not in ALLOW_ANY_TYPE_LIST:
+ ctxt.add_command_or_param_type_bson_any_not_allowed_error(
+ cmd_name, new_field_type.name, old_idl_file_path, new_field.name,
+ is_command_parameter)
+
def check_command_param_or_type_struct_field(
ctxt: IDLCompatibilityContext, old_field: syntax.Field, new_field: syntax.Field,
@@ -617,15 +715,21 @@ def check_command_param_or_type_struct_field(
ctxt.add_new_param_or_command_type_field_required_error(
cmd_name, old_field.name, old_idl_file_path, type_name, is_command_parameter)
- check_param_or_type_validator(ctxt, old_field, new_field, cmd_name, new_idl_file_path,
- type_name, is_command_parameter)
+ if not old_field.unstable:
+ check_param_or_type_validator(ctxt, old_field, new_field, cmd_name, new_idl_file_path,
+ type_name, is_command_parameter)
old_field_type = get_field_type(old_field, old_idl_file, old_idl_file_path)
new_field_type = get_field_type(new_field, new_idl_file, new_idl_file_path)
- check_param_or_command_type(ctxt, old_field_type, new_field_type, cmd_name, old_idl_file,
- new_idl_file, old_idl_file_path, new_idl_file_path, old_field.name,
- is_command_parameter)
+ old_field_compatibility = FieldCompatibility(old_field_type, old_idl_file, old_idl_file_path,
+ old_field.unstable)
+ new_field_compatibility = FieldCompatibility(new_field_type, new_idl_file, new_idl_file_path,
+ new_field.unstable)
+ field_pair = FieldCompatibilityPair(old_field_compatibility, new_field_compatibility, cmd_name,
+ old_field.name)
+
+ check_param_or_command_type(ctxt, field_pair, is_command_parameter)
def check_namespace(ctxt: IDLCompatibilityContext, old_cmd: syntax.Command, new_cmd: syntax.Command,
@@ -654,9 +758,12 @@ def check_namespace(ctxt: IDLCompatibilityContext, old_cmd: syntax.Command, new_
old_type = get_field_type(old_cmd, old_idl_file, old_idl_file_path)
if new_namespace == common.COMMAND_NAMESPACE_TYPE:
new_type = get_field_type(new_cmd, new_idl_file, new_idl_file_path)
- check_param_or_command_type(
- ctxt, old_type, new_type, old_cmd.command_name, old_idl_file, new_idl_file,
- old_idl_file_path, new_idl_file_path, param_name=None, is_command_parameter=False)
+ old = FieldCompatibility(old_type, old_idl_file, old_idl_file_path, unstable=False)
+ new = FieldCompatibility(new_type, new_idl_file, new_idl_file_path, unstable=False)
+
+ check_param_or_command_type(ctxt,
+ FieldCompatibilityPair(old, new, old_cmd.command_name, ""),
+ is_command_parameter=False)
# If old type is "namespacestring", the new namespace can be changed to any
# of the other namespace types.
diff --git a/buildscripts/idl/tests/compatibility_test_fail/new/compatibility_test_fail_new.idl b/buildscripts/idl/tests/compatibility_test_fail/new/compatibility_test_fail_new.idl
index 3d1fe968cb6..2fc2640fdff 100644
--- a/buildscripts/idl/tests/compatibility_test_fail/new/compatibility_test_fail_new.idl
+++ b/buildscripts/idl/tests/compatibility_test_fail/new/compatibility_test_fail_new.idl
@@ -229,6 +229,108 @@ structs:
cppTypeNotEqualReplyField:
type: bsonSerializationTypeAnyCppTypeNotEqual
+ NewlyAddedBsonSerializationTypeAnyReply:
+ description: "This reply contains a newly added field whose type has a bson_serialization_type
+ that contains 'any' that is not explicitly allowed"
+ fields:
+ newlyAddedBsonSerializationTypeAnyReplyField:
+ type:
+ variant: [string, bsonSerializationTypeAny]
+
+ OldBsonSerializationTypeAnyUnstableReply:
+ description: "This reply contains a field that is unstable in the old version
+ and whose old type has a bson_serialization_type
+ that contains 'any'"
+ fields:
+ oldBsonSerializationTypeAnyUnstableReplyField:
+ type: oldBsonSerializationTypeAny
+
+ NewBsonSerializationTypeAnyUnstableReply:
+ description: "This reply contains a field that is unstable in the old version
+ and whose new type has a bson_serialization_type
+ that contains 'any'"
+ fields:
+ newBsonSerializationTypeAnyUnstableReplyField:
+ type: newBsonSerializationTypeAny
+
+ BsonSerializationTypeAnyUnstableReply:
+ description: "This reply contains a field that is unstable in the old version
+ and whose old and new type have a bson_serialization_type
+ that contains 'any' that is not explicitly allowed."
+ fields:
+ bsonSerializationTypeAnyUnstableReplyField:
+ type: bsonSerializationTypeAny
+
+ BsonSerializationTypeWithVariantAnyUnstableReply:
+ description: "This reply contains a field whose old and new variant types have a bson_serialization_type
+ that contains 'any' that is not compatible and where the old field is unstable"
+ fields:
+ bsonSerializationTypeWithVariantAnyUnstableReplyField:
+ type:
+ variant: [oldBsonSerializationTypeAny, newBsonSerializationTypeAny]
+
+ CppTypeNotEqualUnstableReply:
+ description: "This reply contains a field whose old and new type have a bson_serialization_type
+ that contains 'any' and the cpp_types are not equal and where the old field
+ is unstable"
+ fields:
+ cppTypeNotEqualReplyUnstableField:
+ type: bsonSerializationTypeAnyCppTypeNotEqual
+
+ NewlyAddedBsonSerializationTypeAnyStruct:
+ description: "This struct contains a newly added field whose type has a bson_serialization_type
+ that contains 'any' that is not explicitly allowed"
+ fields:
+ newlyAddedBsonSerializationTypeAnyStructField:
+ optional: true
+ type:
+ variant: [string, bsonSerializationTypeAny]
+
+ OldBsonSerializationTypeAnyUnstableStruct:
+ description: "This struct contains a field that is unstable in the old version
+ and whose old type has a bson_serialization_type
+ that contains 'any'"
+ fields:
+ oldBsonSerializationTypeAnyUnstableStructField:
+ optional: true
+ type: oldBsonSerializationTypeAny
+
+ NewBsonSerializationTypeAnyUnstableStruct:
+ description: "This struct contains a field that is unstable in the old version
+ and whose new type has a bson_serialization_type
+ that contains 'any'"
+ fields:
+ newBsonSerializationTypeAnyUnstableStructField:
+ optional: true
+ type: newBsonSerializationTypeAny
+
+ BsonSerializationTypeAnyUnstableStruct:
+ description: "This struct contains a field that is unstable in the old version
+ and whose old and new type have a bson_serialization_type
+ that contains 'any' that is not explicitly allowed."
+ fields:
+ bsonSerializationTypeAnyUnstableStructField:
+ optional: true
+ type: bsonSerializationTypeAny
+
+ BsonSerializationTypeWithVariantAnyUnstableStruct:
+ description: "This struct contains a field whose old and new variant types have a bson_serialization_type
+ that contains 'any' that is not compatible and where the old field is unstable"
+ fields:
+ bsonSerializationTypeWithVariantAnyUnstableStructField:
+ optional: true
+ type:
+ variant: [oldBsonSerializationTypeAny, newBsonSerializationTypeAny]
+
+ CppTypeNotEqualUnstableStruct:
+ description: "This struct contains a field whose old and new type have a bson_serialization_type
+ that contains 'any' and the cpp_types are not equal and where the old field
+ is unstable"
+ fields:
+ cppTypeNotEqualStructUnstableField:
+ optional: true
+ type: bsonSerializationTypeAnyCppTypeNotEqual
+
StructFieldTypeRecursiveReplyOne:
description: "This reply contains a field whose new type is a struct that is not
compatible with the old field type"
@@ -682,6 +784,92 @@ commands:
cppTypeNotEqualParam:
type: bsonSerializationTypeAnyCppTypeNotEqual
+ oldCommandParamTypeBsonAnyUnstable:
+ description: "old command fails because it has a parameter type that has a
+ bson_serialization_type that contains 'any' and the old param is unstable"
+ command_name: oldCommandParamTypeBsonAnyUnstable
+ namespace: ignored
+ cpp_name: oldCommandParamTypeBsonAnyUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+ fields:
+ bsonTypeAnyUnstableParam:
+ type: oldBsonSerializationTypeAny
+ optional: true
+
+ newCommandParamTypeBsonAnyUnstable:
+ description: "new command fails because it has a parameter type that has a
+ bson_serialization_type that contains 'any' and the old param is unstable"
+ command_name: newCommandParamTypeBsonAnyUnstable
+ namespace: ignored
+ cpp_name: newCommandParamTypeBsonAnyUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+ fields:
+ bsonTypeAnyUnstableParam:
+ type: newBsonSerializationTypeAny
+ optional: true
+
+ commandParamTypeBsonAnyNotAllowedUnstable:
+ description: "command fails because it has a parameter type that has a
+ bson_serialization_type that contains 'any' that is not
+ explicitly allowed"
+ command_name: commandParamTypeBsonAnyNotAllowedUnstable
+ namespace: ignored
+ cpp_name: commandParamTypeBsonAnyNotAllowedUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+ fields:
+ bsonTypeAnyUnstableParam:
+ type: bsonSerializationTypeAny
+ optional: true
+
+ commandParameterCppTypeNotEqualUnstable:
+ description: "command fails because it has a parameter type that has a
+ bson_serialization_type that contains 'any' and where the cpp_types
+ are not equal"
+ command_name: commandParameterCppTypeNotEqualUnstable
+ namespace: ignored
+ cpp_name: commandParameterCppTypeNotEqualUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+ fields:
+ cppTypeNotEqualParam:
+ type: bsonSerializationTypeAnyCppTypeNotEqual
+ optional: true
+
+ parameterFieldTypeBsonAnyWithVariantUnstable:
+ description: "command fails when its paramter field variant types have bson_serialization_type
+ 'any' that is not compatible with each other"
+ command_name: parameterFieldTypeBsonAnyWithVariantUnstable
+ namespace: ignored
+ cpp_name: parameterFieldTypeBsonAnyWithVariantUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+ fields:
+ variantAnyUnstableField:
+ type: BsonSerializationTypeWithVariantAnyStruct
+ optional: true
+
+ newlyAddedParamBsonAnyNotAllowed:
+ description: "command fails when its parameter is newly added and has bson type 'any'
+ that is not explicitly allowed"
+ command_name: newlyAddedParamBsonAnyNotAllowed
+ namespace: ignored
+ cpp_name: newlyAddedParamBsonAnyNotAllowed
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+ fields:
+ newlyAddedBsonAnyNotAllowedParam:
+ type: bsonSerializationTypeAny
+ optional: true
+
newCommandParameterTypeEnumNotSuperset:
description: "new command fails because its parameter type is an enum that is not
a superset of the corresponding old parameter type's enum values"
@@ -1197,6 +1385,72 @@ commands:
api_version: "1"
reply_type: OkReply
+ oldTypeBsonAnyUnstable:
+ description: "old command fails because its type has a bson_serialization_type
+ that contains 'any' and the old type field is unstable"
+ command_name: oldTypeBsonAnyUnstable
+ namespace: type
+ type: OldBsonSerializationTypeAnyUnstableStruct
+ cpp_name: oldTypeBsonAnyUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+
+ newTypeBsonAnyUnstable:
+ description: "new command fails because its type has a bson_serialization_type
+ that contains 'any' and the old type field is unstable"
+ command_name: newTypeBsonAnyUnstable
+ namespace: type
+ type: NewBsonSerializationTypeAnyUnstableStruct
+ cpp_name: newTypeBsonAnyUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+
+ typeBsonAnyNotAllowedUnstable:
+ description: "command fails because its type has a bson_serialization_type
+ that contains 'any' that is not explicitly allowed and the old type field is unstable"
+ command_name: typeBsonAnyNotAllowedUnstable
+ namespace: type
+ type: BsonSerializationTypeAnyUnstableStruct
+ cpp_name: typeBsonAnyNotAllowedUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+
+ commandCppTypeNotEqualUnstable:
+ description: "command fails because its type has a bson_serialization_type
+ that contains 'any' and the cpp_types are not equal and the old type field is unstable"
+ command_name: commandCppTypeNotEqualUnstable
+ namespace: type
+ type: CppTypeNotEqualUnstableStruct
+ cpp_name: commandCppTypeNotEqualUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+
+ commandTypeBsonAnyWithVariantUnstable:
+ description: "command fails when its variant types have bson_serialization_type
+ 'any' that is not compatible with each other and the old type field is unstable"
+ command_name: commandTypeBsonAnyWithVariantUnstable
+ namespace: type
+ type: BsonSerializationTypeWithVariantAnyUnstableStruct
+ cpp_name: commandTypeBsonAnyWithVariantUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+
+ newlyAddedTypeFieldBsonAnyNotAllowed:
+ description: "command fails because it has a newly added type field has a bson_serialization_type
+ that contains 'any' that is not explicitly allowed"
+ command_name: newlyAddedTypeFieldBsonAnyNotAllowed
+ namespace: type
+ type: NewlyAddedBsonSerializationTypeAnyStruct
+ cpp_name: newlyAddedTypeFieldBsonAnyNotAllowed
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+
newTypeNotSuperset:
description: "new command fails because its type is not a superset
of the old type"
@@ -1992,3 +2246,63 @@ commands:
reply_type: OkReply
access_check:
none: true
+
+ oldReplyFieldTypeBsonAnyUnstable:
+ description: "old command fails when its reply field type has a bson_serialization_type
+ that contains 'any' and the old reply field is unstable"
+ command_name: oldReplyFieldTypeBsonAnyUnstable
+ namespace: ignored
+ cpp_name: oldReplyFieldTypeBsonAnyUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OldBsonSerializationTypeAnyUnstableReply
+
+ newReplyFieldTypeBsonAnyUnstable:
+ description: "new command fails when its reply field type has a bson_serialization_type
+ that contains 'any' and the old reply field is unstable"
+ command_name: newReplyFieldTypeBsonAnyUnstable
+ namespace: ignored
+ cpp_name: newReplyFieldTypeBsonAnyUnstable
+ strict: true
+ api_version: "1"
+ reply_type: NewBsonSerializationTypeAnyUnstableReply
+
+ replyFieldTypeBsonAnyNotAllowedUnstable:
+ description: "command fails when its reply field type has a bson_serialization_type
+ that contains 'any' that is not explicitly allowed and the old reply field is unstable"
+ command_name: replyFieldTypeBsonAnyNotAllowedUnstable
+ namespace: ignored
+ cpp_name: replyFieldTypeBsonAnyNotAllowedUnstable
+ strict: true
+ api_version: "1"
+ reply_type: BsonSerializationTypeAnyUnstableReply
+
+ replyFieldTypeBsonAnyWithVariantUnstable:
+ description: "command fails when its reply field variant types have bson_serialization_type
+ 'any' that is not compatible with each other and the old reply field is unstable"
+ command_name: replyFieldTypeBsonAnyWithVariantUnstable
+ namespace: ignored
+ cpp_name: replyFieldTypeBsonAnyWithVariantUnstable
+ strict: true
+ api_version: "1"
+ reply_type: BsonSerializationTypeWithVariantAnyUnstableReply
+
+ replyFieldCppTypeNotEqualUnstable:
+ description: "command fails because its reply field type has a bson_serialization_type
+ that contains 'any', and the cpp_types are not equal and the old reply field is unstable"
+ command_name: replyFieldCppTypeNotEqualUnstable
+ namespace: ignored
+ cpp_name: replyFieldCppTypeNotEqualUnstable
+ strict: true
+ api_version: "1"
+ reply_type: CppTypeNotEqualUnstableReply
+
+ newlyAddedReplyFieldTypeBsonAnyNotAllowed:
+ description: "command fails because it has a newly added reply field type has a bson_serialization_type
+ that contains 'any' that is not explicitly allowed"
+ command_name: newlyAddedReplyFieldTypeBsonAnyNotAllowed
+ namespace: ignored
+ cpp_name: newlyAddedReplyFieldTypeBsonAnyNotAllowed
+ strict: true
+ api_version: "1"
+ reply_type: NewlyAddedBsonSerializationTypeAnyReply
diff --git a/buildscripts/idl/tests/compatibility_test_fail/old/compatibility_test_fail_old.idl b/buildscripts/idl/tests/compatibility_test_fail/old/compatibility_test_fail_old.idl
index 52fec6da542..3064ee29b8f 100644
--- a/buildscripts/idl/tests/compatibility_test_fail/old/compatibility_test_fail_old.idl
+++ b/buildscripts/idl/tests/compatibility_test_fail/old/compatibility_test_fail_old.idl
@@ -210,6 +210,109 @@ structs:
bsonSerializationTypeAnyReplyField:
type: bsonSerializationTypeAny
+ NewlyAddedBsonSerializationTypeAnyReply:
+ description: "This reply contains a newly added field whose type has a bson_serialization_type
+ that contains 'any' that is not explicitly allowed"
+
+ OldBsonSerializationTypeAnyUnstableReply:
+ description: "This reply contains a field that is unstable in the old version
+ and whose old type has a bson_serialization_type
+ that contains 'any'"
+ fields:
+ oldBsonSerializationTypeAnyUnstableReplyField:
+ type: oldBsonSerializationTypeAny
+ unstable: true
+
+ NewBsonSerializationTypeAnyUnstableReply:
+ description: "This reply contains a field that is unstable in the old version
+ and whose new type has a bson_serialization_type
+ that contains 'any'"
+ fields:
+ newBsonSerializationTypeAnyUnstableReplyField:
+ type: newBsonSerializationTypeAny
+ unstable: true
+
+ BsonSerializationTypeAnyUnstableReply:
+ description: "This reply contains a field that is unstable in the old version
+ and whose old and new type have a bson_serialization_type
+ that contains 'any' that is not explicitly allowed."
+ fields:
+ bsonSerializationTypeAnyUnstableReplyField:
+ type: bsonSerializationTypeAny
+ unstable: true
+
+ BsonSerializationTypeWithVariantAnyUnstableReply:
+ description: "This reply contains a field whose old and new variant types have a bson_serialization_type
+ that contains 'any' that is not compatible and where the old field is unstable"
+ fields:
+ bsonSerializationTypeWithVariantAnyUnstableReplyField:
+ type:
+ variant: [oldBsonSerializationTypeAny, newBsonSerializationTypeAny]
+ unstable: true
+
+ CppTypeNotEqualUnstableReply:
+ description: "This reply contains a field whose old and new type have a bson_serialization_type
+ that contains 'any' and the cpp_types are not equal and where the old field
+ is unstable"
+ fields:
+ cppTypeNotEqualReplyUnstableField:
+ type: bsonSerializationTypeAnyCppTypeNotEqual
+ unstable: true
+
+ NewlyAddedBsonSerializationTypeAnyStruct:
+ description: "This struct contains a newly added field whose type has a bson_serialization_type
+ that contains 'any' that is not explicitly allowed"
+ fields:
+ newlyAddedBsonSerializationTypeAnyStructField:
+ unstable: true
+ type:
+ variant: [string, bsonSerializationTypeAny]
+
+ OldBsonSerializationTypeAnyUnstableStruct:
+ description: "This struct contains a field that is unstable in the old version
+ and whose old type has a bson_serialization_type
+ that contains 'any'"
+ fields:
+ oldBsonSerializationTypeAnyUnstableStructField:
+ unstable: true
+ type: oldBsonSerializationTypeAny
+
+ NewBsonSerializationTypeAnyUnstableStruct:
+ description: "This struct contains a field that is unstable in the old version
+ and whose new type has a bson_serialization_type
+ that contains 'any'"
+ fields:
+ newBsonSerializationTypeAnyUnstableStructField:
+ unstable: true
+ type: newBsonSerializationTypeAny
+
+ BsonSerializationTypeAnyUnstableStruct:
+ description: "This struct contains a field that is unstable in the old version
+ and whose old and new type have a bson_serialization_type
+ that contains 'any' that is not explicitly allowed."
+ fields:
+ bsonSerializationTypeAnyUnstableStructField:
+ unstable: true
+ type: bsonSerializationTypeAny
+
+ BsonSerializationTypeWithVariantAnyUnstableStruct:
+ description: "This struct contains a field whose old and new variant types have a bson_serialization_type
+ that contains 'any' that is not compatible and where the old field is unstable"
+ fields:
+ bsonSerializationTypeWithVariantAnyUnstableStructField:
+ unstable: true
+ type:
+ variant: [oldBsonSerializationTypeAny, newBsonSerializationTypeAny]
+
+ CppTypeNotEqualUnstableStruct:
+ description: "This struct contains a field whose old and new type have a bson_serialization_type
+ that contains 'any' and the cpp_types are not equal and where the old field
+ is unstable"
+ fields:
+ cppTypeNotEqualStructUnstableField:
+ unstable: true
+ type: bsonSerializationTypeAnyCppTypeNotEqual
+
BsonSerializationTypeWithVariantAnyStruct:
description: "This struct contains a field whose old and new variant types have a bson_serialization_type
that contains 'any' that is not compatible"
@@ -672,6 +775,88 @@ commands:
cppTypeNotEqualParam:
type: bsonSerializationTypeAnyCppTypeNotEqual
+ oldCommandParamTypeBsonAnyUnstable:
+ description: "old command fails because it has a parameter type that has a
+ bson_serialization_type that contains 'any' and the old param is unstable"
+ command_name: oldCommandParamTypeBsonAnyUnstable
+ namespace: ignored
+ cpp_name: oldCommandParamTypeBsonAnyUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+ fields:
+ bsonTypeAnyUnstableParam:
+ type: oldBsonSerializationTypeAny
+ unstable: true
+
+ newCommandParamTypeBsonAnyUnstable:
+ description: "new command fails because it has a parameter type that has a
+ bson_serialization_type that contains 'any' and the old param is unstable"
+ command_name: newCommandParamTypeBsonAnyUnstable
+ namespace: ignored
+ cpp_name: newCommandParamTypeBsonAnyUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+ fields:
+ bsonTypeAnyUnstableParam:
+ type: newBsonSerializationTypeAny
+ unstable: true
+
+ commandParamTypeBsonAnyNotAllowedUnstable:
+ description: "command fails because it has a parameter type that has a
+ bson_serialization_type that contains 'any' that is not
+ explicitly allowed"
+ command_name: commandParamTypeBsonAnyNotAllowedUnstable
+ namespace: ignored
+ cpp_name: commandParamTypeBsonAnyNotAllowedUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+ fields:
+ bsonTypeAnyUnstableParam:
+ type: bsonSerializationTypeAny
+ unstable: true
+
+ commandParameterCppTypeNotEqualUnstable:
+ description: "command fails because it has a parameter type that has a
+ bson_serialization_type that contains 'any' and where the cpp_types
+ are not equal"
+ command_name: commandParameterCppTypeNotEqualUnstable
+ namespace: ignored
+ cpp_name: commandParameterCppTypeNotEqualUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+ fields:
+ cppTypeNotEqualParam:
+ type: bsonSerializationTypeAnyCppTypeNotEqual
+ unstable: true
+
+ parameterFieldTypeBsonAnyWithVariantUnstable:
+ description: "command fails when its paramter field variant types have bson_serialization_type
+ 'any' that is not compatible with each other"
+ command_name: parameterFieldTypeBsonAnyWithVariantUnstable
+ namespace: ignored
+ cpp_name: parameterFieldTypeBsonAnyWithVariantUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+ fields:
+ variantAnyUnstableField:
+ type: BsonSerializationTypeWithVariantAnyStruct
+ unstable: true
+
+ newlyAddedParamBsonAnyNotAllowed:
+ description: "command fails when its parameter is newly added and has bson type 'any'
+ that is not explicitly allowed"
+ command_name: newlyAddedParamBsonAnyNotAllowed
+ namespace: ignored
+ cpp_name: newlyAddedParamBsonAnyNotAllowed
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+
newCommandParameterTypeEnumNotSuperset:
description: "new command fails because its parameter type is an enum that is not
a superset of the corresponding old parameter type's enum values"
@@ -1060,6 +1245,66 @@ commands:
api_version: "1"
reply_type: CppTypeNotEqualReply
+ oldReplyFieldTypeBsonAnyUnstable:
+ description: "old command fails when its reply field type has a bson_serialization_type
+ that contains 'any' and the old reply field is unstable"
+ command_name: oldReplyFieldTypeBsonAnyUnstable
+ namespace: ignored
+ cpp_name: oldReplyFieldTypeBsonAnyUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OldBsonSerializationTypeAnyUnstableReply
+
+ newReplyFieldTypeBsonAnyUnstable:
+ description: "new command fails when its reply field type has a bson_serialization_type
+ that contains 'any' and the old reply field is unstable"
+ command_name: newReplyFieldTypeBsonAnyUnstable
+ namespace: ignored
+ cpp_name: newReplyFieldTypeBsonAnyUnstable
+ strict: true
+ api_version: "1"
+ reply_type: NewBsonSerializationTypeAnyUnstableReply
+
+ replyFieldTypeBsonAnyNotAllowedUnstable:
+ description: "command fails when its reply field type has a bson_serialization_type
+ that contains 'any' that is not explicitly allowed and the old reply field is unstable"
+ command_name: replyFieldTypeBsonAnyNotAllowedUnstable
+ namespace: ignored
+ cpp_name: replyFieldTypeBsonAnyNotAllowedUnstable
+ strict: true
+ api_version: "1"
+ reply_type: BsonSerializationTypeAnyUnstableReply
+
+ replyFieldTypeBsonAnyWithVariantUnstable:
+ description: "command fails when its reply field variant types have bson_serialization_type
+ 'any' that is not compatible with each other and the old reply field is unstable"
+ command_name: replyFieldTypeBsonAnyWithVariantUnstable
+ namespace: ignored
+ cpp_name: replyFieldTypeBsonAnyWithVariantUnstable
+ strict: true
+ api_version: "1"
+ reply_type: BsonSerializationTypeWithVariantAnyUnstableReply
+
+ replyFieldCppTypeNotEqualUnstable:
+ description: "command fails because its reply field type has a bson_serialization_type
+ that contains 'any', and the cpp_types are not equal and the old reply field is unstable"
+ command_name: replyFieldCppTypeNotEqualUnstable
+ namespace: ignored
+ cpp_name: replyFieldCppTypeNotEqualUnstable
+ strict: true
+ api_version: "1"
+ reply_type: CppTypeNotEqualUnstableReply
+
+ newlyAddedReplyFieldTypeBsonAnyNotAllowed:
+ description: "command fails because it has a newly added reply field type has a bson_serialization_type
+ that contains 'any' that is not explicitly allowed"
+ command_name: newlyAddedReplyFieldTypeBsonAnyNotAllowed
+ namespace: ignored
+ cpp_name: newlyAddedReplyFieldTypeBsonAnyNotAllowed
+ strict: true
+ api_version: "1"
+ reply_type: NewlyAddedBsonSerializationTypeAnyReply
+
newReplyFieldTypeStructRecursiveOne:
description: "new command fails because its reply field type is a struct that is
incompatible with the old reply field type struct"
@@ -1185,6 +1430,72 @@ commands:
api_version: "1"
reply_type: OkReply
+ oldTypeBsonAnyUnstable:
+ description: "old command fails because its type has a bson_serialization_type
+ that contains 'any' and the old type field is unstable"
+ command_name: oldTypeBsonAnyUnstable
+ namespace: type
+ type: OldBsonSerializationTypeAnyUnstableStruct
+ cpp_name: oldTypeBsonAnyUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+
+ newTypeBsonAnyUnstable:
+ description: "new command fails because its type has a bson_serialization_type
+ that contains 'any' and the old type field is unstable"
+ command_name: newTypeBsonAnyUnstable
+ namespace: type
+ type: NewBsonSerializationTypeAnyUnstableStruct
+ cpp_name: newTypeBsonAnyUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+
+ typeBsonAnyNotAllowedUnstable:
+ description: "command fails because its type has a bson_serialization_type
+ that contains 'any' that is not explicitly allowed and the old type field is unstable"
+ command_name: typeBsonAnyNotAllowedUnstable
+ namespace: type
+ type: BsonSerializationTypeAnyUnstableStruct
+ cpp_name: typeBsonAnyNotAllowedUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+
+ commandCppTypeNotEqualUnstable:
+ description: "command fails because its type has a bson_serialization_type
+ that contains 'any' and the cpp_types are not equal and the old type field is unstable"
+ command_name: commandCppTypeNotEqualUnstable
+ namespace: type
+ type: CppTypeNotEqualUnstableStruct
+ cpp_name: commandCppTypeNotEqualUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+
+ commandTypeBsonAnyWithVariantUnstable:
+ description: "command fails when its variant types have bson_serialization_type
+ 'any' that is not compatible with each other and the old type field is unstable"
+ command_name: commandTypeBsonAnyWithVariantUnstable
+ namespace: type
+ type: BsonSerializationTypeWithVariantAnyUnstableStruct
+ cpp_name: commandTypeBsonAnyWithVariantUnstable
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+
+ newlyAddedTypeFieldBsonAnyNotAllowed:
+ description: "command fails because it has a newly added type field has a bson_serialization_type
+ that contains 'any' that is not explicitly allowed"
+ command_name: newlyAddedTypeFieldBsonAnyNotAllowed
+ namespace: type
+ type: NewlyAddedBsonSerializationTypeAnyStruct
+ cpp_name: newlyAddedTypeFieldBsonAnyNotAllowed
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+
newTypeNotSuperset:
description: "new command fails because its type is not a superset
of the old type"
diff --git a/buildscripts/idl/tests/compatibility_test_pass/new/compatibility_test_pass_new.idl b/buildscripts/idl/tests/compatibility_test_pass/new/compatibility_test_pass_new.idl
index d5efb295f0a..018d8ddcd01 100644
--- a/buildscripts/idl/tests/compatibility_test_pass/new/compatibility_test_pass_new.idl
+++ b/buildscripts/idl/tests/compatibility_test_pass/new/compatibility_test_pass_new.idl
@@ -363,6 +363,39 @@ structs:
anyTypeField:
type: bsonSerializationTypeAnyAllowed
+ NewlyAddedBsonSerializationTypeAnyReply:
+ description: "This reply contains a newly added field whose type has a bson_serialization_type
+ that contains 'any' that is explicitly allowed"
+ fields:
+ newlyAddedBsonSerializationTypeAnyReplyField:
+ type: bsonSerializationTypeAnyAllowed
+
+ OldUnstableTypeChangesReply:
+ description: "This reply contains a field that is unstable in the old version and has type changes"
+ fields:
+ oldUnstableTypeChangesReplyField:
+ unstable: true
+ type: intStringToIntStringBool
+ validator:
+ lt: 0
+
+ NewlyAddedBsonSerializationTypeAnyStruct:
+ description: "This struct contains a newly added field whose type has a bson_serialization_type
+ that contains 'any' that is explicitly allowed"
+ fields:
+ newlyAddedBsonSerializationTypeAnyStructField:
+ type: bsonSerializationTypeAnyAllowed
+ optional: true
+
+ OldUnstableTypeChangesStruct:
+ description: "This struct contains a field that is unstable in the old version and has type changes"
+ fields:
+ oldUnstableTypeChangesField:
+ type: intStringBoolToIntString
+ optional: true
+ validator:
+ lt: 0
+
BsonSerializationTypeAnyWithVariantReply:
description: "This reply contains a new reply field with variant types where one of the
bson serialization types is 'any' and is explicitly allowed"
@@ -588,6 +621,56 @@ commands:
supersetStructParameter:
type: CommandParamStructRecursiveTwo
+ newlyAddedParamBsonAnyAllowList:
+ description: "command passes when its parameter is newly added and has bson type 'any'
+ that is explicitly allowed"
+ command_name: newlyAddedParamBsonAnyAllowList
+ namespace: ignored
+ cpp_name: newlyAddedParamBsonAnyAllowList
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+ fields:
+ newlyAddedBsonAnyAllowListParam:
+ type: bsonSerializationTypeAnyAllowed
+ optional: true
+
+ oldUnstableParamTypeChanges:
+ description: "command passes when it has an old unstable param with incompatible type changes"
+ command_name: oldUnstableParamTypeChanges
+ namespace: ignored
+ cpp_name: oldUnstableParamTypeChanges
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+ fields:
+ oldUnstableTypeChangesParam:
+ type: intStringBoolToIntString
+ optional: true
+ validator:
+ lt: 0
+
+ newlyAddedTypeFieldBsonAnyAllowList:
+ description: "command passes when its type field is newly added and has bson type 'any'
+ that is explicitly allowed"
+ command_name: newlyAddedTypeFieldBsonAnyAllowList
+ namespace: type
+ type: NewlyAddedBsonSerializationTypeAnyStruct
+ cpp_name: newlyAddedTypeFieldBsonAnyAllowList
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+
+ oldUnstableTypeChanges:
+ description: "command passes when it has an old unstable type field with incompatible type changes"
+ command_name: oldUnstableTypeChanges
+ namespace: type
+ type: OldUnstableTypeChangesStruct
+ cpp_name: oldUnstableParamTypeChanges
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+
oldCommandParameterValidator:
description: "new command passes when it contains a parameter that does not contain a validator
that is present in the old parameter"
@@ -948,6 +1031,25 @@ commands:
api_version: "1"
reply_type: VariantStructRecursiveReply
+ newlyAddedReplyFieldTypeBsonAnyAllowed:
+ description: "command passes because it has a newly added reply field type has a bson_serialization_type
+ that contains 'any' that is explicitly allowed"
+ command_name: newlyAddedReplyFieldTypeBsonAnyAllowed
+ namespace: ignored
+ cpp_name: newlyAddedReplyFieldTypeBsonAnyAllowed
+ strict: true
+ api_version: "1"
+ reply_type: NewlyAddedBsonSerializationTypeAnyReply
+
+ oldUnstableReplyFieldTypeChanges:
+ description: "command passes when it has an old unstable reply field with incompatible type changes"
+ command_name: oldUnstableReplyFieldTypeChanges
+ namespace: ignored
+ cpp_name: oldUnstableReplyFieldTypeChanges
+ strict: true
+ api_version: "1"
+ reply_type: OldUnstableTypeChangesReply
+
commandAllowedAnyTypes:
description: "new command that has parameter and reply type with
explicitly allowed 'any' bson serialization type passes"
diff --git a/buildscripts/idl/tests/compatibility_test_pass/old/compatibility_test_pass_old.idl b/buildscripts/idl/tests/compatibility_test_pass/old/compatibility_test_pass_old.idl
index 1d17dd4366a..5c7535c3e23 100644
--- a/buildscripts/idl/tests/compatibility_test_pass/old/compatibility_test_pass_old.idl
+++ b/buildscripts/idl/tests/compatibility_test_pass/old/compatibility_test_pass_old.idl
@@ -359,6 +359,28 @@ structs:
anyTypeField:
type: bsonSerializationTypeAnyAllowed
+ NewlyAddedBsonSerializationTypeAnyReply:
+ description: "This reply contains a newly added field whose type has a bson_serialization_type
+ that contains 'any' that is explicitly allowed"
+
+ OldUnstableTypeChangesReply:
+ description: "This reply contains a field that is unstable in the old version and has type changes"
+ fields:
+ oldUnstableTypeChangesReplyField:
+ unstable: true
+ type: intStringToIntStringBool
+
+ NewlyAddedBsonSerializationTypeAnyStruct:
+ description: "This struct contains a newly added field whose type has a bson_serialization_type
+ that contains 'any' that is explicitly allowed"
+
+ OldUnstableTypeChangesStruct:
+ description: "This struct contains a field that is unstable in the old version and has type changes"
+ fields:
+ oldUnstableTypeChangesField:
+ unstable: true
+ type: intStringBoolToIntString
+
BsonSerializationTypeAnyWithVariantReply:
description: "This reply contains a new reply field with variant types where one of the
bson serialization types is 'any' and is explicitly allowed"
@@ -583,6 +605,50 @@ commands:
supersetStructParameter:
type: CommandParamStructRecursiveTwo
+ newlyAddedParamBsonAnyAllowList:
+ description: "command passes when its parameter is newly added and has bson type 'any'
+ that is explicitly allowed"
+ command_name: newlyAddedParamBsonAnyAllowList
+ namespace: ignored
+ cpp_name: newlyAddedParamBsonAnyAllowList
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+
+ oldUnstableParamTypeChanges:
+ description: "command passes when it has an old unstable param with incompatible type changes"
+ command_name: oldUnstableParamTypeChanges
+ namespace: ignored
+ cpp_name: oldUnstableParamTypeChanges
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+ fields:
+ oldUnstableTypeChangesParam:
+ type: intStringBoolToIntString
+ unstable: true
+
+ newlyAddedTypeFieldBsonAnyAllowList:
+ description: "command passes when its type field is newly added and has bson type 'any'
+ that is explicitly allowed"
+ command_name: newlyAddedTypeFieldBsonAnyAllowList
+ namespace: type
+ type: NewlyAddedBsonSerializationTypeAnyStruct
+ cpp_name: newlyAddedTypeFieldBsonAnyAllowList
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+
+ oldUnstableTypeChanges:
+ description: "command passes when it has an old unstable type field with incompatible type changes"
+ command_name: oldUnstableTypeChanges
+ namespace: type
+ type: OldUnstableTypeChangesStruct
+ cpp_name: oldUnstableParamTypeChanges
+ strict: true
+ api_version: "1"
+ reply_type: OkReply
+
oldCommandParameterValidator:
description: "new command passes when it contains a parameter that does not contain a validator
that is present in the old parameter"
@@ -948,6 +1014,25 @@ commands:
api_version: "1"
reply_type: VariantStructRecursiveReply
+ newlyAddedReplyFieldTypeBsonAnyAllowed:
+ description: "command passes because it has a newly added reply field type has a bson_serialization_type
+ that contains 'any' that is explicitly allowed"
+ command_name: newlyAddedReplyFieldTypeBsonAnyAllowed
+ namespace: ignored
+ cpp_name: newlyAddedReplyFieldTypeBsonAnyAllowed
+ strict: true
+ api_version: "1"
+ reply_type: NewlyAddedBsonSerializationTypeAnyReply
+
+ oldUnstableReplyFieldTypeChanges:
+ description: "command passes when it has an old unstable reply field with incompatible type changes"
+ command_name: oldUnstableReplyFieldTypeChanges
+ namespace: ignored
+ cpp_name: oldUnstableReplyFieldTypeChanges
+ strict: true
+ api_version: "1"
+ reply_type: OldUnstableTypeChangesReply
+
commandAllowedAnyTypes:
description: "new command that has parameter and reply type with
explicitly allowed 'any' bson serialization type passes"
diff --git a/buildscripts/idl/tests/test_compatibility.py b/buildscripts/idl/tests/test_compatibility.py
index 1a2978a0299..93da6030c14 100644
--- a/buildscripts/idl/tests/test_compatibility.py
+++ b/buildscripts/idl/tests/test_compatibility.py
@@ -126,7 +126,7 @@ class TestIDLCompatibilityChecker(unittest.TestCase):
path.join(dir_path, "compatibility_test_fail/new"), ["src"])
self.assertTrue(error_collection.has_errors())
- self.assertTrue(error_collection.count() == 139)
+ self.assertTrue(error_collection.count() == 160)
invalid_api_version_new_error = error_collection.get_error_by_command_name(
"invalidAPIVersionNew")
@@ -246,6 +246,69 @@ class TestIDLCompatibilityChecker(unittest.TestCase):
self.assertRegex(
str(command_parameter_cpp_type_not_equal_error), "commandParameterCppTypeNotEqual")
+ old_command_parameter_type_bson_any_unstable_error = error_collection.get_error_by_command_name(
+ "oldCommandParamTypeBsonAnyUnstable")
+ self.assertTrue(
+ old_command_parameter_type_bson_any_unstable_error.error_id == idl_compatibility_errors.
+ ERROR_ID_OLD_COMMAND_PARAMETER_TYPE_BSON_SERIALIZATION_TYPE_ANY)
+ self.assertRegex(
+ str(old_command_parameter_type_bson_any_unstable_error),
+ "oldCommandParamTypeBsonAnyUnstable")
+
+ new_command_parameter_type_bson_any_unstable_error = error_collection.get_error_by_command_name(
+ "newCommandParamTypeBsonAnyUnstable")
+ self.assertTrue(
+ new_command_parameter_type_bson_any_unstable_error.error_id == idl_compatibility_errors.
+ ERROR_ID_NEW_COMMAND_PARAMETER_TYPE_BSON_SERIALIZATION_TYPE_ANY)
+ self.assertRegex(
+ str(new_command_parameter_type_bson_any_unstable_error),
+ "newCommandParamTypeBsonAnyUnstable")
+
+ command_parameter_type_bson_any_not_allowed_unstable_error = error_collection.get_error_by_command_name(
+ "commandParamTypeBsonAnyNotAllowedUnstable")
+ self.assertTrue(command_parameter_type_bson_any_not_allowed_unstable_error.error_id ==
+ idl_compatibility_errors.
+ ERROR_ID_COMMAND_PARAMETER_BSON_SERIALIZATION_TYPE_ANY_NOT_ALLOWED)
+ self.assertRegex(
+ str(command_parameter_type_bson_any_not_allowed_unstable_error),
+ "commandParamTypeBsonAnyNotAllowedUnstable")
+
+ command_parameter_cpp_type_not_equal_unstable_error = error_collection.get_error_by_command_name(
+ "commandParameterCppTypeNotEqualUnstable")
+ self.assertTrue(command_parameter_cpp_type_not_equal_unstable_error.error_id ==
+ idl_compatibility_errors.ERROR_ID_COMMAND_PARAMETER_CPP_TYPE_NOT_EQUAL)
+ self.assertRegex(
+ str(command_parameter_cpp_type_not_equal_unstable_error),
+ "commandParameterCppTypeNotEqualUnstable")
+
+ parameter_field_type_bson_any_with_variant_unstable_error = error_collection.get_error_by_command_name_and_error_id(
+ "parameterFieldTypeBsonAnyWithVariantUnstable", idl_compatibility_errors.
+ ERROR_ID_OLD_COMMAND_PARAMETER_TYPE_BSON_SERIALIZATION_TYPE_ANY)
+ self.assertTrue(parameter_field_type_bson_any_with_variant_unstable_error.error_id ==
+ idl_compatibility_errors.
+ ERROR_ID_OLD_COMMAND_PARAMETER_TYPE_BSON_SERIALIZATION_TYPE_ANY)
+ self.assertRegex(
+ str(parameter_field_type_bson_any_with_variant_unstable_error),
+ "parameterFieldTypeBsonAnyWithVariantUnstable")
+
+ parameter_field_type_bson_any_with_variant_unstable_error = error_collection.get_error_by_command_name_and_error_id(
+ "parameterFieldTypeBsonAnyWithVariantUnstable", idl_compatibility_errors.
+ ERROR_ID_NEW_COMMAND_PARAMETER_TYPE_BSON_SERIALIZATION_TYPE_ANY)
+ self.assertTrue(parameter_field_type_bson_any_with_variant_unstable_error.error_id ==
+ idl_compatibility_errors.
+ ERROR_ID_NEW_COMMAND_PARAMETER_TYPE_BSON_SERIALIZATION_TYPE_ANY)
+ self.assertRegex(
+ str(parameter_field_type_bson_any_with_variant_unstable_error),
+ "parameterFieldTypeBsonAnyWithVariantUnstable")
+
+ newly_added_param_bson_any_not_allowed_error = error_collection.get_error_by_command_name(
+ "newlyAddedParamBsonAnyNotAllowed")
+ self.assertTrue(
+ newly_added_param_bson_any_not_allowed_error.error_id == idl_compatibility_errors.
+ ERROR_ID_COMMAND_PARAMETER_BSON_SERIALIZATION_TYPE_ANY_NOT_ALLOWED)
+ self.assertRegex(
+ str(newly_added_param_bson_any_not_allowed_error), "newlyAddedParamBsonAnyNotAllowed")
+
new_command_parameter_type_enum_not_superset = error_collection.get_error_by_command_name(
"newCommandParameterTypeEnumNotSuperset")
self.assertTrue(new_command_parameter_type_enum_not_superset.error_id ==
@@ -418,6 +481,67 @@ class TestIDLCompatibilityChecker(unittest.TestCase):
self.assertRegex(
str(reply_field_type_bson_any_with_variant_error), "replyFieldTypeBsonAnyWithVariant")
+ old_reply_field_type_bson_any_unstable_error = error_collection.get_error_by_command_name(
+ "oldReplyFieldTypeBsonAnyUnstable")
+ self.assertTrue(
+ old_reply_field_type_bson_any_unstable_error.error_id ==
+ idl_compatibility_errors.ERROR_ID_OLD_REPLY_FIELD_BSON_SERIALIZATION_TYPE_ANY)
+ self.assertRegex(
+ str(old_reply_field_type_bson_any_unstable_error), "oldReplyFieldTypeBsonAnyUnstable")
+
+ new_reply_field_type_bson_any_unstable_error = error_collection.get_error_by_command_name(
+ "newReplyFieldTypeBsonAnyUnstable")
+ self.assertTrue(
+ new_reply_field_type_bson_any_unstable_error.error_id ==
+ idl_compatibility_errors.ERROR_ID_NEW_REPLY_FIELD_BSON_SERIALIZATION_TYPE_ANY)
+ self.assertRegex(
+ str(new_reply_field_type_bson_any_unstable_error), "newReplyFieldTypeBsonAnyUnstable")
+
+ reply_field_type_bson_any_not_allowed_unstable_error = error_collection.get_error_by_command_name(
+ "replyFieldTypeBsonAnyNotAllowedUnstable")
+ self.assertTrue(
+ reply_field_type_bson_any_not_allowed_unstable_error.error_id ==
+ idl_compatibility_errors.ERROR_ID_REPLY_FIELD_BSON_SERIALIZATION_TYPE_ANY_NOT_ALLOWED)
+ self.assertRegex(
+ str(reply_field_type_bson_any_not_allowed_unstable_error),
+ "replyFieldTypeBsonAnyNotAllowedUnstable")
+
+ reply_field_type_bson_any_with_variant_unstable_error = error_collection.get_error_by_command_name_and_error_id(
+ "replyFieldTypeBsonAnyWithVariantUnstable",
+ idl_compatibility_errors.ERROR_ID_OLD_REPLY_FIELD_BSON_SERIALIZATION_TYPE_ANY)
+ self.assertTrue(
+ reply_field_type_bson_any_with_variant_unstable_error.error_id ==
+ idl_compatibility_errors.ERROR_ID_OLD_REPLY_FIELD_BSON_SERIALIZATION_TYPE_ANY)
+ self.assertRegex(
+ str(reply_field_type_bson_any_with_variant_unstable_error),
+ "replyFieldTypeBsonAnyWithVariantUnstable")
+
+ reply_field_type_bson_any_with_variant_unstable_error = error_collection.get_error_by_command_name_and_error_id(
+ "replyFieldTypeBsonAnyWithVariantUnstable",
+ idl_compatibility_errors.ERROR_ID_NEW_REPLY_FIELD_BSON_SERIALIZATION_TYPE_ANY)
+ self.assertTrue(
+ reply_field_type_bson_any_with_variant_unstable_error.error_id ==
+ idl_compatibility_errors.ERROR_ID_NEW_REPLY_FIELD_BSON_SERIALIZATION_TYPE_ANY)
+ self.assertRegex(
+ str(reply_field_type_bson_any_with_variant_unstable_error),
+ "replyFieldTypeBsonAnyWithVariantUnstable")
+
+ reply_field_cpp_type_not_equal_unstable_error = error_collection.get_error_by_command_name(
+ "replyFieldCppTypeNotEqualUnstable")
+ self.assertTrue(reply_field_cpp_type_not_equal_unstable_error.error_id ==
+ idl_compatibility_errors.ERROR_ID_REPLY_FIELD_CPP_TYPE_NOT_EQUAL)
+ self.assertRegex(
+ str(reply_field_cpp_type_not_equal_unstable_error), "replyFieldCppTypeNotEqualUnstable")
+
+ newly_added_reply_field_bson_any_not_allowed_error = error_collection.get_error_by_command_name(
+ "newlyAddedReplyFieldTypeBsonAnyNotAllowed")
+ self.assertTrue(
+ newly_added_reply_field_bson_any_not_allowed_error.error_id ==
+ idl_compatibility_errors.ERROR_ID_REPLY_FIELD_BSON_SERIALIZATION_TYPE_ANY_NOT_ALLOWED)
+ self.assertRegex(
+ str(newly_added_reply_field_bson_any_not_allowed_error),
+ "newlyAddedReplyFieldTypeBsonAnyNotAllowed")
+
reply_field_type_bson_any_with_variant_with_array_error = error_collection.get_error_by_command_name_and_error_id(
"replyFieldTypeBsonAnyWithVariantWithArray",
idl_compatibility_errors.ERROR_ID_OLD_REPLY_FIELD_BSON_SERIALIZATION_TYPE_ANY)
@@ -597,6 +721,62 @@ class TestIDLCompatibilityChecker(unittest.TestCase):
idl_compatibility_errors.ERROR_ID_COMMAND_CPP_TYPE_NOT_EQUAL)
self.assertRegex(str(command_cpp_type_not_equal_error), "commandCppTypeNotEqual")
+ old_type_bson_any_unstable_error = error_collection.get_error_by_command_name(
+ "oldTypeBsonAnyUnstable")
+ self.assertTrue(old_type_bson_any_unstable_error.error_id == idl_compatibility_errors.
+ ERROR_ID_OLD_COMMAND_TYPE_BSON_SERIALIZATION_TYPE_ANY)
+ self.assertRegex(str(old_type_bson_any_unstable_error), "oldTypeBsonAnyUnstable")
+
+ new_type_bson_any_unstable_error = error_collection.get_error_by_command_name(
+ "newTypeBsonAnyUnstable")
+ self.assertTrue(new_type_bson_any_unstable_error.error_id == idl_compatibility_errors.
+ ERROR_ID_NEW_COMMAND_TYPE_BSON_SERIALIZATION_TYPE_ANY)
+ self.assertRegex(str(new_type_bson_any_unstable_error), "newTypeBsonAnyUnstable")
+
+ type_bson_any_not_allowed_unstable_error = error_collection.get_error_by_command_name(
+ "typeBsonAnyNotAllowedUnstable")
+ self.assertTrue(
+ type_bson_any_not_allowed_unstable_error.error_id ==
+ idl_compatibility_errors.ERROR_ID_COMMAND_TYPE_BSON_SERIALIZATION_TYPE_ANY_NOT_ALLOWED)
+ self.assertRegex(
+ str(type_bson_any_not_allowed_unstable_error), "typeBsonAnyNotAllowedUnstable")
+
+ command_cpp_type_not_equal_unstable_error = error_collection.get_error_by_command_name(
+ "commandCppTypeNotEqualUnstable")
+ self.assertTrue(command_cpp_type_not_equal_unstable_error.error_id ==
+ idl_compatibility_errors.ERROR_ID_COMMAND_CPP_TYPE_NOT_EQUAL)
+ self.assertRegex(
+ str(command_cpp_type_not_equal_unstable_error), "commandCppTypeNotEqualUnstable")
+
+ command_type_bson_any_with_variant_unstable_error = error_collection.get_error_by_command_name_and_error_id(
+ "commandTypeBsonAnyWithVariantUnstable",
+ idl_compatibility_errors.ERROR_ID_OLD_COMMAND_TYPE_BSON_SERIALIZATION_TYPE_ANY)
+ self.assertTrue(
+ command_type_bson_any_with_variant_unstable_error.error_id ==
+ idl_compatibility_errors.ERROR_ID_OLD_COMMAND_TYPE_BSON_SERIALIZATION_TYPE_ANY)
+ self.assertRegex(
+ str(command_type_bson_any_with_variant_unstable_error),
+ "commandTypeBsonAnyWithVariantUnstable")
+
+ command_type_bson_any_with_variant_unstable_error = error_collection.get_error_by_command_name_and_error_id(
+ "commandTypeBsonAnyWithVariantUnstable",
+ idl_compatibility_errors.ERROR_ID_NEW_COMMAND_TYPE_BSON_SERIALIZATION_TYPE_ANY)
+ self.assertTrue(
+ command_type_bson_any_with_variant_unstable_error.error_id ==
+ idl_compatibility_errors.ERROR_ID_NEW_COMMAND_TYPE_BSON_SERIALIZATION_TYPE_ANY)
+ self.assertRegex(
+ str(command_type_bson_any_with_variant_unstable_error),
+ "commandTypeBsonAnyWithVariantUnstable")
+
+ newly_added_type_field_bson_any_not_allowed_error = error_collection.get_error_by_command_name(
+ "newlyAddedTypeFieldBsonAnyNotAllowed")
+ self.assertTrue(
+ newly_added_type_field_bson_any_not_allowed_error.error_id ==
+ idl_compatibility_errors.ERROR_ID_COMMAND_TYPE_BSON_SERIALIZATION_TYPE_ANY_NOT_ALLOWED)
+ self.assertRegex(
+ str(newly_added_type_field_bson_any_not_allowed_error),
+ "newlyAddedTypeFieldBsonAnyNotAllowed")
+
new_type_not_enum_error = error_collection.get_error_by_error_id(
idl_compatibility_errors.ERROR_ID_NEW_COMMAND_TYPE_NOT_ENUM)
self.assertRegex(str(new_type_not_enum_error), "newTypeNotEnum")