1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file or at 6 // https://developers.google.com/open-source/licenses/bsd 7 8 #ifndef CONFORMANCE_BINARY_JSON_CONFORMANCE_SUITE_H 9 #define CONFORMANCE_BINARY_JSON_CONFORMANCE_SUITE_H 10 11 #include <functional> 12 #include <memory> 13 #include <string> 14 #include <utility> 15 #include <vector> 16 17 #include "absl/strings/string_view.h" 18 #include "json/json.h" 19 #include "conformance_test.h" 20 #include "google/protobuf/descriptor.h" 21 #include "google/protobuf/util/type_resolver.h" 22 23 namespace google { 24 namespace protobuf { 25 26 class BinaryAndJsonConformanceSuite : public ConformanceTestSuite { 27 public: 28 BinaryAndJsonConformanceSuite() = default; 29 30 private: 31 void RunSuiteImpl() override; 32 bool ParseJsonResponse(const conformance::ConformanceResponse& response, 33 Message* test_message); 34 bool ParseResponse(const conformance::ConformanceResponse& response, 35 const ConformanceRequestSetting& setting, 36 Message* test_message) override; SetTypeUrl(absl::string_view type_url)37 void SetTypeUrl(absl::string_view type_url) { 38 type_url_ = std::string(type_url); 39 } 40 41 template <typename MessageType> 42 void RunValidBinaryProtobufTest(const std::string& test_name, 43 ConformanceLevel level, 44 const std::string& input_protobuf, 45 const std::string& equivalent_text_format); 46 47 template <typename MessageType> 48 void RunValidProtobufTest(const std::string& test_name, 49 ConformanceLevel level, 50 const std::string& input_protobuf, 51 const std::string& equivalent_text_format); 52 53 void RunDelimitedFieldTests(); 54 55 template <typename MessageType> 56 friend class BinaryAndJsonConformanceSuiteImpl; 57 58 std::unique_ptr<google::protobuf::util::TypeResolver> type_resolver_; 59 std::string type_url_; 60 }; 61 62 template <typename MessageType> 63 class BinaryAndJsonConformanceSuiteImpl { 64 public: 65 explicit BinaryAndJsonConformanceSuiteImpl( 66 BinaryAndJsonConformanceSuite* suite, bool run_proto3_tests); 67 68 private: 69 using ConformanceRequestSetting = 70 BinaryAndJsonConformanceSuite::ConformanceRequestSetting; 71 using ConformanceLevel = BinaryAndJsonConformanceSuite::ConformanceLevel; 72 constexpr static ConformanceLevel RECOMMENDED = ConformanceLevel::RECOMMENDED; 73 constexpr static ConformanceLevel REQUIRED = ConformanceLevel::REQUIRED; 74 75 void RunAllTests(); 76 77 void RunBinaryPerformanceTests(); 78 void RunJsonPerformanceTests(); 79 void RunJsonTests(); 80 void RunJsonTestsForStoresDefaultPrimitive(); 81 void RunJsonTestsForFieldNameConvention(); 82 void RunJsonTestsForNonRepeatedTypes(); 83 void RunJsonTestsForRepeatedTypes(); 84 void RunJsonTestsForNullTypes(); 85 void RunJsonTestsForWrapperTypes(); 86 void RunJsonTestsForFieldMask(); 87 void RunJsonTestsForStruct(); 88 void RunJsonTestsForValue(); 89 void RunJsonTestsForAny(); 90 void RunJsonTestsForUnknownEnumStringValues(); 91 void RunValidJsonTest(const std::string& test_name, ConformanceLevel level, 92 const std::string& input_json, 93 const std::string& equivalent_text_format); 94 void RunValidJsonTestWithMessage(const std::string& test_name, 95 ConformanceLevel level, 96 const std::string& input_json, 97 const std::string& equivalent_text_forma, 98 const Message& prototype); 99 void RunValidJsonTestWithProtobufInput( 100 const std::string& test_name, ConformanceLevel level, 101 const MessageType& input, const std::string& equivalent_text_format); 102 void RunValidJsonIgnoreUnknownTest(const std::string& test_name, 103 ConformanceLevel level, 104 const std::string& input_json, 105 const std::string& equivalent_text_format); 106 void RunValidProtobufTest(const std::string& test_name, 107 ConformanceLevel level, 108 const std::string& input_protobuf, 109 const std::string& equivalent_text_format); 110 void RunValidBinaryProtobufTest(const std::string& test_name, 111 ConformanceLevel level, 112 const std::string& input_protobuf); 113 void RunValidBinaryProtobufTest(const std::string& test_name, 114 ConformanceLevel level, 115 const std::string& input_protobuf, 116 const std::string& expected_protobuf); 117 void RunBinaryPerformanceMergeMessageWithField( 118 const std::string& test_name, const std::string& field_proto); 119 120 void RunValidProtobufTestWithMessage( 121 const std::string& test_name, ConformanceLevel level, 122 const Message* input, const std::string& equivalent_text_format); 123 124 typedef std::function<bool(const Json::Value&)> Validator; 125 void RunValidJsonTestWithValidator(const std::string& test_name, 126 ConformanceLevel level, 127 const std::string& input_json, 128 const Validator& validator); 129 void ExpectParseFailureForJson(const std::string& test_name, 130 ConformanceLevel level, 131 const std::string& input_json); 132 void ExpectSerializeFailureForJson(const std::string& test_name, 133 ConformanceLevel level, 134 const std::string& text_format); 135 void ExpectParseFailureForProtoWithProtoVersion(const std::string& proto, 136 const std::string& test_name, 137 ConformanceLevel level); 138 void ExpectParseFailureForProto(const std::string& proto, 139 const std::string& test_name, 140 ConformanceLevel level); 141 void ExpectHardParseFailureForProto(const std::string& proto, 142 const std::string& test_name, 143 ConformanceLevel level); 144 void TestPrematureEOFForType(google::protobuf::FieldDescriptor::Type type); 145 void TestIllegalTags(); 146 void TestUnknownWireType(); 147 void TestOneofMessage(); 148 void TestUnknownMessage(); 149 void TestUnknownOrdering(); 150 void TestValidDataForType( 151 google::protobuf::FieldDescriptor::Type, 152 std::vector<std::pair<std::string, std::string>> values); 153 void TestValidDataForRepeatedScalarMessage(); 154 void TestValidDataForMapType(google::protobuf::FieldDescriptor::Type, 155 google::protobuf::FieldDescriptor::Type); 156 void TestValidDataForOneofType(google::protobuf::FieldDescriptor::Type); 157 void TestMergeOneofMessage(); 158 void TestOverwriteMessageValueMap(); 159 void TestBinaryPerformanceForAlternatingUnknownFields(); 160 void TestBinaryPerformanceMergeMessageWithRepeatedFieldForType( 161 google::protobuf::FieldDescriptor::Type); 162 void TestBinaryPerformanceMergeMessageWithUnknownFieldForType( 163 google::protobuf::FieldDescriptor::Type); 164 void TestJsonPerformanceMergeMessageWithRepeatedFieldForType( 165 google::protobuf::FieldDescriptor::Type, std::string field_value); 166 167 enum class Packed { 168 kUnspecified = 0, 169 kTrue = 1, 170 kFalse = 2, 171 }; 172 const FieldDescriptor* GetFieldForType( 173 FieldDescriptor::Type type, bool repeated, 174 Packed packed = Packed::kUnspecified) const; 175 const FieldDescriptor* GetFieldForMapType( 176 FieldDescriptor::Type key_type, FieldDescriptor::Type value_type) const; 177 const FieldDescriptor* GetFieldForOneofType(FieldDescriptor::Type type, 178 bool exclusive = false) const; 179 std::string SyntaxIdentifier() const; 180 181 BinaryAndJsonConformanceSuite& suite_; 182 bool run_proto3_tests_; 183 }; 184 185 } // namespace protobuf 186 } // namespace google 187 188 #endif // CONFORMANCE_BINARY_JSON_CONFORMANCE_SUITE_H 189