/**
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 Sep 11, 2010
*/
package com.bigdata.bop.fed;
import java.io.Serializable;
import java.rmi.RemoteException;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
import junit.framework.TestCase2;
import com.bigdata.bop.Constant;
import com.bigdata.bop.IBindingSet;
import com.bigdata.bop.IConstant;
import com.bigdata.bop.PipelineOp;
import com.bigdata.bop.Var;
import com.bigdata.bop.bindingSet.ListBindingSet;
import com.bigdata.bop.engine.IChunkMessage;
import com.bigdata.bop.engine.IHaltOpMessage;
import com.bigdata.bop.engine.IQueryClient;
import com.bigdata.bop.engine.IQueryDecl;
import com.bigdata.bop.engine.IQueryPeer;
import com.bigdata.bop.engine.IStartOpMessage;
import com.bigdata.io.SerializerUtil;
import com.bigdata.rdf.internal.IV;
import com.bigdata.rdf.internal.IVCache;
import com.bigdata.rdf.internal.VTE;
import com.bigdata.rdf.internal.impl.TermId;
import com.bigdata.rdf.model.BigdataLiteral;
import com.bigdata.rdf.model.BigdataValueFactory;
import com.bigdata.rdf.model.BigdataValueFactoryImpl;
import com.bigdata.striterator.Dechunkerator;
/**
* Unit tests for {@link ThickChunkMessage}.
*
* @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a>
*/
public class TestThickChunkMessage extends TestCase2 {
/**
*
*/
public TestThickChunkMessage() {
}
/**
* @param name
*/
public TestThickChunkMessage(String name) {
super(name);
}
private String namespace;
private BigdataValueFactory valueFactory;
private long nextId = 1;
@Override
protected void setUp() throws Exception {
super.setUp();
this.namespace = getName();
this.valueFactory = BigdataValueFactoryImpl.getInstance(namespace);
}
@Override
protected void tearDown() throws Exception {
this.namespace = null;
this.valueFactory.remove();
super.tearDown();
}
/**
* Create an {@link IV} for a {@link BigdataLiteral}, set the
* {@link IVCache} association, and wrap it as an {@link IConstant}.
*
* @param s
* The literal value.
*
* @return The {@link IConstant}.
*/
private IConstant<IV<?, ?>> makeLiteral(final String s) {
final BigdataLiteral value = valueFactory.createLiteral(s);
final TermId<BigdataLiteral> termId = new TermId<BigdataLiteral>(
VTE.LITERAL, nextId++);
termId.setValue(value);
return new Constant<IV<?, ?>>(termId);
}
/**
* Correct rejection test for an empty chunk (no solutions, not even an
* empty solution).
*/
public void test_emptyChunk() {
final IQueryClient queryController = new MockQueryController();
final UUID queryId = UUID.randomUUID();
final int bopId = 1;
final int partitionId = 2;
final IBindingSet[] source = new IBindingSet[]{};
// build the chunk.
try {
new ThickChunkMessage<IBindingSet>(queryController, queryId, bopId,
partitionId, source);
fail("Expecting: " + IllegalArgumentException.class);
} catch (IllegalArgumentException ex) {
if (log.isInfoEnabled())
log.info("Ignoring expected exception: " + ex);
}
}
/**
* Unit test for a message with a single chunk containing a single empty
* binding set.
*/
public void test_oneChunkWithEmptyBindingSet() {
final List<IBindingSet> data = new LinkedList<IBindingSet>();
{
data.add(new ListBindingSet());
}
final IQueryClient queryController = new MockQueryController();
final UUID queryId = UUID.randomUUID();
final int bopId = 1;
final int partitionId = 2;
final IBindingSet[] source = data.toArray(new IBindingSet[0]);
// build the chunk.
final IChunkMessage<IBindingSet> msg1 = new ThickChunkMessage<IBindingSet>(
queryController, queryId, bopId, partitionId, source);
// same reference.
assertTrue(queryController == msg1.getQueryController());
// encode/decode.
final IChunkMessage<IBindingSet> msg = (IChunkMessage<IBindingSet>) SerializerUtil
.deserialize(SerializerUtil.serialize(msg1));
// equals()
assertEquals(queryController, msg.getQueryController());
assertEquals(queryId, msg.getQueryId());
assertEquals(bopId, msg.getBOpId());
assertEquals(partitionId, msg.getPartitionId());
// the data is inline with the message.
assertTrue(msg.isMaterialized());
// verify the iterator.
assertSameIterator(data.toArray(new IBindingSet[0]),
new Dechunkerator<IBindingSet>(msg.getChunkAccessor()
.iterator()));
}
/**
* Unit test for a message with a single chunk of binding sets.
*/
public void test_oneChunk() {
final Var<?> x = Var.var("x");
final Var<?> y = Var.var("y");
final List<IBindingSet> data = new LinkedList<IBindingSet>();
{
IBindingSet bset = null;
{
bset = new ListBindingSet();
bset.set(x, makeLiteral("John"));
bset.set(y, makeLiteral("Mary"));
data.add(bset);
}
{
bset = new ListBindingSet();
bset.set(x, makeLiteral("Mary"));
bset.set(y, makeLiteral("Paul"));
data.add(bset);
}
{
bset = new ListBindingSet();
bset.set(x, makeLiteral("Mary"));
bset.set(y, makeLiteral("Jane"));
data.add(bset);
}
{
bset = new ListBindingSet();
bset.set(x, makeLiteral("Paul"));
bset.set(y, makeLiteral("Leon"));
data.add(bset);
}
{
bset = new ListBindingSet();
bset.set(x, makeLiteral("Paul"));
bset.set(y, makeLiteral("John"));
data.add(bset);
}
{
bset = new ListBindingSet();
bset.set(x, makeLiteral("Leon"));
bset.set(y, makeLiteral("Paul"));
data.add(bset);
}
}
final IQueryClient queryController = new MockQueryController();
final UUID queryId = UUID.randomUUID();
final int bopId = 1;
final int partitionId = 2;
//
final IBindingSet[] source = data.toArray(new IBindingSet[0]);
// build the chunk.
final IChunkMessage<IBindingSet> msg1 = new ThickChunkMessage<IBindingSet>(
queryController, queryId, bopId, partitionId, source);
// same reference.
assertTrue(queryController == msg1.getQueryController());
// encode/decode.
final IChunkMessage<IBindingSet> msg = (IChunkMessage<IBindingSet>) SerializerUtil
.deserialize(SerializerUtil.serialize(msg1));
// equals()
assertEquals(queryController, msg.getQueryController());
assertEquals(queryId, msg.getQueryId());
assertEquals(bopId, msg.getBOpId());
assertEquals(partitionId, msg.getPartitionId());
// the data is inline with the message.
assertTrue(msg.isMaterialized());
assertSameIterator(data.toArray(new IBindingSet[0]),
new Dechunkerator<IBindingSet>(msg.getChunkAccessor()
.iterator()));
}
/**
* Mock object.
* <p>
* Note: This needs to be serializable since we are sending the proxy with
* the {@link IChunkMessage}. There is an issue open to change that. See
* {@link IChunkMessage#getQueryController()}.
*/
private static class MockQueryController implements IQueryClient,
Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
final private UUID serviceId = UUID.randomUUID();
@Override
public void haltOp(IHaltOpMessage msg) throws RemoteException {
}
@Override
public void startOp(IStartOpMessage msg) throws RemoteException {
}
@Override
public void bufferReady(IChunkMessage<IBindingSet> msg)
throws RemoteException {
}
@Override
public void declareQuery(IQueryDecl queryDecl) {
}
@Override
public UUID getServiceUUID() throws RemoteException {
return serviceId;
}
@Override
public PipelineOp getQuery(UUID queryId)
throws RemoteException {
return null;
}
@Override
public void cancelQuery(UUID queryId, Throwable cause)
throws RemoteException {
}
@Override
public UUID[] getRunningQueries() {
return null;
}
/**
* Note: Assume equal as long as same class. This is used by the code
* which tests the serialization of the {@link ThickChunkMessage}. In a
* real federation, the query controller is a proxy. But also see
* {@link IChunkMessage#getQueryController()}, which is an issue to
* remove the {@link IQueryPeer} proxy from the {@link IChunkMessage}.
*/
@Override
public boolean equals(Object o) {
final MockQueryController x = (MockQueryController) o;
return true;
}
}
}