1ffe3c632Sopenharmony_ci/** 2ffe3c632Sopenharmony_ci * @fileoverview Tests to make sure Kernel can read data in a backward 3ffe3c632Sopenharmony_ci * compatible way even when protobuf schema changes according to the rules 4ffe3c632Sopenharmony_ci * defined in 5ffe3c632Sopenharmony_ci * https://developers.google.com/protocol-buffers/docs/proto#updating and 6ffe3c632Sopenharmony_ci * https://developers.google.com/protocol-buffers/docs/proto3#updating. 7ffe3c632Sopenharmony_ci * 8ffe3c632Sopenharmony_ci * third_party/protobuf/conformance/binary_json_conformance_suite.cc already 9ffe3c632Sopenharmony_ci * covers many compatibility tests, this file covers only the tests not covered 10ffe3c632Sopenharmony_ci * by binary_json_conformance_suite. Ultimately all of the tests in this file 11ffe3c632Sopenharmony_ci * should be moved to binary_json_conformance_suite. 12ffe3c632Sopenharmony_ci */ 13ffe3c632Sopenharmony_cigoog.module('protobuf.runtime.KernelCompatibilityTest'); 14ffe3c632Sopenharmony_ci 15ffe3c632Sopenharmony_cigoog.setTestOnly(); 16ffe3c632Sopenharmony_ci 17ffe3c632Sopenharmony_ciconst ByteString = goog.require('protobuf.ByteString'); 18ffe3c632Sopenharmony_ciconst Int64 = goog.require('protobuf.Int64'); 19ffe3c632Sopenharmony_ciconst Kernel = goog.require('protobuf.runtime.Kernel'); 20ffe3c632Sopenharmony_ciconst TestMessage = goog.require('protobuf.testing.binary.TestMessage'); 21ffe3c632Sopenharmony_ciconst {CHECK_CRITICAL_STATE} = goog.require('protobuf.internal.checks'); 22ffe3c632Sopenharmony_ci 23ffe3c632Sopenharmony_ci/** 24ffe3c632Sopenharmony_ci * @param {...number} bytes 25ffe3c632Sopenharmony_ci * @return {!ArrayBuffer} 26ffe3c632Sopenharmony_ci */ 27ffe3c632Sopenharmony_cifunction createArrayBuffer(...bytes) { 28ffe3c632Sopenharmony_ci return new Uint8Array(bytes).buffer; 29ffe3c632Sopenharmony_ci} 30ffe3c632Sopenharmony_ci 31ffe3c632Sopenharmony_ci/** 32ffe3c632Sopenharmony_ci * Returns the Unicode character codes of a string. 33ffe3c632Sopenharmony_ci * @param {string} str 34ffe3c632Sopenharmony_ci * @return {!Array<number>} 35ffe3c632Sopenharmony_ci */ 36ffe3c632Sopenharmony_cifunction getCharacterCodes(str) { 37ffe3c632Sopenharmony_ci return Array.from(str, (c) => c.charCodeAt(0)); 38ffe3c632Sopenharmony_ci} 39ffe3c632Sopenharmony_ci 40ffe3c632Sopenharmony_cidescribe('optional -> repeated compatibility', () => { 41ffe3c632Sopenharmony_ci it('is maintained for scalars', () => { 42ffe3c632Sopenharmony_ci const oldAccessor = Kernel.createEmpty(); 43ffe3c632Sopenharmony_ci oldAccessor.setInt32(1, 1); 44ffe3c632Sopenharmony_ci const serializedData = oldAccessor.serialize(); 45ffe3c632Sopenharmony_ci expect(serializedData).toEqual(createArrayBuffer(0x8, 0x1)); 46ffe3c632Sopenharmony_ci 47ffe3c632Sopenharmony_ci const newAccessor = Kernel.fromArrayBuffer(serializedData); 48ffe3c632Sopenharmony_ci expect(newAccessor.getRepeatedInt32Size(1)).toEqual(1); 49ffe3c632Sopenharmony_ci expect(newAccessor.getRepeatedInt32Element(1, 0)).toEqual(1); 50ffe3c632Sopenharmony_ci }); 51ffe3c632Sopenharmony_ci 52ffe3c632Sopenharmony_ci it('is maintained for messages', () => { 53ffe3c632Sopenharmony_ci const message = new TestMessage(Kernel.createEmpty()); 54ffe3c632Sopenharmony_ci message.setInt32(1, 1); 55ffe3c632Sopenharmony_ci 56ffe3c632Sopenharmony_ci const oldAccessor = Kernel.createEmpty(); 57ffe3c632Sopenharmony_ci oldAccessor.setMessage(1, message); 58ffe3c632Sopenharmony_ci const serializedData = oldAccessor.serialize(); 59ffe3c632Sopenharmony_ci expect(serializedData).toEqual(createArrayBuffer(0xA, 0x2, 0x8, 0x1)); 60ffe3c632Sopenharmony_ci 61ffe3c632Sopenharmony_ci const newAccessor = Kernel.fromArrayBuffer(serializedData); 62ffe3c632Sopenharmony_ci expect(newAccessor.getRepeatedMessageSize(1, TestMessage.instanceCreator)) 63ffe3c632Sopenharmony_ci .toEqual(1); 64ffe3c632Sopenharmony_ci expect( 65ffe3c632Sopenharmony_ci newAccessor.getRepeatedMessageElement(1, TestMessage.instanceCreator, 0) 66ffe3c632Sopenharmony_ci .serialize()) 67ffe3c632Sopenharmony_ci .toEqual(message.serialize()); 68ffe3c632Sopenharmony_ci }); 69ffe3c632Sopenharmony_ci 70ffe3c632Sopenharmony_ci it('is maintained for bytes', () => { 71ffe3c632Sopenharmony_ci const message = new TestMessage(Kernel.createEmpty()); 72ffe3c632Sopenharmony_ci message.setInt32(1, 1); 73ffe3c632Sopenharmony_ci 74ffe3c632Sopenharmony_ci const oldAccessor = Kernel.createEmpty(); 75ffe3c632Sopenharmony_ci oldAccessor.setBytes( 76ffe3c632Sopenharmony_ci 1, ByteString.fromArrayBuffer(createArrayBuffer(0xA, 0xB))); 77ffe3c632Sopenharmony_ci const serializedData = oldAccessor.serialize(); 78ffe3c632Sopenharmony_ci expect(serializedData).toEqual(createArrayBuffer(0xA, 0x2, 0xA, 0xB)); 79ffe3c632Sopenharmony_ci 80ffe3c632Sopenharmony_ci const newAccessor = Kernel.fromArrayBuffer(serializedData); 81ffe3c632Sopenharmony_ci expect(newAccessor.getRepeatedBytesSize(1)).toEqual(1); 82ffe3c632Sopenharmony_ci expect(newAccessor.getRepeatedBoolElement(1, 0)) 83ffe3c632Sopenharmony_ci .toEqual(ByteString.fromArrayBuffer(createArrayBuffer(0xA, 0xB))); 84ffe3c632Sopenharmony_ci }); 85ffe3c632Sopenharmony_ci 86ffe3c632Sopenharmony_ci it('is maintained for strings', () => { 87ffe3c632Sopenharmony_ci const oldAccessor = Kernel.createEmpty(); 88ffe3c632Sopenharmony_ci oldAccessor.setString(1, 'hello'); 89ffe3c632Sopenharmony_ci const serializedData = oldAccessor.serialize(); 90ffe3c632Sopenharmony_ci expect(serializedData) 91ffe3c632Sopenharmony_ci .toEqual(createArrayBuffer(0xA, 0x5, 0x68, 0x65, 0x6C, 0x6C, 0x6F)); 92ffe3c632Sopenharmony_ci 93ffe3c632Sopenharmony_ci const newAccessor = Kernel.fromArrayBuffer(serializedData); 94ffe3c632Sopenharmony_ci expect(newAccessor.getRepeatedStringSize(1)).toEqual(1); 95ffe3c632Sopenharmony_ci expect(newAccessor.getRepeatedStringElement(1, 0)).toEqual('hello'); 96ffe3c632Sopenharmony_ci }); 97ffe3c632Sopenharmony_ci}); 98ffe3c632Sopenharmony_ci 99ffe3c632Sopenharmony_cidescribe('Kernel repeated -> optional compatibility', () => { 100ffe3c632Sopenharmony_ci it('is maintained for unpacked scalars', () => { 101ffe3c632Sopenharmony_ci const oldAccessor = Kernel.createEmpty(); 102ffe3c632Sopenharmony_ci oldAccessor.addUnpackedInt32Element(1, 0); 103ffe3c632Sopenharmony_ci oldAccessor.addUnpackedInt32Element(1, 1); 104ffe3c632Sopenharmony_ci const serializedData = oldAccessor.serialize(); 105ffe3c632Sopenharmony_ci expect(serializedData).toEqual(createArrayBuffer(0x8, 0x0, 0x8, 0x1)); 106ffe3c632Sopenharmony_ci 107ffe3c632Sopenharmony_ci const newAccessor = Kernel.fromArrayBuffer(serializedData); 108ffe3c632Sopenharmony_ci expect(newAccessor.getInt32WithDefault(1)).toEqual(1); 109ffe3c632Sopenharmony_ci expect(newAccessor.serialize()).toEqual(serializedData); 110ffe3c632Sopenharmony_ci }); 111ffe3c632Sopenharmony_ci 112ffe3c632Sopenharmony_ci // repeated -> optional transformation is not supported for packed fields yet: 113ffe3c632Sopenharmony_ci // go/proto-schema-repeated 114ffe3c632Sopenharmony_ci it('is not maintained for packed scalars', () => { 115ffe3c632Sopenharmony_ci const oldAccessor = Kernel.createEmpty(); 116ffe3c632Sopenharmony_ci oldAccessor.addPackedInt32Element(1, 0); 117ffe3c632Sopenharmony_ci oldAccessor.addPackedInt32Element(1, 1); 118ffe3c632Sopenharmony_ci const serializedData = oldAccessor.serialize(); 119ffe3c632Sopenharmony_ci expect(serializedData).toEqual(createArrayBuffer(0xA, 0x2, 0x0, 0x1)); 120ffe3c632Sopenharmony_ci 121ffe3c632Sopenharmony_ci const newAccessor = Kernel.fromArrayBuffer(serializedData); 122ffe3c632Sopenharmony_ci if (CHECK_CRITICAL_STATE) { 123ffe3c632Sopenharmony_ci expect(() => newAccessor.getInt32WithDefault(1)).toThrow(); 124ffe3c632Sopenharmony_ci } 125ffe3c632Sopenharmony_ci }); 126ffe3c632Sopenharmony_ci 127ffe3c632Sopenharmony_ci it('is maintained for messages', () => { 128ffe3c632Sopenharmony_ci const message1 = new TestMessage(Kernel.createEmpty()); 129ffe3c632Sopenharmony_ci message1.setInt32(1, 1); 130ffe3c632Sopenharmony_ci const message2 = new TestMessage(Kernel.createEmpty()); 131ffe3c632Sopenharmony_ci message2.setInt32(1, 2); 132ffe3c632Sopenharmony_ci message2.setInt32(2, 3); 133ffe3c632Sopenharmony_ci 134ffe3c632Sopenharmony_ci const oldAccessor = Kernel.createEmpty(); 135ffe3c632Sopenharmony_ci oldAccessor.addRepeatedMessageElement( 136ffe3c632Sopenharmony_ci 1, message1, TestMessage.instanceCreator); 137ffe3c632Sopenharmony_ci oldAccessor.addRepeatedMessageElement( 138ffe3c632Sopenharmony_ci 1, message2, TestMessage.instanceCreator); 139ffe3c632Sopenharmony_ci const serializedData = oldAccessor.serialize(); 140ffe3c632Sopenharmony_ci expect(serializedData) 141ffe3c632Sopenharmony_ci .toEqual(createArrayBuffer( 142ffe3c632Sopenharmony_ci 0xA, 0x2, 0x8, 0x1, 0xA, 0x4, 0x8, 0x2, 0x10, 0x3)); 143ffe3c632Sopenharmony_ci 144ffe3c632Sopenharmony_ci const newAccessor = Kernel.fromArrayBuffer(serializedData); 145ffe3c632Sopenharmony_ci // Values from message1 and message2 have been merged 146ffe3c632Sopenharmony_ci const newMessage = newAccessor.getMessage(1, TestMessage.instanceCreator); 147ffe3c632Sopenharmony_ci expect(newMessage.getRepeatedInt32Size(1)).toEqual(2); 148ffe3c632Sopenharmony_ci expect(newMessage.getRepeatedInt32Element(1, 0)).toEqual(1); 149ffe3c632Sopenharmony_ci expect(newMessage.getRepeatedInt32Element(1, 1)).toEqual(2); 150ffe3c632Sopenharmony_ci expect(newMessage.getInt32WithDefault(2)).toEqual(3); 151ffe3c632Sopenharmony_ci expect(newMessage.serialize()) 152ffe3c632Sopenharmony_ci .toEqual(createArrayBuffer(0x8, 0x1, 0x8, 0x2, 0x10, 0x3)); 153ffe3c632Sopenharmony_ci }); 154ffe3c632Sopenharmony_ci 155ffe3c632Sopenharmony_ci it('is maintained for bytes', () => { 156ffe3c632Sopenharmony_ci const oldAccessor = Kernel.createEmpty(); 157ffe3c632Sopenharmony_ci oldAccessor.addRepeatedBytesElement( 158ffe3c632Sopenharmony_ci 1, ByteString.fromArrayBuffer(createArrayBuffer(0xA, 0xB))); 159ffe3c632Sopenharmony_ci oldAccessor.addRepeatedBytesElement( 160ffe3c632Sopenharmony_ci 1, ByteString.fromArrayBuffer(createArrayBuffer(0xC, 0xD))); 161ffe3c632Sopenharmony_ci const serializedData = oldAccessor.serialize(); 162ffe3c632Sopenharmony_ci expect(serializedData) 163ffe3c632Sopenharmony_ci .toEqual(createArrayBuffer(0xA, 0x2, 0xA, 0xB, 0xA, 0x2, 0xC, 0xD)); 164ffe3c632Sopenharmony_ci 165ffe3c632Sopenharmony_ci const newAccessor = Kernel.fromArrayBuffer(serializedData); 166ffe3c632Sopenharmony_ci expect(newAccessor.getBytesWithDefault(1)) 167ffe3c632Sopenharmony_ci .toEqual(ByteString.fromArrayBuffer(createArrayBuffer(0xC, 0xD))); 168ffe3c632Sopenharmony_ci expect(newAccessor.serialize()).toEqual(serializedData); 169ffe3c632Sopenharmony_ci }); 170ffe3c632Sopenharmony_ci 171ffe3c632Sopenharmony_ci it('is maintained for strings', () => { 172ffe3c632Sopenharmony_ci const oldAccessor = Kernel.createEmpty(); 173ffe3c632Sopenharmony_ci oldAccessor.addRepeatedStringElement(1, 'hello'); 174ffe3c632Sopenharmony_ci oldAccessor.addRepeatedStringElement(1, 'world'); 175ffe3c632Sopenharmony_ci const serializedData = oldAccessor.serialize(); 176ffe3c632Sopenharmony_ci expect(serializedData) 177ffe3c632Sopenharmony_ci .toEqual(createArrayBuffer( 178ffe3c632Sopenharmony_ci 0xA, 0x5, ...getCharacterCodes('hello'), 0xA, 0x5, 179ffe3c632Sopenharmony_ci ...getCharacterCodes('world'))); 180ffe3c632Sopenharmony_ci 181ffe3c632Sopenharmony_ci const newAccessor = Kernel.fromArrayBuffer(serializedData); 182ffe3c632Sopenharmony_ci expect(newAccessor.getStringWithDefault(1)).toEqual('world'); 183ffe3c632Sopenharmony_ci expect(newAccessor.serialize()).toEqual(serializedData); 184ffe3c632Sopenharmony_ci }); 185ffe3c632Sopenharmony_ci}); 186ffe3c632Sopenharmony_ci 187ffe3c632Sopenharmony_cidescribe('Type change', () => { 188ffe3c632Sopenharmony_ci it('is supported for fixed32 -> sfixed32', () => { 189ffe3c632Sopenharmony_ci const oldAccessor = Kernel.createEmpty(); 190ffe3c632Sopenharmony_ci oldAccessor.setFixed32(1, 4294967295); 191ffe3c632Sopenharmony_ci const serializedData = oldAccessor.serialize(); 192ffe3c632Sopenharmony_ci expect(serializedData) 193ffe3c632Sopenharmony_ci .toEqual(createArrayBuffer(0xD, 0xFF, 0xFF, 0xFF, 0xFF)); 194ffe3c632Sopenharmony_ci 195ffe3c632Sopenharmony_ci const newAccessor = Kernel.fromArrayBuffer(serializedData); 196ffe3c632Sopenharmony_ci expect(newAccessor.getSfixed32WithDefault(1)).toEqual(-1); 197ffe3c632Sopenharmony_ci expect(newAccessor.serialize()).toEqual(serializedData); 198ffe3c632Sopenharmony_ci }); 199ffe3c632Sopenharmony_ci 200ffe3c632Sopenharmony_ci it('is supported for sfixed32 -> fixed32', () => { 201ffe3c632Sopenharmony_ci const oldAccessor = Kernel.createEmpty(); 202ffe3c632Sopenharmony_ci oldAccessor.setSfixed32(1, -1); 203ffe3c632Sopenharmony_ci const serializedData = oldAccessor.serialize(); 204ffe3c632Sopenharmony_ci expect(serializedData) 205ffe3c632Sopenharmony_ci .toEqual(createArrayBuffer(0xD, 0xFF, 0xFF, 0xFF, 0xFF)); 206ffe3c632Sopenharmony_ci 207ffe3c632Sopenharmony_ci const newAccessor = Kernel.fromArrayBuffer(serializedData); 208ffe3c632Sopenharmony_ci expect(newAccessor.getFixed32WithDefault(1)).toEqual(4294967295); 209ffe3c632Sopenharmony_ci expect(newAccessor.serialize()).toEqual(serializedData); 210ffe3c632Sopenharmony_ci }); 211ffe3c632Sopenharmony_ci 212ffe3c632Sopenharmony_ci it('is supported for fixed64 -> sfixed64', () => { 213ffe3c632Sopenharmony_ci const oldAccessor = Kernel.createEmpty(); 214ffe3c632Sopenharmony_ci oldAccessor.setFixed64(1, Int64.fromHexString('0xFFFFFFFFFFFFFFFF')); 215ffe3c632Sopenharmony_ci const serializedData = oldAccessor.serialize(); 216ffe3c632Sopenharmony_ci expect(serializedData) 217ffe3c632Sopenharmony_ci .toEqual(createArrayBuffer( 218ffe3c632Sopenharmony_ci 0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)); 219ffe3c632Sopenharmony_ci 220ffe3c632Sopenharmony_ci const newAccessor = Kernel.fromArrayBuffer(serializedData); 221ffe3c632Sopenharmony_ci expect(newAccessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(-1)); 222ffe3c632Sopenharmony_ci expect(newAccessor.serialize()).toEqual(serializedData); 223ffe3c632Sopenharmony_ci }); 224ffe3c632Sopenharmony_ci 225ffe3c632Sopenharmony_ci it('is supported for sfixed64 -> fixed64', () => { 226ffe3c632Sopenharmony_ci const oldAccessor = Kernel.createEmpty(); 227ffe3c632Sopenharmony_ci oldAccessor.setSfixed64(1, Int64.fromInt(-1)); 228ffe3c632Sopenharmony_ci const serializedData = oldAccessor.serialize(); 229ffe3c632Sopenharmony_ci expect(serializedData) 230ffe3c632Sopenharmony_ci .toEqual(createArrayBuffer( 231ffe3c632Sopenharmony_ci 0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)); 232ffe3c632Sopenharmony_ci 233ffe3c632Sopenharmony_ci const newAccessor = Kernel.fromArrayBuffer(serializedData); 234ffe3c632Sopenharmony_ci expect(newAccessor.getFixed64WithDefault(1)) 235ffe3c632Sopenharmony_ci .toEqual(Int64.fromHexString('0xFFFFFFFFFFFFFFFF')); 236ffe3c632Sopenharmony_ci expect(newAccessor.serialize()).toEqual(serializedData); 237ffe3c632Sopenharmony_ci }); 238ffe3c632Sopenharmony_ci 239ffe3c632Sopenharmony_ci it('is supported for bytes -> message', () => { 240ffe3c632Sopenharmony_ci const oldAccessor = Kernel.createEmpty(); 241ffe3c632Sopenharmony_ci oldAccessor.setBytes( 242ffe3c632Sopenharmony_ci 1, ByteString.fromArrayBuffer(createArrayBuffer(0x8, 0x1))); 243ffe3c632Sopenharmony_ci const serializedData = oldAccessor.serialize(); 244ffe3c632Sopenharmony_ci expect(serializedData).toEqual(createArrayBuffer(0xA, 0x2, 0x8, 0x1)); 245ffe3c632Sopenharmony_ci 246ffe3c632Sopenharmony_ci const newAccessor = Kernel.fromArrayBuffer(serializedData); 247ffe3c632Sopenharmony_ci const message = newAccessor.getMessage(1, TestMessage.instanceCreator); 248ffe3c632Sopenharmony_ci expect(message.getInt32WithDefault(1)).toEqual(1); 249ffe3c632Sopenharmony_ci expect(message.serialize()).toEqual(createArrayBuffer(0x8, 0x1)); 250ffe3c632Sopenharmony_ci expect(newAccessor.serialize()).toEqual(serializedData); 251ffe3c632Sopenharmony_ci }); 252ffe3c632Sopenharmony_ci 253ffe3c632Sopenharmony_ci it('is supported for message -> bytes', () => { 254ffe3c632Sopenharmony_ci const oldAccessor = Kernel.createEmpty(); 255ffe3c632Sopenharmony_ci const message = new TestMessage(Kernel.createEmpty()); 256ffe3c632Sopenharmony_ci message.setInt32(1, 1); 257ffe3c632Sopenharmony_ci oldAccessor.setMessage(1, message); 258ffe3c632Sopenharmony_ci const serializedData = oldAccessor.serialize(); 259ffe3c632Sopenharmony_ci expect(serializedData).toEqual(createArrayBuffer(0xA, 0x2, 0x8, 0x1)); 260ffe3c632Sopenharmony_ci 261ffe3c632Sopenharmony_ci const newAccessor = Kernel.fromArrayBuffer(serializedData); 262ffe3c632Sopenharmony_ci expect(newAccessor.getBytesWithDefault(1)) 263ffe3c632Sopenharmony_ci .toEqual(ByteString.fromArrayBuffer(createArrayBuffer(0x8, 0x1))); 264ffe3c632Sopenharmony_ci expect(newAccessor.serialize()).toEqual(serializedData); 265ffe3c632Sopenharmony_ci }); 266ffe3c632Sopenharmony_ci}); 267