package water;
import org.junit.*;
import water.util.JSONUtils;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
public class AutoSerialTest extends Iced {
@BeforeClass public static void stall() { TestUtil.stall_till_cloudsize(1); }
@AfterClass public static void checkLeakedKeys() { TestUtil.checkLeakedKeys(); }
byte _byte, _bytes[];
short _short, _shorts[];
int _int, _ints[];
float _float, _floats[];
long _long, _longs[], _longss[][];
double _double,_doubles[],_doubless[][];
String _string;
Key _key;
static AutoBuffer _ab = new AutoBuffer(new byte[1000]);
static AutoBuffer abw() { return _ab.clearForWriting((byte)0); }
static AutoBuffer abr() { return _ab. flipForReading(); }
@Test public void testByte() throws Exception {
byte[] tests = { 0, 4, -1, 127, -128 };
for( byte exp : tests) {
_byte = exp;
this.write(abw());
this. read(abr());
Assert.assertEquals(exp, _byte);
}
}
@Test public void testShort() throws Exception {
short[] tests = { 0, 4, -1, 127, -128 };
for( short exp : tests) {
_short = exp;
this.write(abw());
this. read(abr());
Assert.assertEquals(exp, _short);
}
}
@Test public void testInt() throws Exception {
int[] tests = { 0, 4, Integer.MAX_VALUE, Integer.MIN_VALUE, -1 };
for( int exp : tests) {
_int = exp;
this.write(abw());
this. read(abr());
Assert.assertEquals(exp, _int);
}
}
@Test public void testLong() throws Exception {
long[] tests = { 0, 4, Integer.MAX_VALUE, Integer.MIN_VALUE, -1,
Long.MAX_VALUE, Long.MIN_VALUE, Long.MAX_VALUE - Integer.MAX_VALUE
};
for( long exp : tests) {
_long = exp;
this.write(abw());
this. read(abr());
Assert.assertEquals(exp, _long);
}
}
@Test public void testFloat() throws Exception {
float[] tests = { 0, 4, Integer.MAX_VALUE, Integer.MIN_VALUE, -1,
Long.MAX_VALUE, Long.MIN_VALUE, Long.MAX_VALUE - Integer.MAX_VALUE,
Float.NaN, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY
};
for( float exp : tests) {
_float = exp;
this.write(abw());
this. read(abr());
Assert.assertEquals(exp, _float, Math.ulp(exp));
}
}
@Test public void testDouble() throws Exception {
double[] tests = { 0, 4, Integer.MAX_VALUE, Integer.MIN_VALUE, -1,
Long.MAX_VALUE, Long.MIN_VALUE, Long.MAX_VALUE - Integer.MAX_VALUE,
Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY
};
for( double exp : tests) {
_double = exp;
this.write(abw());
this. read(abr());
Assert.assertEquals(exp, _double, Math.ulp(exp));
}
}
@Test public void testKey() throws Exception {
H2O.main(new String[0]);
Key[] tests = { Key.make(), Key.make("monkey"), Key.make("ninja"), null };
for( Key exp : tests) {
_key = exp;
this.write(abw());
this. read(abr());
Assert.assertEquals(exp, _key);
}
}
@Test public void testString() throws Exception {
H2O.main(new String[0]);
String[] tests = { "", "monkey", "ninja", null };
for( String exp : tests) {
_string = exp;
this.write(abw());
this. read(abr());
Assert.assertEquals(exp, _string);
}
}
@Test public void testByteArray() throws Exception {
byte[][] tests = {
{ 0, 1, 2 },
{ },
null,
{ 6, -1, 19, -49 }
};
for( byte[] exp : tests) {
_bytes = exp;
this.write(abw());
this. read(abr());
Assert.assertArrayEquals(exp, _bytes);
}
}
@Test public void testShortArray() throws Exception {
short[][] tests = {
{ 0, 1, 2 },
{ },
null,
{ 6, -1, 19, -49, Short.MAX_VALUE }
};
for( short[] exp : tests) {
_shorts = exp;
this.write(abw());
this. read(abr());
Assert.assertArrayEquals(exp, _shorts);
}
}
@Test public void testIntArray() throws Exception {
int[][] tests = new int[][] {
{ 0, 1, 2 },
{ },
null,
{ 6, Integer.MAX_VALUE, -1, 19, -49 }
};
for( int[] exp : tests) {
_ints = exp;
this.write(abw());
this. read(abr());
Assert.assertArrayEquals(exp, _ints);
}
}
@Test public void testLongArray() throws Exception {
long[][] tests = {
{ 0, 1, 2 },
{ },
null,
{ 6, -1, 19, -49 },
{ Long.MAX_VALUE, Long.MIN_VALUE}
};
for( long[] exp : tests) {
_longs = exp;
this.write(abw());
this. read(abr());
Assert.assertArrayEquals(exp, _longs);
}
}
// test that simple freezable works (gets autoserializaed correctly)
public static class SimpleFreezableTest implements Freezable<SimpleFreezableTest>, Serializable {
final int x;
double y;
String str;
public static int DEBUG_WEAVER = 1;
public SimpleFreezableTest(){x = -1;}
public SimpleFreezableTest(int x, double y, String str) {this.x = x; this.y = y; this.str = str;}
@Override public SimpleFreezableTest clone(){
try {
return (SimpleFreezableTest)super.clone();
} catch (CloneNotSupportedException e) {throw water.util.Log.throwErr(e);}
}
@Override
public AutoBuffer write(AutoBuffer ab) {
return TypeMap.getIcer(this).write(ab,this);
}
@Override
public SimpleFreezableTest read(AutoBuffer ab) {
Icer icer =TypeMap.getIcer(this);
return (SimpleFreezableTest) icer.read(ab,this);
}
@Override
public AutoBuffer writeJSON(AutoBuffer ab) {
return TypeMap.getIcer(this).writeJSON(ab,this);
}
@Override
public SimpleFreezableTest readJSON(AutoBuffer ab) {
return (SimpleFreezableTest) TypeMap.getIcer(this).read(ab,this);
}
@Override
public int frozenType() {
return TypeMap.getIcer(this).frozenType();
}
@Override
public byte[] asBytes() {
return write(new AutoBuffer()).buf();
}
@Override
public SimpleFreezableTest reloadFromBytes(byte[] ary) {
return read(new AutoBuffer(ary));
}
}
// test that inheritance works
public static class SimpleFreezableTestChild extends SimpleFreezableTest{
public static int DEBUG_WEAVER = 1;
int [] intAry;
double [] dAry;
public SimpleFreezableTestChild(){}
public SimpleFreezableTestChild(int x, int y, String str, int [] intAry, double [] dAry) {super(x,y,str); this.intAry = intAry; this.dAry = dAry;}
}
// test that custom serialization using final method flavor works
public static class SimpleFreezableTestChild2 extends SimpleFreezableTest {
public static int DEBUG_WEAVER = 1;
ArrayList<Number> _nums = new ArrayList<>();
public SimpleFreezableTestChild2() {
}
public SimpleFreezableTestChild2(int x, int y, String str, int[] intAry, double[] dAry) {
super(x, y, str);
for (int i : intAry) _nums.add(new Double(i));
for (double d : dAry) _nums.add(new Double(d));
}
public final AutoBuffer write_impl(AutoBuffer ab) {
ab.put4(_nums.size());
for (int i = 0; i < _nums.size(); ++i)
ab.put8d(_nums.get(i).doubleValue());
return ab;
}
public final SimpleFreezableTestChild2 read_impl(AutoBuffer ab) {
int n = ab.get4();
_nums = new ArrayList<>();
for (int i = 0; i < n; ++i)
_nums.add(ab.get8d());
return this;
}
}
// test that custom serialization inheritace works
public static class SimpleFreezableTestChild3 extends SimpleFreezableTestChild2 {
public static int DEBUG_WEAVER = 1;
ArrayList<Number> _nums2 = new ArrayList<>();
public SimpleFreezableTestChild3() {}
public SimpleFreezableTestChild3(int x, int y, String str, int[] intAry, double[] dAry) {
super(x, y, str, intAry, dAry);
for (int i : intAry) _nums2.add(new Double(i) * 2);
for (double d : dAry) _nums2.add(new Double(d) * 2);
}
public static AutoBuffer write_impl(SimpleFreezableTestChild3 self, AutoBuffer ab) {
ab.put4(self._nums2.size());
for (int i = 0; i < self._nums2.size(); ++i)
ab.put8d(self._nums2.get(i).doubleValue());
return ab;
}
public static SimpleFreezableTestChild3 read_impl(SimpleFreezableTestChild3 self, AutoBuffer ab) {
int n = ab.get4();
self._nums2 = new ArrayList<>();
for (int i = 0; i < n; ++i)
self._nums2.add(ab.get8d());
return self;
}
}
@Test public void testFreezable(){
SimpleFreezableTest a = new SimpleFreezableTest(12,345,"6789");
SimpleFreezableTest b = new SimpleFreezableTest().read(new AutoBuffer(a.write(new AutoBuffer()).bufClose()));
byte [] abytes = AutoBuffer.javaSerializeWritePojo(a);
b = new AutoBuffer(new AutoBuffer().put(a).bufClose()).get();
Assert.assertArrayEquals(abytes,AutoBuffer.javaSerializeWritePojo(b));
byte [] jsonBytes = a.writeJSON(new AutoBuffer()).buf();
String jsonStr = new String(jsonBytes);
Map<String, Object> m = JSONUtils.parse(jsonStr);
int x = (int)((Double)m.get("x")).doubleValue();
int y = (int)((Double)m.get("y")).doubleValue();
String str = (String) m.get("str");
Assert.assertEquals(12,x);
Assert.assertEquals(345,y);
Assert.assertEquals("6789",str);
// todo readJSON does not work, it is also not used anywehere, we should either fix it or remove it.
// SimpleFreezableTest c = new SimpleFreezableTest().readJSON(new AutoBuffer(jsonBytes));
// byte [] cbytes = AutoBuffer.javaSerializeWritePojo(c);
// Assert.assertArrayEquals(abytes,cbytes);
SimpleFreezableTestChild d = new SimpleFreezableTestChild(12,345,"6789",new int[]{10,20,30,40,50}, new double[]{10.1,10.2,10.3,10.4,10.5});
Assert.assertArrayEquals(AutoBuffer.javaSerializeWritePojo(d),AutoBuffer.javaSerializeWritePojo(new SimpleFreezableTestChild().reloadFromBytes(d.asBytes())));
SimpleFreezableTestChild3 e = new SimpleFreezableTestChild3(12,345,"6789",new int[]{10,20,30,40,50}, new double[]{10.1,10.2,10.3,10.4,10.5});
SimpleFreezableTest e2 = new AutoBuffer(new AutoBuffer().put(e).buf()).get();
Assert.assertArrayEquals(AutoBuffer.javaSerializeWritePojo(e),AutoBuffer.javaSerializeWritePojo(e2));
}
@Test public void testFloatArray() throws Exception {
float[][] tests = {
{ 0, 1, 2 },
{ },
null,
{ 6, -1, 19, -49 },
{ Float.MAX_VALUE, Float.MIN_VALUE}
};
for( float[] exp : tests) {
_floats = exp;
this.write(abw());
this. read(abr());
Assert.assertTrue(Arrays.equals(exp, _floats));
}
}
@Test public void testDoubleArray() throws Exception {
double[][] tests = {
{ 0, 1, 2 },
{ },
null,
{ 6, -1, 19, -49 },
{ Double.MAX_VALUE, Double.MIN_VALUE}
};
for( double[] exp : tests) {
_doubles = exp;
this.write(abw());
this. read(abr());
Assert.assertTrue(Arrays.equals(exp, _doubles));
}
}
@Test public void testLongArrayArray() throws Exception {
long[][][] tests = {
{ { 0, 1, 2 },
{ },
null,
{ 6, -1, 19, -49 },
{ Long.MAX_VALUE, Long.MIN_VALUE}
},
null,
{ },
};
for( long[][] exp : tests) {
_longss = exp;
this.write(abw());
this. read(abr());
if( exp != null ) {
Assert.assertEquals(_longss.length,exp.length);
for( int i=0; i<exp.length; i++ )
Assert.assertArrayEquals(_longss[i],exp[i]);
} else Assert.assertNull(_longss);
}
}
@Test public void testDoubleArrayArray() throws Exception {
double[][][] tests = {
{ { 0.5, 1.5, 2.5 },
{ },
null,
{ 6.3, -1.3, 19.3, -49.4 },
{ Double.MAX_VALUE, Double.MIN_VALUE}
},
null,
{ },
};
for( double[][] exp : tests) {
_doubless = exp;
this.write(abw());
this. read(abr());
if( exp != null ) {
Assert.assertEquals(_doubless.length,exp.length);
for( int i=0; i<exp.length; i++ )
Assert.assertTrue(Arrays.equals(_doubless[i],exp[i]));
} else Assert.assertNull(_doubless);
}
}
private static class IcedSerTest extends Iced {
final double x;
public IcedSerTest(double x){this.x = x;}
}
Freezable [][][] _aaa;
@Test public void testIcedArrays() {
_aaa = new IcedSerTest[][][]{{{new IcedSerTest(Math.PI)}}};
this.write(abw());
this.read(abr());
Assert.assertTrue(_aaa.length == 1);
Assert.assertTrue(_aaa[0].length == 1);
Assert.assertTrue(_aaa[0][0].length == 1);
Assert.assertTrue(((IcedSerTest)_aaa[0][0][0]).x == Math.PI);
_aaa = null;
}
/* =======================
Enum array serialization
======================== */
enum TestEnum {
A, B, C;
}
TestEnum[] _ea;
/** Test for PUBDEV-1914 */
@Test
public void testArrayOfEnums() {
_ea = new TestEnum[] { TestEnum.B, null, TestEnum.A, TestEnum.B, TestEnum.C};
this.write(abw());
_ea = null;
this.read(abr());
Assert.assertTrue(_ea.length == 5);
Assert.assertTrue(Arrays.deepEquals(_ea, new TestEnum[] { TestEnum.B, null, TestEnum.A, TestEnum.B, TestEnum.C}));
_ea = null;
}
/* =======================
Generic type array serialization
======================== */
abstract static class P extends Iced { }
static class P1 extends P {}
static class PA<T extends P> extends Iced<PA> {
public PA(T[] ps) {
_ps = ps;
}
final T[] _ps;
}
PA<P1> _gcs;
// Right now we do not support serialization of generic arrays since
// the weaver forgets type annotation.
@Ignore("PUBDEV-1863")
public void testGenericArray() {
_gcs = new PA(new P1[] { new P1(), null, new P1() });
this.write(abw());
_gcs = null;
this.read(abr());
Assert.assertEquals("Size of array has to match", _gcs._ps.length, 3);
Assert.assertArrayEquals("Content of array has to match", _gcs._ps, new P1[]{new P1(), null, new P1() });
_gcs = null;
}
}