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 sint32 methods on the ProtoOutputStream class. 28 */ 29 public class ProtoOutputStreamSInt32Test extends TestCase { 30 31 // ---------------------------------------------------------------------- 32 // writeSInt32 33 // ---------------------------------------------------------------------- 34 35 /** 36 * Test writeSInt32. 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_SINT32; 50 51 po.writeSInt32(ProtoOutputStream.makeFieldId(1, fieldFlags), 0); 52 po.writeSInt32(ProtoOutputStream.makeFieldId(2, fieldFlags), 1); 53 po.writeSInt32(ProtoOutputStream.makeFieldId(3, fieldFlags), -1); 54 po.writeSInt32(ProtoOutputStream.makeFieldId(4, fieldFlags), Integer.MIN_VALUE); 55 po.writeSInt32(ProtoOutputStream.makeFieldId(5, fieldFlags), Integer.MAX_VALUE); 56 57 final byte[] result = po.getBytes(); 58 Assert.assertArrayEquals(new byte[] { 59 // 1 -> 0 - default value, not written 60 // 2 -> 1 61 (byte)0x10, 62 (byte)0x02, 63 // 3 -> -1 64 (byte)0x18, 65 (byte)0x01, 66 // 4 -> MIN_VALUE 67 (byte)0x20, 68 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x0f, 69 // 5 -> MAX_VALUE 70 (byte)0x28, 71 (byte)0xfe, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x0f, 72 }, result); 73 } 74 75 /** 76 * Test that writing a with ProtoOutputStream matches, and can be read by standard proto. 77 */ 78 public void testWriteCompat() throws Exception { 79 testWriteCompat(0); 80 testWriteCompat(1); 81 testWriteCompat(-1); 82 testWriteCompat(Integer.MIN_VALUE); 83 testWriteCompat(Integer.MAX_VALUE); 84 } 85 86 /** 87 * Implementation of testWriteCompat with a given value. 88 */ 89 public void testWriteCompat(int val) throws Exception { 90 final int fieldId = 70; 91 final long fieldFlags = ProtoOutputStream.FIELD_COUNT_SINGLE | ProtoOutputStream.FIELD_TYPE_SINT32; 92 93 final Test.All all = new Test.All(); 94 final ProtoOutputStream po = new ProtoOutputStream(0); 95 96 all.sint32Field = val; 97 po.writeSInt32(ProtoOutputStream.makeFieldId(fieldId, fieldFlags), val); 98 99 final byte[] result = po.getBytes(); 100 final byte[] expected = MessageNano.toByteArray(all); 101 102 Assert.assertArrayEquals(expected, result); 103 104 final Test.All readback = Test.All.parseFrom(result); 105 106 assertEquals(val, readback.sint32Field); 107 } 108 109 // ---------------------------------------------------------------------- 110 // writeRepeatedSInt32 111 // ---------------------------------------------------------------------- 112 113 /** 114 * Test writeSInt32. 115 */ 116 public void testRepeated() throws Exception { 117 testRepeated(0); 118 testRepeated(1); 119 testRepeated(5); 120 } 121 122 /** 123 * Implementation of testRepeated with a given chunkSize. 124 */ 125 public void testRepeated(int chunkSize) throws Exception { 126 final ProtoOutputStream po = new ProtoOutputStream(chunkSize); 127 final long fieldFlags = ProtoOutputStream.FIELD_COUNT_REPEATED | ProtoOutputStream.FIELD_TYPE_SINT32; 128 129 po.writeRepeatedSInt32(ProtoOutputStream.makeFieldId(1, fieldFlags), 0); 130 po.writeRepeatedSInt32(ProtoOutputStream.makeFieldId(2, fieldFlags), 1); 131 po.writeRepeatedSInt32(ProtoOutputStream.makeFieldId(3, fieldFlags), -1); 132 po.writeRepeatedSInt32(ProtoOutputStream.makeFieldId(4, fieldFlags), Integer.MIN_VALUE); 133 po.writeRepeatedSInt32(ProtoOutputStream.makeFieldId(5, fieldFlags), Integer.MAX_VALUE); 134 135 po.writeRepeatedSInt32(ProtoOutputStream.makeFieldId(1, fieldFlags), 0); 136 po.writeRepeatedSInt32(ProtoOutputStream.makeFieldId(2, fieldFlags), 1); 137 po.writeRepeatedSInt32(ProtoOutputStream.makeFieldId(3, fieldFlags), -1); 138 po.writeRepeatedSInt32(ProtoOutputStream.makeFieldId(4, fieldFlags), Integer.MIN_VALUE); 139 po.writeRepeatedSInt32(ProtoOutputStream.makeFieldId(5, fieldFlags), Integer.MAX_VALUE); 140 141 final byte[] result = po.getBytes(); 142 Assert.assertArrayEquals(new byte[] { 143 // 1 -> 0 - default value, written when repeated 144 (byte)0x08, 145 (byte)0x00, 146 // 2 -> 1 147 (byte)0x10, 148 (byte)0x02, 149 // 3 -> -1 150 (byte)0x18, 151 (byte)0x01, 152 // 4 -> MIN_VALUE 153 (byte)0x20, 154 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x0f, 155 // 5 -> MAX_VALUE 156 (byte)0x28, 157 (byte)0xfe, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x0f, 158 159 // 1 -> 0 - default value, written when repeated 160 (byte)0x08, 161 (byte)0x00, 162 // 2 -> 1 163 (byte)0x10, 164 (byte)0x02, 165 // 3 -> -1 166 (byte)0x18, 167 (byte)0x01, 168 // 4 -> MIN_VALUE 169 (byte)0x20, 170 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x0f, 171 // 5 -> MAX_VALUE 172 (byte)0x28, 173 (byte)0xfe, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x0f, 174 }, result); 175 } 176 177 /** 178 * Test that writing a with ProtoOutputStream matches, and can be read by standard proto. 179 */ 180 public void testRepeatedCompat() throws Exception { 181 testRepeatedCompat(new int[0]); 182 testRepeatedCompat(new int[] { 0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE }); 183 } 184 185 /** 186 * Implementation of testRepeatedCompat with a given value. 187 */ 188 public void testRepeatedCompat(int[] val) throws Exception { 189 final int fieldId = 71; 190 final long fieldFlags = ProtoOutputStream.FIELD_COUNT_REPEATED | ProtoOutputStream.FIELD_TYPE_SINT32; 191 192 final Test.All all = new Test.All(); 193 final ProtoOutputStream po = new ProtoOutputStream(0); 194 195 all.sint32FieldRepeated = val; 196 for (int i=0; i<val.length; i++) { 197 po.writeRepeatedSInt32(ProtoOutputStream.makeFieldId(fieldId, fieldFlags), val[i]); 198 } 199 200 final byte[] result = po.getBytes(); 201 final byte[] expected = MessageNano.toByteArray(all); 202 203 Assert.assertArrayEquals(expected, result); 204 205 final Test.All readback = Test.All.parseFrom(result); 206 207 assertNotNull(readback.sint32FieldRepeated); 208 assertEquals(val.length, readback.sint32FieldRepeated.length); 209 for (int i=0; i<val.length; i++) { 210 assertEquals(val[i], readback.sint32FieldRepeated[i]); 211 } 212 } 213 214 // ---------------------------------------------------------------------- 215 // writePackedSInt32 216 // ---------------------------------------------------------------------- 217 218 /** 219 * Test writeSInt32. 220 */ 221 public void testPacked() throws Exception { 222 testPacked(0); 223 testPacked(1); 224 testPacked(5); 225 } 226 227 /** 228 * Create an array of the val, and write it. 229 */ 230 private void writePackedSInt32(ProtoOutputStream po, int fieldId, int val) { 231 final long fieldFlags = ProtoOutputStream.FIELD_COUNT_PACKED | ProtoOutputStream.FIELD_TYPE_SINT32; 232 po.writePackedSInt32(ProtoOutputStream.makeFieldId(fieldId, fieldFlags), new int[] { val, val }); 233 } 234 235 /** 236 * Implementation of testPacked with a given chunkSize. 237 */ 238 public void testPacked(int chunkSize) throws Exception { 239 final ProtoOutputStream po = new ProtoOutputStream(chunkSize); 240 final long fieldFlags = ProtoOutputStream.FIELD_COUNT_PACKED | ProtoOutputStream.FIELD_TYPE_SINT32; 241 242 po.writePackedSInt32(ProtoOutputStream.makeFieldId(1000, fieldFlags), null); 243 po.writePackedSInt32(ProtoOutputStream.makeFieldId(1001, fieldFlags), new int[0]); 244 writePackedSInt32(po, 1, 0); 245 writePackedSInt32(po, 2, 1); 246 writePackedSInt32(po, 3, -1); 247 writePackedSInt32(po, 4, Integer.MIN_VALUE); 248 writePackedSInt32(po, 5, Integer.MAX_VALUE); 249 250 final byte[] result = po.getBytes(); 251 Assert.assertArrayEquals(new byte[] { 252 // 1 -> 0 - default value, written when repeated 253 (byte)0x0a, 254 (byte)0x02, 255 (byte)0x00, 256 (byte)0x00, 257 // 2 -> 1 258 (byte)0x12, 259 (byte)0x02, 260 (byte)0x02, 261 (byte)0x02, 262 // 3 -> -1 263 (byte)0x1a, 264 (byte)0x02, 265 (byte)0x01, 266 (byte)0x01, 267 // 4 -> MIN_VALUE 268 (byte)0x22, 269 (byte)0x0a, 270 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x0f, 271 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x0f, 272 // 5 -> MAX_VALUE 273 (byte)0x2a, 274 (byte)0x0a, 275 (byte)0xfe, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x0f, 276 (byte)0xfe, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x0f, 277 }, result); 278 } 279 280 /** 281 * Test that writing a with ProtoOutputStream matches, and can be read by standard proto. 282 */ 283 public void testPackedCompat() throws Exception { 284 testPackedCompat(new int[] {}); 285 testPackedCompat(new int[] { 0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE }); 286 } 287 288 /** 289 * Implementation of testPackedSInt32Compat with a given value. 290 */ 291 public void testPackedCompat(int[] val) throws Exception { 292 final int fieldId = 72; 293 final long fieldFlags = ProtoOutputStream.FIELD_COUNT_PACKED | ProtoOutputStream.FIELD_TYPE_SINT32; 294 295 final Test.All all = new Test.All(); 296 final ProtoOutputStream po = new ProtoOutputStream(0); 297 298 all.sint32FieldPacked = val; 299 po.writePackedSInt32(ProtoOutputStream.makeFieldId(fieldId, fieldFlags), val); 300 301 final byte[] result = po.getBytes(); 302 final byte[] expected = MessageNano.toByteArray(all); 303 304 Assert.assertArrayEquals(expected, result); 305 306 final Test.All readback = Test.All.parseFrom(result); 307 308 Assert.assertArrayEquals(val, readback.sint32FieldPacked); 309 } 310 311 /** 312 * Test that if you pass in the wrong type of fieldId, it throws. 313 */ 314 public void testBadFieldIds() { 315 // Single 316 317 // Good Count / Bad Type 318 try { 319 final ProtoOutputStream po = new ProtoOutputStream(); 320 po.writeSInt32(ProtoOutputStream.makeFieldId(1, 321 ProtoOutputStream.FIELD_COUNT_SINGLE | ProtoOutputStream.FIELD_TYPE_DOUBLE), 0); 322 } catch (IllegalArgumentException ex) { 323 // good 324 } 325 326 // Bad Count / Good Type 327 try { 328 final ProtoOutputStream po = new ProtoOutputStream(); 329 po.writeSInt32(ProtoOutputStream.makeFieldId(1, 330 ProtoOutputStream.FIELD_COUNT_PACKED | ProtoOutputStream.FIELD_TYPE_SINT32), 0); 331 } catch (IllegalArgumentException ex) { 332 // good 333 } 334 335 // Repeated 336 337 // Good Count / Bad Type 338 try { 339 final ProtoOutputStream po = new ProtoOutputStream(); 340 po.writeRepeatedSInt32(ProtoOutputStream.makeFieldId(1, 341 ProtoOutputStream.FIELD_COUNT_REPEATED | ProtoOutputStream.FIELD_TYPE_DOUBLE), 0); 342 } catch (IllegalArgumentException ex) { 343 // good 344 } 345 346 // Bad Count / Good Type 347 try { 348 final ProtoOutputStream po = new ProtoOutputStream(); 349 po.writeRepeatedSInt32(ProtoOutputStream.makeFieldId(1, 350 ProtoOutputStream.FIELD_COUNT_PACKED | ProtoOutputStream.FIELD_TYPE_SINT32), 0); 351 } catch (IllegalArgumentException ex) { 352 // good 353 } 354 355 // Packed 356 357 // Good Count / Bad Type 358 try { 359 final ProtoOutputStream po = new ProtoOutputStream(); 360 po.writePackedSInt32(ProtoOutputStream.makeFieldId(1, 361 ProtoOutputStream.FIELD_COUNT_PACKED | ProtoOutputStream.FIELD_TYPE_DOUBLE), 362 new int[0]); 363 } catch (IllegalArgumentException ex) { 364 // good 365 } 366 367 // Bad Count / Good Type 368 try { 369 final ProtoOutputStream po = new ProtoOutputStream(); 370 po.writePackedSInt32(ProtoOutputStream.makeFieldId(1, 371 ProtoOutputStream.FIELD_COUNT_SINGLE | ProtoOutputStream.FIELD_TYPE_SINT32), 372 new int[0]); 373 } catch (IllegalArgumentException ex) { 374 // good 375 } 376 } 377 } 378