diff options
author | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2017-05-02 09:16:56 -0400 |
---|---|---|
committer | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2017-05-02 09:16:56 -0400 |
commit | 49cf0ebd80e8b007a6bcd08d3c956b149afa6f81 (patch) | |
tree | 5426b926fda611d8f956ab05bf987895881c491e /src/mongo | |
parent | 3d06c50d9427ac64785d2b62ca368010890aa9be (diff) | |
download | mongo-49cf0ebd80e8b007a6bcd08d3c956b149afa6f81.tar.gz |
SERVER-28827 BinData for IDL
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/bson/bsonelement.h | 26 | ||||
-rw-r--r-- | src/mongo/idl/basic_types.idl | 32 | ||||
-rw-r--r-- | src/mongo/idl/idl_parser.cpp | 25 | ||||
-rw-r--r-- | src/mongo/idl/idl_parser.h | 13 | ||||
-rw-r--r-- | src/mongo/idl/idl_test.cpp | 270 | ||||
-rw-r--r-- | src/mongo/idl/idl_test_types.h | 31 | ||||
-rw-r--r-- | src/mongo/idl/unittest.idl | 52 | ||||
-rw-r--r-- | src/mongo/idl/unittest_import.idl | 20 |
8 files changed, 456 insertions, 13 deletions
diff --git a/src/mongo/bson/bsonelement.h b/src/mongo/bson/bsonelement.h index 2d815383b2c..dd68d333f63 100644 --- a/src/mongo/bson/bsonelement.h +++ b/src/mongo/bson/bsonelement.h @@ -35,6 +35,7 @@ #include <string> #include <vector> +#include "mongo/base/data_range.h" #include "mongo/base/data_type_endian.h" #include "mongo/base/data_view.h" #include "mongo/base/string_data_comparator_interface.h" @@ -468,6 +469,19 @@ public: return (BinDataType)c; } + std::vector<uint8_t> _binDataVector() const { + if (binDataType() != ByteArrayDeprecated) { + return std::vector<uint8_t>(reinterpret_cast<const uint8_t*>(value()) + 5, + reinterpret_cast<const uint8_t*>(value()) + 5 + + valuestrsize()); + } else { + // Skip the extra int32 size + return std::vector<uint8_t>(reinterpret_cast<const uint8_t*>(value()) + 4, + reinterpret_cast<const uint8_t*>(value()) + 4 + + valuestrsize() - 4); + } + } + /** Retrieve the regex std::string for a Regex element */ const char* regex() const { verify(type() == RegEx); @@ -592,6 +606,18 @@ public: return result; } + const std::array<unsigned char, 16> md5() const { + int len = 0; + const char* data = nullptr; + if (type() == BinData && binDataType() == BinDataType::MD5Type) + data = binData(len); + uassert(550418, "md5 must be a 16-byte binary field with MD5 (5) subtype", len == 16); + std::array<unsigned char, 16> result; + memcpy(&result, data, len); + return result; + } + + Date_t timestampTime() const { unsigned long long t = ConstDataView(value() + 4).read<LittleEndian<unsigned int>>(); return Date_t::fromMillisSinceEpoch(t * 1000); diff --git a/src/mongo/idl/basic_types.idl b/src/mongo/idl/basic_types.idl index 76438ecc01f..1dd9495d65e 100644 --- a/src/mongo/idl/basic_types.idl +++ b/src/mongo/idl/basic_types.idl @@ -54,11 +54,33 @@ types: cpp_type: "bool" deserializer: "mongo::BSONElement::boolean" - # TODO: support bindata - # bindata: - # bson_serialization_type: bindata - # cpp_type: "std:" - # deserializer: "mongo::BSONElement::str" + bindata_generic: + bson_serialization_type: bindata + bindata_subtype: generic + description: "A BSON bindata of " + cpp_type: "std::vector<std::uint8_t>" + deserializer: "mongo::BSONElement::_binDataVector" + + bindata_function: + bson_serialization_type: bindata + bindata_subtype: function + description: "A BSON bindata of function sub type" + cpp_type: "std::vector<std::uint8_t>" + deserializer: "mongo::BSONElement::_binDataVector" + + bindata_uuid: + bson_serialization_type: bindata + bindata_subtype: uuid + description: "A BSON bindata of uuid sub type" + cpp_type: "std::array<std::uint8_t, 16>" + deserializer: "mongo::BSONElement::uuid" + + bindata_md5: + bson_serialization_type: bindata + bindata_subtype: md5 + description: "A BSON bindata of uuid sub type" + cpp_type: "std::array<std::uint8_t, 16>" + deserializer: "mongo::BSONElement::md5" objectid: bson_serialization_type: objectid diff --git a/src/mongo/idl/idl_parser.cpp b/src/mongo/idl/idl_parser.cpp index fee9678f485..c9450664c71 100644 --- a/src/mongo/idl/idl_parser.cpp +++ b/src/mongo/idl/idl_parser.cpp @@ -218,4 +218,29 @@ std::vector<std::string> transformVector(const std::vector<StringData>& input) { return output; } +std::vector<ConstDataRange> transformVector(const std::vector<std::vector<std::uint8_t>>& input) { + std::vector<ConstDataRange> output; + + output.reserve(input.size()); + + std::transform(begin(input), end(input), std::back_inserter(output), [](auto&& vec) { + return makeCDR(vec); + }); + + return output; +} + +std::vector<std::vector<std::uint8_t>> transformVector(const std::vector<ConstDataRange>& input) { + std::vector<std::vector<std::uint8_t>> output; + + output.reserve(input.size()); + + std::transform(begin(input), end(input), std::back_inserter(output), [](auto&& cdr) { + return std::vector<std::uint8_t>(reinterpret_cast<const uint8_t*>(cdr.data()), + reinterpret_cast<const uint8_t*>(cdr.data()) + + cdr.length()); + }); + + return output; +} } // namespace mongo diff --git a/src/mongo/idl/idl_parser.h b/src/mongo/idl/idl_parser.h index 2a6ee4a1db7..e249be26b87 100644 --- a/src/mongo/idl/idl_parser.h +++ b/src/mongo/idl/idl_parser.h @@ -142,5 +142,18 @@ private: */ std::vector<StringData> transformVector(const std::vector<std::string>& input); std::vector<std::string> transformVector(const std::vector<StringData>& input); +std::vector<ConstDataRange> transformVector(const std::vector<std::vector<std::uint8_t>>& input); +std::vector<std::vector<std::uint8_t>> transformVector(const std::vector<ConstDataRange>& input); + +/** + * Get a ConstDataRange from a vector or an array of bytes. + */ +inline ConstDataRange makeCDR(const std::vector<uint8_t>& value) { + return ConstDataRange(reinterpret_cast<const char*>(value.data()), value.size()); +} + +inline ConstDataRange makeCDR(const std::array<uint8_t, 16>& value) { + return ConstDataRange(reinterpret_cast<const char*>(value.data()), value.size()); +} } // namespace mongo diff --git a/src/mongo/idl/idl_test.cpp b/src/mongo/idl/idl_test.cpp index 55c1cf0b6f9..4f26af506c9 100644 --- a/src/mongo/idl/idl_test.cpp +++ b/src/mongo/idl/idl_test.cpp @@ -37,7 +37,41 @@ using namespace mongo::idl::test; namespace mongo { -// Use a seperate function to get better error messages when types do not match. +namespace { + +bool isEquals(ConstDataRange left, const std::vector<uint8_t>& right) { + auto rightCDR = makeCDR(right); + return std::equal(left.data(), + left.data() + left.length(), + rightCDR.data(), + rightCDR.data() + rightCDR.length()); +} + +bool isEquals(const std::array<uint8_t, 16>& left, const std::array<uint8_t, 16>& right) { + return std::equal( + left.data(), left.data() + left.size(), right.data(), right.data() + right.size()); +} + +bool isEqual(const ConstDataRange& left, const ConstDataRange& right) { + return std::equal( + left.data(), left.data() + left.length(), right.data(), right.data() + right.length()); +} + +bool isEquals(const std::vector<ConstDataRange>& left, + const std::vector<std::vector<std::uint8_t>>& rightVector) { + auto right = transformVector(rightVector); + return std::equal( + left.data(), left.data() + left.size(), right.data(), right.data() + right.size(), isEqual); +} + +bool isEquals(const std::vector<std::array<std::uint8_t, 16>>& left, + const std::vector<std::array<std::uint8_t, 16>>& right) { + return std::equal( + left.data(), left.data() + left.size(), right.data(), right.data() + right.size()); +} + + +// Use a separate function to get better error messages when types do not match. template <typename T1, typename T2> void assert_same_types() { MONGO_STATIC_ASSERT(std::is_same<T1, T2>::value); @@ -187,8 +221,7 @@ TEST(IDLOneTypeTests, TestSafeInt32) { TEST(IDLOneTypeTests, TestNamespaceString) { IDLParserErrorContext ctxt("root"); - auto testDoc = BSON(One_namespacestring::kValueFieldName - << "foo.bar"); + auto testDoc = BSON(One_namespacestring::kValueFieldName << "foo.bar"); auto element = testDoc.firstElement(); ASSERT_EQUALS(element.type(), String); @@ -440,6 +473,10 @@ TEST(IDLFieldTests, TestOptionalFields) { const boost::optional<mongo::StringData>>(); assert_same_types<decltype(testStruct.getField3()), const boost::optional<mongo::BSONObj>>(); + assert_same_types<decltype(testStruct.getField4()), + const boost::optional<ConstDataRange>>(); + assert_same_types<decltype(testStruct.getField5()), + const boost::optional<std::array<std::uint8_t, 16>>>(); ASSERT_EQUALS("Foo", testStruct.getField1().get()); ASSERT_FALSE(testStruct.getField2().is_initialized()); @@ -480,9 +517,8 @@ TEST(IDLFieldTests, TestOptionalFields) { } } - // Positive: Test a nested struct -TEST(IDLNestedStruct, TestDuplicatTypes) { +TEST(IDLNestedStruct, TestDuplicateTypes) { IDLParserErrorContext ctxt("root"); @@ -544,6 +580,12 @@ TEST(IDLArrayTests, TestSimpleArrays) { IDLParserErrorContext ctxt("root"); // Positive: Test document + uint8_t array1[] = {1, 2, 3}; + uint8_t array2[] = {4, 6, 8}; + + uint8_t array15[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + uint8_t array16[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; + auto testDoc = BSON("field1" << BSON_ARRAY("Foo" << "Bar" << "???") @@ -551,13 +593,20 @@ TEST(IDLArrayTests, TestSimpleArrays) { << BSON_ARRAY(1 << 2 << 3) << "field3" << BSON_ARRAY(1.2 << 3.4 << 5.6) - - ); + << "field4" + << BSON_ARRAY(BSONBinData(array1, 3, BinDataGeneral) + << BSONBinData(array2, 3, BinDataGeneral)) + << "field5" + << BSON_ARRAY(BSONBinData(array15, 16, newUUID) + << BSONBinData(array16, 16, newUUID))); auto testStruct = Simple_array_fields::parse(ctxt, testDoc); assert_same_types<decltype(testStruct.getField1()), const std::vector<mongo::StringData>>(); assert_same_types<decltype(testStruct.getField2()), const std::vector<std::int32_t>&>(); assert_same_types<decltype(testStruct.getField3()), const std::vector<double>&>(); + assert_same_types<decltype(testStruct.getField4()), const std::vector<ConstDataRange>>(); + assert_same_types<decltype(testStruct.getField5()), + const std::vector<std::array<std::uint8_t, 16>>&>(); std::vector<StringData> field1{"Foo", "Bar", "???"}; ASSERT_TRUE(field1 == testStruct.getField1()); @@ -566,6 +615,14 @@ TEST(IDLArrayTests, TestSimpleArrays) { std::vector<double> field3{1.2, 3.4, 5.6}; ASSERT_TRUE(field3 == testStruct.getField3()); + std::vector<std::vector<uint8_t>> field4{{1, 2, 3}, {4, 6, 8}}; + ASSERT_TRUE(isEquals(testStruct.getField4(), field4)); + + std::vector<std::array<uint8_t, 16>> field5{ + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}}; + ASSERT_TRUE(isEquals(testStruct.getField5(), field5)); + // Positive: Test we can roundtrip from the just parsed document { BSONObjBuilder builder; @@ -582,6 +639,8 @@ TEST(IDLArrayTests, TestSimpleArrays) { array_fields.setField1(field1); array_fields.setField2(field2); array_fields.setField3(field3); + array_fields.setField4(transformVector(field4)); + array_fields.setField5(field5); array_fields.serialize(&builder); auto serializedDoc = builder.obj(); @@ -611,6 +670,10 @@ TEST(IDLArrayTests, TestSimpleOptionalArrays) { const boost::optional<std::vector<std::int32_t>>>(); assert_same_types<decltype(testStruct.getField3()), const boost::optional<std::vector<double>>>(); + assert_same_types<decltype(testStruct.getField4()), + const boost::optional<std::vector<ConstDataRange>>>(); + assert_same_types<decltype(testStruct.getField5()), + const boost::optional<std::vector<std::array<std::uint8_t, 16>>>>(); std::vector<StringData> field1{"Foo", "Bar", "???"}; ASSERT_TRUE(field1 == testStruct.getField1().get()); @@ -736,6 +799,11 @@ TEST(IDLArrayTests, TestArraysOfComplexTypes) { << BSON_ARRAY(BSONObj() << BSONObj()) << "field5" << BSON_ARRAY(BSONObj() << BSONObj() << BSONObj()) + << "field6" + << BSON_ARRAY(BSON("value" + << "hello") + << BSON("value" + << "world")) << "field1o" << BSON_ARRAY(1 << 2 << 3) << "field2o" @@ -744,7 +812,14 @@ TEST(IDLArrayTests, TestArraysOfComplexTypes) { << "field3o" << BSON_ARRAY(1 << "2") << "field4o" - << BSON_ARRAY(BSONObj() << BSONObj())); + << BSON_ARRAY(BSONObj() << BSONObj()) + << "field6o" + << BSON_ARRAY(BSON("value" + << "goodbye") + << BSON("value" + << "world")) + + ); auto testStruct = Complex_array_fields::parse(ctxt, testDoc); assert_same_types<decltype(testStruct.getField1()), const std::vector<std::int64_t>&>(); @@ -754,6 +829,7 @@ TEST(IDLArrayTests, TestArraysOfComplexTypes) { assert_same_types<decltype(testStruct.getField4()), const std::vector<mongo::ObjectBasicType>&>(); assert_same_types<decltype(testStruct.getField5()), const std::vector<mongo::BSONObj>&>(); + assert_same_types<decltype(testStruct.getField6()), const std::vector<mongo::One_string>&>(); assert_same_types<decltype(testStruct.getField1o()), const boost::optional<std::vector<std::int64_t>>>(); @@ -765,11 +841,188 @@ TEST(IDLArrayTests, TestArraysOfComplexTypes) { const boost::optional<std::vector<mongo::ObjectBasicType>>>(); assert_same_types<decltype(testStruct.getField5o()), const boost::optional<std::vector<mongo::BSONObj>>>(); + assert_same_types<decltype(testStruct.getField6o()), + const boost::optional<std::vector<mongo::One_string>>>(); std::vector<std::int64_t> field1{1, 2, 3}; ASSERT_TRUE(field1 == testStruct.getField1()); std::vector<NamespaceString> field2{{"a", "b"}, {"c", "d"}}; ASSERT_TRUE(field2 == testStruct.getField2()); + + ASSERT_EQUALS(testStruct.getField6().size(), 2u); + ASSERT_EQUALS(testStruct.getField6()[0].getValue(), "hello"); + ASSERT_EQUALS(testStruct.getField6()[1].getValue(), "world"); + ASSERT_EQUALS(testStruct.getField6o().get().size(), 2u); + ASSERT_EQUALS(testStruct.getField6o().get()[0].getValue(), "goodbye"); + ASSERT_EQUALS(testStruct.getField6o().get()[1].getValue(), "world"); +} + +template <typename ParserT, BinDataType bindata_type> +void TestBinDataVector() { + IDLParserErrorContext ctxt("root"); + + // Positive: Test document with only a generic bindata field + uint8_t testData[] = {1, 2, 3}; + auto testDoc = BSON("value" << BSONBinData(testData, 3, bindata_type)); + auto testStruct = ParserT::parse(ctxt, testDoc); + + assert_same_types<decltype(testStruct.getValue()), const ConstDataRange>(); + + std::vector<std::uint8_t> expected{1, 2, 3}; + + ASSERT_TRUE(isEquals(testStruct.getValue(), expected)); + + // Positive: Test we can roundtrip from the just parsed document + { + BSONObjBuilder builder; + testStruct.serialize(&builder); + auto loopbackDoc = builder.obj(); + + ASSERT_BSONOBJ_EQ(testDoc, loopbackDoc); + } + + // Positive: Test we can serialize from nothing the same document + { + BSONObjBuilder builder; + ParserT one_new; + one_new.setValue(makeCDR(expected)); + testStruct.serialize(&builder); + + auto serializedDoc = builder.obj(); + ASSERT_BSONOBJ_EQ(testDoc, serializedDoc); + } +} + +TEST(IDLBinData, TestGeneric) { + TestBinDataVector<One_bindata, BinDataGeneral>(); +} + +TEST(IDLBinData, TestFunction) { + TestBinDataVector<One_function, Function>(); +} + +template <typename ParserT, BinDataType bindata_type> +void TestBinDataArray() { + IDLParserErrorContext ctxt("root"); + + // Positive: Test document with only a generic bindata field + uint8_t testData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; + auto testDoc = BSON("value" << BSONBinData(testData, 16, bindata_type)); + auto testStruct = ParserT::parse(ctxt, testDoc); + + assert_same_types<decltype(testStruct.getValue()), const std::array<uint8_t, 16>>(); + + std::array<std::uint8_t, 16> expected{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; + + ASSERT_TRUE(isEquals(testStruct.getValue(), expected)); + + // Positive: Test we can roundtrip from the just parsed document + { + BSONObjBuilder builder; + testStruct.serialize(&builder); + auto loopbackDoc = builder.obj(); + + ASSERT_BSONOBJ_EQ(testDoc, loopbackDoc); + } + + // Positive: Test we can serialize from nothing the same document + { + BSONObjBuilder builder; + ParserT one_new; + one_new.setValue(expected); + one_new.serialize(&builder); + + auto serializedDoc = builder.obj(); + ASSERT_BSONOBJ_EQ(testDoc, serializedDoc); + } +} + +TEST(IDLBinData, TestUUID) { + TestBinDataArray<One_uuid, newUUID>(); +} + +TEST(IDLBinData, TestMD5) { + TestBinDataArray<One_md5, MD5Type>(); + + // Negative: Test document with a incorrectly size md5 field + { + IDLParserErrorContext ctxt("root"); + + uint8_t testData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + auto testDoc = BSON("value" << BSONBinData(testData, 15, MD5Type)); + ASSERT_THROWS(One_md5::parse(ctxt, testDoc), UserException); + } +} + +// Test if a given value for a given bson document parses successfully or fails if the bson types +// mismatch. +template <typename ParserT, BinDataType Parser_bindata_type, BinDataType Test_bindata_type> +void TestBinDataParse() { + IDLParserErrorContext ctxt("root"); + + uint8_t testData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; + auto testDoc = BSON("value" << BSONBinData(testData, 16, Test_bindata_type)); + + auto element = testDoc.firstElement(); + ASSERT_EQUALS(element.type(), BinData); + ASSERT_EQUALS(element.binDataType(), Test_bindata_type); + + if (Parser_bindata_type != Test_bindata_type) { + ASSERT_THROWS(ParserT::parse(ctxt, testDoc), UserException); + } else { + (void)ParserT::parse(ctxt, testDoc); + } +} + +template <typename ParserT, BinDataType Parser_bindata_type> +void TestBinDataParser() { + TestBinDataParse<ParserT, Parser_bindata_type, BinDataGeneral>(); + TestBinDataParse<ParserT, Parser_bindata_type, Function>(); + TestBinDataParse<ParserT, Parser_bindata_type, MD5Type>(); + TestBinDataParse<ParserT, Parser_bindata_type, newUUID>(); +} + +TEST(IDLBinData, TestParse) { + TestBinDataParser<One_bindata, BinDataGeneral>(); + TestBinDataParser<One_function, Function>(); + TestBinDataParser<One_uuid, newUUID>(); + TestBinDataParser<One_md5, MD5Type>(); +} + +// Mixed: test a type that accepts a custom bindata type +TEST(IDLBinData, TestCustomType) { + IDLParserErrorContext ctxt("root"); + + uint8_t testData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; + auto testDoc = BSON("value" << BSONBinData(testData, 14, BinDataGeneral)); + + auto element = testDoc.firstElement(); + ASSERT_EQUALS(element.type(), BinData); + ASSERT_EQUALS(element.binDataType(), BinDataGeneral); + + auto testStruct = One_bindata_custom::parse(ctxt, testDoc); + std::vector<std::uint8_t> testVector = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; + ASSERT_TRUE(testStruct.getValue().getVector() == testVector); + + // Positive: Test we can roundtrip from the just parsed document + { + BSONObjBuilder builder; + testStruct.serialize(&builder); + auto loopbackDoc = builder.obj(); + + ASSERT_BSONOBJ_EQ(testDoc, loopbackDoc); + } + + // Positive: Test we can serialize from nothing the same document + { + BSONObjBuilder builder; + One_bindata_custom one_new; + one_new.setValue(testVector); + one_new.serialize(&builder); + + auto serializedDoc = builder.obj(); + ASSERT_BSONOBJ_EQ(testDoc, serializedDoc); + } } /** @@ -831,4 +1084,5 @@ TEST(IDLCustomType, TestDerivedParser) { } } +} // namespace } // namespace mongo diff --git a/src/mongo/idl/idl_test_types.h b/src/mongo/idl/idl_test_types.h index 41f75c796f0..6e03d48b470 100644 --- a/src/mongo/idl/idl_test_types.h +++ b/src/mongo/idl/idl_test_types.h @@ -28,6 +28,9 @@ #pragma once +#include <vector> + +#include "mongo/base/data_range.h" #include "mongo/bson/bsonobj.h" #include "mongo/bson/bsonobjbuilder.h" @@ -82,4 +85,32 @@ private: BSONObj _obj; }; +/** + * Simple class that demonstrates the contract a class must implement to parse a BSON "bindata" + * variable length type + * from the IDL parser. + */ +class BinDataCustomType { +public: + BinDataCustomType() {} + BinDataCustomType(std::vector<std::uint8_t>& vec) : _vec(std::move(vec)) {} + + static BinDataCustomType parse(const std::vector<std::uint8_t> vec) { + BinDataCustomType b; + b._vec = std::move(vec); + return b; + } + + ConstDataRange serialize() const { + return makeCDR(_vec); + } + + const std::vector<std::uint8_t>& getVector() const { + return _vec; + } + +private: + std::vector<std::uint8_t> _vec; +}; + } // namespace mongo diff --git a/src/mongo/idl/unittest.idl b/src/mongo/idl/unittest.idl index 5d49ea37560..7aecd720ad4 100644 --- a/src/mongo/idl/unittest.idl +++ b/src/mongo/idl/unittest.idl @@ -41,6 +41,20 @@ types: ################################################################################################## # +# Test a custom non-BSONElement deserialization and serialization methods for a bindata type +# +################################################################################################## + + bindata_custom: + bson_serialization_type: bindata + bindata_subtype: generic + description: "A MongoDB BinDataCustomType" + cpp_type: "mongo::BinDataCustomType" + serializer: mongo::BinDataCustomType::serialize + deserializer: mongo::BinDataCustomType::parse + +################################################################################################## +# # Test a custom non-BSONElement deserialization and serialization methods for an any type # ################################################################################################## @@ -81,6 +95,11 @@ types: - double deserializer: "mongo::BSONElement::numberInt" +################################################################################################## +# +# Unit test structs for a single value to ensure type validation works correctly +# +################################################################################################## structs: @@ -172,6 +191,17 @@ structs: ################################################################################################## # +# Test a custom non-BSONElement deserialization and serialization methods for a bindata type +# +################################################################################################## + + one_bindata_custom: + description: UnitTest for a custom bindata + fields: + value: bindata_custom + +################################################################################################## +# # Test a custom non-BSONElement deserialization and serialization methods for an any type # ################################################################################################## @@ -248,6 +278,12 @@ structs: field3: type: object optional: true + field4: + type: bindata_generic + optional: true + field5: + type: bindata_uuid + optional: true ################################################################################################## # @@ -269,6 +305,10 @@ structs: type: array<int> field3: type: array<double> + field4: + type: array<bindata_generic> + field5: + type: array<bindata_uuid> optional_array_fields: description: UnitTest for arrays of optional simple types @@ -282,6 +322,12 @@ structs: field3: type: array<double> optional: true + field4: + type: array<bindata_generic> + optional: true + field5: + type: array<bindata_uuid> + optional: true ################################################################################################## # @@ -302,6 +348,8 @@ structs: type: array<object_basic_type> field5: type: array<object> + field6: + type: array<one_string> field1o: type: array<safeInt32> optional: true @@ -317,3 +365,7 @@ structs: field5o: type: array<object> optional: true + field6o: + type: array<one_string> + optional: true +# diff --git a/src/mongo/idl/unittest_import.idl b/src/mongo/idl/unittest_import.idl index a2064766133..0e9403f65d5 100644 --- a/src/mongo/idl/unittest_import.idl +++ b/src/mongo/idl/unittest_import.idl @@ -58,6 +58,26 @@ structs: fields: value: bool + one_bindata: + description: UnitTest for a single bindata_generic + fields: + value: bindata_generic + + one_function: + description: UnitTest for a single bindata_function + fields: + value: bindata_function + + one_uuid: + description: UnitTest for a single bindata_uuid + fields: + value: bindata_uuid + + one_md5: + description: UnitTest for a single bindata_md5 + fields: + value: bindata_md5 + one_objectid: description: UnitTest for a single objectid fields: |