Home | History | Annotate | Download | only in cts
      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 bytes methods on the ProtoOutputStream class.
     28  */
     29 public class ProtoOutputStreamBytesTest extends TestCase {
     30     private static byte[] makeData() {
     31         final byte[] data = new byte[523];
     32         for (int i=0; i<data.length; i++) {
     33             data[i] = (byte)i;
     34         }
     35         return data;
     36     }
     37 
     38     // ----------------------------------------------------------------------
     39     //  writeBytes
     40     // ----------------------------------------------------------------------
     41 
     42     /**
     43      * Test writeBytes.
     44      */
     45     public void testWrite() throws Exception {
     46         testWrite(0);
     47         testWrite(1);
     48         testWrite(5);
     49     }
     50 
     51     /**
     52      * Implementation of testWrite with a given chunkSize.
     53      */
     54     public void testWrite(int chunkSize) throws Exception {
     55         final ProtoOutputStream po = new ProtoOutputStream(chunkSize);
     56         final long fieldFlags = ProtoOutputStream.FIELD_COUNT_SINGLE | ProtoOutputStream.FIELD_TYPE_BYTES;
     57 
     58         final byte[] data = makeData();
     59 
     60         po.writeBytes(ProtoOutputStream.makeFieldId(1, fieldFlags), data);
     61 
     62         final byte[] expected = new byte[data.length + 3];
     63         expected[0] = (byte)0x0a;
     64         expected[1] = (byte)0x8b;
     65         expected[2] = (byte)0x04;
     66         for (int i=0; i<data.length; i++) {
     67             expected[i+3] = (byte)i;
     68         }
     69 
     70         Assert.assertArrayEquals(expected, po.getBytes());
     71     }
     72 
     73     /**
     74      * Test that writing a with ProtoOutputStream matches, and can be read by standard proto.
     75      */
     76     public void testWriteCompat() throws Exception {
     77         // Nano doesn't work with null.
     78         // testWriteCompat(null);
     79 
     80         testWriteCompat(new byte[0]);
     81         testWriteCompat(new byte[] { 0 } );
     82         testWriteCompat(new byte[] { 1 } );
     83         testWriteCompat(makeData());
     84     }
     85 
     86     /**
     87      * Implementation of testWriteCompat with a given value.
     88      */
     89     public void testWriteCompat(byte[] val) throws Exception {
     90         final int fieldId = 150;
     91         final long fieldFlags = ProtoOutputStream.FIELD_COUNT_SINGLE | ProtoOutputStream.FIELD_TYPE_BYTES;
     92 
     93         final Test.All all = new Test.All();
     94         final ProtoOutputStream po = new ProtoOutputStream(0);
     95 
     96         all.bytesField = val;
     97         po.writeBytes(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         Assert.assertArrayEquals(val, readback.bytesField);
    107     }
    108 
    109     // ----------------------------------------------------------------------
    110     //  writeRepeatedBytes
    111     // ----------------------------------------------------------------------
    112 
    113     /**
    114      * Test writeBytes.
    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_BYTES;
    128 
    129         po.writeRepeatedBytes(ProtoOutputStream.makeFieldId(1, fieldFlags), null);
    130         po.writeRepeatedBytes(ProtoOutputStream.makeFieldId(2, fieldFlags), new byte[0]);
    131         po.writeRepeatedBytes(ProtoOutputStream.makeFieldId(3, fieldFlags),
    132                 new byte[] { 0, 1, 2, 3, 4, 5 });
    133         po.writeRepeatedBytes(ProtoOutputStream.makeFieldId(4, fieldFlags),
    134                 new byte[] { (byte)0xff, (byte)0xfe, (byte)0xfd, (byte)0xfc });
    135 
    136         po.writeRepeatedBytes(ProtoOutputStream.makeFieldId(1, fieldFlags), null);
    137         po.writeRepeatedBytes(ProtoOutputStream.makeFieldId(2, fieldFlags), new byte[0]);
    138         po.writeRepeatedBytes(ProtoOutputStream.makeFieldId(3, fieldFlags),
    139                 new byte[] { 0, 1, 2, 3, 4, 5 });
    140         po.writeRepeatedBytes(ProtoOutputStream.makeFieldId(4, fieldFlags),
    141                 new byte[] { (byte)0xff, (byte)0xfe, (byte)0xfd, (byte)0xfc });
    142 
    143         final byte[] result = po.getBytes();
    144         Assert.assertArrayEquals(new byte[] {
    145                 // 1 -> null - default value, written when repeated
    146                 (byte)0x0a,
    147                 (byte)0x00,
    148                 // 2 -> { } - default value, written when repeated
    149                 (byte)0x12,
    150                 (byte)0x00,
    151                 // 3 -> { 0, 1, 2, 3, 4, 5 }
    152                 (byte)0x1a,
    153                 (byte)0x06,
    154                 (byte)0x00, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05,
    155                 // 4 -> { (byte)0xff, (byte)0xfe, (byte)0xfd, (byte)0xfc }
    156                 (byte)0x22,
    157                 (byte)0x04,
    158                 (byte)0xff, (byte)0xfe, (byte)0xfd, (byte)0xfc,
    159 
    160                 // 1 -> null - default value, written when repeated
    161                 (byte)0x0a,
    162                 (byte)0x00,
    163                 // 2 -> { } - default value, written when repeated
    164                 (byte)0x12,
    165                 (byte)0x00,
    166                 // 3 -> { 0, 1, 2, 3, 4, 5 }
    167                 (byte)0x1a,
    168                 (byte)0x06,
    169                 (byte)0x00, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05,
    170                 // 4 -> { (byte)0xff, (byte)0xfe, (byte)0xfd, (byte)0xfc }
    171                 (byte)0x22,
    172                 (byte)0x04,
    173                 (byte)0xff, (byte)0xfe, (byte)0xfd, (byte)0xfc,
    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 byte[0][]);
    182         testRepeatedCompat(new byte[][] {
    183                     new byte[0],
    184                     new byte[] { 0 },
    185                     new byte[] { 1 },
    186                     makeData(),
    187                 });
    188     }
    189 
    190     /**
    191      * Implementation of testRepeatedCompat with a given value.
    192      */
    193     public void testRepeatedCompat(byte[][] val) throws Exception {
    194         final int fieldId = 151;
    195         final long fieldFlags = ProtoOutputStream.FIELD_COUNT_REPEATED | ProtoOutputStream.FIELD_TYPE_BYTES;
    196 
    197         final Test.All all = new Test.All();
    198         final ProtoOutputStream po = new ProtoOutputStream(0);
    199 
    200         all.bytesFieldRepeated = val;
    201         for (int i=0; i<val.length; i++) {
    202             po.writeRepeatedBytes(ProtoOutputStream.makeFieldId(fieldId, fieldFlags), val[i]);
    203         }
    204 
    205         final byte[] result = po.getBytes();
    206         final byte[] expected = MessageNano.toByteArray(all);
    207 
    208         Assert.assertArrayEquals(expected, result);
    209 
    210         final Test.All readback = Test.All.parseFrom(result);
    211 
    212         assertNotNull(readback.bytesFieldRepeated);
    213         assertEquals(val.length, readback.bytesFieldRepeated.length);
    214         for (int i=0; i<val.length; i++) {
    215             Assert.assertArrayEquals(val[i], readback.bytesFieldRepeated[i]);
    216         }
    217     }
    218 
    219     /**
    220      * Test that if you pass in the wrong type of fieldId, it throws.
    221      */
    222     public void testBadFieldIds() {
    223         // Single
    224 
    225         // Good Count / Bad Type
    226         try {
    227             final ProtoOutputStream po = new ProtoOutputStream();
    228             po.writeBytes(ProtoOutputStream.makeFieldId(1,
    229                         ProtoOutputStream.FIELD_COUNT_SINGLE | ProtoOutputStream.FIELD_TYPE_DOUBLE),
    230                     new byte[0]);
    231         } catch (IllegalArgumentException ex) {
    232             // good
    233         }
    234 
    235         // Bad Count / Good Type
    236         try {
    237             final ProtoOutputStream po = new ProtoOutputStream();
    238             po.writeBytes(ProtoOutputStream.makeFieldId(1,
    239                         ProtoOutputStream.FIELD_COUNT_PACKED | ProtoOutputStream.FIELD_TYPE_BYTES),
    240                     new byte[0]);
    241         } catch (IllegalArgumentException ex) {
    242             // good
    243         }
    244 
    245         // Repeated
    246 
    247         // Good Count / Bad Type
    248         try {
    249             final ProtoOutputStream po = new ProtoOutputStream();
    250             po.writeRepeatedBytes(ProtoOutputStream.makeFieldId(1,
    251                         ProtoOutputStream.FIELD_COUNT_REPEATED | ProtoOutputStream.FIELD_TYPE_DOUBLE),
    252                     new byte[0]);
    253         } catch (IllegalArgumentException ex) {
    254             // good
    255         }
    256 
    257         // Bad Count / Good Type
    258         try {
    259             final ProtoOutputStream po = new ProtoOutputStream();
    260             po.writeRepeatedBytes(ProtoOutputStream.makeFieldId(1,
    261                         ProtoOutputStream.FIELD_COUNT_PACKED | ProtoOutputStream.FIELD_TYPE_BYTES),
    262                     new byte[0]);
    263         } catch (IllegalArgumentException ex) {
    264             // good
    265         }
    266     }
    267 }
    268