1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.util.proto.cts; 18 19 import android.util.proto.ProtoOutputStream; 20 import android.util.proto.cts.nano.Test; 21 22 import com.google.protobuf.nano.MessageNano; 23 import junit.framework.TestCase; 24 import org.junit.Assert; 25 26 /** 27 * Test the sfixed64 methods on the ProtoOutputStream class. 28 */ 29 public class ProtoOutputStreamSFixed64Test extends TestCase { 30 31 // ---------------------------------------------------------------------- 32 // writeSFixed64 33 // ---------------------------------------------------------------------- 34 35 /** 36 * Test writeSFixed64. 37 */ 38 public void testWrite() throws Exception { 39 testWrite(0); 40 testWrite(1); 41 testWrite(5); 42 } 43 44 /** 45 * Implementation of testWrite with a given chunkSize. 46 */ 47 public void testWrite(int chunkSize) throws Exception { 48 final ProtoOutputStream po = new ProtoOutputStream(chunkSize); 49 final long fieldFlags = ProtoOutputStream.FIELD_COUNT_SINGLE | ProtoOutputStream.FIELD_TYPE_SFIXED64; 50 51 po.writeSFixed64(ProtoOutputStream.makeFieldId(1, fieldFlags), 0); 52 po.writeSFixed64(ProtoOutputStream.makeFieldId(2, fieldFlags), 1); 53 po.writeSFixed64(ProtoOutputStream.makeFieldId(3, fieldFlags), -1); 54 po.writeSFixed64(ProtoOutputStream.makeFieldId(4, fieldFlags), Integer.MIN_VALUE); 55 po.writeSFixed64(ProtoOutputStream.makeFieldId(5, fieldFlags), Integer.MAX_VALUE); 56 po.writeSFixed64(ProtoOutputStream.makeFieldId(6, fieldFlags), Long.MIN_VALUE); 57 po.writeSFixed64(ProtoOutputStream.makeFieldId(7, fieldFlags), Long.MAX_VALUE); 58 59 60 final byte[] result = po.getBytes(); 61 Assert.assertArrayEquals(new byte[] { 62 // 1 -> 0 - default value, not written 63 // 2 -> 1 64 (byte)0x11, 65 (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, 66 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 67 // 3 -> -1 68 (byte)0x19, 69 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 70 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 71 // 4 -> Integer.MIN_VALUE 72 (byte)0x21, 73 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, 74 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 75 // 5 -> Integer.MAX_VALUE 76 (byte)0x29, 77 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f, 78 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 79 // 6 -> Long.MIN_VALUE 80 (byte)0x31, 81 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 82 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, 83 // 7 -> Long.MAX_VALUE 84 (byte)0x39, 85 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 86 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f, 87 }, result); 88 } 89 90 /** 91 * Test that writing a with ProtoOutputStream matches, and can be read by standard proto. 92 */ 93 public void testWriteCompat() throws Exception { 94 testWriteCompat(0); 95 testWriteCompat(1); 96 testWriteCompat(-1); 97 testWriteCompat(Integer.MIN_VALUE); 98 testWriteCompat(Integer.MAX_VALUE); 99 testWriteCompat(Long.MIN_VALUE); 100 testWriteCompat(Long.MAX_VALUE); 101 } 102 103 /** 104 * Implementation of testWriteCompat with a given value. 105 */ 106 public void testWriteCompat(long val) throws Exception { 107 final int fieldId = 120; 108 final long fieldFlags = ProtoOutputStream.FIELD_COUNT_SINGLE | ProtoOutputStream.FIELD_TYPE_SFIXED64; 109 110 final Test.All all = new Test.All(); 111 final ProtoOutputStream po = new ProtoOutputStream(0); 112 113 all.sfixed64Field = val; 114 po.writeSFixed64(ProtoOutputStream.makeFieldId(fieldId, fieldFlags), val); 115 116 final byte[] result = po.getBytes(); 117 final byte[] expected = MessageNano.toByteArray(all); 118 119 Assert.assertArrayEquals(expected, result); 120 121 final Test.All readback = Test.All.parseFrom(result); 122 123 assertEquals(val, readback.sfixed64Field); 124 } 125 126 // ---------------------------------------------------------------------- 127 // writeRepeatedSFixed64 128 // ---------------------------------------------------------------------- 129 130 /** 131 * Test writeSFixed64. 132 */ 133 public void testRepeated() throws Exception { 134 testRepeated(0); 135 testRepeated(1); 136 testRepeated(5); 137 } 138 139 /** 140 * Implementation of testRepeated with a given chunkSize. 141 */ 142 public void testRepeated(int chunkSize) throws Exception { 143 final ProtoOutputStream po = new ProtoOutputStream(chunkSize); 144 final long fieldFlags = ProtoOutputStream.FIELD_COUNT_REPEATED | ProtoOutputStream.FIELD_TYPE_SFIXED64; 145 146 po.writeRepeatedSFixed64(ProtoOutputStream.makeFieldId(1, fieldFlags), 0); 147 po.writeRepeatedSFixed64(ProtoOutputStream.makeFieldId(2, fieldFlags), 1); 148 po.writeRepeatedSFixed64(ProtoOutputStream.makeFieldId(3, fieldFlags), -1); 149 po.writeRepeatedSFixed64(ProtoOutputStream.makeFieldId(4, fieldFlags), Integer.MIN_VALUE); 150 po.writeRepeatedSFixed64(ProtoOutputStream.makeFieldId(5, fieldFlags), Integer.MAX_VALUE); 151 po.writeRepeatedSFixed64(ProtoOutputStream.makeFieldId(6, fieldFlags), Long.MIN_VALUE); 152 po.writeRepeatedSFixed64(ProtoOutputStream.makeFieldId(7, fieldFlags), Long.MAX_VALUE); 153 154 po.writeRepeatedSFixed64(ProtoOutputStream.makeFieldId(1, fieldFlags), 0); 155 po.writeRepeatedSFixed64(ProtoOutputStream.makeFieldId(2, fieldFlags), 1); 156 po.writeRepeatedSFixed64(ProtoOutputStream.makeFieldId(3, fieldFlags), -1); 157 po.writeRepeatedSFixed64(ProtoOutputStream.makeFieldId(4, fieldFlags), Integer.MIN_VALUE); 158 po.writeRepeatedSFixed64(ProtoOutputStream.makeFieldId(5, fieldFlags), Integer.MAX_VALUE); 159 po.writeRepeatedSFixed64(ProtoOutputStream.makeFieldId(6, fieldFlags), Long.MIN_VALUE); 160 po.writeRepeatedSFixed64(ProtoOutputStream.makeFieldId(7, fieldFlags), Long.MAX_VALUE); 161 162 final byte[] result = po.getBytes(); 163 Assert.assertArrayEquals(new byte[] { 164 // 1 -> 0 - default value, written when repeated 165 (byte)0x09, 166 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 167 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 168 // 2 -> 1 169 (byte)0x11, 170 (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, 171 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 172 // 3 -> -1 173 (byte)0x19, 174 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 175 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 176 // 4 -> Integer.MIN_VALUE 177 (byte)0x21, 178 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, 179 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 180 // 5 -> Integer.MAX_VALUE 181 (byte)0x29, 182 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f, 183 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 184 // 6 -> Long.MIN_VALUE 185 (byte)0x31, 186 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 187 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, 188 // 7 -> Long.MAX_VALUE 189 (byte)0x39, 190 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 191 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f, 192 193 // 1 -> 0 - default value, written when repeated 194 (byte)0x09, 195 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 196 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 197 // 2 -> 1 198 (byte)0x11, 199 (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, 200 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 201 // 3 -> -1 202 (byte)0x19, 203 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 204 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 205 // 4 -> Integer.MIN_VALUE 206 (byte)0x21, 207 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, 208 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 209 // 5 -> Integer.MAX_VALUE 210 (byte)0x29, 211 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f, 212 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 213 // 6 -> Long.MIN_VALUE 214 (byte)0x31, 215 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 216 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, 217 // 7 -> Long.MAX_VALUE 218 (byte)0x39, 219 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 220 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f, 221 }, result); 222 } 223 224 /** 225 * Test that writing a with ProtoOutputStream matches, and can be read by standard proto. 226 */ 227 public void testRepeatedCompat() throws Exception { 228 testRepeatedCompat(new long[0]); 229 testRepeatedCompat(new long[] { 0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE, 230 Long.MIN_VALUE, Long.MAX_VALUE }); 231 } 232 233 /** 234 * Implementation of testRepeatedCompat with a given value. 235 */ 236 public void testRepeatedCompat(long[] val) throws Exception { 237 final int fieldId = 121; 238 final long fieldFlags = ProtoOutputStream.FIELD_COUNT_REPEATED | ProtoOutputStream.FIELD_TYPE_SFIXED64; 239 240 final Test.All all = new Test.All(); 241 final ProtoOutputStream po = new ProtoOutputStream(0); 242 243 all.sfixed64FieldRepeated = val; 244 for (int i=0; i<val.length; i++) { 245 po.writeRepeatedSFixed64(ProtoOutputStream.makeFieldId(fieldId, fieldFlags), val[i]); 246 } 247 248 final byte[] result = po.getBytes(); 249 final byte[] expected = MessageNano.toByteArray(all); 250 251 Assert.assertArrayEquals(expected, result); 252 253 final Test.All readback = Test.All.parseFrom(result); 254 255 assertNotNull(readback.sfixed64FieldRepeated); 256 assertEquals(val.length, readback.sfixed64FieldRepeated.length); 257 for (int i=0; i<val.length; i++) { 258 assertEquals(val[i], readback.sfixed64FieldRepeated[i]); 259 } 260 } 261 262 // ---------------------------------------------------------------------- 263 // writePackedSFixed64 264 // ---------------------------------------------------------------------- 265 266 /** 267 * Test writeSFixed64. 268 */ 269 public void testPacked() throws Exception { 270 testPacked(0); 271 testPacked(1); 272 testPacked(5); 273 } 274 275 /** 276 * Create an array of the val, and write it. 277 */ 278 private void writePackedSFixed64(ProtoOutputStream po, int fieldId, long val) { 279 final long fieldFlags = ProtoOutputStream.FIELD_COUNT_PACKED | ProtoOutputStream.FIELD_TYPE_SFIXED64; 280 po.writePackedSFixed64(ProtoOutputStream.makeFieldId(fieldId, fieldFlags), 281 new long[] { val, val }); 282 } 283 284 /** 285 * Implementation of testPacked with a given chunkSize. 286 */ 287 public void testPacked(int chunkSize) throws Exception { 288 final ProtoOutputStream po = new ProtoOutputStream(chunkSize); 289 final long fieldFlags = ProtoOutputStream.FIELD_COUNT_PACKED | ProtoOutputStream.FIELD_TYPE_SFIXED64; 290 291 po.writePackedSFixed64(ProtoOutputStream.makeFieldId(1000, fieldFlags), null); 292 po.writePackedSFixed64(ProtoOutputStream.makeFieldId(1001, fieldFlags), new long[0]); 293 writePackedSFixed64(po, 1, 0); 294 writePackedSFixed64(po, 2, 1); 295 writePackedSFixed64(po, 3, -1); 296 writePackedSFixed64(po, 4, Integer.MIN_VALUE); 297 writePackedSFixed64(po, 5, Integer.MAX_VALUE); 298 writePackedSFixed64(po, 6, Long.MIN_VALUE); 299 writePackedSFixed64(po, 7, Long.MAX_VALUE); 300 301 final byte[] result = po.getBytes(); 302 Assert.assertArrayEquals(new byte[] { 303 // 1 -> 0 - default value, written when repeated 304 (byte)0x0a, 305 (byte)0x10, 306 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 307 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 308 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 309 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 310 // 2 -> 1 311 (byte)0x12, 312 (byte)0x10, 313 (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, 314 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 315 (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, 316 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 317 // 3 -> -1 318 (byte)0x1a, 319 (byte)0x10, 320 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 321 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 322 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 323 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 324 // 4 -> Integer.MIN_VALUE 325 (byte)0x22, 326 (byte)0x10, 327 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, 328 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 329 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, 330 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 331 // 5 -> Integer.MAX_VALUE 332 (byte)0x2a, 333 (byte)0x10, 334 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f, 335 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 336 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f, 337 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 338 // 6 -> Long.MIN_VALUE 339 (byte)0x32, 340 (byte)0x10, 341 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 342 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, 343 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 344 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, 345 // 7 -> Long.MAX_VALUE 346 (byte)0x3a, 347 (byte)0x10, 348 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 349 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f, 350 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 351 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f, 352 }, result); 353 } 354 355 /** 356 * Test that writing a with ProtoOutputStream matches, and can be read by standard proto. 357 */ 358 public void testPackedCompat() throws Exception { 359 testPackedCompat(new long[] {}); 360 testPackedCompat(new long[] { 0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE, 361 Long.MIN_VALUE, Long.MAX_VALUE }); 362 } 363 364 /** 365 * Implementation of testPackedSFixed64Compat with a given value. 366 */ 367 public void testPackedCompat(long[] val) throws Exception { 368 final int fieldId = 122; 369 final long fieldFlags = ProtoOutputStream.FIELD_COUNT_PACKED | ProtoOutputStream.FIELD_TYPE_SFIXED64; 370 371 final Test.All all = new Test.All(); 372 final ProtoOutputStream po = new ProtoOutputStream(0); 373 374 all.sfixed64FieldPacked = val; 375 po.writePackedSFixed64(ProtoOutputStream.makeFieldId(fieldId, fieldFlags), val); 376 377 final byte[] result = po.getBytes(); 378 final byte[] expected = MessageNano.toByteArray(all); 379 380 Assert.assertArrayEquals(expected, result); 381 382 final Test.All readback = Test.All.parseFrom(result); 383 384 Assert.assertArrayEquals(val, readback.sfixed64FieldPacked); 385 } 386 387 /** 388 * Test that if you pass in the wrong type of fieldId, it throws. 389 */ 390 public void testBadFieldIds() { 391 // Single 392 393 // Good Count / Bad Type 394 try { 395 final ProtoOutputStream po = new ProtoOutputStream(); 396 po.writeSFixed64(ProtoOutputStream.makeFieldId(1, 397 ProtoOutputStream.FIELD_COUNT_SINGLE | ProtoOutputStream.FIELD_TYPE_DOUBLE), 0); 398 } catch (IllegalArgumentException ex) { 399 // good 400 } 401 402 // Bad Count / Good Type 403 try { 404 final ProtoOutputStream po = new ProtoOutputStream(); 405 po.writeSFixed64(ProtoOutputStream.makeFieldId(1, 406 ProtoOutputStream.FIELD_COUNT_PACKED | ProtoOutputStream.FIELD_TYPE_SFIXED64), 0); 407 } catch (IllegalArgumentException ex) { 408 // good 409 } 410 411 // Repeated 412 413 // Good Count / Bad Type 414 try { 415 final ProtoOutputStream po = new ProtoOutputStream(); 416 po.writeRepeatedSFixed64(ProtoOutputStream.makeFieldId(1, 417 ProtoOutputStream.FIELD_COUNT_REPEATED | ProtoOutputStream.FIELD_TYPE_DOUBLE), 0); 418 } catch (IllegalArgumentException ex) { 419 // good 420 } 421 422 // Bad Count / Good Type 423 try { 424 final ProtoOutputStream po = new ProtoOutputStream(); 425 po.writeRepeatedSFixed64(ProtoOutputStream.makeFieldId(1, 426 ProtoOutputStream.FIELD_COUNT_PACKED | ProtoOutputStream.FIELD_TYPE_SFIXED64), 0); 427 } catch (IllegalArgumentException ex) { 428 // good 429 } 430 431 // Packed 432 433 // Good Count / Bad Type 434 try { 435 final ProtoOutputStream po = new ProtoOutputStream(); 436 po.writePackedSFixed64(ProtoOutputStream.makeFieldId(1, 437 ProtoOutputStream.FIELD_COUNT_PACKED | ProtoOutputStream.FIELD_TYPE_DOUBLE), 438 new long[0]); 439 } catch (IllegalArgumentException ex) { 440 // good 441 } 442 443 // Bad Count / Good Type 444 try { 445 final ProtoOutputStream po = new ProtoOutputStream(); 446 po.writePackedSFixed64(ProtoOutputStream.makeFieldId(1, 447 ProtoOutputStream.FIELD_COUNT_SINGLE | ProtoOutputStream.FIELD_TYPE_SFIXED64), 448 new long[0]); 449 } catch (IllegalArgumentException ex) { 450 // good 451 } 452 } 453 } 454