package org.yamcs.yarch.rocksdb; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import org.junit.Test; import org.yamcs.TimeInterval; import org.yamcs.archive.TagReceiver; import org.yamcs.protobuf.Yamcs.ArchiveTag; import org.yamcs.utils.FileUtils; import org.yamcs.yarch.YarchTestCase; public class TagsTest extends YarchTestCase { private ArrayList<ArchiveTag> tags; private RdbTagDb tagDb; @Test public void testTags() throws Exception { final int n=1000; tags=new ArrayList<ArchiveTag>(n+4); String path = "/tmp/test_rdbtags"; FileUtils.deleteRecursively(new File(path).toPath()); tagDb = new RdbTagDb(path); //insert two tags without stop insertTag(ArchiveTag.newBuilder().setName("plusinfinity1").setStart(1000).build()); insertTag(ArchiveTag.newBuilder().setName("plusinfinity2").setStart(2000).build()); for(int i=n;i>0;i--) { insertTag(ArchiveTag.newBuilder().setName("tag"+i).setStart(i*1000).setStop(i*1500).build()); } insertTag(ArchiveTag.newBuilder().setName("minusinfinity1").setStop(1000).build());//n+3 insertTag(ArchiveTag.newBuilder().setName("minusinfinity2").setStop(2000).build());//n+4 Collections.sort(tags, new ArchiveTagComparator()); checkRetrieval(-1, -1); checkRetrieval(-1, n/2); checkRetrieval(n/2,-1); checkRetrieval(n/3,2*n/3); //remove minusinfinity1 ArchiveTag t = tags.get(findId("minusinfinity1")); ArchiveTag rtag=tagDb.deleteTag(t.hasStart()?t.getStart():0, t.getId()); checkTag(tags.get(0), rtag); tags.remove(0); checkRetrieval(-1,1); //remove plusinfinity2 t = tags.get(findId("plusinfinity2")); rtag=tagDb.deleteTag(t.hasStart()?t.getStart():0, t.getId()); checkTag(tags.get(3), rtag); tags.remove(3); checkRetrieval(-1,-1); //remove n/3 from the others for(int i=3;i<3+n/3;i++) { ArchiveTag tag=tags.get(3); rtag=tagDb.deleteTag(tag.hasStart()?tag.getStart():0, tag.getId()); checkTag(tag, rtag); tags.remove(3); } checkRetrieval(-1,-1); //change plusinfinity1 ArchiveTag ntag=ArchiveTag.newBuilder().setName("plusinfinity1changed").setStart(20000).setId(1).build(); ArchiveTag otag=tags.get(findId("plusinfinity1")); rtag=tagDb.updateTag(otag.hasStart()?otag.getStart():0, otag.getId(), ntag); checkTag(ntag,rtag); tags.remove(findId("plusinfinity1")); tags.add(rtag); Collections.sort(tags, new ArchiveTagComparator()); checkRetrieval(-1,-1); //change minusinfinity2 ntag=ArchiveTag.newBuilder().setName("minunsinfinity2changed").setStart(40000).setId(n+4).build(); otag=tags.get(findId("minusinfinity2")); rtag=tagDb.updateTag(otag.hasStart()?otag.getStart():0, otag.getId(), ntag); checkTag(ntag,rtag); tags.remove(findId("minusinfinity2")); tags.add(rtag); Collections.sort(tags, new ArchiveTagComparator()); checkRetrieval(-1,-1); int m=tags.size(); checkRetrieval(-1, m/3); checkRetrieval(m/3,-1); checkRetrieval(m/4,2*m/4); } private int findId(String name){ for(int i=0;i<tags.size();i++) { if(name.equals(tags.get(i).getName())) { return i; } } return -1; } private ArchiveTag insertTag(ArchiveTag tag) throws IOException { ArchiveTag rtag=tagDb.insertTag(tag); checkTag(tag, rtag); assertTrue(rtag.hasId()); tags.add(rtag); assertEquals(tags.size(), rtag.getId()); return rtag; } private void checkRetrieval(int k1, int k2) throws IOException { TimeInterval intv = new TimeInterval(); long start=Long.MIN_VALUE,stop=Long.MAX_VALUE; if(k1!=-1) { start=tags.get(k1).getStart(); intv.setStart(tags.get(k1).getStart()); } if(k2!=-1){ stop=tags.get(k2).getStop(); intv.setStop(tags.get(k2).getStop()); } final long lo = start; final long hi = stop; tagDb.getTags(intv, new TagReceiver() { int i=0; @Override public void onTag(ArchiveTag tag) { while (i<tags.size()) { if(tags.get(i).hasStop() && tags.get(i).getStop()<lo) { i++; continue; } if(tags.get(i).hasStart() && tags.get(i).getStart()>hi) { i++; continue; } break; } assertTrue(tag.hasId()); checkTag(tags.get(i), tag); i++; } @Override public void finished() {} }); } private void checkTag(ArchiveTag tag, ArchiveTag rtag) { if(tag.hasStart()) { assertTrue(rtag.hasStart()); assertEquals(tag.getStart(), rtag.getStart()); } else { assertFalse(rtag.hasStart()); } if(tag.hasStop()) { assertTrue(rtag.hasStop()); assertEquals(tag.getStop(), rtag.getStop()); } else { assertFalse(rtag.hasStop()); } assertEquals(tag.getName(), rtag.getName()); if(tag.hasDescription())assertEquals(tag.getDescription(), rtag.getDescription()); if(tag.hasColor())assertEquals(tag.getColor(), rtag.getColor()); } static class ArchiveTagComparator implements Comparator<ArchiveTag> { @Override public int compare(ArchiveTag t1, ArchiveTag t2) { if(t1.hasStart()) { if(t2.hasStart()){ if(t1.getStart()==t2.getStart()) return Integer.valueOf(t1.getId()).compareTo(t2.getId()); else return Long.valueOf(t1.getStart()).compareTo(t2.getStart()); } else { return 1; } } else if(t2.hasStart()){ return -1; } else { return Integer.valueOf(t1.getId()).compareTo(t2.getId()); } } } }