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.Log; 20 import android.util.proto.ProtoOutputStream; 21 import static android.util.proto.ProtoOutputStream.*; 22 23 import com.google.protobuf.nano.MessageNano; 24 import junit.framework.TestCase; 25 import org.junit.Assert; 26 27 import java.util.HashMap; 28 import java.util.ArrayList; 29 30 /** 31 * Tests that the write() functions produce the same values as their typed counterparts. 32 */ 33 public class ProtoOutputStreamSwitchedWriteTest extends TestCase { 34 private static final String TAG = "ProtoOutputStreamSwitchedWriteTest"; 35 36 public static abstract class WriteTester { 37 public final String name; 38 WriteTester(String n)39 public WriteTester(String n) { 40 name = n; 41 } 42 write(Number val, long fieldId, ProtoOutputStream po)43 abstract void write(Number val, long fieldId, ProtoOutputStream po); 44 } 45 46 private static final HashMap<Long,WriteTester> TYPED = new HashMap<Long,WriteTester>(); 47 private static final ArrayList<WriteTester> SWITCHED = new ArrayList<WriteTester>(); 48 49 static { 50 TYPED.put(FIELD_TYPE_DOUBLE | FIELD_COUNT_SINGLE, 51 new WriteTester("FIELD_TYPE_DOUBLE | FIELD_COUNT_SINGLE") { 52 @Override 53 public void write(Number val, long fieldId, ProtoOutputStream po) { 54 po.writeDouble(fieldId, val.doubleValue()); 55 } 56 }); 57 TYPED.put(FIELD_TYPE_FLOAT | FIELD_COUNT_SINGLE, 58 new WriteTester("FIELD_TYPE_FLOAT | FIELD_COUNT_SINGLE") { 59 @Override 60 public void write(Number val, long fieldId, ProtoOutputStream po) { 61 po.writeFloat(fieldId, val.floatValue()); 62 } 63 }); 64 TYPED.put(FIELD_TYPE_INT32 | FIELD_COUNT_SINGLE, 65 new WriteTester("FIELD_TYPE_INT32 | FIELD_COUNT_SINGLE") { 66 @Override 67 public void write(Number val, long fieldId, ProtoOutputStream po) { 68 po.writeInt32(fieldId, val.intValue()); 69 } 70 }); 71 TYPED.put(FIELD_TYPE_INT64 | FIELD_COUNT_SINGLE, 72 new WriteTester("FIELD_TYPE_INT64 | FIELD_COUNT_SINGLE") { 73 @Override 74 public void write(Number val, long fieldId, ProtoOutputStream po) { 75 po.writeInt64(fieldId, val.longValue()); 76 } 77 }); 78 TYPED.put(FIELD_TYPE_UINT32 | FIELD_COUNT_SINGLE, 79 new WriteTester("FIELD_TYPE_UINT32 | FIELD_COUNT_SINGLE") { 80 @Override 81 public void write(Number val, long fieldId, ProtoOutputStream po) { 82 po.writeUInt32(fieldId, val.intValue()); 83 } 84 }); 85 TYPED.put(FIELD_TYPE_UINT64 | FIELD_COUNT_SINGLE, 86 new WriteTester("FIELD_TYPE_UINT64 | FIELD_COUNT_SINGLE") { 87 @Override 88 public void write(Number val, long fieldId, ProtoOutputStream po) { 89 po.writeUInt64(fieldId, val.longValue()); 90 } 91 }); 92 TYPED.put(FIELD_TYPE_SINT32 | FIELD_COUNT_SINGLE, 93 new WriteTester("FIELD_TYPE_SINT32 | FIELD_COUNT_SINGLE") { 94 @Override 95 public void write(Number val, long fieldId, ProtoOutputStream po) { 96 po.writeSInt32(fieldId, val.intValue()); 97 } 98 }); 99 TYPED.put(FIELD_TYPE_SINT64 | FIELD_COUNT_SINGLE, 100 new WriteTester("FIELD_TYPE_SINT64 | FIELD_COUNT_SINGLE") { 101 @Override 102 public void write(Number val, long fieldId, ProtoOutputStream po) { 103 po.writeSInt64(fieldId, val.longValue()); 104 } 105 }); 106 TYPED.put(FIELD_TYPE_FIXED32 | FIELD_COUNT_SINGLE, 107 new WriteTester("FIELD_TYPE_FIXED32 | FIELD_COUNT_SINGLE") { 108 @Override 109 public void write(Number val, long fieldId, ProtoOutputStream po) { 110 po.writeFixed32(fieldId, val.intValue()); 111 } 112 }); 113 TYPED.put(FIELD_TYPE_FIXED64 | FIELD_COUNT_SINGLE, 114 new WriteTester("FIELD_TYPE_FIXED64 | FIELD_COUNT_SINGLE") { 115 @Override 116 public void write(Number val, long fieldId, ProtoOutputStream po) { 117 po.writeFixed64(fieldId, val.longValue()); 118 } 119 }); 120 TYPED.put(FIELD_TYPE_SFIXED32 | FIELD_COUNT_SINGLE, 121 new WriteTester("FIELD_TYPE_SFIXED32 | FIELD_COUNT_SINGLE") { 122 @Override 123 public void write(Number val, long fieldId, ProtoOutputStream po) { 124 po.writeSFixed32(fieldId, val.intValue()); 125 } 126 }); 127 TYPED.put(FIELD_TYPE_SFIXED64 | FIELD_COUNT_SINGLE, 128 new WriteTester("FIELD_TYPE_SFIXED64 | FIELD_COUNT_SINGLE") { 129 @Override 130 public void write(Number val, long fieldId, ProtoOutputStream po) { 131 po.writeSFixed64(fieldId, val.longValue()); 132 } 133 }); 134 TYPED.put(FIELD_TYPE_BOOL | FIELD_COUNT_SINGLE, 135 new WriteTester("FIELD_TYPE_BOOL | FIELD_COUNT_SINGLE") { 136 @Override 137 public void write(Number val, long fieldId, ProtoOutputStream po) { 138 po.writeBool(fieldId, val.longValue() != 0); 139 } 140 }); 141 TYPED.put(FIELD_TYPE_ENUM | FIELD_COUNT_SINGLE, 142 new WriteTester("FIELD_TYPE_ENUM | FIELD_COUNT_SINGLE") { 143 @Override 144 public void write(Number val, long fieldId, ProtoOutputStream po) { 145 po.writeEnum(fieldId, val.intValue()); 146 } 147 }); 148 SWITCHED.add(new WriteTester("write(long, double)") { @Override public void write(Number val, long fieldId, ProtoOutputStream po) { po.write(fieldId, val.doubleValue()); } })149 SWITCHED.add(new WriteTester("write(long, double)") { 150 @Override 151 public void write(Number val, long fieldId, ProtoOutputStream po) { 152 po.write(fieldId, val.doubleValue()); 153 } 154 }); SWITCHED.add(new WriteTester("write(long, float)") { @Override public void write(Number val, long fieldId, ProtoOutputStream po) { po.write(fieldId, val.floatValue()); } })155 SWITCHED.add(new WriteTester("write(long, float)") { 156 @Override 157 public void write(Number val, long fieldId, ProtoOutputStream po) { 158 po.write(fieldId, val.floatValue()); 159 } 160 }); SWITCHED.add(new WriteTester("write(long, int)") { @Override public void write(Number val, long fieldId, ProtoOutputStream po) { po.write(fieldId, val.intValue()); } })161 SWITCHED.add(new WriteTester("write(long, int)") { 162 @Override 163 public void write(Number val, long fieldId, ProtoOutputStream po) { 164 po.write(fieldId, val.intValue()); 165 } 166 }); SWITCHED.add(new WriteTester("write(long, long)") { @Override public void write(Number val, long fieldId, ProtoOutputStream po) { po.write(fieldId, val.longValue()); } })167 SWITCHED.add(new WriteTester("write(long, long)") { 168 @Override 169 public void write(Number val, long fieldId, ProtoOutputStream po) { 170 po.write(fieldId, val.longValue()); 171 } 172 }); 173 } 174 testAWrite(Number val, long fieldId, WriteTester typed, WriteTester switched)175 private static void testAWrite(Number val, long fieldId, 176 WriteTester typed, WriteTester switched) { 177 final ProtoOutputStream switchedPo = new ProtoOutputStream(); 178 final ProtoOutputStream typedPo = new ProtoOutputStream(); 179 180 typed.write(val, fieldId, typedPo); 181 switched.write(val, fieldId, switchedPo); 182 183 final byte[] switchedResult = switchedPo.getBytes(); 184 final byte[] typedResult = typedPo.getBytes(); 185 186 try { 187 Assert.assertArrayEquals(typedResult, switchedResult); 188 } catch (Throwable ex) { 189 throw new RuntimeException("Test for " + typed.name + " and " 190 + switched.name + " value=" + val + " (" + val.getClass().getSimpleName() 191 + ") failed: " + ex.getMessage(), ex); 192 } 193 } 194 testWrites(Number val)195 public static void testWrites(Number val) { 196 for (HashMap.Entry<Long,WriteTester> entry: TYPED.entrySet()) { 197 final long fieldId = ((long)entry.getKey()) | 1; 198 final WriteTester typed = entry.getValue(); 199 200 for (WriteTester switched: SWITCHED) { 201 testAWrite(val, fieldId, typed, switched); 202 } 203 } 204 } 205 /** 206 * Test double 207 */ testWriteDouble()208 public void testWriteDouble() { 209 testWrites(new Double(0)); 210 testWrites(new Double(-1)); 211 testWrites(new Double(1)); 212 testWrites(new Double(100)); 213 } 214 215 /** 216 * Test float 217 */ testWriteFloat()218 public void testWriteFloat() { 219 testWrites(new Float(0)); 220 testWrites(new Float(-1)); 221 testWrites(new Float(1)); 222 testWrites(new Float(100)); 223 } 224 225 /** 226 * Test int 227 */ testWriteInteger()228 public void testWriteInteger() { 229 testWrites(new Integer(0)); 230 testWrites(new Integer(-1)); 231 testWrites(new Integer(1)); 232 testWrites(new Integer(100)); 233 } 234 235 /** 236 * Test long 237 */ testWriteLong()238 public void testWriteLong() { 239 testWrites(new Long(0)); 240 testWrites(new Long(-1)); 241 testWrites(new Long(1)); 242 testWrites(new Long(100)); 243 } 244 245 /** 246 * Test single strings 247 */ testWriteString()248 public void testWriteString() { 249 final ProtoOutputStream typedPo = new ProtoOutputStream(); 250 final ProtoOutputStream switchedPo = new ProtoOutputStream(); 251 252 testString(1, "", typedPo, switchedPo); 253 testString(2, null, typedPo, switchedPo); 254 testString(3, "ABCD", typedPo, switchedPo); 255 256 final byte[] typedResult = typedPo.getBytes(); 257 final byte[] switchedResult = switchedPo.getBytes(); 258 259 Assert.assertArrayEquals(typedResult, switchedResult); 260 } 261 testString(int id, String val, ProtoOutputStream typed, ProtoOutputStream switched)262 private void testString(int id, String val, 263 ProtoOutputStream typed, ProtoOutputStream switched) { 264 switched.write(FIELD_TYPE_STRING | FIELD_COUNT_SINGLE | id, val); 265 typed.writeString(FIELD_TYPE_STRING | FIELD_COUNT_SINGLE | id, val); 266 } 267 268 /** 269 * Test repeated strings 270 */ testWriteRepeatedString()271 public void testWriteRepeatedString() { 272 final ProtoOutputStream typedPo = new ProtoOutputStream(); 273 final ProtoOutputStream switchedPo = new ProtoOutputStream(); 274 275 testRepeatedString(1, "", typedPo, switchedPo); 276 testRepeatedString(2, null, typedPo, switchedPo); 277 testRepeatedString(3, "ABCD", typedPo, switchedPo); 278 279 final byte[] typedResult = typedPo.getBytes(); 280 final byte[] switchedResult = switchedPo.getBytes(); 281 282 Assert.assertArrayEquals(typedResult, switchedResult); 283 } 284 testRepeatedString(int id, String val, ProtoOutputStream typed, ProtoOutputStream switched)285 private void testRepeatedString(int id, String val, 286 ProtoOutputStream typed, ProtoOutputStream switched) { 287 switched.write(FIELD_TYPE_STRING | FIELD_COUNT_REPEATED | id, val); 288 typed.writeRepeatedString(FIELD_TYPE_STRING | FIELD_COUNT_REPEATED | id, val); 289 } 290 291 } 292