diff options
11 files changed, 764 insertions, 71 deletions
diff --git a/buildscripts/idl/idl_check_compatibility.py b/buildscripts/idl/idl_check_compatibility.py index 9a46eaa3583..1f40e304341 100644 --- a/buildscripts/idl/idl_check_compatibility.py +++ b/buildscripts/idl/idl_check_compatibility.py @@ -111,6 +111,16 @@ def check_subset(ctxt: IDLCompatibilityContext, cmd_name: str, field_name: str, ctxt.add_command_not_subset_error(cmd_name, field_name, type_name, file_path) +def check_superset(ctxt: IDLCompatibilityContext, cmd_name: str, param_name: str, type_name: str, + super_list: List[Union[str, syntax.EnumValue]], + sub_list: List[Union[str, syntax.EnumValue]], file_path: str): + # pylint: disable=too-many-arguments + """Check if super_list is a superset of the sub_list and log an error if not.""" + if not set(super_list).issuperset(sub_list): + ctxt.add_command_parameter_type_not_superset_error(cmd_name, param_name, type_name, + file_path) + + def check_type_superset(ctxt: IDLCompatibilityContext, cmd_name: str, type_name: str, sub_list: List[Union[str, syntax.EnumValue]], super_list: List[Union[str, syntax.EnumValue]], file_path: str): @@ -223,6 +233,56 @@ def check_reply_field_type(ctxt: IDLCompatibilityContext, cmd_name, field_name, new_field_type.name, old_field_type.name, new_idl_file_path) +def check_command_parameter_type( + ctxt: IDLCompatibilityContext, + old_parameter_type: Optional[Union[syntax.Enum, syntax.Struct, syntax.Type]], + new_parameter_type: Optional[Union[syntax.Enum, syntax.Struct, syntax.Type]], cmd_name: str, + param_name: str, old_idl_file_path: str, new_idl_file_path: str): + """Check compatibility between old and new command parameter type.""" + # pylint: disable=too-many-arguments,too-many-branches + if old_parameter_type is None: + ctxt.add_command_parameter_type_invalid_error(cmd_name, param_name, old_idl_file_path) + ctxt.errors.dump_errors() + sys.exit(1) + if new_parameter_type is None: + ctxt.add_command_parameter_type_invalid_error(cmd_name, param_name, new_idl_file_path) + ctxt.errors.dump_errors() + sys.exit(1) + + if isinstance(old_parameter_type, syntax.Type): + if isinstance(new_parameter_type, syntax.Type): + if "any" in old_parameter_type.bson_serialization_type: + ctxt.add_old_parameter_type_bson_any_error( + cmd_name, param_name, old_parameter_type.name, old_idl_file_path) + elif "any" in new_parameter_type.bson_serialization_type: + ctxt.add_new_parameter_type_bson_any_error( + cmd_name, param_name, new_parameter_type.name, new_idl_file_path) + + else: + check_superset(ctxt, cmd_name, param_name, new_parameter_type.name, + new_parameter_type.bson_serialization_type, + old_parameter_type.bson_serialization_type, new_idl_file_path) + else: + ctxt.add_new_command_parameter_type_enum_or_struct_error( + cmd_name, param_name, new_parameter_type.name, old_parameter_type.name, + new_idl_file_path) + + elif isinstance(old_parameter_type, syntax.Enum): + if isinstance(new_parameter_type, syntax.Enum): + check_superset(ctxt, cmd_name, param_name, new_parameter_type.name, + new_parameter_type.values, old_parameter_type.values, new_idl_file_path) + else: + ctxt.add_new_command_parameter_type_not_enum_error( + cmd_name, param_name, new_parameter_type.name, old_parameter_type.name, + new_idl_file_path) + + elif isinstance(old_parameter_type, syntax.Struct): + if not isinstance(new_parameter_type, syntax.Struct): + ctxt.add_new_command_parameter_type_not_struct_error( + cmd_name, param_name, new_parameter_type.name, old_parameter_type.name, + new_idl_file_path) + + def check_command_type(ctxt: IDLCompatibilityContext, old_type: Optional[Union[syntax.Enum, syntax.Struct, syntax.Type]], new_type: Optional[Union[syntax.Enum, syntax.Struct, syntax.Type]], @@ -355,8 +415,9 @@ def check_reply_fields(ctxt: IDLCompatibilityContext, old_reply: syntax.Struct, def check_command_parameters(ctxt: IDLCompatibilityContext, old_cmd: syntax.Command, - new_cmd: syntax.Command, cmd_name: str, old_idl_file_path: str, - new_idl_file_path: str): + new_cmd: syntax.Command, cmd_name: str, + old_idl_file: syntax.IDLParsedSpec, new_idl_file: syntax.IDLParsedSpec, + old_idl_file_path: str, new_idl_file_path: str): """Check compatibility between old and new command parameters.""" # pylint: disable=too-many-arguments for old_param in old_cmd.fields: @@ -364,7 +425,8 @@ def check_command_parameters(ctxt: IDLCompatibilityContext, old_cmd: syntax.Comm for new_param in new_cmd.fields: if new_param.name == old_param.name: new_param_exists = True - check_command_parameter(ctxt, old_param, new_param, cmd_name, old_idl_file_path) + check_command_parameter(ctxt, old_param, new_param, cmd_name, old_idl_file, + new_idl_file, old_idl_file_path, new_idl_file_path) break if not new_param_exists and not old_param.unstable: @@ -385,8 +447,11 @@ def check_command_parameters(ctxt: IDLCompatibilityContext, old_cmd: syntax.Comm def check_command_parameter(ctxt: IDLCompatibilityContext, old_param: syntax.Field, - new_param: syntax.Field, cmd_name: str, old_idl_file_path: str): + new_param: syntax.Field, cmd_name: str, + old_idl_file: syntax.IDLParsedSpec, new_idl_file: syntax.IDLParsedSpec, + old_idl_file_path: str, new_idl_file_path: str): """Check compatibility between the old and new command parameter.""" + # pylint: disable=too-many-arguments if not old_param.unstable and new_param.unstable: ctxt.add_command_parameter_unstable_error(cmd_name, old_param.name, old_idl_file_path) if old_param.unstable and not new_param.optional and not new_param.unstable: @@ -394,7 +459,12 @@ def check_command_parameter(ctxt: IDLCompatibilityContext, old_param: syntax.Fie old_idl_file_path) if old_param.optional and not new_param.optional: ctxt.add_command_parameter_required_error(cmd_name, old_param.name, old_idl_file_path) - #TODO (SERVER-53203): Type check command parameters. + + old_parameter_type = get_field_type(old_param, old_idl_file, old_idl_file_path) + new_parameter_type = get_field_type(new_param, new_idl_file, new_idl_file_path) + + check_command_parameter_type(ctxt, old_parameter_type, new_parameter_type, cmd_name, + old_param.name, old_idl_file_path, new_idl_file_path) def check_namespace(ctxt: IDLCompatibilityContext, old_cmd: syntax.Command, new_cmd: syntax.Command, @@ -528,7 +598,8 @@ def check_compatibility(old_idl_dir: str, new_idl_dir: str, # Check compatibility of command's parameters. check_command_parameters(ctxt, old_cmd, new_cmd, old_cmd.command_name, - old_idl_file_path, new_idl_file_path) + old_idl_file, new_idl_file, old_idl_file_path, + new_idl_file_path) check_namespace(ctxt, old_cmd, new_cmd, old_idl_file, new_idl_file, old_idl_file_path, new_idl_file_path) diff --git a/buildscripts/idl/idl_compatibility_errors.py b/buildscripts/idl/idl_compatibility_errors.py index bbcd81d844d..f8e7d91f5dc 100644 --- a/buildscripts/idl/idl_compatibility_errors.py +++ b/buildscripts/idl/idl_compatibility_errors.py @@ -73,6 +73,13 @@ ERROR_ID_ADDED_REQUIRED_COMMAND_PARAMETER = "ID0029" ERROR_ID_COMMAND_PARAMETER_UNSTABLE = "ID0030" ERROR_ID_COMMAND_PARAMETER_STABLE_REQUIRED = "ID0031" ERROR_ID_COMMAND_PARAMETER_REQUIRED = "ID0032" +ERROR_ID_OLD_COMMAND_PARAMETER_TYPE_BSON_SERIALIZATION_TYPE_ANY = "ID0033" +ERROR_ID_NEW_COMMAND_PARAMETER_TYPE_BSON_SERIALIZATION_TYPE_ANY = "ID0034" +ERROR_ID_NEW_COMMAND_PARAMETER_TYPE_NOT_STRUCT = "ID0035" +ERROR_ID_NEW_COMMAND_PARAMETER_TYPE_NOT_ENUM = "ID0036" +ERROR_ID_NEW_COMMAND_PARAMETER_TYPE_ENUM_OR_STRUCT = "ID0037" +ERROR_ID_COMMAND_PARAMETER_TYPE_INVALID = "ID0038" +ERROR_ID_COMMAND_PARAMETER_TYPE_NOT_SUPERSET = "ID0039" class IDLCompatibilityCheckerError(Exception): @@ -278,8 +285,8 @@ class IDLCompatibilityContext(object): """Add an error about the command not being a subset.""" self._add_error( ERROR_ID_COMMAND_NOT_SUBSET, command_name, - "'%s' has field '%s' with type '%s' that is not a subset of the other version of this command." - % (command_name, field_name, type_name), file) + "'%s' has field '%s' with type '%s' that is not a subset of the other version " + "of this command." % (command_name, field_name, type_name), file) def add_command_type_invalid_error(self, command_name: str, file: str) -> None: """Add an error about the command type being invalid.""" @@ -294,6 +301,86 @@ class IDLCompatibilityContext(object): "'%s' has type '%s' that is not a subset of the other version of this command." % (command_name, type_name), file) + def add_old_parameter_type_bson_any_error(self, command_name: str, param_name: str, + old_type: str, file: str) -> None: + """ + Add an error about BSON serialization type. + + Add an error about the old command parameter type's + bson serialization type being of type "any". + """ + self._add_error( + ERROR_ID_OLD_COMMAND_PARAMETER_TYPE_BSON_SERIALIZATION_TYPE_ANY, command_name, + ("The '%s'' command has parameter '%s' that has type '%s' " + "that has a bson serialization type 'any'") % (command_name, param_name, old_type), + file) + + def add_new_parameter_type_bson_any_error(self, command_name: str, param_name: str, + new_type: str, file: str) -> None: + """ + Add an error about BSON serialization type. + + Add an error about the new command parameter type's + bson serialization type being of type "any". + """ + self._add_error( + ERROR_ID_NEW_COMMAND_PARAMETER_TYPE_BSON_SERIALIZATION_TYPE_ANY, command_name, + ("The '%s'' command has parameter '%s' that has type '%s' " + "that has a bson serialization type 'any'") % (command_name, param_name, new_type), + file) + + def add_new_command_parameter_type_not_enum_error(self, command_name: str, param_name: str, + new_type: str, old_type: str, + file: str) -> None: + # pylint: disable=too-many-arguments + """Add an error about the new command parameter type not being an enum when the old one is.""" + self._add_error( + ERROR_ID_NEW_COMMAND_PARAMETER_TYPE_NOT_ENUM, command_name, + ("The '%s' command has parameter '%s' of type '%s' that is not an enum while the " + "corresponding old parameter type was an enum of type '%s'.") % + (command_name, param_name, new_type, old_type), file) + + def add_new_command_parameter_type_not_struct_error(self, command_name: str, param_name: str, + new_type: str, old_type: str, + file: str) -> None: + # pylint: disable=too-many-arguments + """Add an error about the new command parameter type not being a struct when the old one is.""" + self._add_error(ERROR_ID_NEW_COMMAND_PARAMETER_TYPE_NOT_STRUCT, command_name, ( + "The '%s' command has parameter '%s' of type '%s' that is not a struct while the corresponding " + "old parameter type was a struct of type '%s'.") % (command_name, param_name, new_type, + old_type), file) + + def add_new_command_parameter_type_enum_or_struct_error(self, command_name: str, + param_name: str, new_type: str, + old_type: str, file: str) -> None: + # pylint: disable=too-many-arguments + """ + Add an error about a non-enum or non-struct type. + + Add an error when the new command parameter type is an enum or + struct and the old one is a non-enum or non-struct type. + """ + self._add_error( + ERROR_ID_NEW_COMMAND_PARAMETER_TYPE_ENUM_OR_STRUCT, command_name, + ("The command '%s' has parameter '%s' of type '%s' that is an enum or struct " + "while the corresponding old parameter type is a non-enum or " + "non-struct of type '%s'.") % (command_name, param_name, new_type, old_type), file) + + def add_command_parameter_type_invalid_error(self, command_name: str, param_name: str, + file: str) -> None: + """Add an error about the command parameter type being invalid.""" + self._add_error(ERROR_ID_COMMAND_PARAMETER_TYPE_INVALID, command_name, + ("The '%s' command has a parameter '%s' that has an invalid type") % + (command_name, param_name), file) + + def add_command_parameter_type_not_superset_error(self, command_name: str, param_name: str, + type_name: str, file: str) -> None: + """Add an error about the new command parameter not being a superset.""" + self._add_error( + ERROR_ID_COMMAND_PARAMETER_TYPE_NOT_SUPERSET, command_name, + "The command '%s' has parameter '%s' with type '%s' that is not a superset of the older version " + "of this command parameter type." % (command_name, param_name, type_name), file) + def add_missing_error_reply_struct_error(self, file: str) -> None: """Add an error about the file missing the ErrorReply struct.""" self._add_error(ERROR_ID_MISSING_ERROR_REPLY_STRUCT, "n/a", diff --git a/buildscripts/idl/tests/compatibility_test_fail/abort/invalid_command_parameter_type/invalid_command_parameter_type.idl b/buildscripts/idl/tests/compatibility_test_fail/abort/invalid_command_parameter_type/invalid_command_parameter_type.idl new file mode 100644 index 00000000000..d3cb049b4a4 --- /dev/null +++ b/buildscripts/idl/tests/compatibility_test_fail/abort/invalid_command_parameter_type/invalid_command_parameter_type.idl @@ -0,0 +1,46 @@ +# Copyright (C) 2021-present MongoDB, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the Server Side Public License, version 1, +# as published by MongoDB, Inc. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# Server Side Public License for more details. +# +# You should have received a copy of the Server Side Public License +# along with this program. If not, see +# <http://www.mongodb.com/licensing/server-side-public-license>. +# +# As a special exception, the copyright holders give permission to link the +# code of portions of this program with the OpenSSL library under certain +# conditions as described in each individual source file and distribute +# linked combinations including the program with the OpenSSL library. You +# must comply with the Server Side Public License in all respects for +# all of the code used other than as permitted herein. If you modify file(s) +# with this exception, you may extend this exception to your version of the +# file(s), but you are not obligated to do so. If you do not wish to do so, +# delete this exception statement from your version. If you delete this +# exception statement from all source files in the program, then also delete +# it in the license file. +# + +global: + cpp_namespace: "mongo" + +imports: + - "mongo/idl/basic_types.idl" + +commands: + commandParameterTypeInvalid: + description: "invalid command parameter type" + command_name: commandParameterTypeInvalid + namespace: ignored + cpp_name: commandParameterTypeInvalid + strict: true + api_version: "1" + reply_type: OkReply + fields: + invalidParameter: + type: None
\ No newline at end of file diff --git a/buildscripts/idl/tests/compatibility_test_fail/old_abort/compatibility_test_abort_old.idl b/buildscripts/idl/tests/compatibility_test_fail/abort/invalid_reply_field_type/invalid_reply_field_type.idl index 1da78508aa1..0402d5233f7 100644 --- a/buildscripts/idl/tests/compatibility_test_fail/old_abort/compatibility_test_abort_old.idl +++ b/buildscripts/idl/tests/compatibility_test_fail/abort/invalid_reply_field_type/invalid_reply_field_type.idl @@ -34,14 +34,14 @@ imports: structs: InvalidFieldTypeReply: - description: "This reply contains a field where the old type is invalid" + description: "This reply contains a field where the type is invalid" fields: invalidReplyField: type: None commands: replyFieldTypeInvalid: - description: "old command aborts because its reply field type is invalid" + description: "invalid reply field type" command_name: replyFieldTypeInvalid namespace: ignored cpp_name: replyFieldTypeInvalid diff --git a/buildscripts/idl/tests/compatibility_test_fail/abort/valid_command_parameter_type/valid_command_parameter_type.idl b/buildscripts/idl/tests/compatibility_test_fail/abort/valid_command_parameter_type/valid_command_parameter_type.idl new file mode 100644 index 00000000000..55dff356232 --- /dev/null +++ b/buildscripts/idl/tests/compatibility_test_fail/abort/valid_command_parameter_type/valid_command_parameter_type.idl @@ -0,0 +1,46 @@ +# Copyright (C) 2021-present MongoDB, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the Server Side Public License, version 1, +# as published by MongoDB, Inc. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# Server Side Public License for more details. +# +# You should have received a copy of the Server Side Public License +# along with this program. If not, see +# <http://www.mongodb.com/licensing/server-side-public-license>. +# +# As a special exception, the copyright holders give permission to link the +# code of portions of this program with the OpenSSL library under certain +# conditions as described in each individual source file and distribute +# linked combinations including the program with the OpenSSL library. You +# must comply with the Server Side Public License in all respects for +# all of the code used other than as permitted herein. If you modify file(s) +# with this exception, you may extend this exception to your version of the +# file(s), but you are not obligated to do so. If you do not wish to do so, +# delete this exception statement from your version. If you delete this +# exception statement from all source files in the program, then also delete +# it in the license file. +# + +global: + cpp_namespace: "mongo" + +imports: + - "mongo/idl/basic_types.idl" + +commands: + commandParameterTypeInvalid: + description: "valid command parameter type" + command_name: commandParameterTypeInvalid + namespace: ignored + cpp_name: commandParameterTypeInvalid + strict: true + api_version: "1" + reply_type: OkReply + fields: + invalidParameter: + type: string
\ No newline at end of file diff --git a/buildscripts/idl/tests/compatibility_test_fail/new_abort/compatibility_test_abort_new.idl b/buildscripts/idl/tests/compatibility_test_fail/abort/valid_reply_field_type/valid_reply_field_type.idl index 92ced99e57f..c85a5c9b05d 100644 --- a/buildscripts/idl/tests/compatibility_test_fail/new_abort/compatibility_test_abort_new.idl +++ b/buildscripts/idl/tests/compatibility_test_fail/abort/valid_reply_field_type/valid_reply_field_type.idl @@ -34,14 +34,14 @@ imports: structs: InvalidFieldTypeReply: - description: "This reply contains a field where the old type is invalid" + description: "This reply contains a field where the type is valid" fields: invalidReplyField: type: string commands: replyFieldTypeInvalid: - description: "old command abort because its reply field type is invalid" + description: "valid reply field type" command_name: replyFieldTypeInvalid namespace: ignored cpp_name: replyFieldTypeInvalid 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 f3f4b5a0ab5..5bc00d8a445 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 @@ -74,6 +74,13 @@ types: field type" cpp_type: "std::int32_t" + intStringToInt: + bson_serialization_type: + - int + description: "The bson_serialization_type changes from [int, string] in the old command + parameter's type to [int] in the new command parameter's type" + cpp_type: "std::int32_t" + enums: NewReplyFieldEnumNotSubset: description: "The new reply type is an enum that is not a subset of the old reply type's @@ -92,6 +99,9 @@ enums: valueTwo: "two" structs: + StructCommandParameterType: + description: "This is a struct command parameter type" + UnstableNewFieldReply: description: "This reply contains a field that is stable in the old command but is unstable in the new command." @@ -213,8 +223,8 @@ structs: variant: [int, bool, string] VariantRecursiveReply: - description: "This reply contains a field that has a new variant type that is not compatible - with the old variant type" + description: "This reply contains a field that has a new variant type that is not + compatible with the old variant type" fields: variantRecursiveReplyField: type: @@ -229,8 +239,8 @@ structs: variant: [int, string, StructType] VariantStructRecursiveReply: - description: "This reply contains a field that has a new variant struct type that is not compatible - with the old variant struct type" + description: "This reply contains a field that has a new variant struct type that is not + compatible with the old variant struct type" fields: variantStructRecursiveReplyField: type: @@ -277,8 +287,8 @@ commands: reply_type: OkReply removedCommandParameter: - description: "parameter will be removed from command in compatibility_test_fail/new which results - in an error" + description: "parameter will be removed from command in compatibility_test_fail/new + which results in an error" command_name: removedCommandParameter namespace: ignored cpp_name: removedCommandParameter @@ -287,7 +297,8 @@ commands: reply_type: OkReply addedNewCommandParameterRequired: - description: "new command parameter fails because it is required when it should be optional" + description: "new command parameter fails because it is required when + it should be optional" command_name: addedNewCommandParameterRequired namespace: ignored cpp_name: addedNewCommandParameterRequired @@ -339,6 +350,111 @@ commands: type: string optional: false + oldCommandParameterTypeBsonSerializationAny: + description: "old command fails because it has a parameter type that has a + bson_serialization_type that contains 'any'" + command_name: oldCommandParameterTypeBsonSerializationAny + namespace: ignored + cpp_name: oldCommandParameterTypeBsonSerializationAny + strict: true + api_version: "1" + reply_type: OkReply + fields: + bsonTypeAnyParam: + type: oldBsonSerializationTypeAny + + newCommandParameterTypeBsonSerializationAny: + description: "new command fails because it has a parameter type that has a + bson_serialization_type that contains 'any'" + command_name: newCommandParameterTypeBsonSerializationAny + namespace: ignored + cpp_name: newCommandParameterTypeBsonSerializationAny + strict: true + api_version: "1" + reply_type: OkReply + fields: + bsonTypeAnyParam: + type: newBsonSerializationTypeAny + + 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" + command_name: newCommandParameterTypeEnumNotSuperset + namespace: ignored + cpp_name: newCommandParameterTypeEnumNotSuperset + strict: true + api_version: "1" + reply_type: OkReply + fields: + enumNotSupersetParam: + type: EnumNotSuperset + + newCommandParameterTypeNotEnum: + description: "new command fails because its parameter type is not an enum when the + old command parameter type is an enum" + command_name: newCommandParameterTypeNotEnum + namespace: ignored + cpp_name: newCommandParameterTypeNotEnum + strict: true + api_version: "1" + reply_type: OkReply + fields: + newParamNotEnum: + type: string + + newCommandParameterTypeNotStruct: + description: "new command fails because its parameter type is not a struct when the + old command parameter type is a struct" + command_name: newCommandParameterTypeNotStruct + namespace: ignored + cpp_name: newCommandParameterTypeNotStruct + strict: true + api_version: "1" + reply_type: OkReply + fields: + newParamNotStruct: + type: string + + newCommandParameterTypeEnumOrStructOne: + description: "new command fails because its parameter type is an enum while the + parameter type in the old command is an non-enum or non-struct" + command_name: newCommandParameterTypeEnumOrStructOne + namespace: ignored + cpp_name: newCommandParameterTypeEnumOrStructOne + strict: true + api_version: "1" + reply_type: OkReply + fields: + newParamEnum: + type: EnumNotSuperset + + newCommandParameterTypeEnumOrStructTwo: + description: "new command fails because its parameter type is a struct while the + parameter type in the old command is an non-enum or non-struct" + command_name: newCommandParameterTypeEnumOrStructTwo + namespace: ignored + cpp_name: newCommandParameterTypeEnumOrStructTwo + strict: true + api_version: "1" + reply_type: OkReply + fields: + newParamStruct: + type: StructCommandParameterType + + newCommandParameterTypeBsonNotSuperset: + description: "new command fails because its parameter type has a bson_serialization_type + that is not a superset of the corresponding old command parameter type's + bson_serialization_type" + command_name: newCommandParameterTypeBsonNotSuperset + namespace: ignored + cpp_name: newCommandParameterTypeBsonNotSuperset + strict: true + api_version: "1" + reply_type: OkReply + fields: + newParamBsonNotSuperset: + type: intStringToInt + newReplyFieldUnstable: description: "new command fails because it contains an unstable reply field that is stable in the corresponding old command" @@ -681,8 +797,9 @@ commands: reply_type: NewVariantStructNotSubsetReply replyFieldVariantStructRecursive: - description: "new command fails because its reply field type has a variant struct type that is not - compatible with the old reply field variant struct type" + description: "new command fails because its reply field type has a variant + struct type that is not compatible with the old reply field variant + struct type" command_name: replyFieldVariantStructRecursive namespace: ignored cpp_name: replyFieldVariantStructRecursive 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 cb846cea89d..e4ce4cfd775 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 @@ -72,6 +72,14 @@ types: field type" cpp_type: "std::int32_t" + intStringToInt: + bson_serialization_type: + - int + - string + description: "The bson_serialization_type changes from [int, string] in the old command + parameter's type to [int] in the new command parameter's type" + cpp_type: "std::int32_t" + enums: NewReplyFieldEnumNotSubset: description: "The new reply type is an enum that is not a subset of the old reply type's @@ -90,6 +98,9 @@ enums: valueThree: "three" structs: + StructCommandParameterType: + description: "This is a struct command parameter type" + UnstableNewFieldReply: description: "This reply contains a field that is stable in the old command but is unstable in the new command." @@ -215,8 +226,8 @@ structs: variant: [int, string] VariantRecursiveReply: - description: "This reply contains a field that has a new variant type that is not compatible - with the old variant type" + description: "This reply contains a field that has a new variant type that is not + compatible with the old variant type" fields: variantRecursiveReplyField: type: @@ -231,8 +242,8 @@ structs: variant: [int, string] VariantStructRecursiveReply: - description: "This reply contains a field that has a new variant struct type that is not compatible - with the old variant struct type" + description: "This reply contains a field that has a new variant struct type that is not + compatible with the old variant struct type" fields: variantStructRecursiveReplyField: type: @@ -269,8 +280,8 @@ commands: reply_type: OkReply removedCommandParameter: - description: "parameter will be removed from command in compatibility_test_fail/new which results - in an error" + description: "parameter will be removed from command in compatibility_test_fail/new + which results in an error" command_name: removedCommandParameter namespace: ignored cpp_name: removedCommandParameter @@ -282,7 +293,8 @@ commands: type: string addedNewCommandParameterRequired: - description: "new command parameter fails because it is required when it should be optional" + description: "new command parameter fails because it is required when + it should be optional" command_name: addedNewCommandParameterRequired namespace: ignored cpp_name: addedNewCommandParameterRequired @@ -330,7 +342,112 @@ commands: newRequiredParam: type: string optional: true + + oldCommandParameterTypeBsonSerializationAny: + description: "old command fails because it has a parameter type that has a + bson_serialization_type that contains 'any'" + command_name: oldCommandParameterTypeBsonSerializationAny + namespace: ignored + cpp_name: oldCommandParameterTypeBsonSerializationAny + strict: true + api_version: "1" + reply_type: OkReply + fields: + bsonTypeAnyParam: + type: oldBsonSerializationTypeAny + + newCommandParameterTypeBsonSerializationAny: + description: "new command fails because it has a parameter type that has a + bson_serialization_type that contains 'any'" + command_name: newCommandParameterTypeBsonSerializationAny + namespace: ignored + cpp_name: newCommandParameterTypeBsonSerializationAny + strict: true + api_version: "1" + reply_type: OkReply + fields: + bsonTypeAnyParam: + type: newBsonSerializationTypeAny + + 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" + command_name: newCommandParameterTypeEnumNotSuperset + namespace: ignored + cpp_name: newCommandParameterTypeEnumNotSuperset + strict: true + api_version: "1" + reply_type: OkReply + fields: + enumNotSupersetParam: + type: EnumNotSuperset + + newCommandParameterTypeNotEnum: + description: "new command fails because its parameter type is not an enum when the + old command parameter type is an enum" + command_name: newCommandParameterTypeNotEnum + namespace: ignored + cpp_name: newCommandParameterTypeNotEnum + strict: true + api_version: "1" + reply_type: OkReply + fields: + newParamNotEnum: + type: EnumNotSuperset + + newCommandParameterTypeNotStruct: + description: "new command fails because its parameter type is not a struct when the + old command parameter type is a struct" + command_name: newCommandParameterTypeNotStruct + namespace: ignored + cpp_name: newCommandParameterTypeNotStruct + strict: true + api_version: "1" + reply_type: OkReply + fields: + newParamNotStruct: + type: StructCommandParameterType + newCommandParameterTypeEnumOrStructOne: + description: "new command fails because its parameter type is an enum while the + parameter type in the old command is an non-enum or non-struct" + command_name: newCommandParameterTypeEnumOrStructOne + namespace: ignored + cpp_name: newCommandParameterTypeEnumOrStructOne + strict: true + api_version: "1" + reply_type: OkReply + fields: + newParamEnum: + type: string + + newCommandParameterTypeEnumOrStructTwo: + description: "new command fails because its parameter type is a struct while the + parameter type in the old command is an non-enum or non-struct" + command_name: newCommandParameterTypeEnumOrStructTwo + namespace: ignored + cpp_name: newCommandParameterTypeEnumOrStructTwo + strict: true + api_version: "1" + reply_type: OkReply + fields: + newParamStruct: + type: string + + newCommandParameterTypeBsonNotSuperset: + description: "new command fails because its parameter type has a bson_serialization_type + that is not a superset of the corresponding old command parameter type's + bson_serialization_type" + command_name: newCommandParameterTypeBsonNotSuperset + namespace: ignored + cpp_name: newCommandParameterTypeBsonNotSuperset + strict: true + api_version: "1" + reply_type: OkReply + fields: + newParamBsonNotSuperset: + type: intStringToInt + newReplyFieldUnstable: description: "new command fails because it contains an unstable reply field that is stable in the corresponding old command" @@ -673,8 +790,9 @@ commands: reply_type: NewVariantStructNotSubsetReply replyFieldVariantStructRecursive: - description: "new command fails because its reply field type has a variant struct type that is not - compatible with the old reply field variant struct type" + description: "new command fails because its reply field type has a variant + struct type that is not compatible with the old reply field variant + struct type" command_name: replyFieldVariantStructRecursive namespace: ignored cpp_name: replyFieldVariantStructRecursive 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 67c6a14f91b..c918965f5c5 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 @@ -59,9 +59,17 @@ types: type" cpp_type: "std::int32_t" + intToIntString: + bson_serialization_type: + - int + - string + description: "The bson_serialization_type changes from [int] in the old command + parameter's type to [int, string] in the new command parameter's type" + cpp_type: "std::int32_t" + enums: NewReplyFieldEnumSubset: - description: "The new reply type is an enum that is a subset of the old reply type's + description: "The new reply type is an enum that is a subset of the old reply type's enum values" type: string values: @@ -69,7 +77,7 @@ enums: valueTwo: "two" EnumSuperset: - description: "The new enum is not a superset of the old enum values" + description: "The new enum is a superset of the old enum values" type: string values: valueOne: "one" @@ -188,14 +196,18 @@ structs: variant: [int, string] VariantStructRecursiveReply: - description: "This reply contains a field that has a new variant struct type that is compatible - with the old variant struct type" + description: "This reply contains a field that has a new variant struct type that is + compatible with the old variant struct type" fields: variantStructRecursiveReplyField: type: variant: [int, StructFieldTypeRecursiveReplyTwo] + NewCommandParameterStruct: + description: "The new command parameter's type and the + old command parameter's type are both structs" + commands: testCommand: description: "new passing test command, there was no change from the old version" @@ -295,6 +307,59 @@ commands: type: string unstable: true + newCommandParameterType: + description: "new command passes because its command parameter type is compatible with + the corresponding old command's parameter type" + command_name: newCommandParameterType + namespace: ignored + cpp_name: newCommandParameterType + strict: true + api_version: "1" + reply_type: OkReply + fields: + compatibleParameter: + type: string + + newCommandParameterTypeEnumSuperset: + description: "new command passes because its command parameter type is an enum that is + a superset of the corresponding old command parameter's type's enum values" + command_name: newCommandParameterTypeEnumSuperset + namespace: ignored + cpp_name: newCommandParameterTypeEnumSuperset + strict: true + api_version: "1" + reply_type: OkReply + fields: + parameterEnumSuperset: + type: EnumSuperset + + newCommandParameterTypeStruct: + description: "new command passes because its command parameter type is a struct and the + corresponding old command parameter type is also a struct" + command_name: newCommandParameterTypeStruct + namespace: ignored + cpp_name: newCommandParameterTypeStruct + strict: true + api_version: "1" + reply_type: OkReply + fields: + parameterStruct: + type: NewCommandParameterStruct + + newCommandParameterTypeBsonSuperset: + description: "new command passes because its parameter type has a bson_serialization_type + that is a superset of the corresponding old command parameter type's + bson_serialization_type" + command_name: newCommandParameterTypeBsonSuperset + namespace: ignored + cpp_name: newCommandParameterTypeBsonSuperset + strict: true + api_version: "1" + reply_type: OkReply + fields: + bsonSupersetParam: + type: intToIntString + newReplyFieldStable: description: "new command contains a stable reply field that is unstable in the corresponding old command and still passes" @@ -354,9 +419,9 @@ commands: reply_type: EnumSubsetReply newReplyFieldTypeBsonSubset: - description: "new command passes because its reply field type has a bson_serialization_type - that is a subset of the corresponding old reply field type's - bson_serialization_type" + description: "new command passes because its reply field type has a + bson_serialization_type that is a subset of the corresponding + old reply field type's bson_serialization_type" command_name: newReplyFieldTypeBsonSubset namespace: ignored cpp_name: newReplyFieldTypeBsonSubset @@ -365,9 +430,9 @@ commands: reply_type: BsonSubsetReply newReplyFieldTypeBsonSubsetTwo: - description: "new command passes because its reply field type has a bson_serialization_type - that is a subset of the corresponding old reply field type's - bson_serialization_type" + description: "new command passes because its reply field type has a + bson_serialization_type that is a subset of the corresponding + old reply field type's bson_serialization_type" command_name: newReplyFieldTypeBsonSubsetTwo namespace: ignored cpp_name: newReplyFieldTypeBsonSubsetTwo @@ -405,8 +470,8 @@ commands: reply_type: OkReply newNamespaceConcatenateWithDbOrUuid: - description: "new command passes when its namespace is changed to concatenate_with_db_or_uuid - from concatenate_with_db" + description: "new command passes when its namespace is changed to + concatenate_with_db_or_uuid from concatenate_with_db" command_name: newNamespaceConcatenateWithDbOrUuid namespace: concatenate_with_db_or_uuid cpp_name: newNamespaceConcatenateWithDbOrUuid @@ -424,8 +489,8 @@ commands: reply_type: OkReply oldNamespaceTypeNamespaceString: - description: "If old command has namespace: type and type: namespacestring, the new namespace - can be changed to concatenate_with_db" + description: "If old command has namespace: type and type: namespacestring, + the new namespace can be changed to concatenate_with_db" command_name: oldNamespaceTypeNamespaceString namespace: concatenate_with_db cpp_name: oldNamespaceTypeNamespaceString @@ -434,8 +499,8 @@ commands: reply_type: OkReply oldNamespaceTypeNamespaceStringTwo: - description: "If old command has namespace: type and type: namespacestring, the new namespace - can be changed to concatenate_with_db_or_uuid" + description: "If old command has namespace: type and type: namespacestring, + the new namespace can be changed to concatenate_with_db_or_uuid" command_name: oldNamespaceTypeNamespaceStringTwo namespace: concatenate_with_db_or_uuid cpp_name: oldNamespaceTypeNamespaceStringTwo @@ -507,7 +572,7 @@ commands: reply_type: VariantRecursiveReply oldReplyFieldVariantStruct: - description: "new command passes if it doesn't have a variant struct type while the + description: "new command passes if it doesn't have a variant struct type while the old command does" command_name: oldReplyFieldVariantStruct namespace: ignored @@ -517,8 +582,8 @@ commands: reply_type: OldVariantStructReply replyFieldVariantStructRecursive: - description: "new command passes when its reply field type has a variant struct type that is - compatible with the old reply field variant struct type" + description: "new command passes when its reply field type has a variant struct type + that is compatible with the old reply field variant struct type" command_name: replyFieldVariantStructRecursive namespace: ignored cpp_name: replyFieldVariantStructRecursive 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 1883d4b8cb9..bc3a0d0168f 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 @@ -61,9 +61,16 @@ types: type" cpp_type: "std::int32_t" + intToIntString: + bson_serialization_type: + - int + description: "The bson_serialization_type changes from [int] in the old command + parameter's type to [int, string] in the new command parameter's type" + cpp_type: "std::int32_t" + enums: NewReplyFieldEnumSubset: - description: "The new reply type is an enum that is a subset of the old reply type's + description: "The new reply type is an enum that is a subset of the old reply type's enum values" type: string values: @@ -72,7 +79,7 @@ enums: valueThree: "three" EnumSuperset: - description: "The new enum is not a superset of the old enum values" + description: "The new enum is a superset of the old enum values" type: string values: valueOne: "one" @@ -188,13 +195,17 @@ structs: variant: [int, string, StructType] VariantStructRecursiveReply: - description: "This reply contains a field that has a new variant struct type that is compatible - with the old variant struct type" + description: "This reply contains a field that has a new variant struct type that is + compatible with the old variant struct type" fields: variantStructRecursiveReplyField: type: variant: [int, StructFieldTypeRecursiveReplyTwo] + NewCommandParameterStruct: + description: "The new command parameter's type and the + old command parameter's type are both structs" + commands: testCommand: description: "old passing test command" @@ -289,6 +300,59 @@ commands: type: string unstable: true + newCommandParameterType: + description: "new command passes because its command parameter type is compatible with + the corresponding old command's parameter type" + command_name: newCommandParameterType + namespace: ignored + cpp_name: newCommandParameterType + strict: true + api_version: "1" + reply_type: OkReply + fields: + compatibleParameter: + type: string + + newCommandParameterTypeEnumSuperset: + description: "new command passes because its command parameter type is an enum that is + a superset of the corresponding old command parameter's type's enum values" + command_name: newCommandParameterTypeEnumSuperset + namespace: ignored + cpp_name: newCommandParameterTypeEnumSuperset + strict: true + api_version: "1" + reply_type: OkReply + fields: + parameterEnumSuperset: + type: EnumSuperset + + newCommandParameterTypeStruct: + description: "new command passes because its command parameter type is a struct and the + corresponding old command parameter type is also a struct" + command_name: newCommandParameterTypeStruct + namespace: ignored + cpp_name: newCommandParameterTypeStruct + strict: true + api_version: "1" + reply_type: OkReply + fields: + parameterStruct: + type: NewCommandParameterStruct + + newCommandParameterTypeBsonSuperset: + description: "new command passes because its parameter type has a bson_serialization_type + that is a superset of the corresponding old command parameter type's + bson_serialization_type" + command_name: newCommandParameterTypeBsonSuperset + namespace: ignored + cpp_name: newCommandParameterTypeBsonSuperset + strict: true + api_version: "1" + reply_type: OkReply + fields: + bsonSupersetParam: + type: intToIntString + newReplyFieldStable: description: "new command contains a stable reply field that is unstable in the corresponding old command and still passes" @@ -348,9 +412,9 @@ commands: reply_type: EnumSubsetReply newReplyFieldTypeBsonSubset: - description: "new command passes because its reply field type has a bson_serialization_type - that is a subset of the corresponding old reply field type's - bson_serialization_type" + description: "new command passes because its reply field type has a + bson_serialization_type that is a subset of the corresponding + old reply field type's bson_serialization_type" command_name: newReplyFieldTypeBsonSubset namespace: ignored cpp_name: newReplyFieldTypeBsonSubset @@ -359,9 +423,9 @@ commands: reply_type: BsonSubsetReply newReplyFieldTypeBsonSubsetTwo: - description: "new command passes because its reply field type has a bson_serialization_type - that is a subset of the corresponding old reply field type's - bson_serialization_type" + description: "new command passes because its reply field type has a + bson_serialization_type that is a subset of the corresponding + old reply field type's bson_serialization_type" command_name: newReplyFieldTypeBsonSubsetTwo namespace: ignored cpp_name: newReplyFieldTypeBsonSubsetTwo @@ -399,8 +463,8 @@ commands: reply_type: OkReply newNamespaceConcatenateWithDbOrUuid: - description: "new command passes when its namespace is changed to concatenate_with_db_or_uuid - from concatenate_with_db" + description: "new command passes when its namespace is changed to + concatenate_with_db_or_uuid from concatenate_with_db" command_name: newNamespaceConcatenateWithDbOrUuid namespace: concatenate_with_db cpp_name: newNamespaceConcatenateWithDbOrUuid @@ -419,8 +483,8 @@ commands: reply_type: OkReply oldNamespaceTypeNamespaceString: - description: "If old command has namespace: type and type: namespacestring, the new namespace - can be changed to concatenate_with_db" + description: "If old command has namespace: type and type: namespacestring, + the new namespace can be changed to concatenate_with_db" command_name: oldNamespaceTypeNamespaceString namespace: type type: namespacestring @@ -430,8 +494,8 @@ commands: reply_type: OkReply oldNamespaceTypeNamespaceStringTwo: - description: "If old command has namespace: type and type: namespacestring, the new namespace - can be changed to concatenate_with_db_or_uuid" + description: "If old command has namespace: type and type: namespacestring, + the new namespace can be changed to concatenate_with_db_or_uuid" command_name: oldNamespaceTypeNamespaceStringTwo namespace: type type: namespacestring @@ -504,7 +568,7 @@ commands: reply_type: VariantRecursiveReply oldReplyFieldVariantStruct: - description: "new command passes if it doesn't have a variant struct type while the + description: "new command passes if it doesn't have a variant struct type while the old command does" command_name: oldReplyFieldVariantStruct namespace: ignored @@ -514,8 +578,8 @@ commands: reply_type: OldVariantStructReply replyFieldVariantStructRecursive: - description: "new command passes when its reply field type has a variant struct type that is - compatible with the old reply field variant struct type" + description: "new command passes when its reply field type has a variant struct type + that is compatible with the old reply field variant struct type" command_name: replyFieldVariantStructRecursive namespace: ignored cpp_name: replyFieldVariantStructRecursive diff --git a/buildscripts/idl/tests/test_compatibility.py b/buildscripts/idl/tests/test_compatibility.py index 6e3764fa81b..65a79ef776a 100644 --- a/buildscripts/idl/tests/test_compatibility.py +++ b/buildscripts/idl/tests/test_compatibility.py @@ -57,8 +57,24 @@ class TestIDLCompatibilityChecker(unittest.TestCase): dir_path = path.dirname(path.realpath(__file__)) with self.assertRaises(SystemExit): idl_check_compatibility.check_compatibility( - path.join(dir_path, "compatibility_test_fail/old_abort"), - path.join(dir_path, "compatibility_test_fail/new_abort"), ["src"]) + path.join(dir_path, "compatibility_test_fail/abort/invalid_reply_field_type"), + path.join(dir_path, "compatibility_test_fail/abort/valid_reply_field_type"), + ["src"]) + with self.assertRaises(SystemExit): + idl_check_compatibility.check_compatibility( + path.join(dir_path, "compatibility_test_fail/abort/valid_reply_field_type"), + path.join(dir_path, "compatibility_test_fail/abort/invalid_reply_field_type"), + ["src"]) + with self.assertRaises(SystemExit): + idl_check_compatibility.check_compatibility( + path.join(dir_path, "compatibility_test_fail/abort/invalid_command_parameter_type"), + path.join(dir_path, "compatibility_test_fail/abort/valid_command_parameter_type"), + ["src"]) + with self.assertRaises(SystemExit): + idl_check_compatibility.check_compatibility( + path.join(dir_path, "compatibility_test_fail/abort/valid_command_parameter_type"), + path.join(dir_path, "compatibility_test_fail/abort/invalid_command_parameter_type"), + ["src"]) # pylint: disable=too-many-locals,too-many-statements def test_should_fail(self): @@ -69,7 +85,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() == 44) + self.assertTrue(error_collection.count() == 52) invalid_api_version_new_error = error_collection.get_error_by_command_name( "invalidAPIVersionNew") @@ -131,6 +147,69 @@ class TestIDLCompatibilityChecker(unittest.TestCase): idl_compatibility_errors.ERROR_ID_COMMAND_PARAMETER_REQUIRED) self.assertRegex(str(command_parameter_required_error), "commandParameterRequired") + old_command_parameter_type_bson_any_error = error_collection.get_error_by_command_name( + "oldCommandParameterTypeBsonSerializationAny") + self.assertTrue( + old_command_parameter_type_bson_any_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_error), + "oldCommandParameterTypeBsonSerializationAny") + + new_command_parameter_type_bson_any_error = error_collection.get_error_by_command_name( + "newCommandParameterTypeBsonSerializationAny") + self.assertTrue( + new_command_parameter_type_bson_any_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_error), + "newCommandParameterTypeBsonSerializationAny") + + 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 == + idl_compatibility_errors.ERROR_ID_COMMAND_PARAMETER_TYPE_NOT_SUPERSET) + self.assertRegex( + str(new_command_parameter_type_enum_not_superset), + "newCommandParameterTypeEnumNotSuperset") + + new_command_parameter_type_not_enum = error_collection.get_error_by_command_name( + "newCommandParameterTypeNotEnum") + self.assertTrue(new_command_parameter_type_not_enum.error_id == + idl_compatibility_errors.ERROR_ID_NEW_COMMAND_PARAMETER_TYPE_NOT_ENUM) + self.assertRegex(str(new_command_parameter_type_not_enum), "newCommandParameterTypeNotEnum") + + new_command_parameter_type_not_struct = error_collection.get_error_by_command_name( + "newCommandParameterTypeNotStruct") + self.assertTrue(new_command_parameter_type_not_struct.error_id == + idl_compatibility_errors.ERROR_ID_NEW_COMMAND_PARAMETER_TYPE_NOT_STRUCT) + self.assertRegex( + str(new_command_parameter_type_not_struct), "newCommandParameterTypeNotStruct") + + new_command_parameter_type_enum_or_struct_one = error_collection.get_error_by_command_name( + "newCommandParameterTypeEnumOrStructOne") + self.assertTrue(new_command_parameter_type_enum_or_struct_one.error_id == + idl_compatibility_errors.ERROR_ID_NEW_COMMAND_PARAMETER_TYPE_ENUM_OR_STRUCT) + self.assertRegex( + str(new_command_parameter_type_enum_or_struct_one), + "newCommandParameterTypeEnumOrStructOne") + + new_command_parameter_type_enum_or_struct_two = error_collection.get_error_by_command_name( + "newCommandParameterTypeEnumOrStructTwo") + self.assertTrue(new_command_parameter_type_enum_or_struct_two.error_id == + idl_compatibility_errors.ERROR_ID_NEW_COMMAND_PARAMETER_TYPE_ENUM_OR_STRUCT) + self.assertRegex( + str(new_command_parameter_type_enum_or_struct_two), + "newCommandParameterTypeEnumOrStructTwo") + + new_command_parameter_type_bson_not_superset = error_collection.get_error_by_command_name( + "newCommandParameterTypeBsonNotSuperset") + self.assertTrue(new_command_parameter_type_bson_not_superset.error_id == + idl_compatibility_errors.ERROR_ID_COMMAND_PARAMETER_TYPE_NOT_SUPERSET) + self.assertRegex( + str(new_command_parameter_type_bson_not_superset), + "newCommandParameterTypeBsonNotSuperset") + new_reply_field_unstable_error = error_collection.get_error_by_command_name( "newReplyFieldUnstable") self.assertTrue(new_reply_field_unstable_error.error_id == |