summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHuayu Ouyang <huayu.ouyang@mongodb.com>2021-03-08 21:22:50 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-03-10 19:37:50 +0000
commit268847f5318cf1b5ef543317d7a96b5964981847 (patch)
tree36678268ade90dd65232e8e44b8e4450847aec40
parent1f77d6a06078707510aa7bdfa78449ecf347eb3b (diff)
downloadmongo-268847f5318cf1b5ef543317d7a96b5964981847.tar.gz
SERVER-54884 Support validators for API V1 Command Replies
-rw-r--r--buildscripts/idl/idl_check_compatibility.py16
-rw-r--r--buildscripts/idl/idl_compatibility_errors.py16
-rw-r--r--buildscripts/idl/tests/compatibility_test_fail/abort/reply_field_contains_validator/reply_field_contains_validator.idl52
-rw-r--r--buildscripts/idl/tests/compatibility_test_fail/abort/reply_field_no_validator/reply_field_no_validator.idl50
-rw-r--r--buildscripts/idl/tests/compatibility_test_fail/new/compatibility_test_fail_new.idl32
-rw-r--r--buildscripts/idl/tests/compatibility_test_fail/old/compatibility_test_fail_old.idl32
-rw-r--r--buildscripts/idl/tests/compatibility_test_pass/new/compatibility_test_pass_new.idl32
-rw-r--r--buildscripts/idl/tests/compatibility_test_pass/old/compatibility_test_pass_old.idl32
-rw-r--r--buildscripts/idl/tests/test_compatibility.py28
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."""