/*******************************************************************************
* 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.lttng2.kernel.core.tests.perf.analysis.syscall;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import java.io.File;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.test.performance.Dimension;
import org.eclipse.test.performance.Performance;
import org.eclipse.test.performance.PerformanceMeter;
import org.eclipse.tracecompass.analysis.os.linux.core.tid.TidAnalysisModule;
import org.eclipse.tracecompass.internal.analysis.os.linux.core.latency.SystemCallLatencyAnalysis;
import org.eclipse.tracecompass.lttng2.kernel.core.trace.LttngKernelTrace;
import org.eclipse.tracecompass.testtraces.ctf.CtfTestTrace;
import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestHelper;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEvent;
import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTraceUtils;
import org.junit.Test;
/**
* Benchmarks the system call latency analysis
*
* @author Geneviève Bastien
*/
public class SystemCallAnalysisBenchmark {
/**
* Test test ID for the system call analysis benchmarks
*/
public static final String TEST_ID = "org.eclipse.tracecompass#System Call Analysis#";
private static final String TEST_BUILD = "Building Analysis (%s)";
private static final String TEST_MEMORY = "Memory Usage (%s)";
private static final int LOOP_COUNT = 25;
private interface RunMethod {
void execute(PerformanceMeter pm, IAnalysisModule module);
}
private RunMethod cpu = (pm, module) -> {
pm.start();
TmfTestHelper.executeAnalysis(module);
pm.stop();
};
private RunMethod memory = (pm, module) -> {
System.gc();
pm.start();
TmfTestHelper.executeAnalysis(module);
System.gc();
pm.stop();
};
/**
* Run the benchmark with "trace2"
*/
@Test
public void testTrace2() {
runTest(CtfTestTrace.TRACE2, String.format(TEST_BUILD, "Trace2"), cpu, Dimension.CPU_TIME);
runTest(CtfTestTrace.TRACE2, String.format(TEST_MEMORY, "Trace2"), memory, Dimension.USED_JAVA_HEAP);
}
/**
* Run the benchmark with "many thread"
*/
@Test
public void testManyThreads() {
runTest(CtfTestTrace.MANY_THREADS, String.format(TEST_BUILD, "Many threads"), cpu, Dimension.CPU_TIME);
runTest(CtfTestTrace.MANY_THREADS, String.format(TEST_MEMORY, "Many threads"), memory, Dimension.USED_JAVA_HEAP);
}
/**
* Run the benchmark with "django httpd"
*/
@Test
public void testDjangoHttpd() {
runTest(CtfTestTrace.DJANGO_HTTPD, String.format(TEST_BUILD, "Django HTTPD"), cpu, Dimension.CPU_TIME);
runTest(CtfTestTrace.DJANGO_HTTPD, String.format(TEST_MEMORY, "Django HTTPD"), memory, Dimension.USED_JAVA_HEAP);
}
private static void runTest(@NonNull CtfTestTrace testTrace, String testName, RunMethod method, Dimension dimension) {
Performance perf = Performance.getDefault();
PerformanceMeter pm = perf.createPerformanceMeter(TEST_ID + testName);
perf.tagAsSummary(pm, "Syscall " + testName, dimension);
for (int i = 0; i < LOOP_COUNT; i++) {
LttngKernelTrace trace = null;
IAnalysisModule module = null;
String path = CtfTmfTestTraceUtils.getTrace(testTrace).getPath();
try {
// Make sure the TID analysis has run on this trace
trace = new LttngKernelTrace();
trace.initTrace(null, path, CtfTmfEvent.class);
trace.traceOpened(new TmfTraceOpenedSignal(trace, trace, null));
module = trace.getAnalysisModule(TidAnalysisModule.ID);
assertNotNull(module);
module.schedule();
module.waitForCompletion();
module = new SystemCallLatencyAnalysis();
module.setId("test");
module.setTrace(trace);
method.execute(pm, module);
/*
* Delete the supplementary files, so that the next iteration
* rebuilds the state system.
*/
File suppDir = new File(TmfTraceManager.getSupplementaryFileDir(trace));
for (File file : suppDir.listFiles()) {
file.delete();
}
} catch (TmfAnalysisException | TmfTraceException e) {
fail(e.getMessage());
} finally {
if (module != null) {
module.dispose();
}
if (trace != null) {
trace.dispose();
}
}
}
pm.commit();
CtfTmfTestTraceUtils.dispose(testTrace);
}
}