1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 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 package com.google.protobuf; 32 33 import com.google.protobuf.Descriptors.FieldDescriptor; 34 import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize; 35 import protobuf_unittest.UnittestProto; 36 import protobuf_unittest.UnittestProto.ForeignMessage; 37 import protobuf_unittest.UnittestProto.TestAllExtensions; 38 import protobuf_unittest.UnittestProto.TestAllTypes; 39 import protobuf_unittest.UnittestProto.TestPackedTypes; 40 import protobuf_unittest.UnittestProto.TestRequired; 41 import protobuf_unittest.UnittestProto.TestRequiredForeign; 42 import protobuf_unittest.UnittestProto.TestUnpackedTypes; 43 import junit.framework.TestCase; 44 45 import java.util.Map; 46 47 /** 48 * Unit test for {@link AbstractMessage}. 49 * 50 * @author kenton@google.com Kenton Varda 51 */ 52 public class AbstractMessageTest extends TestCase { 53 /** 54 * Extends AbstractMessage and wraps some other message object. The methods 55 * of the Message interface which aren't explicitly implemented by 56 * AbstractMessage are forwarded to the wrapped object. This allows us to 57 * test that AbstractMessage's implementations work even if the wrapped 58 * object does not use them. 59 */ 60 private static class AbstractMessageWrapper extends AbstractMessage { 61 private final Message wrappedMessage; 62 AbstractMessageWrapper(Message wrappedMessage)63 public AbstractMessageWrapper(Message wrappedMessage) { 64 this.wrappedMessage = wrappedMessage; 65 } 66 67 @Override getDescriptorForType()68 public Descriptors.Descriptor getDescriptorForType() { 69 return wrappedMessage.getDescriptorForType(); 70 } 71 @Override getDefaultInstanceForType()72 public AbstractMessageWrapper getDefaultInstanceForType() { 73 return new AbstractMessageWrapper( 74 wrappedMessage.getDefaultInstanceForType()); 75 } 76 @Override getAllFields()77 public Map<Descriptors.FieldDescriptor, Object> getAllFields() { 78 return wrappedMessage.getAllFields(); 79 } 80 @Override hasField(Descriptors.FieldDescriptor field)81 public boolean hasField(Descriptors.FieldDescriptor field) { 82 return wrappedMessage.hasField(field); 83 } 84 @Override getField(Descriptors.FieldDescriptor field)85 public Object getField(Descriptors.FieldDescriptor field) { 86 return wrappedMessage.getField(field); 87 } 88 @Override getRepeatedFieldCount(Descriptors.FieldDescriptor field)89 public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) { 90 return wrappedMessage.getRepeatedFieldCount(field); 91 } 92 @Override getRepeatedField(Descriptors.FieldDescriptor field, int index)93 public Object getRepeatedField(Descriptors.FieldDescriptor field, int index) { 94 return wrappedMessage.getRepeatedField(field, index); 95 } 96 @Override getUnknownFields()97 public UnknownFieldSet getUnknownFields() { 98 return wrappedMessage.getUnknownFields(); 99 } 100 @Override newBuilderForType()101 public Builder newBuilderForType() { 102 return new Builder(wrappedMessage.newBuilderForType()); 103 } 104 @Override toBuilder()105 public Builder toBuilder() { 106 return new Builder(wrappedMessage.toBuilder()); 107 } 108 109 static class Builder extends AbstractMessage.Builder<Builder> { 110 private final Message.Builder wrappedBuilder; 111 Builder(Message.Builder wrappedBuilder)112 public Builder(Message.Builder wrappedBuilder) { 113 this.wrappedBuilder = wrappedBuilder; 114 } 115 116 @Override build()117 public AbstractMessageWrapper build() { 118 return new AbstractMessageWrapper(wrappedBuilder.build()); 119 } 120 @Override buildPartial()121 public AbstractMessageWrapper buildPartial() { 122 return new AbstractMessageWrapper(wrappedBuilder.buildPartial()); 123 } 124 @Override clone()125 public Builder clone() { 126 return new Builder(wrappedBuilder.clone()); 127 } 128 @Override isInitialized()129 public boolean isInitialized() { 130 return clone().buildPartial().isInitialized(); 131 } 132 @Override getDescriptorForType()133 public Descriptors.Descriptor getDescriptorForType() { 134 return wrappedBuilder.getDescriptorForType(); 135 } 136 @Override getDefaultInstanceForType()137 public AbstractMessageWrapper getDefaultInstanceForType() { 138 return new AbstractMessageWrapper( 139 wrappedBuilder.getDefaultInstanceForType()); 140 } 141 @Override getAllFields()142 public Map<Descriptors.FieldDescriptor, Object> getAllFields() { 143 return wrappedBuilder.getAllFields(); 144 } 145 @Override newBuilderForField(Descriptors.FieldDescriptor field)146 public Builder newBuilderForField(Descriptors.FieldDescriptor field) { 147 return new Builder(wrappedBuilder.newBuilderForField(field)); 148 } 149 @Override hasField(Descriptors.FieldDescriptor field)150 public boolean hasField(Descriptors.FieldDescriptor field) { 151 return wrappedBuilder.hasField(field); 152 } 153 @Override getField(Descriptors.FieldDescriptor field)154 public Object getField(Descriptors.FieldDescriptor field) { 155 return wrappedBuilder.getField(field); 156 } 157 @Override setField(Descriptors.FieldDescriptor field, Object value)158 public Builder setField(Descriptors.FieldDescriptor field, Object value) { 159 wrappedBuilder.setField(field, value); 160 return this; 161 } 162 @Override clearField(Descriptors.FieldDescriptor field)163 public Builder clearField(Descriptors.FieldDescriptor field) { 164 wrappedBuilder.clearField(field); 165 return this; 166 } 167 @Override getRepeatedFieldCount(Descriptors.FieldDescriptor field)168 public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) { 169 return wrappedBuilder.getRepeatedFieldCount(field); 170 } 171 @Override getRepeatedField(Descriptors.FieldDescriptor field, int index)172 public Object getRepeatedField(Descriptors.FieldDescriptor field, int index) { 173 return wrappedBuilder.getRepeatedField(field, index); 174 } 175 @Override setRepeatedField(Descriptors.FieldDescriptor field, int index, Object value)176 public Builder setRepeatedField(Descriptors.FieldDescriptor field, int index, Object value) { 177 wrappedBuilder.setRepeatedField(field, index, value); 178 return this; 179 } 180 @Override addRepeatedField(Descriptors.FieldDescriptor field, Object value)181 public Builder addRepeatedField(Descriptors.FieldDescriptor field, Object value) { 182 wrappedBuilder.addRepeatedField(field, value); 183 return this; 184 } 185 @Override getUnknownFields()186 public UnknownFieldSet getUnknownFields() { 187 return wrappedBuilder.getUnknownFields(); 188 } 189 @Override setUnknownFields(UnknownFieldSet unknownFields)190 public Builder setUnknownFields(UnknownFieldSet unknownFields) { 191 wrappedBuilder.setUnknownFields(unknownFields); 192 return this; 193 } 194 @Override getFieldBuilder(FieldDescriptor field)195 public Message.Builder getFieldBuilder(FieldDescriptor field) { 196 return wrappedBuilder.getFieldBuilder(field); 197 } 198 } 199 @Override getParserForType()200 public Parser<? extends Message> getParserForType() { 201 return wrappedMessage.getParserForType(); 202 } 203 } 204 205 // ================================================================= 206 207 TestUtil.ReflectionTester reflectionTester = 208 new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null); 209 210 TestUtil.ReflectionTester extensionsReflectionTester = 211 new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(), 212 TestUtil.getExtensionRegistry()); 213 testClear()214 public void testClear() throws Exception { 215 AbstractMessageWrapper message = 216 new AbstractMessageWrapper.Builder( 217 TestAllTypes.newBuilder(TestUtil.getAllSet())) 218 .clear().build(); 219 TestUtil.assertClear((TestAllTypes) message.wrappedMessage); 220 } 221 testCopy()222 public void testCopy() throws Exception { 223 AbstractMessageWrapper message = 224 new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder()) 225 .mergeFrom(TestUtil.getAllSet()).build(); 226 TestUtil.assertAllFieldsSet((TestAllTypes) message.wrappedMessage); 227 } 228 testSerializedSize()229 public void testSerializedSize() throws Exception { 230 TestAllTypes message = TestUtil.getAllSet(); 231 Message abstractMessage = new AbstractMessageWrapper(TestUtil.getAllSet()); 232 233 assertEquals(message.getSerializedSize(), 234 abstractMessage.getSerializedSize()); 235 } 236 testSerialization()237 public void testSerialization() throws Exception { 238 Message abstractMessage = new AbstractMessageWrapper(TestUtil.getAllSet()); 239 240 TestUtil.assertAllFieldsSet( 241 TestAllTypes.parseFrom(abstractMessage.toByteString())); 242 243 assertEquals(TestUtil.getAllSet().toByteString(), 244 abstractMessage.toByteString()); 245 } 246 testParsing()247 public void testParsing() throws Exception { 248 AbstractMessageWrapper.Builder builder = 249 new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder()); 250 AbstractMessageWrapper message = 251 builder.mergeFrom(TestUtil.getAllSet().toByteString()).build(); 252 TestUtil.assertAllFieldsSet((TestAllTypes) message.wrappedMessage); 253 } 254 testParsingUninitialized()255 public void testParsingUninitialized() throws Exception { 256 TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder(); 257 builder.getOptionalMessageBuilder().setDummy2(10); 258 ByteString bytes = builder.buildPartial().toByteString(); 259 Message.Builder abstractMessageBuilder = 260 new AbstractMessageWrapper.Builder(TestRequiredForeign.newBuilder()); 261 // mergeFrom() should not throw initialization error. 262 abstractMessageBuilder.mergeFrom(bytes).buildPartial(); 263 try { 264 abstractMessageBuilder.mergeFrom(bytes).build(); 265 fail(); 266 } catch (UninitializedMessageException ex) { 267 // pass 268 } 269 270 // test DynamicMessage directly. 271 Message.Builder dynamicMessageBuilder = DynamicMessage.newBuilder( 272 TestRequiredForeign.getDescriptor()); 273 // mergeFrom() should not throw initialization error. 274 dynamicMessageBuilder.mergeFrom(bytes).buildPartial(); 275 try { 276 dynamicMessageBuilder.mergeFrom(bytes).build(); 277 fail(); 278 } catch (UninitializedMessageException ex) { 279 // pass 280 } 281 } 282 testPackedSerialization()283 public void testPackedSerialization() throws Exception { 284 Message abstractMessage = 285 new AbstractMessageWrapper(TestUtil.getPackedSet()); 286 287 TestUtil.assertPackedFieldsSet( 288 TestPackedTypes.parseFrom(abstractMessage.toByteString())); 289 290 assertEquals(TestUtil.getPackedSet().toByteString(), 291 abstractMessage.toByteString()); 292 } 293 testPackedParsing()294 public void testPackedParsing() throws Exception { 295 AbstractMessageWrapper.Builder builder = 296 new AbstractMessageWrapper.Builder(TestPackedTypes.newBuilder()); 297 AbstractMessageWrapper message = 298 builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build(); 299 TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage); 300 } 301 testUnpackedSerialization()302 public void testUnpackedSerialization() throws Exception { 303 Message abstractMessage = 304 new AbstractMessageWrapper(TestUtil.getUnpackedSet()); 305 306 TestUtil.assertUnpackedFieldsSet( 307 TestUnpackedTypes.parseFrom(abstractMessage.toByteString())); 308 309 assertEquals(TestUtil.getUnpackedSet().toByteString(), 310 abstractMessage.toByteString()); 311 } 312 testParsePackedToUnpacked()313 public void testParsePackedToUnpacked() throws Exception { 314 AbstractMessageWrapper.Builder builder = 315 new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder()); 316 AbstractMessageWrapper message = 317 builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build(); 318 TestUtil.assertUnpackedFieldsSet( 319 (TestUnpackedTypes) message.wrappedMessage); 320 } 321 testParseUnpackedToPacked()322 public void testParseUnpackedToPacked() throws Exception { 323 AbstractMessageWrapper.Builder builder = 324 new AbstractMessageWrapper.Builder(TestPackedTypes.newBuilder()); 325 AbstractMessageWrapper message = 326 builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build(); 327 TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage); 328 } 329 testUnpackedParsing()330 public void testUnpackedParsing() throws Exception { 331 AbstractMessageWrapper.Builder builder = 332 new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder()); 333 AbstractMessageWrapper message = 334 builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build(); 335 TestUtil.assertUnpackedFieldsSet( 336 (TestUnpackedTypes) message.wrappedMessage); 337 } 338 testOptimizedForSize()339 public void testOptimizedForSize() throws Exception { 340 // We're mostly only checking that this class was compiled successfully. 341 TestOptimizedForSize message = 342 TestOptimizedForSize.newBuilder().setI(1).build(); 343 message = TestOptimizedForSize.parseFrom(message.toByteString()); 344 assertEquals(2, message.getSerializedSize()); 345 } 346 347 // ----------------------------------------------------------------- 348 // Tests for isInitialized(). 349 350 private static final TestRequired TEST_REQUIRED_UNINITIALIZED = 351 TestRequired.getDefaultInstance(); 352 private static final TestRequired TEST_REQUIRED_INITIALIZED = 353 TestRequired.newBuilder().setA(1).setB(2).setC(3).build(); 354 testIsInitialized()355 public void testIsInitialized() throws Exception { 356 TestRequired.Builder builder = TestRequired.newBuilder(); 357 AbstractMessageWrapper.Builder abstractBuilder = 358 new AbstractMessageWrapper.Builder(builder); 359 360 assertFalse(abstractBuilder.isInitialized()); 361 assertEquals("a, b, c", abstractBuilder.getInitializationErrorString()); 362 builder.setA(1); 363 assertFalse(abstractBuilder.isInitialized()); 364 assertEquals("b, c", abstractBuilder.getInitializationErrorString()); 365 builder.setB(1); 366 assertFalse(abstractBuilder.isInitialized()); 367 assertEquals("c", abstractBuilder.getInitializationErrorString()); 368 builder.setC(1); 369 assertTrue(abstractBuilder.isInitialized()); 370 assertEquals("", abstractBuilder.getInitializationErrorString()); 371 } 372 testForeignIsInitialized()373 public void testForeignIsInitialized() throws Exception { 374 TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder(); 375 AbstractMessageWrapper.Builder abstractBuilder = 376 new AbstractMessageWrapper.Builder(builder); 377 378 assertTrue(abstractBuilder.isInitialized()); 379 assertEquals("", abstractBuilder.getInitializationErrorString()); 380 381 builder.setOptionalMessage(TEST_REQUIRED_UNINITIALIZED); 382 assertFalse(abstractBuilder.isInitialized()); 383 assertEquals( 384 "optional_message.a, optional_message.b, optional_message.c", 385 abstractBuilder.getInitializationErrorString()); 386 387 builder.setOptionalMessage(TEST_REQUIRED_INITIALIZED); 388 assertTrue(abstractBuilder.isInitialized()); 389 assertEquals("", abstractBuilder.getInitializationErrorString()); 390 391 builder.addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED); 392 assertFalse(abstractBuilder.isInitialized()); 393 assertEquals( 394 "repeated_message[0].a, repeated_message[0].b, repeated_message[0].c", 395 abstractBuilder.getInitializationErrorString()); 396 397 builder.setRepeatedMessage(0, TEST_REQUIRED_INITIALIZED); 398 assertTrue(abstractBuilder.isInitialized()); 399 assertEquals("", abstractBuilder.getInitializationErrorString()); 400 } 401 402 // ----------------------------------------------------------------- 403 // Tests for mergeFrom 404 405 static final TestAllTypes MERGE_SOURCE = 406 TestAllTypes.newBuilder() 407 .setOptionalInt32(1) 408 .setOptionalString("foo") 409 .setOptionalForeignMessage(ForeignMessage.getDefaultInstance()) 410 .addRepeatedString("bar") 411 .build(); 412 413 static final TestAllTypes MERGE_DEST = 414 TestAllTypes.newBuilder() 415 .setOptionalInt64(2) 416 .setOptionalString("baz") 417 .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(3).build()) 418 .addRepeatedString("qux") 419 .build(); 420 421 static final String MERGE_RESULT_TEXT = 422 "optional_int32: 1\n" + 423 "optional_int64: 2\n" + 424 "optional_string: \"foo\"\n" + 425 "optional_foreign_message {\n" + 426 " c: 3\n" + 427 "}\n" + 428 "repeated_string: \"qux\"\n" + 429 "repeated_string: \"bar\"\n"; 430 testMergeFrom()431 public void testMergeFrom() throws Exception { 432 AbstractMessageWrapper result = 433 new AbstractMessageWrapper.Builder( 434 TestAllTypes.newBuilder(MERGE_DEST)) 435 .mergeFrom(MERGE_SOURCE).build(); 436 437 assertEquals(MERGE_RESULT_TEXT, result.toString()); 438 } 439 440 // ----------------------------------------------------------------- 441 // Tests for equals and hashCode 442 testEqualsAndHashCode()443 public void testEqualsAndHashCode() throws Exception { 444 TestAllTypes a = TestUtil.getAllSet(); 445 TestAllTypes b = TestAllTypes.newBuilder().build(); 446 TestAllTypes c = TestAllTypes.newBuilder(b).addRepeatedString("x").build(); 447 TestAllTypes d = TestAllTypes.newBuilder(c).addRepeatedString("y").build(); 448 TestAllExtensions e = TestUtil.getAllExtensionsSet(); 449 TestAllExtensions f = TestAllExtensions.newBuilder(e) 450 .addExtension(UnittestProto.repeatedInt32Extension, 999).build(); 451 452 checkEqualsIsConsistent(a); 453 checkEqualsIsConsistent(b); 454 checkEqualsIsConsistent(c); 455 checkEqualsIsConsistent(d); 456 checkEqualsIsConsistent(e); 457 checkEqualsIsConsistent(f); 458 459 checkNotEqual(a, b); 460 checkNotEqual(a, c); 461 checkNotEqual(a, d); 462 checkNotEqual(a, e); 463 checkNotEqual(a, f); 464 465 checkNotEqual(b, c); 466 checkNotEqual(b, d); 467 checkNotEqual(b, e); 468 checkNotEqual(b, f); 469 470 checkNotEqual(c, d); 471 checkNotEqual(c, e); 472 checkNotEqual(c, f); 473 474 checkNotEqual(d, e); 475 checkNotEqual(d, f); 476 477 checkNotEqual(e, f); 478 479 // Deserializing into the TestEmptyMessage such that every field 480 // is an {@link UnknownFieldSet.Field}. 481 UnittestProto.TestEmptyMessage eUnknownFields = 482 UnittestProto.TestEmptyMessage.parseFrom(e.toByteArray()); 483 UnittestProto.TestEmptyMessage fUnknownFields = 484 UnittestProto.TestEmptyMessage.parseFrom(f.toByteArray()); 485 checkNotEqual(eUnknownFields, fUnknownFields); 486 checkEqualsIsConsistent(eUnknownFields); 487 checkEqualsIsConsistent(fUnknownFields); 488 489 // Subsequent reconstitutions should be identical 490 UnittestProto.TestEmptyMessage eUnknownFields2 = 491 UnittestProto.TestEmptyMessage.parseFrom(e.toByteArray()); 492 checkEqualsIsConsistent(eUnknownFields, eUnknownFields2); 493 } 494 495 496 /** 497 * Asserts that the given proto has symmetric equals and hashCode methods. 498 */ checkEqualsIsConsistent(Message message)499 private void checkEqualsIsConsistent(Message message) { 500 // Object should be equal to itself. 501 assertEquals(message, message); 502 503 // Object should be equal to a dynamic copy of itself. 504 DynamicMessage dynamic = DynamicMessage.newBuilder(message).build(); 505 checkEqualsIsConsistent(message, dynamic); 506 } 507 508 /** 509 * Asserts that the given protos are equal and have the same hash code. 510 */ checkEqualsIsConsistent(Message message1, Message message2)511 private void checkEqualsIsConsistent(Message message1, Message message2) { 512 assertEquals(message1, message2); 513 assertEquals(message2, message1); 514 assertEquals(message2.hashCode(), message1.hashCode()); 515 } 516 517 /** 518 * Asserts that the given protos are not equal and have different hash codes. 519 * 520 * @warning It's valid for non-equal objects to have the same hash code, so 521 * this test is stricter than it needs to be. However, this should happen 522 * relatively rarely. 523 */ checkNotEqual(Message m1, Message m2)524 private void checkNotEqual(Message m1, Message m2) { 525 String equalsError = String.format("%s should not be equal to %s", m1, m2); 526 assertFalse(equalsError, m1.equals(m2)); 527 assertFalse(equalsError, m2.equals(m1)); 528 529 assertFalse( 530 String.format("%s should have a different hash code from %s", m1, m2), 531 m1.hashCode() == m2.hashCode()); 532 } 533 testCheckByteStringIsUtf8OnUtf8()534 public void testCheckByteStringIsUtf8OnUtf8() { 535 ByteString byteString = ByteString.copyFromUtf8("some text"); 536 AbstractMessageLite.checkByteStringIsUtf8(byteString); 537 // No exception thrown. 538 } 539 testCheckByteStringIsUtf8OnNonUtf8()540 public void testCheckByteStringIsUtf8OnNonUtf8() { 541 ByteString byteString = 542 ByteString.copyFrom(new byte[]{(byte) 0x80}); // A lone continuation byte. 543 try { 544 AbstractMessageLite.checkByteStringIsUtf8(byteString); 545 fail("Expected AbstractMessageLite.checkByteStringIsUtf8 to throw IllegalArgumentException"); 546 } catch (IllegalArgumentException exception) { 547 assertEquals("Byte string is not UTF-8.", exception.getMessage()); 548 } 549 } 550 551 } 552