blob: 71e1fcf35eb8f89a7c7fa56a6a1241de324be3b2 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package io.v.v23.vom;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.TypeToken;
import junit.framework.TestCase;
import static com.google.common.truth.Truth.assertThat;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Duration;
import io.v.v23.V;
import io.v.v23.vdl.Types;
import io.v.v23.vdl.VdlArray;
import io.v.v23.vdl.VdlType;
import io.v.v23.vdl.VdlValue;
import io.v.v23.verror.VException;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class BinaryDecoderTest extends TestCase {
static {
V.init();
}
public void testDecode80() throws Exception {
decodeTest(Constants.VERSION_80, io.v.v23.vom.testdata.data80.Constants.TESTS);
}
public void testDecode81() throws Exception {
decodeTest(Constants.VERSION_81, io.v.v23.vom.testdata.data81.Constants.TESTS);
}
void decodeTest(Version version, List<io.v.v23.vom.testdata.types.TestCase> tests) throws Exception {
for (io.v.v23.vom.testdata.types.TestCase test : tests) {
byte[] bytes = TestUtil.hexStringToBytes(test.getHex());
Object targetVal = test.getValue();
if (test.getValue().getElem() != null) {
targetVal = test.getValue().getElem();
}
Object value;
if (test.getValue().getElem() != null && test.getValue().getElem().getClass().isArray()) {
value = TestUtil.decode(bytes, test.getValue().getElem().getClass());
} else {
value = TestUtil.decode(bytes);
}
TestUtil.assertEqual(String.format("%s decode(%s) -> %s == %s", version, test.getName(), targetVal, value), targetVal, value);
}
}
public void testDecodeEncode80() throws Exception {
decodeEncodeTest(Constants.VERSION_80, io.v.v23.vom.testdata.data80.Constants.TESTS);
}
public void testDecodeEncode81() throws Exception {
decodeEncodeTest(Constants.VERSION_81, io.v.v23.vom.testdata.data81.Constants.TESTS);
}
public void decodeEncodeTest(Version version, List<io.v.v23.vom.testdata.types.TestCase> tests) throws Exception {
for (io.v.v23.vom.testdata.types.TestCase test : tests) {
byte[] bytes = TestUtil.hexStringToBytes(test.getHex());
VdlValue value = (VdlValue) TestUtil.decode(bytes, VdlValue.class);
assertEquals(String.format("encode(%s) == %s", test.getName(), test.getHex()), test.getHex(), TestUtil.encode(version, value.vdlType(), value));
}
VdlType testsType = Types.getVdlTypeFromReflect(
io.v.v23.vom.testdata.data80.Constants.class.getDeclaredField("TESTS").getGenericType());
String encoded = TestUtil.encode(version, testsType, tests);
VdlValue decoded = (VdlValue) TestUtil.decode(
TestUtil.hexStringToBytes(encoded));
assertEquals(encoded, TestUtil.encode(version, decoded.vdlType(), decoded));
}
public void testDecodeVdlArray() throws Exception {
VdlArray<Byte> v = new VdlArray<Byte>(Types.arrayOf(4, Types.BYTE), new Byte[]{1, 2, 3, 4});
byte[] encoded = TestUtil.hexStringToBytes(TestUtil.encode(Constants.DEFAULT_VERSION, v));
Object decoded = TestUtil.decode(encoded, VdlValue.class);
assertNotNull(decoded);
}
public void testDecodeVException() throws Exception {
Object[] params = {
1,
"2",
ImmutableList.<String>of("3"),
ImmutableMap.<String, String>of("4", "")
};
Type[] paramTypes = {
Integer.class,
String.class,
new TypeToken<List<String>>(){}.getType(),
new TypeToken<Map<String, String>>(){}.getType()
};
VException.IDAction id = VException.register(
"io.v.v23.vom.BinaryDecoderTest.testDecodeVException",
VException.ActionCode.NO_RETRY, "{1} {2} {_}");
VException v = new VException(id, "en", "test", "test", params, paramTypes);
byte[] encoded = TestUtil.hexStringToBytes(TestUtil.encode(Constants.DEFAULT_VERSION, VException.class, v));
Object decoded = TestUtil.decode(encoded);
if (!v.deepEquals(decoded)) {
fail(String.format("Expected error %s, got %s", v, decoded));
}
}
public void testDecodeVExceptionBadParams() throws Exception {
Object[] params = {
ImmutableList.<String>of("3"),
ImmutableMap.<String, String>of("4", "")
};
Type[] paramTypes = {
List.class,
Map.class
};
VException.IDAction id = VException.register(
"io.v.v23.vom.BinaryDecoderTest.testDecodeVExceptionBadParams",
VException.ActionCode.NO_RETRY, "{1} {2} {_}");
VException v = new VException(id, "en", "test", "test", params, paramTypes);
byte[] encoded = TestUtil.hexStringToBytes(TestUtil.encode(Constants.DEFAULT_VERSION, VException.class, v));
Object decoded = TestUtil.decode(encoded);
VException expected = new VException(id, "en", "test", "test");
if (!expected.deepEquals(decoded)) {
fail(String.format("Expected error %s, got %s", v, decoded));
}
}
public void testDecodeEncodeVException() throws Exception {
Object[] params = {
1,
"2",
ImmutableList.<String>of("3"),
ImmutableMap.<String, String>of("4", "")
};
Type[] paramTypes = {
Integer.class,
String.class,
new TypeToken<List<String>>(){}.getType(),
new TypeToken<Map<String, String>>(){}.getType()
};
VException.IDAction id = VException.register(
"io.v.v23.vom.BinaryDecoderTest.testDecodeEncodeVException",
VException.ActionCode.NO_RETRY, "{1} {2} {_}");
VException v = new VException(id, "en", "test", "test", params, paramTypes);
byte[] encoded = TestUtil.hexStringToBytes(TestUtil.encode(Constants.DEFAULT_VERSION, VException.class, v));
Object decoded = TestUtil.decode(encoded);
if (!(decoded instanceof VException)) {
fail(String.format("Decoded into %s, wanted %s", decoded.getClass(), VException.class));
}
VException decodedV = (VException) decoded;
byte[] reEncoded = TestUtil.hexStringToBytes(
TestUtil.encode(Constants.DEFAULT_VERSION, VException.class, decodedV));
assertEquals(Arrays.toString(encoded), Arrays.toString(reEncoded));
}
public void testDecodeSubVException() throws Exception {
SubVException v = new SubVException();
byte[] encoded = TestUtil.hexStringToBytes(TestUtil.encode(Constants.DEFAULT_VERSION, SubVException.class, v));
Object decoded = TestUtil.decode(encoded);
VException expected = new SubVException();
assertThat(decoded).isInstanceOf(SubVException.class);
if (!expected.deepEquals(decoded)) {
fail(String.format("Expected error %s, got %s", v, decoded));
}
}
private static class SubVException extends VException {
static final io.v.v23.verror.VException.IDAction ID_ACTION =
VException.register("v.io/v23/vom.BinaryDecoderTest$SubVException",
VException.ActionCode.NO_RETRY, "{1} {2} {_}");
SubVException(VException e) {
super(e);
}
SubVException() {
super(ID_ACTION, "en", "test", "test", new Object[]{ 5 },
new Type[]{ Integer.class });
}
}
private void assertDecodeEncode(Object value, Version version) throws Exception {
byte[] encoded = TestUtil.hexStringToBytes(TestUtil.encode(version, value.getClass(), value));
Object decoded = TestUtil.decode(encoded);
assertEquals(value, decoded);
}
public void testDecodeEncodeTime() throws Exception {
Version version = Constants.DEFAULT_VERSION;
assertDecodeEncode(new DateTime(2015, 2, 18, 20, 34, 35, 997, DateTimeZone.UTC), version);
assertDecodeEncode(new Duration(239017), version);
}
public void testDecodeEncodeJavaObject() throws Exception {
Version version = Constants.DEFAULT_VERSION;
assertDecodeEncode(new JavaObject(
5, "boo", ImmutableList.of(new JavaObject(7, "foo", null))), version);
}
private static class JavaObject {
private int i;
private final String s;
private List<JavaObject> j;
public JavaObject() {
this.i = 0;
this.s = "";
this.j = null;
}
public JavaObject(int i, String s, List<JavaObject> j) {
this.i = i;
this.s = s;
this.j = j;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
JavaObject that = (JavaObject) o;
if (i != that.i) return false;
if (s != null ? !s.equals(that.s) : that.s != null) return false;
return !(j != null ? !j.equals(that.j) : that.j != null);
}
}
}