/*******************************************************************************
* Copyright (c) 2012-2015 INRIA.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Generoso Pagano - initial API and implementation
******************************************************************************/
package fr.inria.soctrace.test.junit.lib.storage;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import fr.inria.soctrace.lib.model.AnalysisResult;
import fr.inria.soctrace.lib.model.AnalysisResultAnnotationData;
import fr.inria.soctrace.lib.model.AnalysisResultGroupData;
import fr.inria.soctrace.lib.model.AnalysisResultGroupData.DepthFirstIterator;
import fr.inria.soctrace.lib.model.AnalysisResultProcessedTraceData;
import fr.inria.soctrace.lib.model.AnalysisResultSearchData;
import fr.inria.soctrace.lib.model.Annotation;
import fr.inria.soctrace.lib.model.AnnotationParam;
import fr.inria.soctrace.lib.model.AnnotationParamType;
import fr.inria.soctrace.lib.model.AnnotationType;
import fr.inria.soctrace.lib.model.Event;
import fr.inria.soctrace.lib.model.EventParam;
import fr.inria.soctrace.lib.model.EventParamType;
import fr.inria.soctrace.lib.model.EventProducer;
import fr.inria.soctrace.lib.model.EventType;
import fr.inria.soctrace.lib.model.File;
import fr.inria.soctrace.lib.model.Group;
import fr.inria.soctrace.lib.model.Group.LeafMapping;
import fr.inria.soctrace.lib.model.IModelElement;
import fr.inria.soctrace.lib.model.Link;
import fr.inria.soctrace.lib.model.OrderedGroup;
import fr.inria.soctrace.lib.model.State;
import fr.inria.soctrace.lib.model.Tool;
import fr.inria.soctrace.lib.model.Trace;
import fr.inria.soctrace.lib.model.UnorderedGroup;
import fr.inria.soctrace.lib.model.Variable;
import fr.inria.soctrace.lib.model.utils.ModelConstants.EventCategory;
import fr.inria.soctrace.lib.model.utils.SoCTraceException;
import fr.inria.soctrace.lib.query.AnalysisResultAnnotationDataQuery;
import fr.inria.soctrace.lib.query.AnalysisResultGroupDataQuery;
import fr.inria.soctrace.lib.query.AnalysisResultProcessedTraceDataQuery;
import fr.inria.soctrace.lib.query.AnalysisResultQuery;
import fr.inria.soctrace.lib.query.AnalysisResultSearchDataQuery;
import fr.inria.soctrace.lib.query.EventQuery;
import fr.inria.soctrace.lib.query.FileQuery;
import fr.inria.soctrace.lib.storage.DBObject.DBMode;
import fr.inria.soctrace.lib.storage.SystemDBObject;
import fr.inria.soctrace.lib.storage.TraceDBObject;
import fr.inria.soctrace.lib.storage.utils.SQLConstants.FramesocTable;
import fr.inria.soctrace.lib.utils.IdManager;
import fr.inria.soctrace.test.junit.utils.BaseTestClass;
import fr.inria.soctrace.test.junit.utils.IModelFactory;
import fr.inria.soctrace.test.junit.utils.ResourceLoader;
import fr.inria.soctrace.test.junit.utils.TestUtils;
/**
* Test all visitors for Trace DB.
*
* The pattern for each test is:
*
* 0
* - create the elements of the model
*
* 1
* - save them
* - retrieve and check they are OK
*
* 2
* - update them
* - retrieve and check they are OK
*
* 3
* - delete them
* - retrieve and check they are no more there
*
* @author "Generoso Pagano <generoso.pagano@inria.fr>"
*/
public class TraceDBVisitorTest extends BaseTestClass {
private TraceDBObject traceDB;
@Before
public void setUp() throws Exception {
traceDB = new TraceDBObject("TMP_"+TestUtils.getRandomDBName(), DBMode.DB_CREATE);
}
@After
public void tearDown() throws Exception {
traceDB.dropDatabase();
}
@Test
public final void testVisitEvent() throws SoCTraceException {
// 0. create
List<Event> events = IModelFactory.INSTANCE.createEvents(10);
// 1. save and check
saveEvents(events);
Map<Integer, Event> eventMap = new HashMap<Integer, Event>();
for (Event e: events) {
eventMap.put(e.getId(), e);
}
EventQuery query = new EventQuery(traceDB);
List<Event> res = query.getList();
for (Event er: res) {
assertTrue(er.equals(eventMap.get(er.getId())));
}
// 2. update and check
Event first = events.iterator().next();
first.getEventProducer().setLocalId("please");
first.getEventProducer().setName("please");
first.getEventProducer().setParentId(123);
first.getEventProducer().setType("please");
traceDB.update(first.getEventProducer());
first.getType().setName("please");
traceDB.update(first.getType());
int i = 0;
for (EventParamType ept: first.getType().getEventParamTypes()) {
ept.setName("please"+(i++));
ept.setType("please");
traceDB.update(ept);
}
for (Event e: events) {
e.setCpu(123);
e.setPage(123);
e.setTimestamp(123);
traceDB.update(e);
for (EventParam ep: e.getEventParams()) {
ep.setValue("please");
traceDB.update(ep);
}
}
traceDB.flushVisitorBatches();
query.clear();
res = query.getList();
for (Event er: res) {
assertTrue(er.equals(eventMap.get(er.getId())));
}
// 3. delete and check
first = events.iterator().next();
traceDB.delete(first.getEventProducer());
traceDB.delete(first.getType());
for (EventParamType ept: first.getType().getEventParamTypes()) {
traceDB.delete(ept);
}
for (Event e: events) {
traceDB.delete(e);
for (EventParam ep: e.getEventParams()) {
traceDB.delete(ep);
}
}
traceDB.flushVisitorBatches();
assertEquals(0, traceDB.getCount(FramesocTable.EVENT.toString()));
assertEquals(0, traceDB.getCount(FramesocTable.EVENT_TYPE.toString()));
assertEquals(0, traceDB.getCount(FramesocTable.EVENT_PARAM.toString()));
assertEquals(0, traceDB.getCount(FramesocTable.EVENT_PARAM_TYPE.toString()));
assertEquals(0, traceDB.getCount(FramesocTable.EVENT_PRODUCER.toString()));
}
@Test @SuppressWarnings("unchecked")
public final void testVisitAnalysisResultSearch() throws SoCTraceException {
// 0. create
Tool virtualImporter = ResourceLoader.getVirtualImporterTool();
AnalysisResult ar = IModelFactory.INSTANCE.createSearchResult(new IdManager(), "description");
AnalysisResultSearchData data = (AnalysisResultSearchData)ar.getData();
List<Event> events = (List<Event>)(List<?>)data.getElements();
saveEvents(events);
// 1. save and check
traceDB.save(ar);
traceDB.flushVisitorBatches();
AnalysisResultQuery arq = new AnalysisResultQuery(traceDB);
AnalysisResult res = arq.getList().iterator().next();
AnalysisResultSearchDataQuery ardq = new AnalysisResultSearchDataQuery(traceDB);
res.setData(ardq.getAnalysisResultData(res.getId()));
assertTrue(res.equals(ar));
// 2. update and check
ar.setDate(new Timestamp(new Date().getTime()));
ar.setDescription("please");
ar.setTool(virtualImporter);
data.setSearchCommand("please");
traceDB.update(ar);
traceDB.flushVisitorBatches();
res = arq.getList().iterator().next();
res.setData(ardq.getAnalysisResultData(res.getId()));
assertTrue(res.equals(ar));
// 3. delete and check
traceDB.delete(ar);
traceDB.flushVisitorBatches();
assertEquals(0, traceDB.getCount(FramesocTable.ANALYSIS_RESULT.toString()));
assertEquals(0, traceDB.getCount(FramesocTable.SEARCH.toString()));
assertEquals(0, traceDB.getCount(FramesocTable.SEARCH_MAPPING.toString()));
}
/**
* ROOT
* - TYPES
* 1. type1
* 2. type2
* 3. EMPTY
* - EVENTS
* 1. event1
* 2. event2
* 3. EMPTY
*/
@Test
public final void testVisitAnalysisResultGroup() throws SoCTraceException {
// 0. create
Tool virtualImporter = ResourceLoader.getVirtualImporterTool();
AnalysisResult ar = IModelFactory.INSTANCE.createGroupResult(new IdManager(), "description");
AnalysisResultGroupData data = (AnalysisResultGroupData)ar.getData();
UnorderedGroup root = (UnorderedGroup)data.getRoot();
Set<Integer> eventId = new HashSet<Integer>();
Set<Integer> typeId = new HashSet<Integer>();
boolean producerSaved = false;
List<Group> sons = root.getSonGroups();
for (Group son: sons) {
Collection<LeafMapping> leaves = ((OrderedGroup)son).getSonLeaves().values();
for (LeafMapping lm: leaves) {
IModelElement me = (IModelElement) lm.getSon();
if (me instanceof Event) {
Event e = (Event) me;
if (!eventId.contains(e.getId())) {
eventId.add(e.getId());
traceDB.save(e);
if (!producerSaved) {
producerSaved = true;
traceDB.save(e.getEventProducer());
}
for (EventParam ep: e.getEventParams()) {
traceDB.save(ep);
}
}
}
else {
EventType et = (EventType) me;
if (!typeId.contains(et.getId())) {
typeId.add(et.getId());
traceDB.save(et);
for (EventParamType ept: et.getEventParamTypes()) {
traceDB.save(ept);
}
}
}
}
}
traceDB.flushVisitorBatches();
// 1. save and check
traceDB.save(ar);
traceDB.flushVisitorBatches();
AnalysisResultQuery arq = new AnalysisResultQuery(traceDB);
AnalysisResult res = arq.getList().iterator().next();
AnalysisResultGroupDataQuery ardq = new AnalysisResultGroupDataQuery(traceDB);
res.setData(ardq.getAnalysisResultData(res.getId()));
assertTrue(res.equals(ar));
// 2. update and check
ar.setDate(new Timestamp(new Date().getTime()));
ar.setDescription("please");
ar.setTool(virtualImporter);
DepthFirstIterator dit = data.getDepthFirstIterator();
while (dit.hasNext()) {
// group metadata
Group g = dit.next();
g.setName("please");
g.setGroupingOperator("please");
// for ordered group, change the sequence number of leaves
if (g instanceof OrderedGroup) {
OrderedGroup og = (OrderedGroup)g;
Map<Integer, LeafMapping> leaves = og.getSonLeaves();
Iterator<Entry<Integer, LeafMapping>> it = leaves.entrySet().iterator();
Map<Integer, LeafMapping> tmp = new HashMap<Integer, LeafMapping>();
while (it.hasNext()) {
Entry<Integer, LeafMapping> pairs = it.next();
LeafMapping mapping = pairs.getValue();
Integer position = pairs.getKey();
og.getSons().remove(position); // remove also from all sons
it.remove();
tmp.put(position+10, mapping);
}
it = tmp.entrySet().iterator();
while(it.hasNext()) {
Entry<Integer, LeafMapping> pairs = it.next();
LeafMapping mapping = pairs.getValue();
Integer position = pairs.getKey();
og.addSon(mapping.getSon(), position + 10, mapping.getMappingId());
}
}
}
traceDB.update(ar);
traceDB.flushVisitorBatches();
res = arq.getList().iterator().next();
res.setData(ardq.getAnalysisResultData(res.getId()));
assertTrue(res.equals(ar));
// 3. delete and check
traceDB.delete(ar);
traceDB.flushVisitorBatches();
assertEquals(0, traceDB.getCount(FramesocTable.ANALYSIS_RESULT.toString()));
assertEquals(0, traceDB.getCount(FramesocTable.ENTITY_GROUP.toString()));
assertEquals(0, traceDB.getCount(FramesocTable.GROUP_MAPPING.toString()));
}
@Test
public final void testVisitAnalysisResultAnnotation() throws SoCTraceException {
// 0. create
Tool virtualImporter = ResourceLoader.getVirtualImporterTool();
AnalysisResult ar = IModelFactory.INSTANCE.createAnnotationResult(new IdManager(), "description");
AnalysisResultAnnotationData data = (AnalysisResultAnnotationData)ar.getData();
// 1. save and check
traceDB.save(ar);
traceDB.flushVisitorBatches();
AnalysisResultQuery arq = new AnalysisResultQuery(traceDB);
AnalysisResult res = arq.getList().iterator().next();
AnalysisResultAnnotationDataQuery ardq = new AnalysisResultAnnotationDataQuery(traceDB);
res.setData(ardq.getAnalysisResultData(res.getId()));
assertTrue(res.equals(ar));
// 2. update and check
ar.setDate(new Timestamp(new Date().getTime()));
ar.setDescription("please");
ar.setTool(virtualImporter);
Collection<AnnotationType> types = data.getAnnotationTypes();
for (AnnotationType at: types) {
at.setName("please");
int i = 0;
for (AnnotationParamType apt: at.getParamTypes()) {
apt.setName("please"+(i++));
apt.setType("please");
}
}
List<Annotation> annotations = data.getAnnotations();
for (Annotation a: annotations) {
a.setName("please");
for (AnnotationParam ap: a.getParams()) {
ap.setValue("please");
}
}
traceDB.update(ar);
traceDB.flushVisitorBatches();
res = arq.getList().iterator().next();
res.setData(ardq.getAnalysisResultData(res.getId()));
assertTrue(res.equals(ar));
// 3. delete and check
traceDB.delete(ar);
traceDB.flushVisitorBatches();
assertEquals(0, traceDB.getCount(FramesocTable.ANALYSIS_RESULT.toString()));
assertEquals(0, traceDB.getCount(FramesocTable.ANNOTATION.toString()));
assertEquals(0, traceDB.getCount(FramesocTable.ANNOTATION_TYPE.toString()));
assertEquals(0, traceDB.getCount(FramesocTable.ANNOTATION_PARAM.toString()));
assertEquals(0, traceDB.getCount(FramesocTable.ANNOTATION_PARAM_TYPE.toString()));
}
/**
* Note: in this test we save the trace result in a trace DB which
* is actually NOT the one related to the source trace.
* This is done to avoid polluting the real trace DB.
* It has no consequences on the test value since we just want to check
* that the correct values are written and read.
*/
@Test
public final void testVisitAnalysisResultTrace() throws SoCTraceException {
// 0. create
SystemDBObject sysDB = SystemDBObject.openNewInstance();
Tool virtualImporter = ResourceLoader.getVirtualImporterTool();
AnalysisResult ar = IModelFactory.INSTANCE.createTraceResult(new IdManager(), "description");
AnalysisResultProcessedTraceData data = (AnalysisResultProcessedTraceData)ar.getData();
// 1. save and check
traceDB.save(ar);
traceDB.flushVisitorBatches();
AnalysisResultQuery arq = new AnalysisResultQuery(traceDB);
AnalysisResult res = arq.getList().iterator().next();
AnalysisResultProcessedTraceDataQuery ardq = new AnalysisResultProcessedTraceDataQuery(traceDB, sysDB, data.getSourceTrace());
res.setData(ardq.getAnalysisResultData(res.getId()));
assertTrue(res.equals(ar));
// 2. update and check
ar.setDate(new Timestamp(new Date().getTime()));
ar.setDescription("please");
ar.setTool(virtualImporter);
traceDB.update(ar);
traceDB.flushVisitorBatches();
res = arq.getList().iterator().next();
res.setData(ardq.getAnalysisResultData(res.getId()));
assertTrue(res.equals(ar));
// data cannot be changed for processed traces
Trace tmp = data.getProcessedTrace();
data.setProcessedTrace(data.getSourceTrace()); // set dest == source just to test
traceDB.update(ar);
traceDB.flushVisitorBatches();
res = arq.getList().iterator().next();
res.setData(ardq.getAnalysisResultData(res.getId()));
assertTrue(!res.equals(ar));
data.setProcessedTrace(tmp);
// 3. delete and check
traceDB.delete(ar);
traceDB.flushVisitorBatches();
assertEquals(0, traceDB.getCount(FramesocTable.ANALYSIS_RESULT.toString()));
assertEquals(0, traceDB.getCount(FramesocTable.PROCESSED_TRACE.toString()));
}
@Test
public final void testVisitFile() throws SoCTraceException {
// 0. create
File file = new File(0);
file.setDescription("Description");
file.setPath("/my/test/path");
// 1. save and check
traceDB.save(file);
traceDB.flushVisitorBatches();
FileQuery query = new FileQuery(traceDB);
File res = query.getList().iterator().next();
assertTrue(res.equals(file));
// 2. update and check
file.setDescription("please");
file.setPath("please");
traceDB.update(file);
traceDB.flushVisitorBatches();
res = query.getList().iterator().next();
assertTrue(res.equals(file));
// 3. delete and check
traceDB.delete(file);
traceDB.flushVisitorBatches();
assertEquals(0, traceDB.getCount(FramesocTable.EVENT_PARAM_TYPE.toString()));
}
// utilities
/**
* Save the events, the type and the producer
* (same type and producer for all events).
* @throws SoCTraceException
*/
private void saveEvents(List<Event> events) throws SoCTraceException {
Set<Integer> types = new HashSet<Integer>();
Event first = events.iterator().next();
EventProducer prod = first.getEventProducer();
traceDB.save(prod);
for (Event e: events) {
traceDB.save(e);
for (EventParam ep: e.getEventParams()) {
traceDB.save(ep);
}
if (!types.contains(e.getType().getId())) {
types.add(e.getType().getId());
EventType et = e.getType();
traceDB.save(et);
for (EventParamType ept: et.getEventParamTypes()) {
traceDB.save(ept);
}
}
}
traceDB.flushVisitorBatches();
}
@Test
public final void testVisitPajeEvent() throws SoCTraceException {
// 0. create
List<Event> events = IModelFactory.INSTANCE.createCategorizedEvents(3);
// 1. save and check
saveEvents(events);
Map<Integer, Event> eventMap = new HashMap<Integer, Event>();
for (Event e: events) {
eventMap.put(e.getId(), e);
}
EventQuery query = new EventQuery(traceDB);
List<Event> res = query.getList();
for (Event er: res) {
assertTrue(er.equals(eventMap.get(er.getId())));
}
// 2. update and check
// save a new producer first
EventProducer newEp = new EventProducer(666);
traceDB.save(newEp);
Event first = events.iterator().next();
// update producer and type, taking the reference from the first event
first.getEventProducer().setLocalId("please");
first.getEventProducer().setName("please");
first.getEventProducer().setParentId(123);
first.getEventProducer().setType("please");
traceDB.update(first.getEventProducer());
first.getType().setName("please");
traceDB.update(first.getType());
int i = 0;
for (EventParamType ept: first.getType().getEventParamTypes()) {
ept.setName("please"+(i++));
ept.setType("please");
traceDB.update(ept);
}
// update the events
for (Event e: events) {
e.setCpu(123);
e.setPage(123);
e.setTimestamp(123);
switch(e.getCategory()) {
case EventCategory.PUNCTUAL_EVENT:
break;
case EventCategory.LINK:
((Link)e).setEndTimestamp(666);
((Link)e).setEndProducer(newEp); // put the same, since there are no other producers
break;
case EventCategory.STATE:
((State)e).setEndTimestamp(666);
((State)e).setImbricationLevel(666);
break;
case EventCategory.VARIABLE:
((Variable)e).setValue(666);
((Variable)e).setEndTimestamp(666);
break;
}
traceDB.update(e);
for (EventParam ep: e.getEventParams()) {
ep.setValue("please");
traceDB.update(ep);
}
}
traceDB.flushVisitorBatches();
query.clear();
res = query.getList();
for (Event er: res) {
assertTrue(er.equals(eventMap.get(er.getId())));
}
// 3. delete and check
traceDB.delete(newEp);
first = events.iterator().next();
traceDB.delete(first.getEventProducer());
Set<Integer> deletedTypes = new HashSet<Integer>();
for (Event e: events) {
traceDB.delete(e);
for (EventParam ep: e.getEventParams()) {
traceDB.delete(ep);
}
if (!deletedTypes.contains(e.getType().getId())) {
deletedTypes.add(e.getType().getId());
traceDB.delete(e.getType());
for (EventParamType ept: e.getType().getEventParamTypes()) {
traceDB.delete(ept);
}
}
}
traceDB.flushVisitorBatches();
assertEquals(0, traceDB.getCount(FramesocTable.EVENT.toString()));
assertEquals(0, traceDB.getCount(FramesocTable.EVENT_TYPE.toString()));
assertEquals(0, traceDB.getCount(FramesocTable.EVENT_PARAM.toString()));
assertEquals(0, traceDB.getCount(FramesocTable.EVENT_PARAM_TYPE.toString()));
assertEquals(0, traceDB.getCount(FramesocTable.EVENT_PRODUCER.toString()));
}
}