| 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2015 EfficiOS Inc., Alexandre Montplaisir |
| 3 | * |
| 4 | * All rights reserved. This program and the accompanying materials |
| 5 | * are made available under the terms of the Eclipse Public License v1.0 |
| 6 | * which accompanies this distribution, and is available at |
| 7 | * http://www.eclipse.org/legal/epl-v10.html |
| 8 | *******************************************************************************/ |
| 9 | |
| 10 | package org.eclipse.tracecompass.lttng2.ust.core.tests.analysis.debuginfo; |
| 11 | |
| 12 | import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull; |
| 13 | import static org.junit.Assert.assertEquals; |
| 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 java.util.ArrayList; |
| 20 | import java.util.Comparator; |
| 21 | import java.util.List; |
| 22 | |
| 23 | import org.eclipse.jdt.annotation.NonNull; |
| 24 | import org.eclipse.tracecompass.internal.lttng2.ust.core.analysis.debuginfo.UstDebugInfoBinaryFile; |
| 25 | import org.eclipse.tracecompass.lttng2.ust.core.analysis.debuginfo.UstDebugInfoAnalysisModule; |
| 26 | import org.eclipse.tracecompass.lttng2.ust.core.analysis.debuginfo.UstDebugInfoBinaryAspect; |
| 27 | import org.eclipse.tracecompass.lttng2.ust.core.trace.LttngUstEvent; |
| 28 | import org.eclipse.tracecompass.lttng2.ust.core.trace.LttngUstTrace; |
| 29 | import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; |
| 30 | import org.eclipse.tracecompass.testtraces.ctf.CtfTestTrace; |
| 31 | import org.eclipse.tracecompass.tmf.core.analysis.requirements.TmfAbstractAnalysisRequirement; |
| 32 | import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; |
| 33 | import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; |
| 34 | import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; |
| 35 | import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType; |
| 36 | import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; |
| 37 | import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; |
| 38 | import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; |
| 39 | import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEvent; |
| 40 | import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTraceUtils; |
| 41 | import org.junit.After; |
| 42 | import org.junit.Before; |
| 43 | import org.junit.Test; |
| 44 | |
| 45 | import com.google.common.collect.Iterables; |
| 46 | import com.google.common.collect.Lists; |
| 47 | |
| 48 | /** |
| 49 | * Tests for the {@link UstDebugInfoAnalysisModule} |
| 50 | * |
| 51 | * @author Alexandre Montplaisir |
| 52 | */ |
| 53 | public class UstDebugInfoAnalysisModuleTest { |
| 54 | |
| 55 | private static final @NonNull CtfTestTrace TEST_TRACE = CtfTestTrace.DEBUG_INFO3; |
| 56 | private static final @NonNull CtfTestTrace INVALID_TRACE = CtfTestTrace.CYG_PROFILE; |
| 57 | |
| 58 | private LttngUstTrace fTrace; |
| 59 | private UstDebugInfoAnalysisModule fModule; |
| 60 | |
| 61 | /** |
| 62 | * Test setup |
| 63 | */ |
| 64 | @Before |
| 65 | public void setup() { |
| 66 | fModule = new UstDebugInfoAnalysisModule(); |
| 67 | fTrace = new LttngUstTrace(); |
| 68 | try { |
| 69 | fTrace.initTrace(null, CtfTmfTestTraceUtils.getTrace(TEST_TRACE).getPath(), CtfTmfEvent.class); |
| 70 | } catch (TmfTraceException e) { |
| 71 | /* Should not happen if tracesExist() passed */ |
| 72 | throw new RuntimeException(e); |
| 73 | } |
| 74 | } |
| 75 | |
| 76 | /** |
| 77 | * Test cleanup |
| 78 | */ |
| 79 | @After |
| 80 | public void tearDown() { |
| 81 | fTrace.dispose(); |
| 82 | fModule.dispose(); |
| 83 | fTrace = null; |
| 84 | fModule = null; |
| 85 | } |
| 86 | |
| 87 | /** |
| 88 | * Test for {@link UstDebugInfoAnalysisModule#getAnalysisRequirements()} |
| 89 | */ |
| 90 | @Test |
| 91 | public void testGetAnalysisRequirements() { |
| 92 | Iterable<TmfAbstractAnalysisRequirement> requirements = fModule.getAnalysisRequirements(); |
| 93 | assertNotNull(requirements); |
| 94 | assertTrue(Iterables.isEmpty(requirements)); |
| 95 | } |
| 96 | |
| 97 | /** |
| 98 | * Test that the analysis can execute on a valid trace. |
| 99 | */ |
| 100 | @Test |
| 101 | public void testCanExecute() { |
| 102 | assertNotNull(fTrace); |
| 103 | assertTrue(fModule.canExecute(fTrace)); |
| 104 | } |
| 105 | |
| 106 | /** |
| 107 | * Test that the analysis correctly refuses to execute on an invalid trace |
| 108 | * (LTTng-UST < 2.8 in this case). |
| 109 | * |
| 110 | * @throws TmfTraceException |
| 111 | * Should not happen |
| 112 | */ |
| 113 | @Test |
| 114 | public void testCannotExcecute() throws TmfTraceException { |
| 115 | LttngUstTrace invalidTrace = new LttngUstTrace(); |
| 116 | invalidTrace.initTrace(null, CtfTmfTestTraceUtils.getTrace(INVALID_TRACE).getPath(), CtfTmfEvent.class); |
| 117 | assertFalse(fModule.canExecute(invalidTrace)); |
| 118 | |
| 119 | invalidTrace.dispose(); |
| 120 | } |
| 121 | |
| 122 | private void executeModule() { |
| 123 | assertNotNull(fTrace); |
| 124 | try { |
| 125 | fModule.setTrace(fTrace); |
| 126 | } catch (TmfAnalysisException e) { |
| 127 | fail(); |
| 128 | } |
| 129 | fModule.schedule(); |
| 130 | fModule.waitForCompletion(); |
| 131 | } |
| 132 | |
| 133 | /** |
| 134 | * Test that basic execution of the module works well. |
| 135 | */ |
| 136 | @Test |
| 137 | public void testExecution() { |
| 138 | executeModule(); |
| 139 | ITmfStateSystem ss = fModule.getStateSystem(); |
| 140 | assertNotNull(ss); |
| 141 | } |
| 142 | |
| 143 | /** |
| 144 | * Test that the binary callsite aspect resolves correctly for some |
| 145 | * user-defined tracepoints in the trace. |
| 146 | * |
| 147 | * These should be available even without the binaries with debug symbols |
| 148 | * being present on the system. |
| 149 | */ |
| 150 | @Test |
| 151 | public void testBinaryCallsites() { |
| 152 | assertNotNull(fTrace); |
| 153 | /* |
| 154 | * Fake a "trace opened" signal, so that the relevant analyses are |
| 155 | * started. |
| 156 | */ |
| 157 | TmfTraceOpenedSignal signal = new TmfTraceOpenedSignal(this, fTrace, null); |
| 158 | TmfSignalManager.dispatchSignal(signal); |
| 159 | |
| 160 | /* Send a request to get the 3 events we are interested in */ |
| 161 | List<@NonNull LttngUstEvent> events = new ArrayList<>(); |
| 162 | TmfEventRequest request = new TmfEventRequest(LttngUstEvent.class, 287, 3, ExecutionType.FOREGROUND) { |
| 163 | @Override |
| 164 | public void handleData(ITmfEvent event) { |
| 165 | super.handleData(event); |
| 166 | events.add((LttngUstEvent) event); |
| 167 | } |
| 168 | }; |
| 169 | fTrace.sendRequest(request); |
| 170 | try { |
| 171 | request.waitForCompletion(); |
| 172 | } catch (InterruptedException e) { |
| 173 | fail(e.getMessage()); |
| 174 | } |
| 175 | |
| 176 | /* Tests that the aspects are resolved correctly */ |
| 177 | final UstDebugInfoBinaryAspect aspect = UstDebugInfoBinaryAspect.INSTANCE; |
| 178 | |
| 179 | String actual = checkNotNull(aspect.resolve(events.get(0))).toString(); |
| 180 | String expected = "/home/alexandre/src/lttng-project/lttng/trace-utils/dynamicLinking/libhello.so+0x15ae"; |
| 181 | assertEquals(expected, actual); |
| 182 | |
| 183 | actual = checkNotNull(aspect.resolve(events.get(1))).toString(); |
| 184 | expected = "/home/alexandre/src/lttng-project/lttng/trace-utils/dynamicLinking/libhello.so+0x1680"; |
| 185 | assertEquals(expected, actual); |
| 186 | |
| 187 | actual = checkNotNull(aspect.resolve(events.get(2))).toString(); |
| 188 | expected = "/home/alexandre/src/lttng-project/lttng/trace-utils/dynamicLinking/libhello.so+0x1745"; |
| 189 | assertEquals(expected, actual); |
| 190 | } |
| 191 | |
| 192 | /** |
| 193 | * Test the {@link UstDebugInfoAnalysisModule#getAllBinaries} method. |
| 194 | */ |
| 195 | @Test |
| 196 | public void testGetAllBinaries() { |
| 197 | executeModule(); |
| 198 | List<UstDebugInfoBinaryFile> actualBinaries = Lists.newArrayList(fModule.getAllBinaries()); |
| 199 | List<UstDebugInfoBinaryFile> expectedBinaries = Lists.newArrayList( |
| 200 | new UstDebugInfoBinaryFile("/home/alexandre/src/lttng-project/lttng/trace-utils/dynamicLinking/libhello.so", "c9ac43c6b4251b0789ada66931e33487d65f64a6", true), |
| 201 | new UstDebugInfoBinaryFile("/home/alexandre/src/lttng-project/lttng/trace-utils/dynamicLinking/main.out", "0ec3294d0cacff93ec30b7161ff21efcd4cdd327", false), |
| 202 | new UstDebugInfoBinaryFile("/lib/x86_64-linux-gnu/ld-2.23.so", "edfa6d46e00ca97f349fdd3333d88493d442932c", true), |
| 203 | new UstDebugInfoBinaryFile("/lib/x86_64-linux-gnu/libc-2.23.so", "369de0e1d833caa693af17f17c83ba937f0a4dad", true), |
| 204 | new UstDebugInfoBinaryFile("/lib/x86_64-linux-gnu/libdl-2.23.so", "a2adf3615338d49c702c41eb83a99ab743d2b574", true), |
| 205 | new UstDebugInfoBinaryFile("/lib/x86_64-linux-gnu/libgcc_s.so.1", "68220ae2c65d65c1b6aaa12fa6765a6ec2f5f434", true), |
| 206 | new UstDebugInfoBinaryFile("/lib/x86_64-linux-gnu/libglib-2.0.so.0.4800.0", "8b553ecf9133c50f36a7345a4924c5b97e9daa11", true), |
| 207 | new UstDebugInfoBinaryFile("/lib/x86_64-linux-gnu/liblzma.so.5.0.0", "15aed4855920e5a0fb8791b683eb88c7e1199260", true), |
| 208 | new UstDebugInfoBinaryFile("/lib/x86_64-linux-gnu/libm-2.23.so", "5c4078c04888a418f3db0868702ecfdb35b3ad8b", true), |
| 209 | new UstDebugInfoBinaryFile("/lib/x86_64-linux-gnu/libpcre.so.3.13.2", "390b2228e9a1071bb0be285d77b6669cb37ce628", true), |
| 210 | new UstDebugInfoBinaryFile("/lib/x86_64-linux-gnu/libpthread-2.23.so", "b77847cc9cacbca3b5753d0d25a32e5795afe75b", true), |
| 211 | new UstDebugInfoBinaryFile("/lib/x86_64-linux-gnu/libresolv-2.23.so", "81ef82040e9877e63adca93b365f52a4bb831ee1", true), |
| 212 | new UstDebugInfoBinaryFile("/lib/x86_64-linux-gnu/librt-2.23.so", "a779dbcb3a477dc0c8d09b60fac7335d396c19df", true), |
| 213 | new UstDebugInfoBinaryFile("/lib/x86_64-linux-gnu/libselinux.so.1", "62a57085aa17036efdcecf6655d9e7be566f6948", true), |
| 214 | new UstDebugInfoBinaryFile("/lib/x86_64-linux-gnu/libz.so.1.2.8", "340b7b463f981b8a0fb3451751f881df1b0c2f74", true), |
| 215 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/indicator-transfer/indicator-transfer-service", "01c605bcf38d068d77a6e0a02cede6a50c5750b5", false), |
| 216 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/indicator-transfer/libbuteo-transfers.so", "a3a54ba90d7b7b67e0be9baaae3b91675b630a09", true), |
| 217 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/indicator-transfer/libdmtransfers.so", "ad8ebd563d733818f9f4a399b8d34c1b7e846f3d", true), |
| 218 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1", "478d22fbdf6a3e0ec3b499bd2bb8e97dbed84fb6", true), |
| 219 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libQt5Xml.so.5.5.1", "3a16f2feccfdbca6a40d9bd43ae5a966bca065c7", true), |
| 220 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libaccounts-glib.so.0.1.3", "3aaeb6f74d07bd2331fa1664a90b11ca5cc1b71e", true), |
| 221 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libaccounts-qt5.so.1.2.0", "c4c36b5efb4dd5f92a53ed0a2844239f564328d7", true), |
| 222 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.58.0", "8cebf2501fd917f393ef1390777415fca9289878", true), |
| 223 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0", "bb484981ddf4152bb6f02ad3a700ec21ca3805e2", true), |
| 224 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libclick-0.4.so.0.4.0", "79609d999eab77f934f6d7d296074ea54f1410e8", true), |
| 225 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libffi.so.6.0.4", "9d9c958f1f4894afef6aecd90d1c430ea29ac34f", true), |
| 226 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libgee-0.8.so.2.5.1", "96aff01de4c5e4817d483de7278c8cc9c6d02001", true), |
| 227 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libgio-2.0.so.0.4800.0", "01d955da82f10209b515f362b2352d5a0d0b5330", true), |
| 228 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0.4800.0", "a9190276f6246d3a44ba820510ef7d469ea556b1", true), |
| 229 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4800.0", "bce3f25958a5b88c9493990daf0c90a787444c28", true), |
| 230 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libicudata.so.55.1", "233845f0cd27642c4b2cc43979c8801b52bc00a9", true), |
| 231 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libicui18n.so.55.1", "7bf3774116dbb992ffcc2156b6f5c44f0a328f00", true), |
| 232 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libicuuc.so.55.1", "323e4878073bb4e0d7b174ae24e383ec5e05d68a", true), |
| 233 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libindicator-transfer.so.0.0.2", "4e472120f2a19343e1ff5928459edcb4a6c0b1e2", true), |
| 234 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libjson-glib-1.0.so.0.102.0", "55c87753a67b0c24922bd091f042b9d8bd4995dc", true), |
| 235 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/liblttng-ust-dl.so.0.0.0", "450c14d5a7a72780b2d88a3cf73d2e12c2774676", true), |
| 236 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/liblttng-ust-tracepoint.so.0.0.0", "e70e1748e137bb59b542e15e0722455b998355fc", true), |
| 237 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/liblttng-ust.so.0.0.0", "101115876419ead3a8bd9a9a08a6d92984015b99", true), |
| 238 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libmirclient.so.9", "b4c1509382d3ef5f7458db59710b4d30dad86b5d", true), |
| 239 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libmircommon.so.5", "25b5830854701533323f15195ae9e501ad7f772b", true), |
| 240 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libmirprotobuf.so.3", "2f6b1a56f1ac43ae001dffde4dc1a24bfee04dec", true), |
| 241 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libpcre16.so.3.13.2", "2cc13260733c5b35f311725fca88219b338d5390", true), |
| 242 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libprotobuf-lite.so.9.0.1", "625eb54ba7ccc3af18d3193e22cbe9f23dfb88e5", true), |
| 243 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libsqlite3.so.0.8.6", "d9782ba023caec26b15d8676e3a5d07b55e121ef", true), |
| 244 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21", "662f4598d7854c6731f13802486e477a7bdb09c7", true), |
| 245 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libubuntu-app-launch.so.2.0.0", "1e5753f4feda98548bd230eb07b81e330f419463", true), |
| 246 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/liburcu-bp.so.4.0.0", "d208fcd0e6e6968b8110d9c487f63ae1a400e7c2", true), |
| 247 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/liburcu-cds.so.4.0.0", "177fbd0a1b21145ad2f29bf41ba9f45e43b1ae4a", true), |
| 248 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/liburl-dispatcher.so.1.0.0", "58e7febb6e33418eee311c0bad19aace5cba0fd1", true), |
| 249 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libxkbcommon.so.0.0.0", "29ebf0cc0837b321e6a751b9b7d43ae9f8f3f0c0", true), |
| 250 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3", "a155c7bc345d0e0b711be09120204bd88f475f9e", true), |
| 251 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/libzeitgeist-2.0.so.0.0.0", "211049ef6c5ed6e7bbcdc75c0a25d1f11755151d", true), |
| 252 | new UstDebugInfoBinaryFile("/usr/lib/x86_64-linux-gnu/url-dispatcher/url-dispatcher", "694fcf16ee9241e66a33de671d10f854312e0c87", false)); |
| 253 | |
| 254 | Comparator<UstDebugInfoBinaryFile> comparator = Comparator.comparing(UstDebugInfoBinaryFile::getFilePath); |
| 255 | actualBinaries.sort(comparator); |
| 256 | expectedBinaries.sort(comparator); |
| 257 | |
| 258 | /* Highlights failures more easily */ |
| 259 | for (int i = 0; i < expectedBinaries.size(); i++) { |
| 260 | assertEquals(expectedBinaries.get(i), actualBinaries.get(i)); |
| 261 | } |
| 262 | |
| 263 | assertEquals(actualBinaries, expectedBinaries); |
| 264 | } |
| 265 | |
| 266 | } |