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 static org.junit.Assert.assertEquals; 34 import static org.junit.Assert.assertFalse; 35 import static org.junit.Assert.assertNull; 36 37 import com.google.protobuf.testing.Proto2TestingLite.Proto2EmptyLite; 38 import com.google.protobuf.testing.Proto2TestingLite.Proto2MessageLite; 39 import com.google.protobuf.testing.Proto2TestingLite.Proto2MessageLite.TestEnum; 40 import com.google.protobuf.testing.Proto2TestingLite.Proto2MessageLiteWithMaps; 41 import java.io.ByteArrayOutputStream; 42 import java.io.IOException; 43 import java.util.List; 44 import org.junit.Test; 45 46 /** Base class for tests using {@link Proto2MessageLite}. */ 47 public abstract class AbstractProto2LiteSchemaTest extends AbstractSchemaTest<Proto2MessageLite> { 48 49 @Override messageFactory()50 protected Proto2MessageLiteFactory messageFactory() { 51 return new Proto2MessageLiteFactory(10, 20, 2, 2); 52 } 53 54 @Test mergeOptionalMessageFields()55 public void mergeOptionalMessageFields() throws Exception { 56 Proto2MessageLite message1 = 57 newBuilder() 58 .setFieldMessage10(newBuilder().setFieldInt643(123).clearFieldInt325().build()) 59 .build(); 60 Proto2MessageLite message2 = 61 newBuilder() 62 .setFieldMessage10(newBuilder().clearFieldInt643().setFieldInt325(456).build()) 63 .build(); 64 Proto2MessageLite message3 = 65 newBuilder() 66 .setFieldMessage10(newBuilder().setFieldInt643(789).clearFieldInt325().build()) 67 .build(); 68 ByteArrayOutputStream output = new ByteArrayOutputStream(); 69 message1.writeTo(output); 70 message2.writeTo(output); 71 message3.writeTo(output); 72 byte[] data = output.toByteArray(); 73 74 Proto2MessageLite merged = 75 ExperimentalSerializationUtil.fromByteArray(data, Proto2MessageLite.class); 76 assertEquals(789, merged.getFieldMessage10().getFieldInt643()); 77 assertEquals(456, merged.getFieldMessage10().getFieldInt325()); 78 } 79 80 @Test oneofFieldsShouldRoundtrip()81 public void oneofFieldsShouldRoundtrip() throws IOException { 82 roundtrip("Field 53", newBuilder().setFieldDouble53(100).build()); 83 roundtrip("Field 54", newBuilder().setFieldFloat54(100).build()); 84 roundtrip("Field 55", newBuilder().setFieldInt6455(100).build()); 85 roundtrip("Field 56", newBuilder().setFieldUint6456(100L).build()); 86 roundtrip("Field 57", newBuilder().setFieldInt3257(100).build()); 87 roundtrip("Field 58", newBuilder().setFieldFixed6458(100).build()); 88 roundtrip("Field 59", newBuilder().setFieldFixed3259(100).build()); 89 roundtrip("Field 60", newBuilder().setFieldBool60(true).build()); 90 roundtrip("Field 61", newBuilder().setFieldString61(data().getString()).build()); 91 roundtrip( 92 "Field 62", newBuilder().setFieldMessage62(newBuilder().setFieldDouble1(100)).build()); 93 roundtrip("Field 63", newBuilder().setFieldBytes63(data().getBytes()).build()); 94 roundtrip("Field 64", newBuilder().setFieldUint3264(100).build()); 95 roundtrip("Field 65", newBuilder().setFieldSfixed3265(100).build()); 96 roundtrip("Field 66", newBuilder().setFieldSfixed6466(100).build()); 97 roundtrip("Field 67", newBuilder().setFieldSint3267(100).build()); 98 roundtrip("Field 68", newBuilder().setFieldSint6468(100).build()); 99 roundtrip( 100 "Field 69", 101 newBuilder() 102 .setFieldGroup69( 103 Proto2MessageLite.FieldGroup69.newBuilder().setFieldInt3270(data().getInt())) 104 .build()); 105 } 106 newBuilder()107 private Proto2MessageLite.Builder newBuilder() { 108 return messageFactory().newMessage().toBuilder(); 109 } 110 111 @Override newMessagesMissingRequiredFields()112 protected List<Proto2MessageLite> newMessagesMissingRequiredFields() { 113 return messageFactory().newMessagesMissingRequiredFields(); 114 } 115 116 @Test mapsShouldRoundtrip()117 public void mapsShouldRoundtrip() throws IOException { 118 roundtrip( 119 "Proto2MessageLiteWithMaps", 120 new Proto2MessageLiteFactory(2, 10, 2, 2).newMessageWithMaps(), 121 Protobuf.getInstance().schemaFor(Proto2MessageLiteWithMaps.class)); 122 } 123 124 @Test unknownFieldsUnrecognized()125 public void unknownFieldsUnrecognized() throws Exception { 126 Proto2MessageLite expectedMessage = messageFactory().newMessage(); 127 byte[] serializedBytes = expectedMessage.toByteArray(); 128 Proto2EmptyLite empty = 129 ExperimentalSerializationUtil.fromByteArray(serializedBytes, Proto2EmptyLite.class); 130 131 // Merge serialized bytes into an empty message, then reserialize and merge it to a new 132 // Proto2Message. Make sure the two messages equal. 133 byte[] roundtripBytes = ExperimentalSerializationUtil.toByteArray(empty); 134 Proto2MessageLite roundtripMessage = 135 ExperimentalSerializationUtil.fromByteArray(roundtripBytes, Proto2MessageLite.class); 136 assertEquals(expectedMessage, roundtripMessage); 137 } 138 139 @Test unknownEnum()140 public void unknownEnum() throws IOException { 141 // Use unknown fields to hold invalid enum values. 142 UnknownFieldSetLite unknowns = UnknownFieldSetLite.newInstance(); 143 final int outOfRange = 1000; 144 assertNull(TestEnum.forNumber(outOfRange)); 145 unknowns.storeField( 146 WireFormat.makeTag( 147 Proto2MessageLite.FIELD_ENUM_13_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT), 148 (long) outOfRange); 149 unknowns.storeField( 150 WireFormat.makeTag( 151 Proto2MessageLite.FIELD_ENUM_LIST_30_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT), 152 (long) TestEnum.ONE_VALUE); 153 unknowns.storeField( 154 WireFormat.makeTag( 155 Proto2MessageLite.FIELD_ENUM_LIST_30_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT), 156 (long) outOfRange); 157 unknowns.storeField( 158 WireFormat.makeTag( 159 Proto2MessageLite.FIELD_ENUM_LIST_30_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT), 160 (long) TestEnum.TWO_VALUE); 161 162 { 163 // Construct a packed enum list. 164 int packedSize = 165 CodedOutputStream.computeUInt32SizeNoTag(TestEnum.ONE_VALUE) 166 + CodedOutputStream.computeUInt32SizeNoTag(outOfRange) 167 + CodedOutputStream.computeUInt32SizeNoTag(TestEnum.ONE_VALUE); 168 ByteString.CodedBuilder packedBuilder = ByteString.newCodedBuilder(packedSize); 169 CodedOutputStream packedOut = packedBuilder.getCodedOutput(); 170 packedOut.writeEnumNoTag(TestEnum.ONE_VALUE); 171 packedOut.writeEnumNoTag(outOfRange); 172 packedOut.writeEnumNoTag(TestEnum.TWO_VALUE); 173 unknowns.storeField( 174 WireFormat.makeTag( 175 Proto2MessageLite.FIELD_ENUM_LIST_PACKED_44_FIELD_NUMBER, 176 WireFormat.WIRETYPE_LENGTH_DELIMITED), 177 packedBuilder.build()); 178 } 179 int size = unknowns.getSerializedSize(); 180 byte[] output = new byte[size]; 181 CodedOutputStream codedOutput = CodedOutputStream.newInstance(output); 182 unknowns.writeTo(codedOutput); 183 codedOutput.flush(); 184 185 Proto2MessageLite parsed = 186 ExperimentalSerializationUtil.fromByteArray(output, Proto2MessageLite.class); 187 assertFalse("out-of-range singular enum should not be in message", parsed.hasFieldEnum13()); 188 assertEquals( 189 "out-of-range repeated enum should not be in message", 2, parsed.getFieldEnumList30Count()); 190 assertEquals(TestEnum.ONE, parsed.getFieldEnumList30(0)); 191 assertEquals(TestEnum.TWO, parsed.getFieldEnumList30(1)); 192 assertEquals( 193 "out-of-range packed repeated enum should not be in message", 194 2, 195 parsed.getFieldEnumListPacked44Count()); 196 assertEquals(TestEnum.ONE, parsed.getFieldEnumListPacked44(0)); 197 assertEquals(TestEnum.TWO, parsed.getFieldEnumListPacked44(1)); 198 } 199 } 200