blob: fba93226e21c23bfbb78d91081f535ceb198bca1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012, 2015 Obeo.
* 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
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.emf.compare.tests.performance;
import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Iterables.getFirst;
import static com.google.common.collect.Iterables.transform;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map.Entry;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceDescription;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.egit.core.Activator;
import org.eclipse.egit.core.GitCorePreferences;
import org.eclipse.emf.common.EMFPlugin;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Ordering;
import com.google.common.io.Closeables;
import fr.obeo.performance.DataPoint;
import fr.obeo.performance.Dimension;
import fr.obeo.performance.Measure;
import fr.obeo.performance.PerformancePackage;
import fr.obeo.performance.Scenario;
import fr.obeo.performance.TestResult;
import fr.obeo.performance.api.Performance;
/**
* @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
*/
public abstract class AbstractEMFComparePerformanceTest {
private static String timestamp;
private static Performance performance;
private static final Function<Measure, Scenario> MEASURE__SCENARIO = new Function<Measure, Scenario>() {
public Scenario apply(Measure measure) {
return ((TestResult)((DataPoint)measure.eContainer()).eContainer()).getScenario();
}
};
private static final Function<Measure, Double> MEASURE__VALUE = new Function<Measure, Double>() {
public Double apply(Measure measure) {
return measure.getValue();
}
};
private static final Function<Measure, String> MEASURE__NAME = new Function<Measure, String>() {
public String apply(Measure measure) {
return measure.getName();
}
};
private static final Function<DataPoint, List<Measure>> DATAPOINT__MEASURE = new Function<DataPoint, List<Measure>>() {
public List<Measure> apply(DataPoint point) {
return point.getMeasures();
}
};
private static final Function<TestResult, List<DataPoint>> TEST_RESULT__DATA_POINTS = new Function<TestResult, List<DataPoint>>() {
public List<DataPoint> apply(TestResult testResult) {
return testResult.getDataPoints();
}
};
private static final Function<Iterable<Double>, Double> AVERAGE = new Function<Iterable<Double>, Double>() {
public Double apply(Iterable<Double> it) {
Double sum = 0.0;
if (!Iterables.isEmpty(it)) {
for (Double d : it) {
sum += d;
}
return sum.doubleValue() / Iterables.size(it);
}
return sum;
}
};
private static final int DEFAULT_STEPS_NUMBER = 3;
private static final boolean DEFAULT_WARMUP = true;
@BeforeClass
public static void setUp() throws Exception {
if (!EMFPlugin.IS_ECLIPSE_RUNNING) {
EPackage perf = PerformancePackage.eINSTANCE;
EPackage.Registry.INSTANCE.put(perf.getNsURI(), perf);
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("performance",
new XMIResourceFactoryImpl());
}
IEclipsePreferences eGitPreferences = InstanceScope.INSTANCE.getNode(Activator.getPluginId());
eGitPreferences.putBoolean(GitCorePreferences.core_autoShareProjects, false);
// Deactivate auto-building
IWorkspace workspace = ResourcesPlugin.getWorkspace();
if (workspace != null) {
IWorkspaceDescription desc = workspace.getDescription();
boolean isAutoBuilding = desc.isAutoBuilding();
if (isAutoBuilding == true) {
desc.setAutoBuilding(false);
workspace.setDescription(desc);
}
}
timestamp = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date());
performance = new Performance("emf.compare.performance");
}
@Before
public final void configureSUTName() {
setSUTName();
}
protected static final Performance getPerformance() {
return performance;
}
/**
* Should be static but want to force impl.
*/
protected abstract void setSUTName();
protected int getStepsNumber() {
return DEFAULT_STEPS_NUMBER;
}
protected boolean warmup() {
return DEFAULT_WARMUP;
}
@AfterClass
public static void tearDown() {
final NumberFormat nf = NumberFormat.getInstance(Locale.US);
nf.setMaximumFractionDigits(2);
EList<TestResult> allResults = performance.getPerformanceTest().getResults();
Iterable<DataPoint> allDataPoints = concat(transform(allResults, TEST_RESULT__DATA_POINTS));
Iterable<Measure> allMeasures = concat(transform(allDataPoints, DATAPOINT__MEASURE));
ImmutableListMultimap<String, Measure> measuresByName = Multimaps.index(allMeasures, MEASURE__NAME);
for (Entry<String, Collection<Measure>> entry : measuresByName.asMap().entrySet()) {
String measureName = entry.getKey();
File output = new File(MessageFormat.format("{0}-{1}.csv",
performance.getSystemUnderTest().getName().replaceAll(" ", "_"),
measureName.replaceAll(" ", "_")));
PrintWriter writer = null;
try {
writer = new PrintWriter(new BufferedWriter(new FileWriter(output, true), 16384));
BufferedReader br = new BufferedReader(new FileReader(output));
String readLine = br.readLine();
final int columns;
if (readLine == null) {
br.close();
writer.println("Date, Small UML, Nominal UML, Small Split UML, Nominal Split UML");
columns = 4;
} else {
// Get number of columns that contains measures
columns = readLine.split(",").length - 1;
}
writer.print(timestamp + ",");
Collection<Measure> measures = entry.getValue();
ImmutableListMultimap<Scenario, Measure> measuresByScenario = Multimaps.index(measures,
MEASURE__SCENARIO);
String joinedMeasure = Joiner.on(',').join(transform(measuresByScenario.asMap().entrySet(),
new Function<Entry<Scenario, Collection<Measure>>, String>() {
public String apply(Entry<Scenario, Collection<Measure>> entry) {
final Dimension dimension = getFirst(entry.getValue(), null).getDimension();
Iterable<Double> transform = transform(entry.getValue(), MEASURE__VALUE);
List<Double> minAvMax = Lists.newArrayList();
minAvMax.add(Ordering.natural().min(transform));
minAvMax.add(AVERAGE.apply(transform));
minAvMax.add(Ordering.natural().max(transform));
Iterable<String> transform2 = transform(minAvMax,
new Function<Double, String>() {
public String apply(Double d) {
switch (dimension) {
case MEMORY:
return nf.format(SizeUnit.MEBI.convert(d))
.replaceAll(",", "");
case TIME:
return nf.format(d).replaceAll(",", "");
}
return "";
}
});
String ret = Joiner.on(';').join(transform2);
return ret;
}
}));
joinedMeasure = fillEmptyColumns(joinedMeasure, columns);
writer.println(joinedMeasure);
} catch (IOException e) {
Throwables.propagate(e);
} finally {
try {
Closeables.close(writer, true);
} catch (IOException e) {
// already swallowed
}
}
}
performance = null;
}
private static String fillEmptyColumns(String joinedMeasure, int columns) {
final int filled = joinedMeasure.split(",").length;
for (int i = 0; i < columns - filled; i++) {
joinedMeasure += ",";
}
return joinedMeasure;
}
@After
public void after() {
// try to minimize difference between runs
System.gc();
}
}