package org.yamcs.yarch;
import static org.junit.Assert.*;
import java.nio.ByteBuffer;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Test;
import org.yamcs.yarch.streamsql.StreamSqlResult;
import org.yamcs.yarch.streamsql.StreamSqlStatement;
public class StreamMergeTest extends YarchTestCase {
StreamSqlStatement statement;
StreamSqlResult res;
String cmd;
private void populate(String tblName, int start, int stop, int step, int apidSeqCount) throws Exception {
ydb.execute("create table "+tblName+"(\"time\" timestamp, apidSeqCount int, packet binary, primary key(\"time\", apidSeqCount))");
ydb.execute("create stream tm_in(\"time\" timestamp, apidSeqCount int, packet binary)");
ydb.execute("insert into "+tblName+" select * from tm_in");
Stream s=ydb.getStream("tm_in");
ByteBuffer bb=ByteBuffer.allocate(2000);
for (int i=start;i<stop;i+=step) {
bb.position(0);
long time=1000*i;
while(bb.remaining()>0) bb.putInt(i);
Tuple t=new Tuple(s.getDefinition(), new Object[]{time, apidSeqCount, bb.array()});
s.emitTuple(t);
}
res=execute("close stream tm_in");
}
private void verify(String streamQuery, final Checker c) throws Exception {
ydb.execute("create stream tm_out as "+streamQuery);
final AtomicInteger ai=new AtomicInteger(0);
final Semaphore semaphore=new Semaphore(0);
Stream s=ydb.getStream("tm_out");
s.addSubscriber(new StreamSubscriber() {
@Override
public void streamClosed(Stream stream) {
semaphore.release();
}
@Override
public void onTuple(Stream stream, Tuple tuple) {
// System.out.println("got tuple: "+tuple);
int i=ai.getAndIncrement();
long time=(Long)tuple.getColumn(0);
int apidSeqCount=(Integer)tuple.getColumn(1);
byte[]b=(byte[]) tuple.getColumn(2);
c.check(i, time, apidSeqCount);
assertEquals(b.length,2000);
ByteBuffer bb=ByteBuffer.wrap(b);
while(bb.remaining()>0) {
int k=bb.getInt();
assertEquals(k, i);
}
}
});
s.start();
semaphore.tryAcquire(30, TimeUnit.SECONDS);
assertEquals(1000, ai.get());
}
@Test
public void testTableMerge0() throws Exception {
populate("tm1",0,1000,1,1000);
verify("merge tm1 using \"time\"",
new Checker() {
@Override
public void check(int i, long time, int apidSeqCount) {
assertEquals(1000*i,time);
assertEquals(1000,apidSeqCount);
}
});
execute("drop table tm1");
}
@Test
public void testTableMerge1() throws Exception {
populate("tm1", 0, 1000, 2, 1000);
populate("tm2", 1, 1000, 4, 2000);
populate("tm3", 3, 1000, 4, 3000);
verify("merge tm1,tm2,tm3 using \"time\"",
new Checker() {
@Override
public void check(int i, long time, int apidSeqCount) {
assertEquals(1000*i,time);
if(i%2==0) {
assertEquals(1000,apidSeqCount);
} else if(i%4==1) {
assertEquals(2000,apidSeqCount);
} else {
assertEquals(3000,apidSeqCount);
}
}
});
execute("drop table tm1");
execute("drop table tm2");
execute("drop table tm3");
}
@Test
public void testTableMerge2() throws Exception {
populate("tm1",0,200,1,1000);
populate("tm2",200,500,1,2000);
populate("tm3",500,1000,1,3000);
verify("merge tm1,tm2,tm3 using \"time\"",
new Checker() {
@Override
public void check(int i, long time, int apidSeqCount) {
assertEquals(1000*i,time);
if(i<200) {
assertEquals(1000,apidSeqCount);
} else if(i<500) {
assertEquals(2000,apidSeqCount);
} else {
assertEquals(3000,apidSeqCount);
}
}
});
execute("drop table tm1");
execute("drop table tm2");
execute("drop table tm3");
}
@Test
public void testTableMerge3() throws Exception {
populate("tm1",0,1000,1,1000);
populate("tm2",0,1000,1,2000);
populate("tm3",0,1000,1,3000);
verify("merge (select * from tm1 where \"time\"<199999+1), (select * from tm2 where \"time\">=200000 and \"time\"<500000), (select * from tm3 where \"time\">=500000) using \"time\"",
new Checker() {
@Override
public void check(int i, long time, int apidSeqCount) {
assertEquals(1000*i,time);
if(i<200) {
assertEquals(1000,apidSeqCount);
} else if(i<500) {
assertEquals(2000,apidSeqCount);
} else {
assertEquals(3000,apidSeqCount);
}
}
});
execute("drop table tm1");
execute("drop table tm2");
execute("drop table tm3");
}
interface Checker {
public void check(int i, long time, int apidSeqCount);
}
}