1 /*******************************************************************************
2 * Copyright (c) 2016 Ericsson, EfficiOS Inc. and others
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.statesystem
.core
.tests
.backend
;
12 import static org
.junit
.Assert
.assertEquals
;
13 import static org
.junit
.Assert
.assertTrue
;
14 import static org
.junit
.Assert
.fail
;
16 import java
.io
.IOException
;
17 import java
.util
.ArrayList
;
18 import java
.util
.List
;
20 import org
.eclipse
.jdt
.annotation
.Nullable
;
21 import org
.eclipse
.tracecompass
.statesystem
.core
.backend
.IStateHistoryBackend
;
22 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.StateSystemDisposedException
;
23 import org
.eclipse
.tracecompass
.statesystem
.core
.interval
.ITmfStateInterval
;
24 import org
.eclipse
.tracecompass
.statesystem
.core
.interval
.TmfStateInterval
;
25 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.TmfStateValue
;
26 import org
.junit
.Test
;
29 * Abstract class to test implementations of the {@link IStateHistoryBackend} interface.
31 * @author Patrick Tasse
32 * @author Alexandre Montplaisir
34 public abstract class StateHistoryBackendTestBase
{
37 * Gets the backend to be used for building.
40 * The start time of the history
42 * @return The backend to be used for building.
44 * if an exception occurs
46 protected abstract IStateHistoryBackend
getBackendForBuilding(long startTime
) throws IOException
;
49 * Gets the backend to be used for querying. The default implementation
50 * returns the backend that was used for building.
52 * Only the returned backend should be used after calling this method. The
53 * one sent in parameter might have been disposed.
56 * The backend that was used for building
57 * @return The backend to be used for querying.
59 * if an exception occurs
61 @SuppressWarnings("unused")
62 protected IStateHistoryBackend
getBackendForQuerying(IStateHistoryBackend backend
) throws IOException
{
67 * Prepares a backend to be used in tests. The specified intervals will be
68 * inserted in the backend, and then the backend will be closed.
71 * The start time of the history
73 * The end time at which to close the history
75 * The intervals to insert in the history backend
76 * @return The backend to be used for querying.
78 protected final IStateHistoryBackend
prepareBackend(long startTime
, long endTime
,
79 List
<ITmfStateInterval
> intervals
) {
82 IStateHistoryBackend backend
= getBackendForBuilding(startTime
);
83 insertIntervals(backend
, intervals
);
84 backend
.finishedBuilding(Math
.max(endTime
, backend
.getEndTime()));
85 return getBackendForQuerying(backend
);
86 } catch (IOException e
) {
93 * Insert the specified intervals in the provided backend.
96 * The backend to be used
98 * The intervals to insert in the history backend
100 protected static void insertIntervals(IStateHistoryBackend backend
, List
<ITmfStateInterval
> intervals
) {
101 for (ITmfStateInterval interval
: intervals
) {
102 backend
.insertPastState(interval
.getStartTime(), interval
.getEndTime(), interval
.getAttribute(), interval
.getStateValue());
107 * Test the integrity of a backend by first building the backend with the
108 * specified intervals, closing it, and then querying at every single
109 * timestamp, making sure that all returned intervals intersect with the
110 * query time. The backend start and end time will be checked.
112 * If <code>allowNull</code> is false, the specified intervals must cover
113 * the full range for all attributes. The method will make sure that no null
114 * intervals are returned.
117 * The start time of the history
119 * The end time of the history
121 * The number of attributes
123 * The list of intervals to insert
125 * True if null intervals are allowed, false otherwise
126 * @return The backend to be used for querying.
128 protected final IStateHistoryBackend
buildAndQueryFullRange(long startTime
, long endTime
, int nbAttr
, List
<ITmfStateInterval
> intervals
, boolean allowNull
) {
130 final IStateHistoryBackend backend
= prepareBackend(startTime
, endTime
, intervals
);
134 * Query at every valid time stamp, making sure only the expected
135 * intervals are returned.
137 for (long t
= backend
.getStartTime(); t
<= backend
.getEndTime(); t
++) {
138 List
<@Nullable ITmfStateInterval
> stateInfo
= new ArrayList
<>(nbAttr
);
139 for (int i
= 0; i
< nbAttr
; i
++) {
142 backend
.doQuery(stateInfo
, t
);
143 for (int attr
= 0; attr
< stateInfo
.size(); attr
++) {
144 ITmfStateInterval interval
= stateInfo
.get(attr
);
146 assertTrue("null interval at t=" + t
+ " for attr=" + attr
, interval
!= null);
148 if (interval
!= null) {
149 assertTrue(interval
+ " does not intersect t=" + t
, interval
.intersects(t
));
154 assertEquals(startTime
, backend
.getStartTime());
155 assertEquals(endTime
, backend
.getEndTime());
156 } catch (StateSystemDisposedException e
) {
157 fail(e
.getMessage());
164 * Test the full query method by filling a small backend with intervals
165 * placed in a "stair-like" fashion, like this:
175 * and then querying at every single timestamp, making sure all, and only,
176 * the expected intervals are returned.
179 public void testCascadingIntervals() {
180 final int nbAttr
= 10;
181 final long duration
= 10;
182 final long startTime
= 0;
183 final long endTime
= 1000;
185 List
<ITmfStateInterval
> intervals
= new ArrayList
<>();
186 for (long t
= startTime
+ 1; t
<= endTime
+ duration
; t
++) {
187 intervals
.add(new TmfStateInterval(
188 Math
.max(startTime
, t
- duration
),
189 Math
.min(endTime
, t
- 1),
191 TmfStateValue
.newValueLong(t
)));
194 buildAndQueryFullRange(startTime
, endTime
, nbAttr
, intervals
, false);
198 * Test the full query method by filling a small backend with intervals that
199 * take the full time range, like this:
209 * and then querying at every single timestamp, making sure all, and only,
210 * the expected intervals are returned.
213 public void testFullIntervals() {
214 final int nbAttr
= 1000;
215 final long startTime
= 0;
216 final long endTime
= 1000;
218 List
<ITmfStateInterval
> intervals
= new ArrayList
<>();
219 for (int attr
= 0; attr
< nbAttr
; attr
++) {
220 intervals
.add(new TmfStateInterval(
224 TmfStateValue
.newValueLong(attr
)));
227 buildAndQueryFullRange(startTime
, endTime
, nbAttr
, intervals
, false);