diff options
author | Huayu Ouyang <huayu.ouyang@mongodb.com> | 2021-03-08 21:22:50 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-03-10 19:37:50 +0000 |
commit | 268847f5318cf1b5ef543317d7a96b5964981847 (patch) | |
tree | 36678268ade90dd65232e8e44b8e4450847aec40 /buildscripts/idl | |
parent | 1f77d6a06078707510aa7bdfa78449ecf347eb3b (diff) | |
download | mongo-268847f5318cf1b5ef543317d7a96b5964981847.tar.gz |
SERVER-54884 Support validators for API V1 Command Replies
Diffstat (limited to 'buildscripts/idl')
9 files changed, 137 insertions, 153 deletions
diff --git a/buildscripts/idl/idl_check_compatibility.py b/buildscripts/idl/idl_check_compatibility.py index bc42a192c9c..34d668f1e86 100644 --- a/buildscripts/idl/idl_check_compatibility.py +++ b/buildscripts/idl/idl_check_compatibility.py @@ -267,16 +267,14 @@ def check_reply_field(ctxt: IDLCompatibilityContext, old_field: syntax.Field, 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 old_field.validator: - # Not implemented. - ctxt.add_reply_field_contains_validator_error(cmd_name, old_field.name, old_idl_file_path) - ctxt.errors.dump_errors() - sys.exit(1) if new_field.validator: - # Not implemented. - ctxt.add_reply_field_contains_validator_error(cmd_name, new_field.name, new_idl_file_path) - ctxt.errors.dump_errors() - sys.exit(1) + 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) diff --git a/buildscripts/idl/idl_compatibility_errors.py b/buildscripts/idl/idl_compatibility_errors.py index 4b51e989047..13bd6455e5f 100644 --- a/buildscripts/idl/idl_compatibility_errors.py +++ b/buildscripts/idl/idl_compatibility_errors.py @@ -97,6 +97,7 @@ ERROR_ID_NEW_COMMAND_PARAMETER_TYPE_NOT_VARIANT = "ID0053" ERROR_ID_NEW_COMMAND_TYPE_NOT_VARIANT = "ID0054" ERROR_ID_NEW_COMMAND_PARAMETER_VARIANT_TYPE_NOT_SUPERSET = "ID0055" ERROR_ID_NEW_COMMAND_VARIANT_TYPE_NOT_SUPERSET = "ID0056" +ERROR_ID_REPLY_FIELD_VALIDATORS_NOT_EQUAL = "ID0057" class IDLCompatibilityCheckerError(Exception): @@ -768,9 +769,18 @@ class IDLCompatibilityContext(object): def add_reply_field_contains_validator_error(self, command_name: str, field_name: str, file: str) -> None: """Add an error about the reply field containing a validator.""" - self._add_error(ERROR_ID_REPLY_FIELD_CONTAINS_VALIDATOR, command_name, ( - "'%s' has a reply field '%s' that contains a validator; compatibility checking for reply field " - "validators isn't implemented yet") % (command_name, field_name), file) + self._add_error( + ERROR_ID_REPLY_FIELD_CONTAINS_VALIDATOR, command_name, + ("The new version of the command '%s' has a reply field '%s' that contains a validator " + " while the old version does not") % (command_name, field_name), file) + + def add_reply_field_validators_not_equal_error(self, command_name: str, field_name: str, + file: str) -> None: + """Add an error about the reply field containing a validator.""" + self._add_error( + ERROR_ID_REPLY_FIELD_VALIDATORS_NOT_EQUAL, command_name, + ("Validator for reply field '%s' in old command '%s' is not equal to the validator in" + "the new version of the reply field") % (command_name, field_name), file) def add_reply_field_type_invalid_error(self, command_name: str, field_name: str, file: str) -> None: diff --git a/buildscripts/idl/tests/compatibility_test_fail/abort/reply_field_contains_validator/reply_field_contains_validator.idl b/buildscripts/idl/tests/compatibility_test_fail/abort/reply_field_contains_validator/reply_field_contains_validator.idl deleted file mode 100644 index 524a2980524..00000000000 --- a/buildscripts/idl/tests/compatibility_test_fail/abort/reply_field_contains_validator/reply_field_contains_validator.idl +++ /dev/null @@ -1,52 +0,0 @@ -# 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" - -structs: - ValidatorReply: - description: "The reply field contains a validator which is invalid." - fields: - validatorReplyField: - type: string - validator: - lt: 0 - -commands: - replyFieldValidator: - description: "command aborts because its reply field contains a validator" - command_name: replyFieldValidator - namespace: ignored - cpp_name: replyFieldValidator - strict: true - api_version: "1" - reply_type: ValidatorReply diff --git a/buildscripts/idl/tests/compatibility_test_fail/abort/reply_field_no_validator/reply_field_no_validator.idl b/buildscripts/idl/tests/compatibility_test_fail/abort/reply_field_no_validator/reply_field_no_validator.idl deleted file mode 100644 index c4544dc100a..00000000000 --- a/buildscripts/idl/tests/compatibility_test_fail/abort/reply_field_no_validator/reply_field_no_validator.idl +++ /dev/null @@ -1,50 +0,0 @@ -# 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" - -structs: - ValidatorReply: - description: "The other version of the reply field contains a validator which is invalid." - fields: - validatorReplyField: - type: string - -commands: - replyFieldValidator: - description: "the other version of this command aborts because its reply field contains a validator" - command_name: replyFieldValidator - namespace: ignored - cpp_name: replyFieldValidator - strict: true - api_version: "1" - reply_type: ValidatorReply 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 0865850efca..0a7f64a32f8 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 @@ -305,19 +305,19 @@ structs: notSupersetField: type: intStringToInt - NewCommandTypeValidatorStruct: + NewValidatorStruct: description: "This struct contains a field where the new version contains a validator while the old version does not" fields: - newCommandTypeValidatorField: + newValidatorField: type: int validator: lt: 0 - CommandTypeValidatorsNotEqualStruct: + ValidatorsNotEqualStruct: description: "This struct contains a field where the new and old validators are not exactly equal" fields: - commandTypeValidatorsNotEqualField: + validatorsNotEqualField: type: double validator: lt: 0.0 @@ -723,7 +723,7 @@ commands: that is not present in the old type" command_name: newCommandTypeValidator namespace: type - type: NewCommandTypeValidatorStruct + type: NewValidatorStruct cpp_name: newCommandTypeValidator strict: true api_version: "1" @@ -734,7 +734,7 @@ commands: that is not exactly equal to the old type validator" command_name: commandTypeValidatorsNotEqual namespace: type - type: CommandTypeValidatorsNotEqualStruct + type: ValidatorsNotEqualStruct cpp_name: commandTypeValidatorsNotEqual strict: true api_version: "1" @@ -1368,3 +1368,23 @@ commands: strict: true api_version: "1" reply_type: OkReply + + newReplyFieldValidator: + description: "new command fails because it contains a reply field that contains a validator + that is not present in the old reply field" + command_name: newReplyFieldValidator + namespace: ignored + cpp_name: newReplyFieldValidator + strict: true + api_version: "1" + reply_type: NewValidatorStruct + + replyFieldValidatorsNotEqual: + description: "new command fails because it contains a reply field that contains a validator + that is not exactly equal to the old reply field validator" + command_name: replyFieldValidatorsNotEqual + namespace: ignored + cpp_name: replyFieldValidatorsNotEqual + strict: true + api_version: "1" + reply_type: ValidatorsNotEqualStruct 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 57a3622b4b2..eb2e39e5994 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 @@ -307,17 +307,17 @@ structs: notSupersetField: type: intStringToInt - NewCommandTypeValidatorStruct: + NewValidatorStruct: description: "This struct contains a field where the new version contains a validator while the old version does not" fields: - newCommandTypeValidatorField: + newValidatorField: type: int - CommandTypeValidatorsNotEqualStruct: + ValidatorsNotEqualStruct: description: "This struct contains a field where the new and old validators are not exactly equal" fields: - commandTypeValidatorsNotEqualField: + validatorsNotEqualField: type: double validator: lt: 0.0 @@ -710,7 +710,7 @@ commands: that is not present in the old type" command_name: newCommandTypeValidator namespace: type - type: NewCommandTypeValidatorStruct + type: NewValidatorStruct cpp_name: newCommandTypeValidator strict: true api_version: "1" @@ -721,7 +721,7 @@ commands: that is not exactly equal to the old type validator" command_name: commandTypeValidatorsNotEqual namespace: type - type: CommandTypeValidatorsNotEqualStruct + type: ValidatorsNotEqualStruct cpp_name: commandTypeValidatorsNotEqual strict: true api_version: "1" @@ -1356,3 +1356,23 @@ commands: strict: true api_version: "1" reply_type: OkReply + + newReplyFieldValidator: + description: "new command fails because it contains a reply field that contains a validator + that is not present in the old reply field" + command_name: newReplyFieldValidator + namespace: ignored + cpp_name: newReplyFieldValidator + strict: true + api_version: "1" + reply_type: NewValidatorStruct + + replyFieldValidatorsNotEqual: + description: "new command fails because it contains a reply field that contains a validator + that is not exactly equal to the old reply field validator" + command_name: replyFieldValidatorsNotEqual + namespace: ignored + cpp_name: replyFieldValidatorsNotEqual + strict: true + api_version: "1" + reply_type: ValidatorsNotEqualStruct 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 4cd2c50b05d..90c91831285 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 @@ -233,17 +233,17 @@ structs: supersetField: type: intToIntString - OldCommandTypeValidatorStruct: + OldValidatorStruct: description: "This struct contains a field where the old version contains a validator while the new version does not" fields: - oldCommandTypeValidatorField: + oldValidatorField: type: int - CommandTypeValidatorsEqualStruct: + ValidatorsEqualStruct: description: "This struct contains a field where the new and old validator are exactly equal" fields: - commandTypeValidatorsEqualField: + validatorsEqualField: type: double validator: lt: 0.0 @@ -573,7 +573,7 @@ commands: that is present in the old type" command_name: oldCommandTypeValidator namespace: type - type: OldCommandTypeValidatorStruct + type: OldValidatorStruct cpp_name: oldCommandTypeValidator strict: true api_version: "1" @@ -584,7 +584,7 @@ commands: that is exactly equal to the old type validator" command_name: commandTypeValidatorsEqual namespace: type - type: CommandTypeValidatorsEqualStruct + type: ValidatorsEqualStruct cpp_name: commandTypeValidatorsEqual strict: true api_version: "1" @@ -1060,3 +1060,23 @@ commands: strict: true api_version: "1" reply_type: OkReply + + oldReplyFieldValidator: + description: "new command passes because it contains a reply field that does not contain a validator + that is present in the old reply field" + command_name: oldReplyFieldValidator + namespace: ignored + cpp_name: oldReplyFieldValidator + strict: true + api_version: "1" + reply_type: OldValidatorStruct + + replyFieldValidatorsEqual: + description: "new command passes because it contains a reply field that contains a validator + that is exactly equal to the old reply field validator" + command_name: replyFieldValidatorsEqual + namespace: ignored + cpp_name: replyFieldValidatorsEqual + strict: true + api_version: "1" + reply_type: ValidatorsEqualStruct 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 2ed7c0b2494..79dfb4d92d4 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 @@ -236,19 +236,19 @@ structs: supersetField: type: intToIntString - OldCommandTypeValidatorStruct: + OldValidatorStruct: description: "This struct contains a field where the old version contains a validator while the new version does not" fields: - oldCommandTypeValidatorField: + oldValidatorField: type: int validator: lt: 0 - CommandTypeValidatorsEqualStruct: + ValidatorsEqualStruct: description: "This struct contains a field where the new and old validator are exactly equal" fields: - commandTypeValidatorsEqualField: + validatorsEqualField: type: double validator: lt: 0.0 @@ -566,7 +566,7 @@ commands: that is present in the old type" command_name: oldCommandTypeValidator namespace: type - type: OldCommandTypeValidatorStruct + type: OldValidatorStruct cpp_name: oldCommandTypeValidator strict: true api_version: "1" @@ -577,7 +577,7 @@ commands: that is exactly equal to the old type validator" command_name: commandTypeValidatorsEqual namespace: type - type: CommandTypeValidatorsEqualStruct + type: ValidatorsEqualStruct cpp_name: commandTypeValidatorsEqual strict: true api_version: "1" @@ -1056,3 +1056,23 @@ commands: strict: true api_version: "1" reply_type: OkReply + + oldReplyFieldValidator: + description: "new command passes because it contains a reply field that does not contain a validator + that is present in the old reply field" + command_name: oldReplyFieldValidator + namespace: ignored + cpp_name: oldReplyFieldValidator + strict: true + api_version: "1" + reply_type: OldValidatorStruct + + replyFieldValidatorsEqual: + description: "new command passes because it contains a reply field that contains a validator + that is exactly equal to the old reply field validator" + command_name: replyFieldValidatorsEqual + namespace: ignored + cpp_name: replyFieldValidatorsEqual + strict: true + api_version: "1" + reply_type: ValidatorsEqualStruct diff --git a/buildscripts/idl/tests/test_compatibility.py b/buildscripts/idl/tests/test_compatibility.py index 779dcd10c81..f87524f180b 100644 --- a/buildscripts/idl/tests/test_compatibility.py +++ b/buildscripts/idl/tests/test_compatibility.py @@ -83,20 +83,6 @@ class TestIDLCompatibilityChecker(unittest.TestCase): path.join(dir_path, "compatibility_test_fail/abort/invalid_command_parameter_type"), ["src"]) - # Test that when old command has a reply field that contains a validator, the script aborts. - with self.assertRaises(SystemExit): - idl_check_compatibility.check_compatibility( - path.join(dir_path, "compatibility_test_fail/abort/reply_field_contains_validator"), - path.join(dir_path, "compatibility_test_fail/abort/reply_field_no_validator"), - ["src"]) - - # Test that when new command has a reply field that contains a validator, the script aborts. - with self.assertRaises(SystemExit): - idl_check_compatibility.check_compatibility( - path.join(dir_path, "compatibility_test_fail/abort/reply_field_no_validator"), - path.join(dir_path, "compatibility_test_fail/abort/reply_field_contains_validator"), - ["src"]) - # pylint: disable=too-many-locals,too-many-statements def test_should_fail(self): """Tests that incompatible old and new IDL commands should fail.""" @@ -106,7 +92,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() == 90) + self.assertTrue(error_collection.count() == 92) invalid_api_version_new_error = error_collection.get_error_by_command_name( "invalidAPIVersionNew") @@ -671,6 +657,18 @@ class TestIDLCompatibilityChecker(unittest.TestCase): self.assertRegex( str(new_command_type_variant_struct_recursive_error), "newCommandTypeVariantStructRecursive") + new_reply_field_contains_validator_error = error_collection.get_error_by_command_name( + "newReplyFieldValidator") + self.assertTrue(new_reply_field_contains_validator_error.error_id == + idl_compatibility_errors.ERROR_ID_REPLY_FIELD_CONTAINS_VALIDATOR) + self.assertRegex(str(new_reply_field_contains_validator_error), "newReplyFieldValidator") + + reply_field_validators_not_equal_error = error_collection.get_error_by_command_name( + "replyFieldValidatorsNotEqual") + self.assertTrue(reply_field_validators_not_equal_error.error_id == + idl_compatibility_errors.ERROR_ID_REPLY_FIELD_VALIDATORS_NOT_EQUAL) + self.assertRegex( + str(reply_field_validators_not_equal_error), "replyFieldValidatorsNotEqual") def test_error_reply(self): """Tests the compatibility checker with the ErrorReply struct.""" |