tmf: Automatically sync experiments set up with the same hosts
[deliverable/tracecompass.git] / lttng / org.eclipse.tracecompass.lttng2.kernel.core.tests / src / org / eclipse / tracecompass / lttng2 / kernel / core / tests / synchronization / UstKernelSyncTest.java
1 /*******************************************************************************
2 * Copyright (c) 2016 EfficiOS Inc., Alexandre Montplaisir
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.lttng2.kernel.core.tests.synchronization;
11
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertNotNull;
14 import static org.junit.Assert.fail;
15
16 import java.util.Objects;
17 import java.util.concurrent.TimeUnit;
18 import java.util.function.Predicate;
19
20 import org.eclipse.jdt.annotation.NonNull;
21 import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelAnalysisModule;
22 import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelThreadInformationProvider;
23 import org.eclipse.tracecompass.lttng2.kernel.core.trace.LttngKernelTrace;
24 import org.eclipse.tracecompass.testtraces.ctf.CtfTestTrace;
25 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
26 import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
27 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
28 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
29 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal;
30 import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
31 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
32 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
33 import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperiment;
34 import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEvent;
35 import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTraceUtils;
36 import org.junit.After;
37 import org.junit.Before;
38 import org.junit.Rule;
39 import org.junit.Test;
40 import org.junit.rules.TestRule;
41 import org.junit.rules.Timeout;
42
43 /**
44 * Test that synchronization between LTTng UST and kernel traces is done
45 * correctly.
46 *
47 * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=484620
48 *
49 * @author Alexandre Montplaisir
50 */
51 public class UstKernelSyncTest {
52
53 /** Time-out tests after 60 seconds */
54 @Rule public TestRule globalTimeout= new Timeout(60, TimeUnit.SECONDS);
55
56 private static final @NonNull CtfTestTrace KERNEL_TRACE = CtfTestTrace.CONTEXT_SWITCHES_KERNEL;
57 private static final @NonNull CtfTestTrace UST_TRACE = CtfTestTrace.CONTEXT_SWITCHES_UST;
58
59 private TmfExperiment fExperiment;
60 private ITmfTrace fKernelTrace;
61 private ITmfTrace fUstTrace;
62 private KernelAnalysisModule fKernelModule;
63
64 /**
65 * Test setup
66 */
67 @Before
68 public void setup() {
69 ITmfTrace ustTrace = CtfTmfTestTraceUtils.getTrace(UST_TRACE);
70
71 /*
72 * We need to initialize the kernel trace to the "LttngKernelTrace"
73 * type ourselves, so the kernel analysis can run on it.
74 */
75 String kernelTracePath = CtfTmfTestTraceUtils.getTrace(KERNEL_TRACE).getPath();
76 ITmfTrace kernelTrace = new LttngKernelTrace();
77
78 try {
79 kernelTrace.initTrace(null, kernelTracePath, CtfTmfEvent.class);
80 } catch (TmfTraceException e) {
81 fail(e.getMessage());
82 }
83
84 TmfExperiment experiment = new TmfExperiment(CtfTmfEvent.class,
85 "test-exp",
86 new ITmfTrace[] { ustTrace, kernelTrace },
87 TmfExperiment.DEFAULT_INDEX_PAGE_SIZE,
88 null);
89
90 /* Simulate experiment being opened */
91 // We have to "open" the sub-traces too, or their analyses are
92 // never initialized. Is that on purpose?
93 TmfSignalManager.dispatchSignal(new TmfTraceOpenedSignal(this, ustTrace, null));
94 TmfSignalManager.dispatchSignal(new TmfTraceOpenedSignal(this, kernelTrace, null));
95 TmfSignalManager.dispatchSignal(new TmfTraceOpenedSignal(this, experiment, null));
96 TmfSignalManager.dispatchSignal(new TmfTraceSelectedSignal(this, experiment));
97
98 KernelAnalysisModule module = TmfTraceUtils.getAnalysisModuleOfClass(experiment,
99 KernelAnalysisModule.class, KernelAnalysisModule.ID);
100 assertNotNull(module);
101 module.waitForCompletion();
102
103 fExperiment = experiment;
104 fKernelTrace = kernelTrace;
105 fUstTrace = ustTrace;
106 fKernelModule = module;
107 }
108
109 /**
110 * Test teardown
111 */
112 @After
113 public void tearDown() {
114 if (fExperiment != null) {
115 fExperiment.dispose();
116 }
117 if (fKernelTrace != null) {
118 fKernelTrace.dispose();
119 }
120
121 CtfTmfTestTraceUtils.dispose(KERNEL_TRACE);
122 CtfTmfTestTraceUtils.dispose(UST_TRACE);
123 }
124
125 /**
126 * Test that the TID given by the kernel analysis matches the one from the
127 * UST event's context for a given UST event that was known to fail.
128 *
129 * Reproduces the specific example that was pointed out in bug 484620.
130 */
131 @Test
132 public void testOneEvent() {
133 TmfExperiment experiment = fExperiment;
134 ITmfTrace ustTrace = fUstTrace;
135 KernelAnalysisModule module = fKernelModule;
136 assertNotNull(experiment);
137 assertNotNull(ustTrace);
138 assertNotNull(module);
139
140 Predicate<@NonNull ITmfEvent> eventFinder = event -> {
141 Long addr = event.getContent().getFieldValue(Long.class, "addr");
142 Long cs = event.getContent().getFieldValue(Long.class, "call_site");
143 Long ctxVtid = event.getContent().getFieldValue(Long.class, "context._vtid");
144
145 if (addr == null || cs == null || ctxVtid == null) {
146 return false;
147 }
148
149 return Objects.equals(event.getType().getName(), "lttng_ust_cyg_profile:func_entry") &&
150 Objects.equals(Long.toHexString(addr), "804af97") &&
151 Objects.equals(Long.toHexString(cs), "804ab03") &&
152 Objects.equals(ctxVtid.longValue(), 594L);
153 };
154
155 /* The event we're looking for is the second event matching the predicate */
156 CtfTmfEvent ustEvent = (CtfTmfEvent) TmfTraceUtils.getNextEventMatching(experiment, 0, eventFinder, null);
157 assertNotNull(ustEvent);
158 long rank = experiment.seekEvent(ustEvent.getTimestamp()).getRank() + 1;
159 ustEvent = (CtfTmfEvent) TmfTraceUtils.getNextEventMatching(experiment, rank, eventFinder, null);
160 assertNotNull(ustEvent);
161
162 assertEquals(ustTrace, ustEvent.getTrace());
163
164 Integer tidFromKernel = KernelThreadInformationProvider.getThreadOnCpu(module,
165 ustEvent.getCPU(), ustEvent.getTimestamp().toNanos());
166
167 assertNotNull(tidFromKernel);
168 assertEquals(594, tidFromKernel.intValue());
169 }
170
171 /**
172 * Test going through the whole UST trace, making sure the VTID context of
173 * each event corresponds to the TID given by the kernel analysis at the
174 * same timestamp.
175 */
176 @Test
177 public void testWholeUstTrace() {
178 TmfExperiment experiment = fExperiment;
179 ITmfTrace ustTrace = fUstTrace;
180 KernelAnalysisModule module = fKernelModule;
181 assertNotNull(experiment);
182 assertNotNull(ustTrace);
183 assertNotNull(module);
184
185 ITmfContext context = ustTrace.seekEvent(0L);
186 CtfTmfEvent ustEvent = (CtfTmfEvent) ustTrace.getNext(context);
187 int count = 0;
188 while (ustEvent != null) {
189 Long ustVtid = ustEvent.getContent().getFieldValue(Long.class, "context._vtid");
190 /* All events in the trace should have that context */
191 assertNotNull(ustVtid);
192
193 long ts = ustEvent.getTimestamp().toNanos();
194 long cpu = ustEvent.getCPU();
195 Integer kernelTid = KernelThreadInformationProvider.getThreadOnCpu(module, cpu, ts);
196 assertNotNull(kernelTid);
197
198 assertEquals("Wrong TID for trace event " + ustEvent.toString(), ustVtid.longValue(), kernelTid.longValue());
199
200 ustEvent = (CtfTmfEvent) ustTrace.getNext(context);
201 count++;
202 }
203
204 /* Make sure we've read all expected events */
205 assertEquals(UST_TRACE.getNbEvents(), count);
206 }
207 }
This page took 0.044054 seconds and 5 git commands to generate.