1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // http://code.google.com/p/protobuf/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 // Author: kenton (at) google.com (Kenton Varda) 32 // Based on original Protocol Buffers design by 33 // Sanjay Ghemawat, Jeff Dean, and others. 34 // 35 // To test GeneratedMessageReflection, we actually let the protocol compiler 36 // generate a full protocol message implementation and then test its 37 // reflection interface. This is much easier and more maintainable than 38 // trying to create our own Message class for GeneratedMessageReflection 39 // to wrap. 40 // 41 // The tests here closely mirror some of the tests in 42 // compiler/cpp/unittest, except using the reflection interface 43 // rather than generated accessors. 44 45 #include <google/protobuf/generated_message_reflection.h> 46 #include <google/protobuf/descriptor.h> 47 #include <google/protobuf/test_util.h> 48 #include <google/protobuf/unittest.pb.h> 49 50 #include <google/protobuf/stubs/common.h> 51 #include <google/protobuf/testing/googletest.h> 52 #include <gtest/gtest.h> 53 54 namespace google { 55 namespace protobuf { 56 57 namespace { 58 59 // Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes. 60 const FieldDescriptor* F(const string& name) { 61 const FieldDescriptor* result = 62 unittest::TestAllTypes::descriptor()->FindFieldByName(name); 63 GOOGLE_CHECK(result != NULL); 64 return result; 65 } 66 67 TEST(GeneratedMessageReflectionTest, Defaults) { 68 // Check that all default values are set correctly in the initial message. 69 unittest::TestAllTypes message; 70 TestUtil::ReflectionTester reflection_tester( 71 unittest::TestAllTypes::descriptor()); 72 73 reflection_tester.ExpectClearViaReflection(message); 74 75 const Reflection* reflection = message.GetReflection(); 76 77 // Messages should return pointers to default instances until first use. 78 // (This is not checked by ExpectClear() since it is not actually true after 79 // the fields have been set and then cleared.) 80 EXPECT_EQ(&unittest::TestAllTypes::OptionalGroup::default_instance(), 81 &reflection->GetMessage(message, F("optionalgroup"))); 82 EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(), 83 &reflection->GetMessage(message, F("optional_nested_message"))); 84 EXPECT_EQ(&unittest::ForeignMessage::default_instance(), 85 &reflection->GetMessage(message, F("optional_foreign_message"))); 86 EXPECT_EQ(&unittest_import::ImportMessage::default_instance(), 87 &reflection->GetMessage(message, F("optional_import_message"))); 88 } 89 90 TEST(GeneratedMessageReflectionTest, Accessors) { 91 // Set every field to a unique value then go back and check all those 92 // values. 93 unittest::TestAllTypes message; 94 TestUtil::ReflectionTester reflection_tester( 95 unittest::TestAllTypes::descriptor()); 96 97 reflection_tester.SetAllFieldsViaReflection(&message); 98 TestUtil::ExpectAllFieldsSet(message); 99 reflection_tester.ExpectAllFieldsSetViaReflection(message); 100 101 reflection_tester.ModifyRepeatedFieldsViaReflection(&message); 102 TestUtil::ExpectRepeatedFieldsModified(message); 103 } 104 105 TEST(GeneratedMessageReflectionTest, GetStringReference) { 106 // Test that GetStringReference() returns the underlying string when it is 107 // a normal string field. 108 unittest::TestAllTypes message; 109 message.set_optional_string("foo"); 110 message.add_repeated_string("foo"); 111 112 const Reflection* reflection = message.GetReflection(); 113 string scratch; 114 115 EXPECT_EQ(&message.optional_string(), 116 &reflection->GetStringReference(message, F("optional_string"), &scratch)) 117 << "For simple string fields, GetStringReference() should return a " 118 "reference to the underlying string."; 119 EXPECT_EQ(&message.repeated_string(0), 120 &reflection->GetRepeatedStringReference(message, F("repeated_string"), 121 0, &scratch)) 122 << "For simple string fields, GetRepeatedStringReference() should return " 123 "a reference to the underlying string."; 124 } 125 126 127 TEST(GeneratedMessageReflectionTest, DefaultsAfterClear) { 128 // Check that after setting all fields and then clearing, getting an 129 // embedded message does NOT return the default instance. 130 unittest::TestAllTypes message; 131 TestUtil::ReflectionTester reflection_tester( 132 unittest::TestAllTypes::descriptor()); 133 134 TestUtil::SetAllFields(&message); 135 message.Clear(); 136 137 const Reflection* reflection = message.GetReflection(); 138 139 EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(), 140 &reflection->GetMessage(message, F("optionalgroup"))); 141 EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(), 142 &reflection->GetMessage(message, F("optional_nested_message"))); 143 EXPECT_NE(&unittest::ForeignMessage::default_instance(), 144 &reflection->GetMessage(message, F("optional_foreign_message"))); 145 EXPECT_NE(&unittest_import::ImportMessage::default_instance(), 146 &reflection->GetMessage(message, F("optional_import_message"))); 147 } 148 149 150 TEST(GeneratedMessageReflectionTest, Swap) { 151 unittest::TestAllTypes message1; 152 unittest::TestAllTypes message2; 153 154 TestUtil::SetAllFields(&message1); 155 156 const Reflection* reflection = message1.GetReflection(); 157 reflection->Swap(&message1, &message2); 158 159 TestUtil::ExpectClear(message1); 160 TestUtil::ExpectAllFieldsSet(message2); 161 } 162 163 TEST(GeneratedMessageReflectionTest, SwapWithBothSet) { 164 unittest::TestAllTypes message1; 165 unittest::TestAllTypes message2; 166 167 TestUtil::SetAllFields(&message1); 168 TestUtil::SetAllFields(&message2); 169 TestUtil::ModifyRepeatedFields(&message2); 170 171 const Reflection* reflection = message1.GetReflection(); 172 reflection->Swap(&message1, &message2); 173 174 TestUtil::ExpectRepeatedFieldsModified(message1); 175 TestUtil::ExpectAllFieldsSet(message2); 176 177 message1.set_optional_int32(532819); 178 179 reflection->Swap(&message1, &message2); 180 181 EXPECT_EQ(532819, message2.optional_int32()); 182 } 183 184 TEST(GeneratedMessageReflectionTest, SwapExtensions) { 185 unittest::TestAllExtensions message1; 186 unittest::TestAllExtensions message2; 187 188 TestUtil::SetAllExtensions(&message1); 189 190 const Reflection* reflection = message1.GetReflection(); 191 reflection->Swap(&message1, &message2); 192 193 TestUtil::ExpectExtensionsClear(message1); 194 TestUtil::ExpectAllExtensionsSet(message2); 195 } 196 197 TEST(GeneratedMessageReflectionTest, SwapUnknown) { 198 unittest::TestEmptyMessage message1, message2; 199 200 message1.mutable_unknown_fields()->AddVarint(1234, 1); 201 202 EXPECT_EQ(1, message1.unknown_fields().field_count()); 203 EXPECT_EQ(0, message2.unknown_fields().field_count()); 204 const Reflection* reflection = message1.GetReflection(); 205 reflection->Swap(&message1, &message2); 206 EXPECT_EQ(0, message1.unknown_fields().field_count()); 207 EXPECT_EQ(1, message2.unknown_fields().field_count()); 208 } 209 210 TEST(GeneratedMessageReflectionTest, RemoveLast) { 211 unittest::TestAllTypes message; 212 TestUtil::ReflectionTester reflection_tester( 213 unittest::TestAllTypes::descriptor()); 214 215 TestUtil::SetAllFields(&message); 216 217 reflection_tester.RemoveLastRepeatedsViaReflection(&message); 218 219 TestUtil::ExpectLastRepeatedsRemoved(message); 220 } 221 222 TEST(GeneratedMessageReflectionTest, RemoveLastExtensions) { 223 unittest::TestAllExtensions message; 224 TestUtil::ReflectionTester reflection_tester( 225 unittest::TestAllExtensions::descriptor()); 226 227 TestUtil::SetAllExtensions(&message); 228 229 reflection_tester.RemoveLastRepeatedsViaReflection(&message); 230 231 TestUtil::ExpectLastRepeatedExtensionsRemoved(message); 232 } 233 234 TEST(GeneratedMessageReflectionTest, ReleaseLast) { 235 unittest::TestAllTypes message; 236 const Descriptor* descriptor = message.GetDescriptor(); 237 TestUtil::ReflectionTester reflection_tester(descriptor); 238 239 TestUtil::SetAllFields(&message); 240 241 reflection_tester.ReleaseLastRepeatedsViaReflection(&message, false); 242 243 TestUtil::ExpectLastRepeatedsReleased(message); 244 245 // Now test that we actually release the right message. 246 message.Clear(); 247 TestUtil::SetAllFields(&message); 248 ASSERT_EQ(2, message.repeated_foreign_message_size()); 249 const protobuf_unittest::ForeignMessage* expected = 250 message.mutable_repeated_foreign_message(1); 251 scoped_ptr<Message> released(message.GetReflection()->ReleaseLast( 252 &message, descriptor->FindFieldByName("repeated_foreign_message"))); 253 EXPECT_EQ(expected, released.get()); 254 } 255 256 TEST(GeneratedMessageReflectionTest, ReleaseLastExtensions) { 257 unittest::TestAllExtensions message; 258 const Descriptor* descriptor = message.GetDescriptor(); 259 TestUtil::ReflectionTester reflection_tester(descriptor); 260 261 TestUtil::SetAllExtensions(&message); 262 263 reflection_tester.ReleaseLastRepeatedsViaReflection(&message, true); 264 265 TestUtil::ExpectLastRepeatedExtensionsReleased(message); 266 267 // Now test that we actually release the right message. 268 message.Clear(); 269 TestUtil::SetAllExtensions(&message); 270 ASSERT_EQ(2, message.ExtensionSize( 271 unittest::repeated_foreign_message_extension)); 272 const protobuf_unittest::ForeignMessage* expected = message.MutableExtension( 273 unittest::repeated_foreign_message_extension, 1); 274 scoped_ptr<Message> released(message.GetReflection()->ReleaseLast( 275 &message, descriptor->file()->FindExtensionByName( 276 "repeated_foreign_message_extension"))); 277 EXPECT_EQ(expected, released.get()); 278 279 } 280 281 TEST(GeneratedMessageReflectionTest, SwapRepeatedElements) { 282 unittest::TestAllTypes message; 283 TestUtil::ReflectionTester reflection_tester( 284 unittest::TestAllTypes::descriptor()); 285 286 TestUtil::SetAllFields(&message); 287 288 // Swap and test that fields are all swapped. 289 reflection_tester.SwapRepeatedsViaReflection(&message); 290 TestUtil::ExpectRepeatedsSwapped(message); 291 292 // Swap back and test that fields are all back to original values. 293 reflection_tester.SwapRepeatedsViaReflection(&message); 294 TestUtil::ExpectAllFieldsSet(message); 295 } 296 297 TEST(GeneratedMessageReflectionTest, SwapRepeatedElementsExtension) { 298 unittest::TestAllExtensions message; 299 TestUtil::ReflectionTester reflection_tester( 300 unittest::TestAllExtensions::descriptor()); 301 302 TestUtil::SetAllExtensions(&message); 303 304 // Swap and test that fields are all swapped. 305 reflection_tester.SwapRepeatedsViaReflection(&message); 306 TestUtil::ExpectRepeatedExtensionsSwapped(message); 307 308 // Swap back and test that fields are all back to original values. 309 reflection_tester.SwapRepeatedsViaReflection(&message); 310 TestUtil::ExpectAllExtensionsSet(message); 311 } 312 313 TEST(GeneratedMessageReflectionTest, Extensions) { 314 // Set every extension to a unique value then go back and check all those 315 // values. 316 unittest::TestAllExtensions message; 317 TestUtil::ReflectionTester reflection_tester( 318 unittest::TestAllExtensions::descriptor()); 319 320 reflection_tester.SetAllFieldsViaReflection(&message); 321 TestUtil::ExpectAllExtensionsSet(message); 322 reflection_tester.ExpectAllFieldsSetViaReflection(message); 323 324 reflection_tester.ModifyRepeatedFieldsViaReflection(&message); 325 TestUtil::ExpectRepeatedExtensionsModified(message); 326 } 327 328 TEST(GeneratedMessageReflectionTest, FindExtensionTypeByNumber) { 329 const Reflection* reflection = 330 unittest::TestAllExtensions::default_instance().GetReflection(); 331 332 const FieldDescriptor* extension1 = 333 unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( 334 "optional_int32_extension"); 335 const FieldDescriptor* extension2 = 336 unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( 337 "repeated_string_extension"); 338 339 EXPECT_EQ(extension1, 340 reflection->FindKnownExtensionByNumber(extension1->number())); 341 EXPECT_EQ(extension2, 342 reflection->FindKnownExtensionByNumber(extension2->number())); 343 344 // Non-existent extension. 345 EXPECT_TRUE(reflection->FindKnownExtensionByNumber(62341) == NULL); 346 347 // Extensions of TestAllExtensions should not show up as extensions of 348 // other types. 349 EXPECT_TRUE(unittest::TestAllTypes::default_instance().GetReflection()-> 350 FindKnownExtensionByNumber(extension1->number()) == NULL); 351 } 352 353 TEST(GeneratedMessageReflectionTest, FindKnownExtensionByName) { 354 const Reflection* reflection = 355 unittest::TestAllExtensions::default_instance().GetReflection(); 356 357 const FieldDescriptor* extension1 = 358 unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( 359 "optional_int32_extension"); 360 const FieldDescriptor* extension2 = 361 unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( 362 "repeated_string_extension"); 363 364 EXPECT_EQ(extension1, 365 reflection->FindKnownExtensionByName(extension1->full_name())); 366 EXPECT_EQ(extension2, 367 reflection->FindKnownExtensionByName(extension2->full_name())); 368 369 // Non-existent extension. 370 EXPECT_TRUE(reflection->FindKnownExtensionByName("no_such_ext") == NULL); 371 372 // Extensions of TestAllExtensions should not show up as extensions of 373 // other types. 374 EXPECT_TRUE(unittest::TestAllTypes::default_instance().GetReflection()-> 375 FindKnownExtensionByName(extension1->full_name()) == NULL); 376 } 377 378 TEST(GeneratedMessageReflectionTest, ReleaseMessageTest) { 379 unittest::TestAllTypes message; 380 TestUtil::ReflectionTester reflection_tester( 381 unittest::TestAllTypes::descriptor()); 382 383 // When nothing is set, we expect all released messages to be NULL. 384 reflection_tester.ExpectMessagesReleasedViaReflection( 385 &message, TestUtil::ReflectionTester::IS_NULL); 386 387 // After fields are set we should get non-NULL releases. 388 reflection_tester.SetAllFieldsViaReflection(&message); 389 reflection_tester.ExpectMessagesReleasedViaReflection( 390 &message, TestUtil::ReflectionTester::NOT_NULL); 391 392 // After Clear() we may or may not get a message from ReleaseMessage(). 393 // This is implementation specific. 394 reflection_tester.SetAllFieldsViaReflection(&message); 395 message.Clear(); 396 reflection_tester.ExpectMessagesReleasedViaReflection( 397 &message, TestUtil::ReflectionTester::CAN_BE_NULL); 398 399 // Test a different code path for setting after releasing. 400 TestUtil::SetAllFields(&message); 401 TestUtil::ExpectAllFieldsSet(message); 402 } 403 404 TEST(GeneratedMessageReflectionTest, ReleaseExtensionMessageTest) { 405 unittest::TestAllExtensions message; 406 TestUtil::ReflectionTester reflection_tester( 407 unittest::TestAllExtensions::descriptor()); 408 409 // When nothing is set, we expect all released messages to be NULL. 410 reflection_tester.ExpectMessagesReleasedViaReflection( 411 &message, TestUtil::ReflectionTester::IS_NULL); 412 413 // After fields are set we should get non-NULL releases. 414 reflection_tester.SetAllFieldsViaReflection(&message); 415 reflection_tester.ExpectMessagesReleasedViaReflection( 416 &message, TestUtil::ReflectionTester::NOT_NULL); 417 418 // After Clear() we may or may not get a message from ReleaseMessage(). 419 // This is implementation specific. 420 reflection_tester.SetAllFieldsViaReflection(&message); 421 message.Clear(); 422 reflection_tester.ExpectMessagesReleasedViaReflection( 423 &message, TestUtil::ReflectionTester::CAN_BE_NULL); 424 425 // Test a different code path for setting after releasing. 426 TestUtil::SetAllExtensions(&message); 427 TestUtil::ExpectAllExtensionsSet(message); 428 } 429 430 #ifdef PROTOBUF_HAS_DEATH_TEST 431 432 TEST(GeneratedMessageReflectionTest, UsageErrors) { 433 unittest::TestAllTypes message; 434 const Reflection* reflection = message.GetReflection(); 435 const Descriptor* descriptor = message.GetDescriptor(); 436 437 #define f(NAME) descriptor->FindFieldByName(NAME) 438 439 // Testing every single failure mode would be too much work. Let's just 440 // check a few. 441 EXPECT_DEATH( 442 reflection->GetInt32( 443 message, descriptor->FindFieldByName("optional_int64")), 444 "Protocol Buffer reflection usage error:\n" 445 " Method : google::protobuf::Reflection::GetInt32\n" 446 " Message type: protobuf_unittest\\.TestAllTypes\n" 447 " Field : protobuf_unittest\\.TestAllTypes\\.optional_int64\n" 448 " Problem : Field is not the right type for this message:\n" 449 " Expected : CPPTYPE_INT32\n" 450 " Field type: CPPTYPE_INT64"); 451 EXPECT_DEATH( 452 reflection->GetInt32( 453 message, descriptor->FindFieldByName("repeated_int32")), 454 "Protocol Buffer reflection usage error:\n" 455 " Method : google::protobuf::Reflection::GetInt32\n" 456 " Message type: protobuf_unittest.TestAllTypes\n" 457 " Field : protobuf_unittest.TestAllTypes.repeated_int32\n" 458 " Problem : Field is repeated; the method requires a singular field."); 459 EXPECT_DEATH( 460 reflection->GetInt32( 461 message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")), 462 "Protocol Buffer reflection usage error:\n" 463 " Method : google::protobuf::Reflection::GetInt32\n" 464 " Message type: protobuf_unittest.TestAllTypes\n" 465 " Field : protobuf_unittest.ForeignMessage.c\n" 466 " Problem : Field does not match message type."); 467 EXPECT_DEATH( 468 reflection->HasField( 469 message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")), 470 "Protocol Buffer reflection usage error:\n" 471 " Method : google::protobuf::Reflection::HasField\n" 472 " Message type: protobuf_unittest.TestAllTypes\n" 473 " Field : protobuf_unittest.ForeignMessage.c\n" 474 " Problem : Field does not match message type."); 475 476 #undef f 477 } 478 479 #endif // PROTOBUF_HAS_DEATH_TEST 480 481 482 } // namespace 483 } // namespace protobuf 484 } // namespace google 485