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 protobuf_unittest.UnittestProto.optionalInt32Extension; 34 import static protobuf_unittest.UnittestProto.optionalInt64Extension; 35 36 import protobuf_unittest.UnittestProto.TestAllExtensions; 37 import protobuf_unittest.UnittestProto.TestAllTypes; 38 39 import junit.framework.TestCase; 40 41 import java.io.IOException; 42 43 /** 44 * Unit test for {@link LazyFieldLite}. 45 * 46 * @author xiangl@google.com (Xiang Li) 47 */ 48 public class LazyFieldLiteTest extends TestCase { 49 testGetValue()50 public void testGetValue() { 51 MessageLite message = TestUtil.getAllSet(); 52 LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); 53 assertEquals(message, lazyField.getValue(TestAllTypes.getDefaultInstance())); 54 changeValue(lazyField); 55 assertNotEqual(message, lazyField.getValue(TestAllTypes.getDefaultInstance())); 56 } 57 testGetValueEx()58 public void testGetValueEx() throws Exception { 59 TestAllExtensions message = TestUtil.getAllExtensionsSet(); 60 LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); 61 assertEquals(message, lazyField.getValue(TestAllExtensions.getDefaultInstance())); 62 changeValue(lazyField); 63 assertNotEqual(message, lazyField.getValue(TestAllExtensions.getDefaultInstance())); 64 } 65 testSetValue()66 public void testSetValue() { 67 MessageLite message = TestUtil.getAllSet(); 68 LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); 69 changeValue(lazyField); 70 assertNotEqual(message, lazyField.getValue(TestAllTypes.getDefaultInstance())); 71 message = lazyField.getValue(TestAllTypes.getDefaultInstance()); 72 changeValue(lazyField); 73 assertEquals(message, lazyField.getValue(TestAllTypes.getDefaultInstance())); 74 } 75 testSetValueEx()76 public void testSetValueEx() throws Exception { 77 TestAllExtensions message = TestUtil.getAllExtensionsSet(); 78 LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); 79 changeValue(lazyField); 80 assertNotEqual(message, lazyField.getValue(TestAllExtensions.getDefaultInstance())); 81 MessageLite value = lazyField.getValue(TestAllExtensions.getDefaultInstance()); 82 changeValue(lazyField); 83 assertEquals(value, lazyField.getValue(TestAllExtensions.getDefaultInstance())); 84 } 85 testGetSerializedSize()86 public void testGetSerializedSize() { 87 MessageLite message = TestUtil.getAllSet(); 88 LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); 89 assertEquals(message.getSerializedSize(), lazyField.getSerializedSize()); 90 changeValue(lazyField); 91 assertNotEqual(message.getSerializedSize(), lazyField.getSerializedSize()); 92 } 93 testGetSerializedSizeEx()94 public void testGetSerializedSizeEx() throws Exception { 95 TestAllExtensions message = TestUtil.getAllExtensionsSet(); 96 LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); 97 assertEquals(message.getSerializedSize(), lazyField.getSerializedSize()); 98 changeValue(lazyField); 99 assertNotEqual(message.getSerializedSize(), lazyField.getSerializedSize()); 100 } 101 testGetByteString()102 public void testGetByteString() { 103 MessageLite message = TestUtil.getAllSet(); 104 LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); 105 assertEquals(message.toByteString(), lazyField.toByteString()); 106 changeValue(lazyField); 107 assertNotEqual(message.toByteString(), lazyField.toByteString()); 108 } 109 testGetByteStringEx()110 public void testGetByteStringEx() throws Exception { 111 TestAllExtensions message = TestUtil.getAllExtensionsSet(); 112 LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); 113 assertEquals(message.toByteString(), lazyField.toByteString()); 114 changeValue(lazyField); 115 assertNotEqual(message.toByteString(), lazyField.toByteString()); 116 } 117 testMergeExtensions()118 public void testMergeExtensions() throws Exception { 119 TestAllExtensions message = TestUtil.getAllExtensionsSet(); 120 LazyFieldLite original = createLazyFieldLiteFromMessage(message); 121 LazyFieldLite merged = new LazyFieldLite(); 122 merged.merge(original); 123 TestAllExtensions value = (TestAllExtensions) merged.getValue( 124 TestAllExtensions.getDefaultInstance()); 125 assertEquals(message, value); 126 } 127 testEmptyLazyField()128 public void testEmptyLazyField() throws Exception { 129 LazyFieldLite field = new LazyFieldLite(); 130 assertEquals(0, field.getSerializedSize()); 131 assertEquals(ByteString.EMPTY, field.toByteString()); 132 } 133 testInvalidProto()134 public void testInvalidProto() throws Exception { 135 // Silently fails and uses the default instance. 136 LazyFieldLite field = new LazyFieldLite( 137 TestUtil.getExtensionRegistry(), ByteString.copyFromUtf8("invalid")); 138 assertEquals( 139 TestAllTypes.getDefaultInstance(), field.getValue(TestAllTypes.getDefaultInstance())); 140 assertEquals(0, field.getSerializedSize()); 141 assertEquals(ByteString.EMPTY, field.toByteString()); 142 } 143 testMergeBeforeParsing()144 public void testMergeBeforeParsing() throws Exception { 145 TestAllTypes message1 = TestAllTypes.newBuilder().setOptionalInt32(1).build(); 146 LazyFieldLite field1 = createLazyFieldLiteFromMessage(message1); 147 TestAllTypes message2 = TestAllTypes.newBuilder().setOptionalInt64(2).build(); 148 LazyFieldLite field2 = createLazyFieldLiteFromMessage(message2); 149 150 field1.merge(field2); 151 TestAllTypes expected = 152 TestAllTypes.newBuilder().setOptionalInt32(1).setOptionalInt64(2).build(); 153 assertEquals(expected, field1.getValue(TestAllTypes.getDefaultInstance())); 154 } 155 testMergeOneNotParsed()156 public void testMergeOneNotParsed() throws Exception { 157 // Test a few different paths that involve one message that was not parsed. 158 TestAllTypes message1 = TestAllTypes.newBuilder().setOptionalInt32(1).build(); 159 TestAllTypes message2 = TestAllTypes.newBuilder().setOptionalInt64(2).build(); 160 TestAllTypes expected = 161 TestAllTypes.newBuilder().setOptionalInt32(1).setOptionalInt64(2).build(); 162 163 LazyFieldLite field1 = LazyFieldLite.fromValue(message1); 164 field1.getValue(TestAllTypes.getDefaultInstance()); // Force parsing. 165 LazyFieldLite field2 = createLazyFieldLiteFromMessage(message2); 166 field1.merge(field2); 167 assertEquals(expected, field1.getValue(TestAllTypes.getDefaultInstance())); 168 169 // Now reverse which one is parsed first. 170 field1 = LazyFieldLite.fromValue(message1); 171 field2 = createLazyFieldLiteFromMessage(message2); 172 field2.getValue(TestAllTypes.getDefaultInstance()); // Force parsing. 173 field1.merge(field2); 174 assertEquals(expected, field1.getValue(TestAllTypes.getDefaultInstance())); 175 } 176 testMergeInvalid()177 public void testMergeInvalid() throws Exception { 178 // Test a few different paths that involve one message that was not parsed. 179 TestAllTypes message = TestAllTypes.newBuilder().setOptionalInt32(1).build(); 180 LazyFieldLite valid = LazyFieldLite.fromValue(message); 181 LazyFieldLite invalid = new LazyFieldLite( 182 TestUtil.getExtensionRegistry(), ByteString.copyFromUtf8("invalid")); 183 invalid.merge(valid); 184 185 // We swallow the exception and just use the set field. 186 assertEquals(message, invalid.getValue(TestAllTypes.getDefaultInstance())); 187 } 188 testMergeKeepsExtensionsWhenPossible()189 public void testMergeKeepsExtensionsWhenPossible() throws Exception { 190 // In this test we attempt to only use the empty registry, which will strip out all extensions 191 // when serializing and then parsing. We verify that each code path will attempt to not 192 // serialize and parse a message that was set directly without going through the 193 // extensionRegistry. 194 TestAllExtensions messageWithExtensions = 195 TestAllExtensions.newBuilder().setExtension(optionalInt32Extension, 42).build(); 196 TestAllExtensions emptyMessage = TestAllExtensions.newBuilder().build(); 197 198 ExtensionRegistryLite emptyRegistry = ExtensionRegistryLite.getEmptyRegistry(); 199 200 LazyFieldLite field = LazyFieldLite.fromValue(messageWithExtensions); 201 field.merge(createLazyFieldLiteFromMessage(emptyRegistry, emptyMessage)); 202 assertEquals(messageWithExtensions, field.getValue(TestAllExtensions.getDefaultInstance())); 203 204 // Now reverse the order of the merging. 205 field = createLazyFieldLiteFromMessage(emptyRegistry, emptyMessage); 206 field.merge(LazyFieldLite.fromValue(messageWithExtensions)); 207 assertEquals(messageWithExtensions, field.getValue(TestAllExtensions.getDefaultInstance())); 208 209 // Now try parsing the empty field first. 210 field = LazyFieldLite.fromValue(messageWithExtensions); 211 LazyFieldLite other = createLazyFieldLiteFromMessage(emptyRegistry, emptyMessage); 212 other.getValue(TestAllExtensions.getDefaultInstance()); // Force parsing. 213 field.merge(other); 214 assertEquals(messageWithExtensions, field.getValue(TestAllExtensions.getDefaultInstance())); 215 216 // And again reverse. 217 field = createLazyFieldLiteFromMessage(emptyRegistry, emptyMessage); 218 field.getValue(TestAllExtensions.getDefaultInstance()); // Force parsing. 219 other = LazyFieldLite.fromValue(messageWithExtensions); 220 field.merge(other); 221 assertEquals(messageWithExtensions, field.getValue(TestAllExtensions.getDefaultInstance())); 222 } 223 testMergeMightLoseExtensions()224 public void testMergeMightLoseExtensions() throws Exception { 225 // Test that we don't know about the extensions when parsing. 226 TestAllExtensions message1 = 227 TestAllExtensions.newBuilder().setExtension(optionalInt32Extension, 1).build(); 228 TestAllExtensions message2 = 229 TestAllExtensions.newBuilder().setExtension(optionalInt64Extension, 2L).build(); 230 231 LazyFieldLite field = LazyFieldLite.fromValue(message1); 232 field.merge(LazyFieldLite.fromValue(message2)); 233 234 // We lose the extensions from message 2 because we have to serialize it and then parse it 235 // again, using the empty registry this time. 236 TestAllExtensions value = 237 (TestAllExtensions) field.getValue(TestAllExtensions.getDefaultInstance()); 238 assertTrue(value.hasExtension(optionalInt32Extension)); 239 assertEquals(Integer.valueOf(1), value.getExtension(optionalInt32Extension)); 240 assertFalse(value.hasExtension(optionalInt64Extension)); 241 242 // The field is still there, it is just unknown. 243 assertTrue(value.getUnknownFields() 244 .hasField(optionalInt64Extension.getDescriptor().getNumber())); 245 } 246 247 248 // Help methods. 249 createLazyFieldLiteFromMessage(MessageLite message)250 private LazyFieldLite createLazyFieldLiteFromMessage(MessageLite message) { 251 return createLazyFieldLiteFromMessage(TestUtil.getExtensionRegistry(), message); 252 } 253 createLazyFieldLiteFromMessage( ExtensionRegistryLite extensionRegistry, MessageLite message)254 private LazyFieldLite createLazyFieldLiteFromMessage( 255 ExtensionRegistryLite extensionRegistry, MessageLite message) { 256 ByteString bytes = message.toByteString(); 257 return new LazyFieldLite(extensionRegistry, bytes); 258 } 259 changeValue(LazyFieldLite lazyField)260 private void changeValue(LazyFieldLite lazyField) { 261 TestAllTypes.Builder builder = TestUtil.getAllSet().toBuilder(); 262 builder.addRepeatedBool(true); 263 MessageLite newMessage = builder.build(); 264 lazyField.setValue(newMessage); 265 } 266 assertNotEqual(Object unexpected, Object actual)267 private void assertNotEqual(Object unexpected, Object actual) { 268 assertFalse(unexpected == actual 269 || (unexpected != null && unexpected.equals(actual))); 270 } 271 272 } 273