83c60c0807d4f20ca34e116870ef63c6f6e7bf0b
[deliverable/tracecompass.git] / statesystem / org.eclipse.tracecompass.statesystem.core.tests / src / org / eclipse / tracecompass / statesystem / core / tests / backend / StateHistoryBackendTestBase.java
1 /*******************************************************************************
2 * Copyright (c) 2016 Ericsson, EfficiOS Inc. and others
3 *
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 *******************************************************************************/
9
10 package org.eclipse.tracecompass.statesystem.core.tests.backend;
11
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertTrue;
14 import static org.junit.Assert.fail;
15
16 import java.io.IOException;
17 import java.util.ArrayList;
18 import java.util.List;
19
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;
27
28 /**
29 * Abstract class to test implementations of the {@link IStateHistoryBackend} interface.
30 *
31 * @author Patrick Tasse
32 * @author Alexandre Montplaisir
33 */
34 public abstract class StateHistoryBackendTestBase {
35
36 /**
37 * Gets the backend to be used for building.
38 *
39 * @param startTime
40 * The start time of the history
41 *
42 * @return The backend to be used for building.
43 * @throws IOException
44 * if an exception occurs
45 */
46 protected abstract IStateHistoryBackend getBackendForBuilding(long startTime) throws IOException;
47
48 /**
49 * Gets the backend to be used for querying. The default implementation
50 * returns the backend that was used for building.
51 * <p>
52 * Only the returned backend should be used after calling this method. The
53 * one sent in parameter might have been disposed.
54 *
55 * @param backend
56 * The backend that was used for building
57 * @return The backend to be used for querying.
58 * @throws IOException
59 * if an exception occurs
60 */
61 @SuppressWarnings("unused")
62 protected IStateHistoryBackend getBackendForQuerying(IStateHistoryBackend backend) throws IOException {
63 return backend;
64 }
65
66 /**
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.
69 *
70 * @param startTime
71 * The start time of the history
72 * @param endTime
73 * The end time at which to close the history
74 * @param intervals
75 * The intervals to insert in the history backend
76 * @return The backend to be used for querying.
77 */
78 protected final IStateHistoryBackend prepareBackend(long startTime, long endTime,
79 List<ITmfStateInterval> intervals) {
80
81 try {
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) {
87 fail(e.getMessage());
88 return null;
89 }
90 }
91
92 /**
93 * Insert the specified intervals in the provided backend.
94 *
95 * @param backend
96 * The backend to be used
97 * @param intervals
98 * The intervals to insert in the history backend
99 */
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());
103 }
104 }
105
106 /**
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.
111 * <p>
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.
115 *
116 * @param startTime
117 * The start time of the history
118 * @param endTime
119 * The end time of the history
120 * @param nbAttr
121 * The number of attributes
122 * @param intervals
123 * The list of intervals to insert
124 * @param allowNull
125 * True if null intervals are allowed, false otherwise
126 * @return The backend to be used for querying.
127 */
128 protected final IStateHistoryBackend buildAndQueryFullRange(long startTime, long endTime, int nbAttr, List<ITmfStateInterval> intervals, boolean allowNull) {
129
130 final IStateHistoryBackend backend = prepareBackend(startTime, endTime, intervals);
131
132 try {
133 /*
134 * Query at every valid time stamp, making sure only the expected
135 * intervals are returned.
136 */
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++) {
140 stateInfo.add(null);
141 }
142 backend.doQuery(stateInfo, t);
143 for (int attr = 0; attr < stateInfo.size(); attr++) {
144 ITmfStateInterval interval = stateInfo.get(attr);
145 if (!allowNull) {
146 assertTrue("null interval at t=" + t + " for attr=" + attr, interval != null);
147 }
148 if (interval != null) {
149 assertTrue(interval + " does not intersect t=" + t, interval.intersects(t));
150 }
151 }
152 }
153
154 assertEquals(startTime, backend.getStartTime());
155 assertEquals(endTime, backend.getEndTime());
156 } catch (StateSystemDisposedException e) {
157 fail(e.getMessage());
158 return null;
159 }
160 return backend;
161 }
162
163 /**
164 * Test the full query method by filling a small backend with intervals
165 * placed in a "stair-like" fashion, like this:
166 *
167 * <pre>
168 * |x----x----x---x|
169 * |xx----x----x--x|
170 * |x-x----x----x-x|
171 * |x--x----x----xx|
172 * | ... |
173 * </pre>
174 *
175 * and then querying at every single timestamp, making sure all, and only,
176 * the expected intervals are returned.
177 */
178 @Test
179 public void testCascadingIntervals() {
180 final int nbAttr = 10;
181 final long duration = 10;
182 final long startTime = 0;
183 final long endTime = 1000;
184
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),
190 (int) t % nbAttr,
191 TmfStateValue.newValueLong(t)));
192 }
193
194 buildAndQueryFullRange(startTime, endTime, nbAttr, intervals, false);
195 }
196
197 /**
198 * Test the full query method by filling a small backend with intervals that
199 * take the full time range, like this:
200 *
201 * <pre>
202 * |x-------------x|
203 * |x-------------x|
204 * |x-------------x|
205 * |x-------------x|
206 * | ... |
207 * </pre>
208 *
209 * and then querying at every single timestamp, making sure all, and only,
210 * the expected intervals are returned.
211 */
212 @Test
213 public void testFullIntervals() {
214 final int nbAttr = 1000;
215 final long startTime = 0;
216 final long endTime = 1000;
217
218 List<ITmfStateInterval> intervals = new ArrayList<>();
219 for (int attr = 0; attr < nbAttr; attr++) {
220 intervals.add(new TmfStateInterval(
221 startTime,
222 endTime,
223 attr,
224 TmfStateValue.newValueLong(attr)));
225 }
226
227 buildAndQueryFullRange(startTime, endTime, nbAttr, intervals, false);
228 }
229 }
This page took 0.037447 seconds and 5 git commands to generate.