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 35 import com.google.protobuf.testing.Proto3Testing.Proto3Empty; 36 import com.google.protobuf.testing.Proto3Testing.Proto3Message; 37 import com.google.protobuf.testing.Proto3Testing.Proto3MessageWithMaps; 38 import java.io.ByteArrayOutputStream; 39 import java.io.IOException; 40 import java.nio.ByteBuffer; 41 import java.util.ArrayList; 42 import java.util.List; 43 import org.junit.Test; 44 45 /** Base class for tests using {@link Proto3Message}. */ 46 public abstract class AbstractProto3SchemaTest extends AbstractSchemaTest<Proto3Message> { 47 @Override messageFactory()48 protected Proto3MessageFactory messageFactory() { 49 return new Proto3MessageFactory(10, 20, 2, 2); 50 } 51 52 @Override serializedBytesWithInvalidUtf8()53 protected List<ByteBuffer> serializedBytesWithInvalidUtf8() throws IOException { 54 List<ByteBuffer> invalidBytes = new ArrayList<>(); 55 byte[] invalid = new byte[] {(byte) 0x80}; 56 { 57 ByteBuffer buffer = ByteBuffer.allocate(100); 58 CodedOutputStream codedOutput = CodedOutputStream.newInstance(buffer); 59 codedOutput.writeByteArray(Proto3Message.FIELD_STRING_9_FIELD_NUMBER, invalid); 60 codedOutput.flush(); 61 buffer.flip(); 62 invalidBytes.add(buffer); 63 } 64 { 65 ByteBuffer buffer = ByteBuffer.allocate(100); 66 CodedOutputStream codedOutput = CodedOutputStream.newInstance(buffer); 67 codedOutput.writeByteArray(Proto3Message.FIELD_STRING_LIST_26_FIELD_NUMBER, invalid); 68 codedOutput.flush(); 69 buffer.flip(); 70 invalidBytes.add(buffer); 71 } 72 return invalidBytes; 73 } 74 75 @Test mergeOptionalMessageFields()76 public void mergeOptionalMessageFields() throws Exception { 77 Proto3Message message1 = 78 newBuilder() 79 .setFieldMessage10(newBuilder().setFieldInt643(123).clearFieldInt325().build()) 80 .build(); 81 Proto3Message message2 = 82 newBuilder() 83 .setFieldMessage10(newBuilder().clearFieldInt643().setFieldInt325(456).build()) 84 .build(); 85 Proto3Message message3 = 86 newBuilder() 87 .setFieldMessage10(newBuilder().setFieldInt643(789).clearFieldInt325().build()) 88 .build(); 89 ByteArrayOutputStream output = new ByteArrayOutputStream(); 90 message1.writeTo(output); 91 message2.writeTo(output); 92 message3.writeTo(output); 93 byte[] data = output.toByteArray(); 94 95 Proto3Message merged = ExperimentalSerializationUtil.fromByteArray(data, Proto3Message.class); 96 assertEquals(789, merged.getFieldMessage10().getFieldInt643()); 97 assertEquals(456, merged.getFieldMessage10().getFieldInt325()); 98 } 99 100 @Test oneofFieldsShouldRoundtrip()101 public void oneofFieldsShouldRoundtrip() throws IOException { 102 roundtrip("Field 53", newBuilder().setFieldDouble53(100).build()); 103 roundtrip("Field 54", newBuilder().setFieldFloat54(100).build()); 104 roundtrip("Field 55", newBuilder().setFieldInt6455(100).build()); 105 roundtrip("Field 56", newBuilder().setFieldUint6456(100L).build()); 106 roundtrip("Field 57", newBuilder().setFieldInt3257(100).build()); 107 roundtrip("Field 58", newBuilder().setFieldFixed6458(100).build()); 108 roundtrip("Field 59", newBuilder().setFieldFixed3259(100).build()); 109 roundtrip("Field 60", newBuilder().setFieldBool60(true).build()); 110 roundtrip("Field 61", newBuilder().setFieldString61(data().getString()).build()); 111 roundtrip( 112 "Field 62", newBuilder().setFieldMessage62(newBuilder().setFieldDouble1(100)).build()); 113 roundtrip("Field 63", newBuilder().setFieldBytes63(data().getBytes()).build()); 114 roundtrip("Field 64", newBuilder().setFieldUint3264(100).build()); 115 roundtrip("Field 65", newBuilder().setFieldSfixed3265(100).build()); 116 roundtrip("Field 66", newBuilder().setFieldSfixed6466(100).build()); 117 roundtrip("Field 67", newBuilder().setFieldSint3267(100).build()); 118 roundtrip("Field 68", newBuilder().setFieldSint6468(100).build()); 119 } 120 121 @Test preserveUnknownFields()122 public void preserveUnknownFields() { 123 Proto3Message expectedMessage = messageFactory().newMessage(); 124 Proto3Empty empty = 125 ExperimentalSerializationUtil.fromByteArray( 126 expectedMessage.toByteArray(), Proto3Empty.class); 127 assertEquals(expectedMessage.getSerializedSize(), empty.getSerializedSize()); 128 assertEquals(expectedMessage.toByteString(), empty.toByteString()); 129 } 130 131 @Test preserveUnknownFieldsProto2()132 public void preserveUnknownFieldsProto2() { 133 // Make sure we will be able to preserve valid proto2 wireformat, including those that are not 134 // supported in proto3, e.g. groups. 135 byte[] payload = new Proto2MessageFactory(10, 20, 2, 2).newMessage().toByteArray(); 136 Proto3Empty empty = ExperimentalSerializationUtil.fromByteArray(payload, Proto3Empty.class); 137 assertEquals(payload.length, empty.getSerializedSize()); 138 } 139 140 @Test mapsShouldRoundtrip()141 public void mapsShouldRoundtrip() throws IOException { 142 roundtrip( 143 "Proto3MessageWithMaps", 144 new Proto3MessageFactory(2, 10, 2, 2).newMessageWithMaps(), 145 Protobuf.getInstance().schemaFor(Proto3MessageWithMaps.class)); 146 } 147 newBuilder()148 private static Proto3Message.Builder newBuilder() { 149 return Proto3Message.newBuilder(); 150 } 151 } 152