From: Geneviève Bastien Date: Mon, 18 Apr 2016 14:56:52 +0000 (-0400) Subject: ss: Prepare the history tree backend for more unit tests X-Git-Url: http://git.efficios.com/?a=commitdiff_plain;h=068641fafe9bbd69040019b4e5d3639240761019;p=deliverable%2Ftracecompass.git ss: Prepare the history tree backend for more unit tests The constructor calls a new @VisibleForTesting protected method to initialize the history tree. This will allow the stub to provide its own implementation. Change-Id: I8bfdcb454ed49b9e77648c7d6da67aa35d6b9efa Signed-off-by: Geneviève Bastien Signed-off-by: Alexandre Montplaisir Reviewed-on: https://git.eclipse.org/r/70888 Reviewed-by: Hudson CI --- diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core.tests/stubs/org/eclipse/tracecompass/statesystem/core/tests/stubs/backend/HistoryTreeBackendStub.java b/statesystem/org.eclipse.tracecompass.statesystem.core.tests/stubs/org/eclipse/tracecompass/statesystem/core/tests/stubs/backend/HistoryTreeBackendStub.java new file mode 100644 index 0000000000..1f5366761c --- /dev/null +++ b/statesystem/org.eclipse.tracecompass.statesystem.core.tests/stubs/org/eclipse/tracecompass/statesystem/core/tests/stubs/backend/HistoryTreeBackendStub.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2016 École Polytechnique de Montréal + * + * 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 + *******************************************************************************/ + +package org.eclipse.tracecompass.statesystem.core.tests.stubs.backend; + +import java.io.File; +import java.io.IOException; + +import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTConfig; +import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HistoryTree; +import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HistoryTreeBackend; + +/** + * Stub class for the {@link HistoryTreeBackend}. It creates a + * {@link HistoryTreeStub} to grant access to some protected methods. + * + * @author Geneviève Bastien + */ +public class HistoryTreeBackendStub extends HistoryTreeBackend { + + /** + * Constructor for new history files. Use this when creating a new history + * from scratch. + * + * @param ssid + * The state system's ID + * @param newStateFile + * The filename/location where to store the state history (Should + * end in .ht) + * @param providerVersion + * Version of of the state provider. We will only try to reopen + * existing files if this version matches the one in the + * framework. + * @param startTime + * The earliest time stamp that will be stored in the history + * @param blockSize + * The size of the blocks in the history file. This should be a + * multiple of 4096. + * @param maxChildren + * The maximum number of children each core node can have + * @throws IOException + * Thrown if we can't create the file for some reason + */ + public HistoryTreeBackendStub(String ssid, + File newStateFile, + int providerVersion, + long startTime, + int blockSize, + int maxChildren) throws IOException { + super(ssid, newStateFile, providerVersion, startTime, blockSize, maxChildren); + } + + /** + * Existing history constructor. Use this to open an existing state-file. + * + * @param ssid + * The state system's id + * @param existingStateFile + * Filename/location of the history we want to load + * @param providerVersion + * Expected version of of the state provider plugin. + * @throws IOException + * If we can't read the file, if it doesn't exist, is not + * recognized, or if the version of the file does not match the + * expected providerVersion. + */ + public HistoryTreeBackendStub(String ssid, File existingStateFile, int providerVersion) + throws IOException { + super(ssid, existingStateFile, providerVersion); + } + + @Override + protected HistoryTree initializeSHT(HTConfig conf) throws IOException { + return new HistoryTreeStub(conf); + } + + @Override + protected HistoryTree initializeSHT(File existingStateFile, int providerVersion) throws IOException { + return new HistoryTreeStub(existingStateFile, providerVersion); + } + +} diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core.tests/stubs/org/eclipse/tracecompass/statesystem/core/tests/stubs/backend/HistoryTreeStub.java b/statesystem/org.eclipse.tracecompass.statesystem.core.tests/stubs/org/eclipse/tracecompass/statesystem/core/tests/stubs/backend/HistoryTreeStub.java index 63ba47c545..bb68c7ef25 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core.tests/stubs/org/eclipse/tracecompass/statesystem/core/tests/stubs/backend/HistoryTreeStub.java +++ b/statesystem/org.eclipse.tracecompass.statesystem.core.tests/stubs/org/eclipse/tracecompass/statesystem/core/tests/stubs/backend/HistoryTreeStub.java @@ -11,6 +11,7 @@ package org.eclipse.tracecompass.statesystem.core.tests.stubs.backend; import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull; +import java.io.File; import java.io.IOException; import java.util.List; @@ -44,6 +45,21 @@ public class HistoryTreeStub extends HistoryTree { super(conf); } + /** + * "Reader" constructor : instantiate a SHTree from an existing tree file on + * disk + * + * @param existingStateFile + * Path/filename of the history-file we are to open + * @param expProviderVersion + * The expected version of the state provider + * @throws IOException + * If an error happens reading the file + */ + public HistoryTreeStub(File existingStateFile, int expProviderVersion) throws IOException { + super(existingStateFile, expProviderVersion); + } + @Override public List getLatestBranch() { return checkNotNull(super.getLatestBranch()); diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HistoryTreeBackend.java b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HistoryTreeBackend.java index ae8bf0d850..97dd73ee29 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HistoryTreeBackend.java +++ b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HistoryTreeBackend.java @@ -31,6 +31,8 @@ import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval; import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue; import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue; +import com.google.common.annotations.VisibleForTesting; + /** * History Tree backend for storing a state history. This is the basic version * that runs in the same thread as the class creating it. @@ -100,7 +102,7 @@ public class HistoryTreeBackend implements IStateHistoryBackend { fSsid = ssid; final HTConfig conf = new HTConfig(newStateFile, blockSize, maxChildren, providerVersion, startTime); - fSht = new HistoryTree(conf); + fSht = initializeSHT(conf); } /** @@ -142,19 +144,55 @@ public class HistoryTreeBackend implements IStateHistoryBackend { * recognized, or if the version of the file does not match the * expected providerVersion. */ - public HistoryTreeBackend(@NonNull String ssid, File existingStateFile, int providerVersion) + public HistoryTreeBackend(@NonNull String ssid, @NonNull File existingStateFile, int providerVersion) throws IOException { fSsid = ssid; - fSht = new HistoryTree(existingStateFile, providerVersion); + fSht = initializeSHT(existingStateFile, providerVersion); fFinishedBuilding = true; } + /** + * New-tree initializer for the History Tree wrapped by this backend. Can be + * overriden to use different implementations. + * + * @param conf + * The HTConfig configuration object + * @return The new history tree + * @throws IOException + * If there was a problem during creation + */ + @VisibleForTesting + protected HistoryTree initializeSHT(@NonNull HTConfig conf) throws IOException { + return new HistoryTree(conf); + } + + /** + * Existing-tree initializer for the History Tree wrapped by this backend. + * Can be overriden to use different implementations. + * + * @param existingStateFile + * The file to open + * @param providerVersion + * The expected state provider version + * @return The history tree opened from the given file + * @throws IOException + * If there was a problem during creation + */ + @VisibleForTesting + protected HistoryTree initializeSHT(@NonNull File existingStateFile, int providerVersion) throws IOException { + return new HistoryTree(existingStateFile, providerVersion); + } + /** * Get the History Tree built by this backend. * + * Note: Do not override this method. If you want to extend the class to use + * a different History Tree implementation, override both variants of + * {@link #initializeSHT} instead. + * * @return The history tree */ - protected HistoryTree getSHT() { + protected final HistoryTree getSHT() { return fSht; } @@ -165,12 +203,12 @@ public class HistoryTreeBackend implements IStateHistoryBackend { @Override public long getStartTime() { - return fSht.getTreeStart(); + return getSHT().getTreeStart(); } @Override public long getEndTime() { - return fSht.getTreeEnd(); + return getSHT().getTreeEnd(); } @Override @@ -180,46 +218,46 @@ public class HistoryTreeBackend implements IStateHistoryBackend { quark, (TmfStateValue) value); /* Start insertions at the "latest leaf" */ - fSht.insertInterval(interval); + getSHT().insertInterval(interval); } @Override public void finishedBuilding(long endTime) { - fSht.closeTree(endTime); + getSHT().closeTree(endTime); fFinishedBuilding = true; } @Override public FileInputStream supplyAttributeTreeReader() { - return fSht.supplyATReader(); + return getSHT().supplyATReader(); } @Override public File supplyAttributeTreeWriterFile() { - return fSht.supplyATWriterFile(); + return getSHT().supplyATWriterFile(); } @Override public long supplyAttributeTreeWriterFilePosition() { - return fSht.supplyATWriterFilePos(); + return getSHT().supplyATWriterFilePos(); } @Override public void removeFiles() { - fSht.deleteFile(); + getSHT().deleteFile(); } @Override public void dispose() { if (fFinishedBuilding) { - fSht.closeFile(); + getSHT().closeFile(); } else { /* * The build is being interrupted, delete the file we partially * built since it won't be complete, so shouldn't be re-used in the * future (.deleteFile() will close the file first) */ - fSht.deleteFile(); + getSHT().deleteFile(); } } @@ -229,13 +267,13 @@ public class HistoryTreeBackend implements IStateHistoryBackend { checkValidTime(t); /* We start by reading the information in the root node */ - HTNode currentNode = fSht.getRootNode(); + HTNode currentNode = getSHT().getRootNode(); currentNode.writeInfoFromNode(stateInfo, t); /* Then we follow the branch down in the relevant children */ try { while (currentNode.getNodeType() == HTNode.NodeType.CORE) { - currentNode = fSht.selectNextChild((CoreNode) currentNode, t); + currentNode = getSHT().selectNextChild((CoreNode) currentNode, t); currentNode.writeInfoFromNode(stateInfo, t); } } catch (ClosedChannelException e) { @@ -275,12 +313,12 @@ public class HistoryTreeBackend implements IStateHistoryBackend { throws TimeRangeException, StateSystemDisposedException { checkValidTime(t); - HTNode currentNode = fSht.getRootNode(); + HTNode currentNode = getSHT().getRootNode(); HTInterval interval = currentNode.getRelevantInterval(key, t); try { while (interval == null && currentNode.getNodeType() == HTNode.NodeType.CORE) { - currentNode = fSht.selectNextChild((CoreNode) currentNode, t); + currentNode = getSHT().selectNextChild((CoreNode) currentNode, t); interval = currentNode.getRelevantInterval(key, t); } } catch (ClosedChannelException e) { @@ -295,7 +333,7 @@ public class HistoryTreeBackend implements IStateHistoryBackend { * @return The current size of the history file in bytes */ public long getFileSize() { - return fSht.getFileSize(); + return getSHT().getFileSize(); } /** @@ -309,15 +347,15 @@ public class HistoryTreeBackend implements IStateHistoryBackend { long ret; try { - for (int seq = 0; seq < fSht.getNodeCount(); seq++) { - node = fSht.readNode(seq); + for (int seq = 0; seq < getSHT().getNodeCount(); seq++) { + node = getSHT().readNode(seq); total += node.getNodeUsagePercent(); } } catch (ClosedChannelException e) { Activator.getDefault().logError(e.getMessage(), e); } - ret = total / fSht.getNodeCount(); + ret = total / getSHT().getNodeCount(); /* The return value should be a percentage */ if (ret < 0 || ret > 100) { throw new IllegalStateException("Average node usage is not a percentage: " + ret); //$NON-NLS-1$ @@ -346,11 +384,11 @@ public class HistoryTreeBackend implements IStateHistoryBackend { /* Only used for debugging, shouldn't be externalized */ writer.println("------------------------------"); //$NON-NLS-1$ writer.println("State History Tree:\n"); //$NON-NLS-1$ - writer.println(fSht.toString()); + writer.println(getSHT().toString()); writer.println("Average node utilization: " //$NON-NLS-1$ + getAverageNodeUsage()); writer.println(""); //$NON-NLS-1$ - fSht.debugPrintFullTree(writer, printIntervals); + getSHT().debugPrintFullTree(writer, printIntervals); } }