1 /*******************************************************************************
2 * Copyright (c) 2013 Ericsson
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * Matthew Khouzam - Initial API and implementation
10 *******************************************************************************/
12 package org
.eclipse
.linuxtools
.ctf
.core
.tests
.trace
;
14 import static org
.junit
.Assert
.*;
17 import java
.io
.FileOutputStream
;
18 import java
.io
.FileWriter
;
19 import java
.io
.IOException
;
20 import java
.util
.HashMap
;
22 import org
.eclipse
.linuxtools
.ctf
.core
.event
.IEventDeclaration
;
23 import org
.eclipse
.linuxtools
.ctf
.core
.trace
.CTFReaderException
;
24 import org
.eclipse
.linuxtools
.ctf
.core
.trace
.CTFTrace
;
25 import org
.eclipse
.linuxtools
.internal
.ctf
.core
.event
.EventDeclaration
;
26 import org
.eclipse
.linuxtools
.internal
.ctf
.core
.event
.metadata
.IOStructGen
;
27 import org
.junit
.Test
;
30 * Unit tests for {@link IOStructGen}
32 * @author Matthew Khouzam
34 @SuppressWarnings("nls")
35 public class IOstructgenTest
{
38 private static final String metadataDecs
= "typealias integer { size = 8; align = 8; signed = false; } := uint8_t;\n"
39 + "typealias integer { size = 16; align = 8; signed = false; } := uint16_t;\n"
40 + "typealias integer { size = 32; align = 8; signed = false; } := uint32_t;\n"
41 + "typealias integer { size = 64; align = 8; signed = false; } := uint64_t;\n"
42 + "typealias integer { size = 64; align = 8; signed = false; } := unsigned long;\n"
43 + "typealias integer { size = 5; align = 1; signed = false; } := uint5_t;\n"
44 + "typealias integer { size = 27; align = 1; signed = false; } := uint27_t;\n"
45 + "typealias integer { size = 32; align = 1; signed = true; base = decimal; } := int32_t;\n"
46 + "typealias integer { size = 31; align = 1; signed = true; base = dec; } := int31_t;\n"
47 + "typealias integer { size = 30; align = 1; signed = true; base = d; } := int30_t;\n"
48 + "typealias integer { size = 29; align = 1; signed = true; base = i; } := int29_t;\n"
49 + "typealias integer { size = 28; align = 1; signed = true; base = u; } := int28_t;\n"
50 + "typealias integer { size = 27; align = 1; signed = true; base = hexadecimal; } := int27_t;\n"
51 + "typealias integer { size = 26; align = 1; signed = true; base = hex; } := int26_t;\n"
52 + "typealias integer { size = 25; align = 1; signed = true; base = x; } := int25_t;\n"
53 + "typealias integer { size = 24; align = 1; signed = true; base = X; } := int24_t;\n"
54 + "typealias integer { size = 23; align = 1; signed = true; base = p; } := int23_t;\n"
55 + "typealias integer { size = 22; align = 1; signed = true; base = 16; } := int22_t;\n"
56 + "typealias integer { size = 21; align = 1; signed = true; base = oct; } := int21_t;\n"
57 + "typealias integer { size = 20; align = 1; signed = true; base = b; } := int20_t;\n"
58 + "typealias integer { size = 19; align = 1; signed = true; base = octal; } := int19_t;\n"
59 + "typealias integer { size = 18; align = 1; signed = true; base = o; } := int18_t;\n"
60 + "typealias integer { size = 17; align = 1; signed = true; base = binary; } := int17_t;\n"
65 + " uuid = \"b04d391b-e736-44c1-8d89-4bb438857f8d\";\n"
66 + " byte_order = le;\n"
67 + " packet.header := struct {\n"
68 + " uint32_t magic;\n"
69 + " uint8_t uuid[16];\n"
70 + " uint32_t stream_id;\n" + " };\n" + "};\n" + "\n";
71 private static final String environmentMD
= "env {\n"
72 + " hostname = \"DemoSystem\";\n"
74 + " procname = \"demo\";\n"
75 + " domain = \"autogenerated\";\n"
76 + " tracer_name = \"tmf\";\n"
77 + " tracer_major = 2;\n"
78 + " tracer_minor = 0x01;\n"
79 + " tracer_patchlevel = 0;\n"
81 private static final String clockMD
= "clock {\n" + " name = monotonic;\n"
82 + " uuid = \"cbf9f42e-9be7-4798-a96f-11db556e2ebb\";\n"
83 + " description = \"Monotonic Clock\";\n"
84 + " freq = 1000000000; /* Frequency, in Hz */\n"
85 + " /* clock value offset from Epoch is: offset * (1/freq) */\n"
86 + " offset = 1350310657466295832;\n" + "};\n"
89 private static final String ctfStart
=
90 "typealias integer {\n"
91 + " size = 27; align = 1; signed = false;\n"
92 + " map = clock.monotonic.value;\n"
93 + "} := uint27_clock_monotonic_t;\n"
95 + "typealias integer {\n"
96 + " size = 32; align = 8; signed = false;\n"
97 + " map = clock.monotonic.value;\n"
98 + "} := uint32_clock_monotonic_t;\n"
100 + "typealias integer {\n"
101 + " size = 64; align = 8; signed = false;\n"
102 + " map = clock.monotonic.value;\n"
103 + "} := uint64_clock_monotonic_t;\n"
107 private static final String ctfHeaders
=
108 "struct packet_context {\n"
109 + " uint64_clock_monotonic_t timestamp_begin;\n"
110 + " uint64_clock_monotonic_t timestamp_end;\n"
111 + " uint64_t content_size;\n"
112 + " uint64_t packet_size;\n"
113 + " unsigned long events_discarded;\n"
114 + " uint32_t cpu_id;\n"
117 + "struct event_header_compact {\n"
118 + " enum : uint5_t { compact = 0 ... 30, extended = 31 } id;\n"
119 + " variant <id> {\n"
121 + " uint27_clock_monotonic_t timestamp;\n"
125 + " uint64_clock_monotonic_t timestamp;\n"
130 + "struct event_header_large {\n"
131 + " enum : uint16_t { compact = 0 ... 65534, extended = 65535 } id;\n"
132 + " variant <id> {\n" + " struct {\n"
133 + " uint32_clock_monotonic_t timestamp;\n"
134 + " } compact;\n" + " struct {\n"
136 + " uint64_clock_monotonic_t timestamp;\n"
137 + " } extended;\n" + " } v;\n" + "} align(8);\n" + "\n";
139 private static final String ctfBody
= "stream {\n"
141 + " event.header := struct event_header_compact;\n"
142 + " packet.context := struct packet_context;\n"
143 + " event.context := struct {\n"
144 + " integer { size = 64; align = 8; signed = 0; encoding = none; base = 16; } _ip;\n"
149 + " name = \"ust_tests_demo3:done\";\n"
151 + " stream_id = 0;\n"
153 + " fields := struct {\n"
154 + " integer { size = 32; align = 8; signed = 1; encoding = none; base = 10; } _value;\n"
159 + " name = \"ust_tests_demo:starting\";\n"
161 + " stream_id = 0;\n"
163 + " model.emf.uri = \"http://example.com/path_to_model?q=ust_tests_demo:starting\";\n"
164 + " fields := struct {\n"
165 + " integer { size = 32; align = 8; signed = 1; encoding = none; base = 10; } _value;\n"
170 + " name = \"ust_tests_demo:done\";\n"
172 + " stream_id = 0;\n"
174 + " model.emf.uri = \"http://example.com/path_to_model?q=ust_tests_demo:done\";\n"
175 + " fields := struct {\n"
176 + " integer { size = 32; align = 8; signed = 1; encoding = none; base = 10; } _value;\n"
181 + " name = \"ust_tests_demo2:loop\";\n"
183 + " stream_id = 0;\n"
185 + " fields := struct {\n"
186 + " integer { size = 32; align = 8; signed = 1; encoding = none; base = 10; } _intfield;\n"
187 + " integer { size = 32; align = 8; signed = 1; encoding = none; base = 16; } _intfield2;\n"
188 + " integer { size = 64; align = 8; signed = 1; encoding = none; base = 10; } _longfield;\n"
189 + " integer { size = 32; align = 8; signed = 1; encoding = none; base = 10; byte_order = be; } _netintfield;\n"
190 + " integer { size = 32; align = 8; signed = 1; encoding = none; base = 16; byte_order = be; } _netintfieldhex;\n"
191 + " integer { size = 64; align = 8; signed = 1; encoding = none; base = 10; } _arrfield1[3];\n"
192 + " integer { size = 8; align = 8; signed = 1; encoding = UTF8; base = 10; } _arrfield2[10];\n"
193 + " integer { size = 64; align = 8; signed = 0; encoding = none; base = 10; } __seqfield1_length;\n"
194 + " integer { size = 8; align = 8; signed = 1; encoding = none; base = 10; } _seqfield1[ __seqfield1_length ];\n"
195 + " integer { size = 64; align = 8; signed = 0; encoding = none; base = 10; } __seqfield2_length;\n"
196 + " integer { size = 8; align = 8; signed = 1; encoding = UTF8; base = 10; } _seqfield2[ __seqfield2_length ];\n"
197 + " string _stringfield;\n"
198 + " floating_point { exp_dig = 8; mant_dig = 24; align = 8; } _floatfield;\n"
199 + " floating_point { exp_dig = 11; mant_dig = 53; align = 8; } _doublefield;\n"
204 private static final String enumMd
=
205 "typealias integer { size = 32; align = 8; signed = false; } := int;\n"
206 + "typealias enum { ONE = 0, a,b,c=10, d} := useless_enum;\n"
207 + "struct useless{ \n"
208 + " enum : uint8_t { A=0, \"B\",} enum3;\n"
209 + " useless_enum enum2;"
210 + " enum { C, D, E } enum4;\n"
215 + " name = \"enumEvent\";\n"
217 + " stream_id = 0;\n"
219 + " fields := struct{\n"
220 + " uint16_t _some_field;\n"
221 // + " useless junk;\n"
222 // + " bad_enum a;\n"
223 + " enum {A, B, C = 3 , } _other_enum;\n"
228 private final static String contextMD
=
230 " name = \"someOtherEvent\";\n" +
232 " stream_id = 0;\n" +
234 " context := struct{\n" +
235 " uint16_t _someContext;\n" +
237 " fields := struct{\n" +
238 " uint16_t _somefield;\n" +
243 private static final String callsiteMD
=
245 + " name = \"ust_tests_demo2:loop\";\n"
246 + " func = \"main\";\n" + " ip = 0x400a29;\n"
247 + " file = \"demo.c\";\n" + " line = 59;\n" + "};\n" + "\n"
248 + "callsite {\n" + " name = \"ust_tests_demo3:done\";\n"
249 + " func = \"main\";\n" + " ip = 0x400a6c;\n"
250 + " file = \"demo.c\";\n" + " line = 62;\n" + "};\n" + "\n"
251 + "callsite {\n" + " name = \"ust_tests_demo:done\";\n"
252 + " func = \"main\";\n" + " ip = 0x400aaf;\n"
253 + " file = \"demo.c\";\n" + " line = 61;\n" + "};\n" + "\n"
254 + "callsite {\n" + " name = \"ust_tests_demo:starting\";\n"
255 + " func = \"main\";\n" + " ip = 0x400af2;\n"
256 + " file = \"demo.c\";\n" + " line = 55;\n" + "};\n";
258 private static final String simpleTSDL
= metadataDecs
+ ctfStart
+ ctfHeaders
260 private static final String enumTSDL
= metadataDecs
+ ctfStart
+ ctfHeaders
262 private static final String clockTSDL
= metadataDecs
+ clockMD
+ ctfStart
263 + ctfHeaders
+ ctfBody
;
264 private static final String envTSDL
= metadataDecs
+ environmentMD
+ ctfStart
265 + ctfHeaders
+ ctfBody
;
266 private static final String contextTSDL
= metadataDecs
+ environmentMD
+ ctfStart
267 + ctfHeaders
+ ctfBody
+contextMD
;
268 private static final String callsiteTSDL
= metadataDecs
+ ctfStart
+ ctfHeaders
269 + ctfBody
+ callsiteMD
;
270 private static final String allDressedTSDL
= metadataDecs
+ environmentMD
+ clockMD
271 + ctfStart
+ ctfHeaders
+ ctfBody
+enumMd
+ callsiteMD
;
273 static final String tempTraceDir
= System
.getProperty("java.io.tmpdir")
276 private static void deltree(File f
) {
277 for (File elem
: f
.listFiles()) {
278 if (elem
.isDirectory()) {
286 private static void createDummyTrace(String metadata
) {
290 f
= new File(tempTraceDir
);
295 f
= new File(tempTraceDir
+ "/metadata"); //$NON-NLS-1$
296 FileWriter fw
= new FileWriter(f
);
301 byte magicLE
[] = { (byte) 0xC1, (byte) 0x1F, (byte) 0xFC, (byte) 0xC1 };
302 byte uuid
[] = { (byte) 0xb0, 0x4d, 0x39, 0x1b, (byte) 0xe7, 0x36,
303 0x44, (byte) 0xc1, (byte) 0x8d, (byte) 0x89, 0x4b,
304 (byte) 0xb4, 0x38, (byte) 0x85, 0x7f, (byte) 0x8d };
305 final int size
= 4096;
306 byte[] data
= new byte[size
];
307 for (int i
= 0; i
< size
; i
++) {
310 f
= new File(tempTraceDir
+ "/dummyChan"); //$NON-NLS-1$
311 fw
= new FileWriter(f
);
312 FileOutputStream fos
= new FileOutputStream(f
);
319 } catch (IOException e
) {
328 * Simple test (only the minimum)
329 * @throws CTFReaderException something wrong happened
332 public void TSDLSimpleTest() throws CTFReaderException
{
333 createDummyTrace(simpleTSDL
);
334 CTFTrace trace
= new CTFTrace(tempTraceDir
);
335 assertNotNull(trace
);
340 * Test with environment variables
341 * @throws CTFReaderException something wrong happened
344 public void TSDLEnvironmentTest() throws CTFReaderException
{
345 createDummyTrace(envTSDL
);
346 CTFTrace trace
= new CTFTrace(tempTraceDir
);
347 assertNotNull(trace
);
352 * @throws CTFReaderException something wrong happened
355 public void TSDLEnumTest() throws CTFReaderException
{
356 createDummyTrace(enumTSDL
);
357 CTFTrace trace
= new CTFTrace(tempTraceDir
);
358 assertNotNull(trace
);
363 * @throws CTFReaderException something wrong happened
366 public void TSDLClockTest() throws CTFReaderException
{
367 createDummyTrace(clockTSDL
);
368 CTFTrace trace
= new CTFTrace(tempTraceDir
);
369 assertNotNull(trace
);
374 * @throws CTFReaderException something wrong happened
377 public void TSDLContextTest() throws CTFReaderException
{
378 createDummyTrace(contextTSDL
);
379 CTFTrace trace
= new CTFTrace(tempTraceDir
);
380 assertNotNull(trace
);
384 * Test with Callsites
385 * @throws CTFReaderException something wrong happened
388 public void TSDLCallsiteTest() throws CTFReaderException
{
389 createDummyTrace(callsiteTSDL
);
390 CTFTrace trace
= new CTFTrace(tempTraceDir
);
391 assertNotNull(trace
);
396 * @throws CTFReaderException something wrong happened
399 public void TSDLAllTest() throws CTFReaderException
{
400 createDummyTrace(allDressedTSDL
);
401 CTFTrace trace
= new CTFTrace(tempTraceDir
);
402 assertNotNull(trace
);
404 HashMap
<Long
, IEventDeclaration
> events
= trace
.getEvents(0L);
405 final EventDeclaration eventDeclaration
= (EventDeclaration
) events
.get(2L);
406 assertEquals("http://example.com/path_to_model?q=ust_tests_demo:done",
407 eventDeclaration
.getCustomAttribute("model.emf.uri"));