/*
Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved.
Contact:
SYSTAP, LLC DBA Blazegraph
2501 Calvert ST NW #106
Washington, DC 20008
licenses@blazegraph.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Created on Jan 22, 2008
*/
package com.bigdata.sparse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;
import java.util.Iterator;
import junit.framework.TestCase2;
import com.bigdata.sparse.TPS.TPV;
/**
* Test of {@link TPS} (property timestamp set implementation).
*
* @todo write tests for {@link TPS#iterator()}
*
* @todo write tests for {@link TPS#asMap(long, com.bigdata.sparse.TPS.INameFilter)}
*
* @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a>
* @version $Id$
*/
public class TestTPS extends TestCase2 implements IRowStoreConstants {
/**
*
*/
public TestTPS() {
}
/**
* @param arg0
*/
public TestTPS(String arg0) {
super(arg0);
}
final Schema schema = new Schema("testSchema", "pkey", KeyType.Unicode);
final TPS tps = new TPS(schema,0L/*timestamp*/);
final long t0 = 0L;
final long t1 = 10L;
final long t2 = 20L;
final long t3 = 30L;
final long tmax = Long.MAX_VALUE;
/**
* Test get/set semantics. This tests retrieval of the most current value
* for a property when (a) none was ever bound; (b) it was bound once; (c)
* when it was bound and then rebound using the same timestamp; (d) it was
* bound and then rebound using an earlier timestamp; (e) when it was bound
* and then rebound using a later timestamp; and (d) it was bound and then
* deleted (rebound as null at a later timestamp).
*/
public void test_getSet_neverBound() {
assertEquals("size", 0, tps.size());
// read current value before any value is set.
assertNull(tps.get("foo").getValue());
// read value as of a timestamp when none has been set.
assertEquals(null,tps.get("foo", t1).getValue());
}
public void test_getPrimaryKey() {
// note: null since not bound.
assertEquals(null,tps.getPrimaryKey());
// set the primary key.
tps.set(schema.getPrimaryKeyName(), t1, "ABC");
// note: it is now not bound.
assertEquals("ABC",tps.getPrimaryKey());
}
public void test_getSet_boundOnce() {
assertEquals("size", 0, tps.size());
// read current value before any value is set.
assertNull(tps.get("foo").getValue());
// read value as of a timestamp when none has been set.
assertEquals(null,tps.get("foo", t1).getValue());
// set value as of that timestamp.
tps.set("foo", t1, "bar");
// read value as of that timestamp.
assertEquals("bar",tps.get("foo", t1).getValue());
// read current value.
assertEquals("bar", tps.get("foo").getValue());
}
public void test_getSet_boundReboundSameTimestamp() {
assertEquals("size", 0, tps.size());
// read current value before any value is set.
assertNull(tps.get("foo").getValue());
// read value as of a timestamp when none has been set.
assertEquals(null,tps.get("foo", t1).getValue());
// set value as of that timestamp.
tps.set("foo", t1, "bar");
// read value as of that timestamp.
assertEquals("bar",tps.get("foo", t1).getValue());
// read current value.
assertEquals("bar", tps.get("foo").getValue());
/*
* rebind the value using the same timestamp.
*/
// set value as of that timestamp.
tps.set("foo", t1, "baz");
// read value as of that timestamp.
assertEquals("baz",tps.get("foo", t1).getValue());
// read current value.
assertEquals("baz", tps.get("foo").getValue());
}
public void test_getSet_boundReboundEarlierTimestamp() {
assertEquals("size", 0, tps.size());
// read current value before any value is set.
assertNull(tps.get("foo").getValue());
// read value as of a timestamp when none has been set.
assertEquals(null,tps.get("foo", t2).getValue());
// set value as of that timestamp.
tps.set("foo", t2, "bar");
// read value as of that timestamp.
assertEquals("bar",tps.get("foo", t2).getValue());
// read current value.
assertEquals("bar", tps.get("foo").getValue());
/*
* rebind the value using an earlier timestamp.
*/
// set value as of that timestamp.
tps.set("foo", t1, "baz");
// read value as of that timestamp.
assertEquals("baz",tps.get("foo", t1).getValue());
// read current value.
assertEquals("bar", tps.get("foo").getValue());
// read the value @ t2
assertEquals("bar",tps.get("foo", t2).getValue());
}
public void test_getSet_boundReboundLaterTimestamp() {
assertEquals("size", 0, tps.size());
// read current value before any value is set.
assertNull(tps.get("foo").getValue());
// read value as of a timestamp when none has been set.
assertEquals(null,tps.get("foo", t1).getValue());
// set value as of that timestamp.
tps.set("foo", t1, "bar");
// read value as of that timestamp.
assertEquals("bar",tps.get("foo", t1).getValue());
// read current value.
assertEquals("bar", tps.get("foo").getValue());
/*
* rebind the value using a later timestamp.
*/
// set value as of that timestamp.
tps.set("foo", t2, "baz");
// read value as of that timestamp.
assertEquals("baz",tps.get("foo", t2).getValue());
// read current value.
assertEquals("baz", tps.get("foo").getValue());
// read the previous value.
assertEquals("bar",tps.get("foo", t1).getValue());
}
public void test_getSet_boundDeleted() {
assertEquals("size", 0, tps.size());
// read current value before any value is set.
assertNull(tps.get("foo").getValue());
// read value as of a timestamp when none has been set.
assertEquals(null,tps.get("foo", t1).getValue());
// set value as of that timestamp.
tps.set("foo", t1, "bar");
// read value as of that timestamp.
assertEquals("bar",tps.get("foo", t1).getValue());
// read current value.
assertEquals("bar", tps.get("foo").getValue());
/*
* delete (rebind the value as null using a later timestamp).
*/
// set value as of that timestamp.
tps.set("foo", t2, null);
// read value as of that timestamp.
assertEquals(null,tps.get("foo", t2).getValue());
// read current value.
assertEquals(null, tps.get("foo").getValue());
// read the previous value.
assertEquals("bar",tps.get("foo", t1).getValue());
}
/**
* Tests a series of bindings for one property.
*
* @throws ClassNotFoundException
* @throws IOException
*/
public void test_roundTrip01() throws IOException, ClassNotFoundException {
assertRoundTrip(tps);
tps.set("foo", t1, "bar");
assertRoundTrip(tps);
tps.set("foo", t2, "baz");
assertRoundTrip(tps);
tps.set("foo", t3, null);
assertRoundTrip(tps);
}
/**
* Tests a series of bindings for one property where each binding of the
* property uses a different {@link ValueType}.
*/
public void test_roundTrip02() throws IOException, ClassNotFoundException {
// empty
assertRoundTrip(tps);
// Integer
tps.set("foo", 1L, Integer.valueOf(12));
assertRoundTrip(tps);
// Long
tps.set("foo", 2L, Float.valueOf(12L));
assertRoundTrip(tps);
// Float
tps.set("foo", 3L, Float.valueOf(12.0f));
assertRoundTrip(tps);
// Double
tps.set("foo", 4L, Double.valueOf(12.0d));
assertRoundTrip(tps);
// Unicode
tps.set("foo", 5L, "bar");
assertRoundTrip(tps);
// Date
tps.set("foo", 6L, new Date(System.currentTimeMillis()));
assertRoundTrip(tps);
// byte[].
tps.set("foo", 7L, new byte[]{1,2,3});
assertRoundTrip(tps);
}
/**
* Unit tests for {@link TPS#currentRow(INameFilter)}
*/
public void test_currentRow() {
// verify when all property values pass the filter.
{
final TPS expected = new TPS(schema, 0L/* writeTime */);
expected.set("foo", 1L, "bar");
expected.set("goo", 2L, "baz");
assertEquals(expected, expected.currentRow());
}
// verify when a property value gets filtered out by a later binding.
{
final TPS tmp = new TPS(schema, 0L/* writeTime */);
tmp.set("foo", 1L, "bar"); // will be filtered out.
tmp.set("foo", 2L, "bat");
tmp.set("goo", 2L, "baz");
final TPS expected = new TPS(schema, 0L/* writeTime */);
expected.set("foo", 2L, "bat");
expected.set("goo", 2L, "baz");
assertEquals(expected, tmp.currentRow());
}
/*
* verify when a property is filtered out by name.
*/
{
final TPS tmp = new TPS(schema, 0L/* writeTime */);
tmp.set("foo", 1L, "bar");
tmp.set("foo", 2L, "bat");
tmp.set("goo", 2L, "baz"); // will be filtered out.
final TPS expected = new TPS(schema, 0L/* writeTime */);
expected.set("foo", 2L, "bat");
assertEquals(expected, tmp.currentRow(new SingleColumnFilter("foo")));
}
}
/**
* Unit tests for {@link TPS#filter(long, long, INameFilter)}
*/
public void test_filter() {
// verify when an earlier property value gets filtered out by [fromTime].
{
final TPS tmp = new TPS(schema, 0L/* writeTime */);
tmp.set("foo", 1L, "bar"); // will be filtered out.
tmp.set("foo", 2L, "bat");
tmp.set("goo", 2L, "baz");
final TPS expected = new TPS(schema, 0L/* writeTime */);
expected.set("foo", 2L, "bat");
expected.set("goo", 2L, "baz");
assertEquals(expected, tmp
.filter(2L/* fromTime */, MAX_TIMESTAMP/*toTime*/));
}
/*
* verify when a later property value is filter out because it is GTE
* the [toTime].
*/
{
final TPS tmp = new TPS(schema, 0L/* writeTime */);
tmp.set("foo", 1L, "bar");
tmp.set("foo", 2L, "bat"); // will be filtered out.
tmp.set("goo", 2L, "baz"); // will be filtered out.
final TPS expected = new TPS(schema, 0L/* writeTime */);
expected.set("foo", 1L, "bar");
assertEquals(expected, tmp
.filter(MIN_TIMESTAMP/* fromTime */, 2L/* toTime */));
}
/*
* verify when a property is filtered out by name.
*/
{
final TPS tmp = new TPS(schema, 0L/* writeTime */);
tmp.set("foo", 1L, "bar");
tmp.set("foo", 2L, "bat");
tmp.set("goo", 2L, "baz"); // will be filtered out.
final TPS expected = new TPS(schema, 0L/* writeTime */);
expected.set("foo", 1L, "bar");
expected.set("foo", 2L, "bat");
assertEquals(expected, tmp.filter(new SingleColumnFilter("foo")));
}
}
/**
* Test helper for (de-)serialization tests.
*
* @param expected
*
* @throws IOException
* @throws ClassNotFoundException
*/
protected void assertRoundTrip(TPS expected) throws IOException, ClassNotFoundException {
final byte[] serialized;
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
expected.writeExternal(oos);
oos.flush();
serialized = baos.toByteArray();
}
final TPS actual;
{
actual = new TPS(); // deserialization ctor.
ByteArrayInputStream bais = new ByteArrayInputStream(serialized);
ObjectInputStream ois = new ObjectInputStream(bais);
actual.readExternal(ois);
}
assertEquals(expected,actual);
}
/**
*
*/
protected void assertEquals(TPV expected, TPV actual) {
assertEquals("schema", expected.getSchema(), actual.getSchema());
assertEquals("property", expected.getName(), actual.getName());
assertEquals("timestamp", expected.getTimestamp(), actual.getTimestamp());
if(expected.getValue() instanceof byte[]) {
// Note: case necessary to invoke appropriate comparison method.
assertEquals("value", (byte[]) expected.getValue(), (byte[]) actual
.getValue());
} else {
assertEquals("value", expected.getValue(), actual.getValue());
}
}
protected void assertEquals(String msg,Schema expected, Schema actual) {
assertEquals(msg+".name", expected.getName(),actual.getName());
assertEquals(msg+".primaryKey", expected.getPrimaryKeyName(),actual.getPrimaryKeyName());
assertEquals(msg+".primaryKeyType", expected.getPrimaryKeyType(),actual.getPrimaryKeyType());
}
/**
* Asserts the same schema and the same tuples.
*
* @param expected
* @param actual
*/
protected void assertEquals(TPS expected, TPS actual) {
assertEquals("schema", expected.getSchema(), actual.getSchema());
assertEquals("size", expected.size(), actual.size());
Iterator<ITPV> eitr = expected.iterator();
Iterator<ITPV> aitr = actual.iterator();
while(eitr.hasNext()) {
assertTrue(aitr.hasNext());
assertEquals((TPV)eitr.next(), (TPV)aitr.next());
}
assertFalse(aitr.hasNext());
}
}