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 sfixed32 methods on the ProtoOutputStream class. 28 */ 29 public class ProtoOutputStreamSFixed32Test extends TestCase { 30 31 // ---------------------------------------------------------------------- 32 // writeSFixed32 33 // ---------------------------------------------------------------------- 34 35 /** 36 * Test writeSFixed32. 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_SFIXED32; 50 51 po.writeSFixed32(ProtoOutputStream.makeFieldId(1, fieldFlags), 0); 52 po.writeSFixed32(ProtoOutputStream.makeFieldId(2, fieldFlags), 1); 53 po.writeSFixed32(ProtoOutputStream.makeFieldId(3, fieldFlags), -1); 54 po.writeSFixed32(ProtoOutputStream.makeFieldId(4, fieldFlags), Integer.MIN_VALUE); 55 po.writeSFixed32(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)0x15, 62 (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, 63 // 3 -> -1 64 (byte)0x1d, 65 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 66 // 4 -> Integer.MIN_VALUE 67 (byte)0x25, 68 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, 69 // 5 -> Integer.MAX_VALUE 70 (byte)0x2d, 71 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f, 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 = 110; 91 final long fieldFlags = ProtoOutputStream.FIELD_COUNT_SINGLE | ProtoOutputStream.FIELD_TYPE_SFIXED32; 92 93 final Test.All all = new Test.All(); 94 final ProtoOutputStream po = new ProtoOutputStream(0); 95 96 all.sfixed32Field = val; 97 po.writeSFixed32(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.sfixed32Field); 107 } 108 109 // ---------------------------------------------------------------------- 110 // writeRepeatedSFixed32 111 // ---------------------------------------------------------------------- 112 113 /** 114 * Test writeSFixed32. 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_SFIXED32; 128 129 po.writeRepeatedSFixed32(ProtoOutputStream.makeFieldId(1, fieldFlags), 0); 130 po.writeRepeatedSFixed32(ProtoOutputStream.makeFieldId(2, fieldFlags), 1); 131 po.writeRepeatedSFixed32(ProtoOutputStream.makeFieldId(3, fieldFlags), -1); 132 po.writeRepeatedSFixed32(ProtoOutputStream.makeFieldId(4, fieldFlags), Integer.MIN_VALUE); 133 po.writeRepeatedSFixed32(ProtoOutputStream.makeFieldId(5, fieldFlags), Integer.MAX_VALUE); 134 135 po.writeRepeatedSFixed32(ProtoOutputStream.makeFieldId(1, fieldFlags), 0); 136 po.writeRepeatedSFixed32(ProtoOutputStream.makeFieldId(2, fieldFlags), 1); 137 po.writeRepeatedSFixed32(ProtoOutputStream.makeFieldId(3, fieldFlags), -1); 138 po.writeRepeatedSFixed32(ProtoOutputStream.makeFieldId(4, fieldFlags), Integer.MIN_VALUE); 139 po.writeRepeatedSFixed32(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)0x0d, 145 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 146 // 2 -> 1 147 (byte)0x15, 148 (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, 149 // 3 -> -1 150 (byte)0x1d, 151 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 152 // 4 -> Integer.MIN_VALUE 153 (byte)0x25, 154 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, 155 // 5 -> Integer.MAX_VALUE 156 (byte)0x2d, 157 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f, 158 159 // 1 -> 0 - default value, written when repeated 160 (byte)0x0d, 161 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 162 // 2 -> 1 163 (byte)0x15, 164 (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, 165 // 3 -> -1 166 (byte)0x1d, 167 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 168 // 4 -> Integer.MIN_VALUE 169 (byte)0x25, 170 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, 171 // 5 -> Integer.MAX_VALUE 172 (byte)0x2d, 173 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f, 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 = 111; 190 final long fieldFlags = ProtoOutputStream.FIELD_COUNT_REPEATED | ProtoOutputStream.FIELD_TYPE_SFIXED32; 191 192 final Test.All all = new Test.All(); 193 final ProtoOutputStream po = new ProtoOutputStream(0); 194 195 all.sfixed32FieldRepeated = val; 196 for (int i=0; i<val.length; i++) { 197 po.writeRepeatedSFixed32(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.sfixed32FieldRepeated); 208 assertEquals(val.length, readback.sfixed32FieldRepeated.length); 209 for (int i=0; i<val.length; i++) { 210 assertEquals(val[i], readback.sfixed32FieldRepeated[i]); 211 } 212 } 213 214 // ---------------------------------------------------------------------- 215 // writePackedSFixed32 216 // ---------------------------------------------------------------------- 217 218 /** 219 * Test writeSFixed32. 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 writePackedSFixed32(ProtoOutputStream po, int fieldId, int val) { 231 final long fieldFlags = ProtoOutputStream.FIELD_COUNT_PACKED | ProtoOutputStream.FIELD_TYPE_SFIXED32; 232 po.writePackedSFixed32(ProtoOutputStream.makeFieldId(fieldId, fieldFlags), 233 new int[] { val, val }); 234 } 235 236 /** 237 * Implementation of testPacked with a given chunkSize. 238 */ 239 public void testPacked(int chunkSize) throws Exception { 240 final ProtoOutputStream po = new ProtoOutputStream(chunkSize); 241 final long fieldFlags = ProtoOutputStream.FIELD_COUNT_PACKED | ProtoOutputStream.FIELD_TYPE_SFIXED32; 242 243 po.writePackedSFixed32(ProtoOutputStream.makeFieldId(1000, fieldFlags), null); 244 po.writePackedSFixed32(ProtoOutputStream.makeFieldId(1001, fieldFlags), new int[0]); 245 writePackedSFixed32(po, 1, 0); 246 writePackedSFixed32(po, 2, 1); 247 writePackedSFixed32(po, 3, -1); 248 writePackedSFixed32(po, 4, Integer.MIN_VALUE); 249 writePackedSFixed32(po, 5, Integer.MAX_VALUE); 250 251 final byte[] result = po.getBytes(); 252 Assert.assertArrayEquals(new byte[] { 253 // 1 -> 0 - default value, written when repeated 254 (byte)0x0a, 255 (byte)0x08, 256 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 257 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 258 // 2 -> 1 259 (byte)0x12, 260 (byte)0x08, 261 (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, 262 (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, 263 // 3 -> -1 264 (byte)0x1a, 265 (byte)0x08, 266 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 267 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 268 // 4 -> Integer.MIN_VALUE 269 (byte)0x22, 270 (byte)0x08, 271 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, 272 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, 273 // 5 -> Integer.MAX_VALUE 274 (byte)0x2a, 275 (byte)0x08, 276 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f, 277 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f, 278 }, result); 279 } 280 281 /** 282 * Test that writing a with ProtoOutputStream matches, and can be read by standard proto. 283 */ 284 public void testPackedCompat() throws Exception { 285 testPackedCompat(new int[] {}); 286 testPackedCompat(new int[] { 0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE, }); 287 } 288 289 /** 290 * Implementation of testPackedSFixed32Compat with a given value. 291 */ 292 public void testPackedCompat(int[] val) throws Exception { 293 final int fieldId = 112; 294 final long fieldFlags = ProtoOutputStream.FIELD_COUNT_PACKED | ProtoOutputStream.FIELD_TYPE_SFIXED32; 295 296 final Test.All all = new Test.All(); 297 final ProtoOutputStream po = new ProtoOutputStream(0); 298 299 all.sfixed32FieldPacked = val; 300 po.writePackedSFixed32(ProtoOutputStream.makeFieldId(fieldId, fieldFlags), val); 301 302 final byte[] result = po.getBytes(); 303 final byte[] expected = MessageNano.toByteArray(all); 304 305 Assert.assertArrayEquals(expected, result); 306 307 final Test.All readback = Test.All.parseFrom(result); 308 309 Assert.assertArrayEquals(val, readback.sfixed32FieldPacked); 310 } 311 312 /** 313 * Test that if you pass in the wrong type of fieldId, it throws. 314 */ 315 public void testBadFieldIds() { 316 // Single 317 318 // Good Count / Bad Type 319 try { 320 final ProtoOutputStream po = new ProtoOutputStream(); 321 po.writeSFixed32(ProtoOutputStream.makeFieldId(1, 322 ProtoOutputStream.FIELD_COUNT_SINGLE | ProtoOutputStream.FIELD_TYPE_DOUBLE), 0); 323 } catch (IllegalArgumentException ex) { 324 // good 325 } 326 327 // Bad Count / Good Type 328 try { 329 final ProtoOutputStream po = new ProtoOutputStream(); 330 po.writeSFixed32(ProtoOutputStream.makeFieldId(1, 331 ProtoOutputStream.FIELD_COUNT_PACKED | ProtoOutputStream.FIELD_TYPE_SFIXED32), 0); 332 } catch (IllegalArgumentException ex) { 333 // good 334 } 335 336 // Repeated 337 338 // Good Count / Bad Type 339 try { 340 final ProtoOutputStream po = new ProtoOutputStream(); 341 po.writeRepeatedSFixed32(ProtoOutputStream.makeFieldId(1, 342 ProtoOutputStream.FIELD_COUNT_REPEATED | ProtoOutputStream.FIELD_TYPE_DOUBLE), 0); 343 } catch (IllegalArgumentException ex) { 344 // good 345 } 346 347 // Bad Count / Good Type 348 try { 349 final ProtoOutputStream po = new ProtoOutputStream(); 350 po.writeRepeatedSFixed32(ProtoOutputStream.makeFieldId(1, 351 ProtoOutputStream.FIELD_COUNT_PACKED | ProtoOutputStream.FIELD_TYPE_SFIXED32), 0); 352 } catch (IllegalArgumentException ex) { 353 // good 354 } 355 356 // Packed 357 358 // Good Count / Bad Type 359 try { 360 final ProtoOutputStream po = new ProtoOutputStream(); 361 po.writePackedSFixed32(ProtoOutputStream.makeFieldId(1, 362 ProtoOutputStream.FIELD_COUNT_PACKED | ProtoOutputStream.FIELD_TYPE_DOUBLE), 363 new int[0]); 364 } catch (IllegalArgumentException ex) { 365 // good 366 } 367 368 // Bad Count / Good Type 369 try { 370 final ProtoOutputStream po = new ProtoOutputStream(); 371 po.writePackedSFixed32(ProtoOutputStream.makeFieldId(1, 372 ProtoOutputStream.FIELD_COUNT_SINGLE | ProtoOutputStream.FIELD_TYPE_SFIXED32), 373 new int[0]); 374 } catch (IllegalArgumentException ex) { 375 // good 376 } 377 } 378 } 379