Skip to content

Commit e58b260

Browse files
committed
xml.config: Delete supplementary files when deleting xml analysis config
Fixes #267 [Fixed] Delete supplementary files when deleting xml analysis config Signed-off-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
1 parent 4eef073 commit e58b260

File tree

4 files changed

+323
-2
lines changed

4 files changed

+323
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2019 É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 2.0 which
6+
* accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*******************************************************************************/
11+
12+
package org.eclipse.tracecompass.tmf.analysis.xml.core.tests.module;
13+
14+
import static org.junit.Assert.assertFalse;
15+
import static org.junit.Assert.assertNotNull;
16+
import static org.junit.Assert.assertTrue;
17+
import static org.junit.Assert.fail;
18+
19+
import org.eclipse.core.resources.IFolder;
20+
import org.eclipse.core.resources.IProject;
21+
import org.eclipse.core.resources.IProjectDescription;
22+
import org.eclipse.core.resources.IResource;
23+
import org.eclipse.core.resources.IWorkspaceRoot;
24+
import org.eclipse.core.resources.ResourcesPlugin;
25+
import org.eclipse.core.runtime.CoreException;
26+
import org.eclipse.core.runtime.IPath;
27+
import org.eclipse.core.runtime.IStatus;
28+
import org.eclipse.core.runtime.Path;
29+
import org.eclipse.jdt.annotation.NonNull;
30+
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.XmlAnalysisModuleSource;
31+
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.XmlUtils;
32+
import org.eclipse.tracecompass.tmf.analysis.xml.core.tests.Activator;
33+
import org.eclipse.tracecompass.tmf.analysis.xml.core.tests.common.TmfXmlTestFiles;
34+
import org.eclipse.tracecompass.tmf.core.TmfCommonConstants;
35+
import org.eclipse.tracecompass.tmf.core.TmfProjectNature;
36+
import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
37+
import org.eclipse.tracecompass.tmf.core.event.TmfEvent;
38+
import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
39+
import org.eclipse.tracecompass.tmf.core.io.ResourceUtil;
40+
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal;
41+
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
42+
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
43+
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
44+
import org.eclipse.tracecompass.tmf.tests.stubs.trace.xml.TmfXmlTraceStubNs;
45+
import org.junit.AfterClass;
46+
import org.junit.Before;
47+
import org.junit.BeforeClass;
48+
import org.junit.Test;
49+
50+
import com.google.common.collect.ImmutableList;
51+
52+
/**
53+
* Test the XML Utils delete supplementary directory
54+
*
55+
* @author Geneviève Bastien
56+
*/
57+
public class XmlUtilsWithTraceTest {
58+
59+
private static final @NonNull String TEST_TRACE_NAME = "testTrace4.xml";
60+
61+
private static final @NonNull String TEST_TRACE = "test_traces/" + TEST_TRACE_NAME;
62+
63+
private static final @NonNull String ANALYSIS_ID = "xml.core.tests.simple.pattern";
64+
65+
private static IProject sfProject;
66+
67+
/**
68+
* Class setup
69+
*
70+
* @throws CoreException
71+
* if an error occurs
72+
*/
73+
@BeforeClass
74+
public static void startUp() throws CoreException {
75+
IProject project = ResourcesPlugin.getWorkspace().getRoot()
76+
.getProject(TmfCommonConstants.DEFAULT_TRACE_PROJECT_NAME);
77+
if (!project.exists()) {
78+
project.create(null);
79+
if (!project.isOpen()) {
80+
project.open(null);
81+
}
82+
IProjectDescription description = project.getDescription();
83+
description.setNatureIds(new String[] { TmfProjectNature.ID });
84+
project.setDescription(description, null);
85+
}
86+
if (!project.isOpen()) {
87+
project.open(null);
88+
}
89+
90+
IFolder tracesFolder = project.getFolder("Traces"); //$NON-NLS-1$
91+
if (!tracesFolder.exists()) {
92+
tracesFolder.create(true, true, null);
93+
}
94+
95+
IFolder supplRootFolder = project.getFolder(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER_NAME);
96+
if (!supplRootFolder.exists()) {
97+
supplRootFolder.create(true, true, null);
98+
}
99+
sfProject = project;
100+
}
101+
102+
/**
103+
* Class tear down
104+
*
105+
* @throws CoreException
106+
* if an error occurs
107+
*/
108+
@AfterClass
109+
public static void tearDown() throws CoreException {
110+
if (sfProject != null) {
111+
sfProject.delete(true, null);
112+
}
113+
}
114+
115+
/**
116+
* Load the XML files for the current test
117+
*/
118+
@Before
119+
public void setUp() {
120+
XmlUtils.addXmlFile(TmfXmlTestFiles.VALID_PATTERN_SIMPLE_FILE.getFile());
121+
XmlAnalysisModuleSource.notifyModuleChange();
122+
}
123+
124+
/**
125+
* Clean
126+
*/
127+
public void cleanUp() {
128+
XmlUtils.deleteFiles(ImmutableList.of(
129+
TmfXmlTestFiles.VALID_PATTERN_SIMPLE_FILE.getFile().getName()));
130+
XmlAnalysisModuleSource.notifyModuleChange();
131+
}
132+
133+
private ITmfTrace getTrace() throws CoreException {
134+
TmfXmlTraceStubNs trace = new TmfXmlTraceStubNs();
135+
String absolutePath = Activator.getAbsolutePath(new Path(TEST_TRACE)).toOSString();
136+
IStatus status = trace.validate(null, absolutePath);
137+
if (!status.isOK()) {
138+
fail(status.getException().getMessage());
139+
}
140+
141+
IResource resource = createResource(absolutePath);
142+
try {
143+
trace.initTrace(resource, absolutePath, TmfEvent.class);
144+
} catch (TmfTraceException e) {
145+
trace.dispose();
146+
fail(e.getMessage());
147+
}
148+
149+
// Initialize the trace and module
150+
TmfTraceOpenedSignal signal = new TmfTraceOpenedSignal(this, trace, null);
151+
trace.traceOpened(signal);
152+
// The data provider manager uses opened traces from the manager
153+
TmfTraceManager.getInstance().traceOpened(signal);
154+
return trace;
155+
}
156+
157+
@SuppressWarnings("null")
158+
private static IResource createResource(String path) throws CoreException {
159+
IPath targetLocation = new Path(path);
160+
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
161+
IProject project = root.getProject(TmfCommonConstants.DEFAULT_TRACE_PROJECT_NAME);
162+
project.refreshLocal(IResource.DEPTH_INFINITE, null);
163+
IFolder tracesFolder = project.getFolder("Traces");
164+
IResource resource = tracesFolder.getFile(TEST_TRACE_NAME);
165+
ResourceUtil.createSymbolicLink(resource, targetLocation, true, null);
166+
167+
IFolder supplRootFolder = project.getFolder(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER_NAME);
168+
IFolder supplFolder = supplRootFolder.getFolder(resource.getProjectRelativePath().removeFirstSegments(1));
169+
if (!supplFolder.exists()) {
170+
supplFolder.create(true, true, null);
171+
}
172+
resource.setPersistentProperty(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER, supplFolder.getLocation().toOSString());
173+
174+
return resource;
175+
}
176+
177+
private static void runModule(ITmfTrace trace) {
178+
IAnalysisModule module = trace.getAnalysisModule(ANALYSIS_ID);
179+
assertNotNull(module);
180+
module.schedule();
181+
assertTrue(module.waitForCompletion());
182+
}
183+
184+
/**
185+
* Test delete supplementary dir when trace is open
186+
*
187+
* @throws CoreException
188+
* Exception thrown by analyses
189+
*/
190+
@Test
191+
public void testDeleteSupplDirWithTraceOpen() throws CoreException {
192+
ITmfTrace trace = getTrace();
193+
assertNotNull(trace);
194+
try {
195+
runModule(trace);
196+
String supplPathString = TmfTraceManager.getSupplementaryFileDir(trace);
197+
IPath path = new Path(supplPathString);
198+
IPath ssFile = path.addTrailingSeparator().append(ANALYSIS_ID).addFileExtension("ht");
199+
IPath segFile = path.addTrailingSeparator().append(ANALYSIS_ID).addFileExtension("dat");
200+
assertTrue(ssFile.toFile().exists());
201+
assertTrue(segFile.toFile().exists());
202+
XmlUtils.deleteSupplementaryResources(TmfXmlTestFiles.VALID_PATTERN_SIMPLE_FILE.getFile().getName(), null);
203+
assertFalse(ssFile.toFile().exists());
204+
assertFalse(segFile.toFile().exists());
205+
206+
} finally {
207+
trace.dispose();
208+
TmfTraceManager.getInstance().traceClosed(new TmfTraceClosedSignal(this, trace));
209+
}
210+
}
211+
212+
213+
/**
214+
* Test delete supplementary dir when trace is open
215+
*
216+
* @throws CoreException
217+
* Exception thrown by analyses
218+
*/
219+
@Test
220+
public void testDeleteSupplDirWithTraceClosed() throws CoreException {
221+
ITmfTrace trace = getTrace();
222+
assertNotNull(trace);
223+
try {
224+
runModule(trace);
225+
String supplPathString = TmfTraceManager.getSupplementaryFileDir(trace);
226+
IPath path = new Path(supplPathString);
227+
IPath ssFile = path.addTrailingSeparator().append(ANALYSIS_ID).addFileExtension("ht");
228+
IPath segFile = path.addTrailingSeparator().append(ANALYSIS_ID).addFileExtension("dat");
229+
assertTrue(ssFile.toFile().exists());
230+
assertTrue(segFile.toFile().exists());
231+
232+
TmfTraceClosedSignal signal = new TmfTraceClosedSignal(this, trace);
233+
TmfTraceManager.getInstance().traceClosed(signal);
234+
trace.dispose();
235+
236+
XmlUtils.deleteSupplementaryResources(TmfXmlTestFiles.VALID_PATTERN_SIMPLE_FILE.getFile().getName(), null);
237+
assertFalse(ssFile.toFile().exists());
238+
assertFalse(segFile.toFile().exists());
239+
240+
} finally {
241+
trace.dispose();
242+
TmfTraceManager.getInstance().traceClosed(new TmfTraceClosedSignal(this, trace));
243+
}
244+
}
245+
246+
}

tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/META-INF/MANIFEST.MF

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ Require-Bundle: org.eclipse.core.runtime,
1717
org.eclipse.tracecompass.analysis.profiling.core,
1818
org.eclipse.core.commands,
1919
com.google.guava,
20-
org.eclipse.jdt.annotation;bundle-version="[2.0.0,3.0.0)";resolution:=optional
20+
org.eclipse.jdt.annotation;bundle-version="[2.0.0,3.0.0)";resolution:=optional,
21+
org.eclipse.core.resources
2122
Export-Package: org.eclipse.tracecompass.internal.tmf.analysis.xml.core;x-friends:="org.eclipse.tracecompass.tmf.analysis.xml.core.tests",
2223
org.eclipse.tracecompass.internal.tmf.analysis.xml.core.callstack;x-friends:="org.eclipse.tracecompass.tmf.analysis.xml.core.tests",
2324
org.eclipse.tracecompass.internal.tmf.analysis.xml.core.config;x-friends:="org.eclipse.tracecompass.tmf.analysis.xml.core.tests",

tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/config/XmlConfigurationSource.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public ITmfConfiguration update(String id, Map<String, Object> parameters) throw
108108
if (!XmlUtils.listFiles().containsKey(id)) {
109109
return null;
110110
}
111-
111+
XmlUtils.deleteSupplementaryResources(id, null);
112112
XmlUtils.deleteFiles(ImmutableList.of(id));
113113
XmlUtils.saveFilesStatus();
114114
XmlAnalysisModuleSource.notifyModuleChange();

tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/XmlUtils.java

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,20 @@
4242
import javax.xml.validation.SchemaFactory;
4343

4444
import org.apache.commons.io.FilenameUtils;
45+
import org.eclipse.core.resources.IFile;
46+
import org.eclipse.core.resources.IFolder;
47+
import org.eclipse.core.resources.IProject;
48+
import org.eclipse.core.resources.IResource;
49+
import org.eclipse.core.resources.IResourceVisitor;
50+
import org.eclipse.core.resources.ResourcesPlugin;
4551
import org.eclipse.core.runtime.CoreException;
4652
import org.eclipse.core.runtime.FileLocator;
4753
import org.eclipse.core.runtime.IConfigurationElement;
4854
import org.eclipse.core.runtime.IPath;
55+
import org.eclipse.core.runtime.IProgressMonitor;
4956
import org.eclipse.core.runtime.ISafeRunnable;
5057
import org.eclipse.core.runtime.IStatus;
58+
import org.eclipse.core.runtime.NullProgressMonitor;
5159
import org.eclipse.core.runtime.Path;
5260
import org.eclipse.core.runtime.Platform;
5361
import org.eclipse.core.runtime.SafeRunner;
@@ -61,6 +69,11 @@
6169
import org.eclipse.tracecompass.tmf.analysis.xml.core.module.ITmfXmlSchemaParser;
6270
import org.eclipse.tracecompass.tmf.analysis.xml.core.module.TmfXmlStrings;
6371
import org.eclipse.tracecompass.tmf.analysis.xml.core.module.TmfXmlUtils;
72+
import org.eclipse.tracecompass.tmf.core.TmfCommonConstants;
73+
import org.eclipse.tracecompass.tmf.core.TmfProjectNature;
74+
import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
75+
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
76+
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
6477
import org.osgi.framework.Bundle;
6578
import org.osgi.service.prefs.BackingStoreException;
6679
import org.w3c.dom.Document;
@@ -722,4 +735,65 @@ public static String createXmlFileString(String baseName) {
722735
});
723736
return enabledFiles;
724737
}
738+
739+
/**
740+
* Deletes all supplementary resources created by an XML analysis file
741+
*
742+
* @param xmlFileName
743+
* the file name of xml analysis
744+
* @param monitor
745+
* a progress monitor
746+
*/
747+
public static void deleteSupplementaryResources(String xmlFileName, @Nullable IProgressMonitor monitor) {
748+
final IProgressMonitor mon = (monitor == null ? new NullProgressMonitor() : monitor);
749+
// Get unique list of analysis IDs
750+
Set<String> analysisIds = new HashSet<>();
751+
analysisIds.addAll(XmlUtils.getAnalysisIdsFromFile(xmlFileName));
752+
753+
// Delete persistent data of all open traces (this will close the file before deleting it)
754+
for (ITmfTrace trace : TmfTraceManager.getInstance().getOpenedTraces()) {
755+
for (ITmfTrace tr : TmfTraceManager.getTraceSetWithExperiment(trace)) {
756+
analysisIds.forEach(analysisId -> {
757+
IAnalysisModule module = tr.getAnalysisModule(analysisId);
758+
if (module != null) {
759+
module.clearPersistentData();
760+
}
761+
});
762+
}
763+
if (mon.isCanceled()) {
764+
return;
765+
}
766+
}
767+
// Delete applicable persistent data of non-opened traces
768+
for (IProject project : ResourcesPlugin.getWorkspace().getRoot().getProjects()) {
769+
try {
770+
if (project.hasNature(TmfProjectNature.ID)) {
771+
project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
772+
IFolder supplFolder = project.getFolder(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER_NAME);
773+
if (supplFolder != null && supplFolder.exists()) {
774+
supplFolder.accept((IResourceVisitor) resource -> {
775+
if (mon.isCanceled()) {
776+
return false;
777+
}
778+
if (resource instanceof IFile) {
779+
analysisIds.forEach(analysisId -> {
780+
if (resource.getName().startsWith(analysisId)) {
781+
try {
782+
resource.delete(true, null);
783+
} catch (CoreException e) {
784+
Activator.logError("Can't delete supplementary resource " + resource.getName(), e); //$NON-NLS-1$
785+
}
786+
}
787+
});
788+
}
789+
return true;
790+
}, IResource.DEPTH_INFINITE, IResource.NONE);
791+
}
792+
}
793+
} catch (CoreException e) {
794+
Activator.logError("Can't delete supplementary resources for XML anlayses", e); //$NON-NLS-1$
795+
}
796+
}
797+
}
798+
725799
}

0 commit comments

Comments
 (0)