/*******************************************************************************
* 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.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import fr.inria.soctrace.lib.model.Tool;
import fr.inria.soctrace.lib.model.Trace;
import fr.inria.soctrace.lib.model.TraceParam;
import fr.inria.soctrace.lib.model.TraceParamType;
import fr.inria.soctrace.lib.model.TraceType;
import fr.inria.soctrace.lib.model.utils.SoCTraceException;
import fr.inria.soctrace.lib.model.utils.ModelConstants.TimeUnit;
import fr.inria.soctrace.lib.query.ToolQuery;
import fr.inria.soctrace.lib.query.TraceQuery;
import fr.inria.soctrace.lib.storage.DBObject.DBMode;
import fr.inria.soctrace.lib.storage.SystemDBObject;
import fr.inria.soctrace.lib.storage.utils.SQLConstants.FramesocTable;
import fr.inria.soctrace.test.junit.utils.IModelFactory;
import fr.inria.soctrace.test.junit.utils.TestUtils;
/**
* Test all visitors for System 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 SystemDBVisitorTest {
private SystemDBObject sysDB;
@Before
public void setUp() throws Exception {
sysDB = new SystemDBObject("TMP_"+TestUtils.getRandomDBName(), DBMode.DB_CREATE);
}
@After
public void tearDown() throws Exception {
sysDB.dropDatabase();
}
@Test
public final void testVisitTrace() throws SoCTraceException {
// 0. create
List<Trace> traces = IModelFactory.INSTANCE.createTraces(10);
// 1. save and check
TraceType tt = traces.iterator().next().getType();
sysDB.save(tt);
for (TraceParamType tpt: tt.getTraceParamTypes()) {
sysDB.save(tpt);
}
Map<Integer, Trace> traceMap = new HashMap<Integer, Trace>();
for (Trace t: traces) {
traceMap.put(t.getId(), t);
sysDB.save(t);
for (TraceParam tp: t.getParams()) {
sysDB.save(tp);
}
}
sysDB.flushVisitorBatches();
TraceQuery query = new TraceQuery(sysDB);
List<Trace> res = query.getList();
assertEquals(traces.size(), res.size());
for (Trace tr: res) {
assertTrue(tr.equals(traceMap.get(tr.getId())));
}
// 2. update and check
Trace first = traces.iterator().next();
first.getType().setName("please");
sysDB.update(first.getType());
int i = 0;
for (TraceParamType tpt: first.getType().getTraceParamTypes()) {
tpt.setName("please"+(i++));
tpt.setType("please");
sysDB.update(tpt);
}
for (Trace t: traces) {
t.setAlias("please");
t.setTimeUnit(TimeUnit.MILLISECONDS.getInt());
t.setBoard("please");
t.setDbName("please");
t.setDescription("please");
t.setNumberOfCpus(123);
t.setNumberOfEvents(123123);
t.setMinTimestamp(123456789);
t.setMaxTimestamp(987654321);
t.setOperatingSystem("please");
t.setOutputDevice("please");
t.setProcessed(true);
t.setTracedApplication("please");
t.setTracingDate(new Timestamp(new Date().getTime()));
t.setNumberOfProducers(123);
sysDB.update(t);
for (TraceParam tp: t.getParams()) {
tp.setValue("please");
sysDB.update(tp);
}
}
sysDB.flushVisitorBatches();
query.clear();
res = query.getList();
for (Trace tr: res) {
assertTrue(tr.equals(traceMap.get(tr.getId())));
}
// 3. delete and check
first = traces.iterator().next();
sysDB.delete(first.getType());
for (TraceParamType tpt: first.getType().getTraceParamTypes()) {
sysDB.delete(tpt);
}
for (Trace t: traces) {
sysDB.delete(t);
for (TraceParam tp: t.getParams()) {
sysDB.delete(tp);
}
}
sysDB.flushVisitorBatches();
assertEquals(0, sysDB.getCount(FramesocTable.TRACE.toString()));
assertEquals(0, sysDB.getCount(FramesocTable.TRACE_TYPE.toString()));
assertEquals(0, sysDB.getCount(FramesocTable.TRACE_PARAM.toString()));
assertEquals(0, sysDB.getCount(FramesocTable.TRACE_PARAM_TYPE.toString()));
}
/**
* Bug scenario.
*
* The TraceType object created and the TraceType object
* in the db cache are different objects even if with the same
* values.
*
* Adding in cache at save operation solves the issue.
*
* Investigate:
* without adding to cache at save, the type in the trace
* object and the type in the trace param type are different
* (only the second is the updated one).
*
*
* @throws SoCTraceException
*/
@Ignore
public final void testVisitTraceSimple() throws SoCTraceException {
// 0. create
Trace trace = IModelFactory.INSTANCE.createTrace();
// 1. save and check
TraceType tt = trace.getType();
System.out.println("created");
System.out.println(System.identityHashCode(tt));
sysDB.save(tt);
for (TraceParamType tpt: tt.getTraceParamTypes()) {
sysDB.save(tpt);
}
sysDB.save(trace);
for (TraceParam tp: trace.getParams()) {
sysDB.save(tp);
}
sysDB.flushVisitorBatches();
TraceQuery query = new TraceQuery(sysDB);
/**
* Commenting the following 2 lines does not work
* if the cache is not written at save operation!
*
* In fact, if save() does not write the cache and
* update() writes the cache:
* - created event type is not in the cache, since never updated()
* so the cache will contain a newly created event type object
* - when the cache is loaded, a new event param type object is written
* inside, but the update() operation write a new event param type object
* in the cache (the one created at the beginning of this test program)
* - so the next query will find in the cache:
* - a new event type (created at cache loading)
* - the old event param type (written in the cache at update)
* - the assert true at the end will fail because the event type reachable
* by the trace object (the one created at cache loading) contains
*/
// *************** LINES COMMENTED ***************
//trace.getType().setName("please");
//sysDB.update(trace.getType());
// *************** LINES COMMENTED ***************
int i = 0;
for (TraceParamType tpt: tt.getTraceParamTypes()) {
tpt.setName("please"+(i++));
tpt.setType("please");
sysDB.update(tpt);
/* this update load the OLD values from the cache
* and after, only the new tpt is written in the cache.
* So the cache is inconsistent:
* - the tt in cache points to the old tpt
* - the tpt in cache is the new one!
*/
}
sysDB.flushVisitorBatches();
TraceType ttt = sysDB.getTraceTypeCache().get(TraceType.class, 0);
System.out.println("cached");
System.out.println(System.identityHashCode(ttt));
query.clear();
Trace res = query.getList().iterator().next();
System.out.println("trace after query: different types referred");
System.out.println("via the trace: ");
System.out.println(System.identityHashCode(res.getType()));
System.out.println("via the param: ");
System.out.println(System.identityHashCode(res.getParams().iterator().next().getTraceParamType().getTraceType()));
/**
* If the above two lines are commented and the cache is not
* written at save operation:
* - res contains old param types
* - trace contains new param types
*/
assertTrue(res.equals(trace));
}
@Test
public final void testVisitTool() throws SoCTraceException {
// 0. create
Tool tool = IModelFactory.INSTANCE.createAnalysisTool();
// 1. save and check
sysDB.save(tool);
sysDB.flushVisitorBatches();
ToolQuery query = new ToolQuery(sysDB);
Tool res = query.getList().iterator().next();
assertTrue(res.equals(tool));
// 2. update and check
tool.setCommand("please");
tool.setDoc("please");
tool.setName("please");
tool.setPlugin(false);
tool.setType("please");
sysDB.update(tool);
sysDB.flushVisitorBatches();
res = query.getList().iterator().next();
assertTrue(res.equals(tool));
// 3. delete and check
sysDB.delete(tool);
sysDB.flushVisitorBatches();
assertEquals(0, sysDB.getCount(FramesocTable.TOOL.toString()));
}
}