49354ea7db5d3c247b20fc18691ac5e4af9ae9c9
[deliverable/tracecompass.git] / statesystem / org.eclipse.tracecompass.statesystem.core.tests / stubs / org / eclipse / tracecompass / statesystem / core / tests / stubs / backend / HistoryTreeClassicStub.java
1 /*******************************************************************************
2 * Copyright (c) 2015 École Polytechnique de Montréal
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.stubs.backend;
11
12 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
13 import static org.junit.Assert.assertEquals;
14 import static org.junit.Assert.assertTrue;
15 import static org.junit.Assert.fail;
16
17 import java.io.File;
18 import java.io.IOException;
19 import java.io.PrintWriter;
20 import java.nio.channels.ClosedChannelException;
21 import java.util.List;
22
23 import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.CoreNode;
24 import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTConfig;
25 import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTNode;
26 import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HistoryTreeClassic;
27 import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.IHistoryTree;
28
29 import com.google.common.collect.Iterables;
30
31 /**
32 * Stub class to unit test the history tree. You can set the size of the
33 * interval section before using the tree, in order to fine-tune the test.
34 *
35 * Note to developers: This tree is not meant to be used with a backend. It just
36 * exposes some info from the history tree.
37 *
38 * @author Geneviève Bastien
39 */
40 public class HistoryTreeClassicStub extends HistoryTreeClassic {
41
42 /**
43 * Minimum size a block of this tree should have
44 */
45 public static final int MINIMUM_BLOCK_SIZE = IHistoryTree.TREE_HEADER_SIZE;
46
47 /**
48 * Constructor for this history tree stub
49 *
50 * @param conf
51 * The config to use for this History Tree.
52 * @throws IOException
53 * If an error happens trying to open/write to the file
54 * specified in the config
55 */
56 public HistoryTreeClassicStub(HTConfig conf) throws IOException {
57 super(conf);
58 }
59
60 /**
61 * "Reader" constructor : instantiate a SHTree from an existing tree file on
62 * disk
63 *
64 * @param existingStateFile
65 * Path/filename of the history-file we are to open
66 * @param expProviderVersion
67 * The expected version of the state provider
68 * @throws IOException
69 * If an error happens reading the file
70 */
71 public HistoryTreeClassicStub(File existingStateFile, int expProviderVersion) throws IOException {
72 super(existingStateFile, expProviderVersion);
73 }
74
75 // ------------------------------------------------------------------------
76 // Extra test accessors
77 // ------------------------------------------------------------------------
78
79 @Override
80 public List<HTNode> getLatestBranch() {
81 /* Super method is not public */
82 return checkNotNull(super.getLatestBranch());
83 }
84
85 /**
86 * Get the latest leaf of the tree
87 *
88 * @return The current leaf node of the tree
89 */
90 public HTNode getLatestLeaf() {
91 List<HTNode> latest = getLatestBranch();
92 return Iterables.getLast(latest);
93 }
94
95 /**
96 * Get the node from the latest branch at a given position, 0 being the root
97 * and <size of latest branch - 1> being a leaf node.
98 *
99 * @param pos
100 * The position at which to return the node
101 * @return The node at position pos
102 */
103 public HTNode getNodeAt(int pos) {
104 List<HTNode> latest = getLatestBranch();
105 return latest.get(pos);
106 }
107
108 /**
109 * Get the depth of the tree
110 *
111 * @return The depth of the tree
112 */
113 public int getDepth() {
114 return getLatestBranch().size();
115 }
116
117 // ------------------------------------------------------------------------
118 // Debug printing methods
119 // ------------------------------------------------------------------------
120
121 /**
122 * Print out the full tree for debugging purposes
123 *
124 * @param writer
125 * PrintWriter in which to write the output
126 * @param printIntervals
127 * Flag to enable full output of the interval information
128 * @param ts
129 * The timestamp that nodes have to intersect for intervals to be
130 * printed. A negative value will print intervals for all nodes.
131 * The timestamp only applies if printIntervals is true.
132 */
133 public void debugPrintFullTree(PrintWriter writer, boolean printIntervals, long ts) {
134 preOrderPrint(writer, false, getLatestBranch().get(0), 0, ts);
135
136 if (printIntervals) {
137 preOrderPrint(writer, true, getLatestBranch().get(0), 0, ts);
138 }
139 writer.println('\n');
140 }
141
142 /**
143 * Start at currentNode and print the contents of all its children, in
144 * pre-order. Give the root node in parameter to visit the whole tree, and
145 * have a nice overview.
146 */
147 private void preOrderPrint(PrintWriter writer, boolean printIntervals,
148 HTNode currentNode, int curDepth, long ts) {
149
150 writer.println(currentNode.toString());
151 /*
152 * Print intervals only if timestamp is negative or within the range of
153 * the node
154 */
155 if (printIntervals &&
156 (ts <= 0 ||
157 (ts >= currentNode.getNodeStart() && ts <= currentNode.getNodeEnd()))) {
158 currentNode.debugPrintIntervals(writer);
159 }
160
161 switch (currentNode.getNodeType()) {
162 case LEAF:
163 /* Stop if it's the leaf node */
164 return;
165
166 case CORE:
167 try {
168 final CoreNode node = (CoreNode) currentNode;
169 /* If node extensions were used, they would be printed here. */
170
171 /* Print the child nodes */
172 for (int i = 0; i < node.getNbChildren(); i++) {
173 HTNode nextNode = getTreeIO().readNode(node.getChild(i));
174 for (int j = 0; j < curDepth; j++) {
175 writer.print(" ");
176 }
177 writer.print("+-");
178 preOrderPrint(writer, printIntervals, nextNode, curDepth + 1, ts);
179 }
180 } catch (ClosedChannelException e) {
181 }
182 break;
183
184 default:
185 break;
186 }
187 }
188
189 // ------------------------------------------------------------------------
190 // Assertion methods, for use with JUnit tests
191 // ------------------------------------------------------------------------
192
193 /**
194 * Check the integrity of all the nodes in the tree. Calls
195 * {@link #assertNodeIntegrity} for every node in the tree.
196 */
197 public void assertIntegrity() {
198 try {
199 for (int i = 0; i < getNodeCount(); i++) {
200 assertNodeIntegrity(getNode(i));
201 }
202 } catch (ClosedChannelException e) {
203 fail(e.getMessage());
204 }
205 }
206
207 /**
208 * Debugging method to make sure all intervals contained in the given node
209 * have valid start and end times.
210 *
211 * @param node
212 * The node to check
213 */
214 private void assertNodeIntegrity(HTNode node) {
215 if (node instanceof CoreNode) {
216 assertChildrenIntegrity((CoreNode) node);
217 }
218
219 /* Check that all intervals are within the node's range */
220 // TODO: Get the intervals of a node
221
222 }
223
224 private void assertChildrenIntegrity(CoreNode node) {
225 try {
226 /*
227 * Test that this node's start and end times match the start of the
228 * first child and the end of the last child, respectively
229 */
230 if (node.getNbChildren() > 0) {
231 HTNode childNode = getNode(node.getChild(0));
232 assertEquals("Equals start time of parent " + node.getSequenceNumber() + " and first child " + childNode.getSequenceNumber(),
233 node.getNodeStart(), childNode.getNodeStart());
234 if (node.isOnDisk()) {
235 childNode = getNode(node.getLatestChild());
236 assertEquals("Equals end time of parent " + node.getSequenceNumber() + " and last child " + childNode.getSequenceNumber(),
237 node.getNodeEnd(), childNode.getNodeEnd());
238 }
239 }
240
241 /*
242 * Test that the childStartTimes[] array matches the real nodes'
243 * start times
244 *
245 * Also test that children range is within the parent's range
246 */
247 for (int i = 0; i < node.getNbChildren(); i++) {
248 HTNode childNode = getNode(node.getChild(i));
249 assertEquals("Start time in parent " + node.getSequenceNumber() + " of child at index " + i,
250 childNode.getNodeStart(), node.getChildStart(i));
251 assertTrue("Child at index " + i + " of parent " + node.getSequenceNumber() + " has correct start time",
252 node.getNodeStart() <= childNode.getNodeStart());
253 if (node.isOnDisk() && childNode.isOnDisk()) {
254 assertTrue("Child at index " + i + " of parent " + node.getSequenceNumber() + " has correct start time",
255 childNode.getNodeEnd() <= childNode.getNodeEnd());
256 }
257 }
258
259 } catch (ClosedChannelException e) {
260 fail(e.getMessage());
261 }
262 }
263
264 }
This page took 0.037387 seconds and 4 git commands to generate.