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