File: 12-tips_%26_troubleshooting.adoc

package info (click to toggle)
eclipse-titan 6.5.0-1
  • links: PTS
  • area: main
  • in suites: buster
  • size: 101,128 kB
  • sloc: cpp: 259,139; ansic: 47,560; yacc: 22,554; makefile: 14,074; sh: 12,630; lex: 9,101; xml: 5,362; java: 4,849; perl: 3,784; awk: 48; php: 32; python: 13
file content (408 lines) | stat: -rw-r--r-- 16,368 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
= Tips & Troubleshooting
:toc:

This chapter deals with various topics, which could not have been assigned to any of the previous chapters.

== Type Aliasing

Type aliasing in TTCN–3 means that you can assign an alternative name to an existing type. The syntax is similar to a subtype definition, but the subtype restriction tag (value list or length restriction) is missing.

`type MyType MyAlternativeName;`

The type aliasing is implemented in the test executor, but it translates this TTCN–3 definition to a C `typedef` statement.

`typedef MyType MyAlternativeName;`

The limitation of the C typedef is that the {cpp} compiler cannot distinguish between the original and alias name in polymorphism (i.e. the identically named functions with parameter type `MyType` and `MyAlternativeName` are treated as same). That is, if you define a port type that allows the sending or receiving both of the original and aliased type, the generated {cpp} code cannot be compiled because the Test Port class contains two identical send/receive function.

As a work-around to this problem you can repeat the definition of the original type using the alternative name instead of type aliasing. In this case two differently named, but identical classes will be generated and the polymorphism problem will not occur.

[[reusing-logged-values-or-templates-in-ttcn-3-code]]
== Reusing Logged Values or Templates in TTCN–3 Code

Writing templates can be time-consuming task. To save some time and work, you can use the logs of the messages already sent or received to write templates.

If you would like to use a logged value in TTCN–3 code, then using the `logformat` utility (see the section 13.3 of the TITAN User Guide [13] about this utility) you have to follow these steps:

. Start a text editor and open the (formatted) log file and the TTCN–3 source file.
. Select and copy the desired value from the log file.
. Paste the value at the corresponding position in the TTCN–3 code.
. Finally, make the following changes:
+
* The enumerated values are followed by their numerical equivalents within parentheses. Delete them including the parentheses.
+
* If an octetstring value contains only visible ASCII characters, then the hexadecimal octetstring notation is followed by its character string representation between quotation marks and parentheses. Delete the character string (including the parentheses).
+
* If a `record`, `set`, `record of` or set of value contains no fields or elements, then the logformat utility changes the value from `{}` to `{(empty)}` in the log. Delete the word (empty) (including parentheses).

[[using-the-ttcn-3-preprocessing-functionality]]
== Using the TTCN-3 Preprocessing Functionality

NOTE: This feature, as preprocessors in general, should be avoided if not absolutely necessary.

Tips for the `Makefile` generated using the option `-p:`

* All the options for the C precompiler can be specified using the variable `CPPFLAGS_TTCN3`. Do not confuse it with the variable `CPPFLAGS`, which is used on the generated {cpp} code. If standard TTCN-3 output is needed the flag `-P` has to be added manually to the variable `CPPFLAGS_TTCN3`. The resulting `ttcn` files can be compiled with any TTCN-3 compiler (if other special language extensions are not used). Globally used preprocessor symbols can be defined here with the option `-D`. For example to compile the debug version of a project a `DEBUG` symbol can be specified with `-DDEBUG`.

* Files which are included in the `.ttcnpp` source files (with `#include`) and do not need to be translated can be specified in the `TTCN3_INCLUDES` variable. These files will be checked for modification when the `.ttcnpp` files are processed by `make`; any modification will trigger preprocessing of all the `.ttcnpp` files and the recompilation of the affected modules. If the suffix of a file is `.ttcnin` the Makefile Generator will add it to `TTCN3_INCLUDES`; in all other cases the file has to be added manually.

* Do not use any file name identical to the name of the intermediate file produced by the C preprocessor. The intermediate file name is generated by replacing the suffix `.ttcnpp` with `.ttcn`. Use the naming convention of naming the file as the module name avoiding such name collisions.

* The default C preprocessor used to preprocess TTCN-3 files can be replaced by editing the CPP variable.

There are minor issues when precompiling TTCN-3 code with a C preprocessor, these are resulting from the differences between the C and TTCN-3 languages. Tips for writing the `.ttcnpp` files:

* Do not define the B, O and H macros, these letters are used as part of the bitstring, octetstring and hexstring tokens in TTCN-3, but the C preprocessor will replace them.

* There are some predefined macros in the C preprocessor which will be always replaced, do not use any TTCN-3 identifier identical to these. These macros start with double underscore followed by uppercase letters. Some of the most common macros which might be useful:

** – *FILE* This macro expands to the name of the current input file, in the form of a C string constant.
** – *LINE* This macro expands to the current input line number, in the form of a decimal integer constant.
** – *DATE* This macro expands to a string constant that describes the date on which the preprocessor is being run.
** – *TIME* This macro expands to a string constant that describes the time at which the preprocessor is being run.

When writing preprocessor directives keep in mind that within the directive the C preprocessor syntax is in use, not the TTCN-3. Operators such as `defined` or || can be used.

Watch out for macro pitfalls, some well known are: side effects, misnesting, and operator precedence problems.

== More Efficient Implementation of the Types record of and set of

The new implementation of the mentioned TTCN types and their ASN counterparts was introduced in TITAN version 1.7.pl2 (R7C). The performance of assigning record of/set of typed variables improved significantly since TITAN version 1.7.pl1 (R7B). The new implementation uses reference counting when an assignment is made. The whole data structure is copied only when necessary, for example, the user wants to modify its value. Using temporary variables improves the quality of the code.

== Workflow for Native XML Support

In this very short and simple example we are presenting and explaining the procedure of using the XML encoding / decoding. Through the steps of the workflow you can understand the XML related possibilities of TITAN.

First look at data types. These are the base of every test. If you have data representation in XML format (XSD is the standard for defining data types), you have to convert it into the equivalent TTCN-3 data types using the XSD converter. This is a shortened variant of the commonly used SOAP protocol.
[source]
----
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.ericsson.com/cai3g1.2/" targetNamespace="http://schemas.ericsson.com/cai3g1.2/" elementFormDefault="qualified" attributeFormDefault="unqualified">

    <xs:element name="Set">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="MOType" type="MoType" />
                <xs:element name="MOId" type="AnyMOIdType" />
                <xs:element name="MOAttributes">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element ref="SetMODefinition" />
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="extension" type="AnySequenceType"
                    minOccurs="0" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="AbstractSetAttributeType" abstract="true"/>

<xs:element name="SetMODefinition"
type="AbstractSetAttributeType" abstract="true"/>

    <xs:complexType name="AnyMOIdType">
        <xs:sequence>
            <xs:any namespace="##any"
processContents="lax" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="AnySequenceType">
        <xs:sequence>
            <xs:any namespace="##any"
processContents="lax" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>

    <xs:simpleType name="MoType">
        <xs:restriction base="xs:string">
            <xs:pattern value="[A-Za-z][_A-Za-z0-9]*@.*"/>
        </xs:restriction>
    </xs:simpleType>

</xs:schema>
----

After conversion you have a TTCN-3 module whose name is derived from the targetNamespace attribute of <schema> element. This module contains only data types. Two other files are generated also with standardized base datatypes:

* UsefulTtcn3Types.ttcn

* XSD.ttcn

The content of the generated TTCN-3 file:
[source]
----
module schemas_ericsson_com_cai3g1_2 {

import from XSD all;

type record Set
{
    MoType mOType,
    AnyMOIdType mOId,
    record {
        SetMODefinition setMODefinition
    } mOAttributes,
    AnySequenceType extension_ optional
}
with {
variant (mOType) "name as capitalized";
variant (mOId) "name as capitalized";
variant (mOAttributes) "name as capitalized";
variant (mOAttributes.setMODefinition) "name as capitalized";
variant (extension_) "name as 'extension'";
};

type record AbstractSetAttributeType
{};

type AbstractSetAttributeType SetMODefinition;

type record AnyMOIdType
{
    record length(1 .. infinity) of XSD.String elem_list
}
with {
variant (elem_list) "untagged";
variant (elem_list[-]) "anyElement";
};

type record AnySequenceType
{
    record length(1 .. infinity) of XSD.String elem_list
}
with {
variant (elem_list) "untagged";
variant (elem_list[-]) "anyElement";
};

type XSD.String MoType /* (pattern "[A-Za-z][_A-Za-z0-9]*@.*") */;

}
with {
encode "XML";
variant "namespace as 'http://schemas.ericsson.com/cai3g1.2/'";
variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'";
variant "elementFormQualified";
}
----

Also manually created type definitions can be used and combined together. This example shows the next module containing also data types.
[source]
----
module SOAP {

import from XSD all;
import from schemas_ericsson_com_cai3g1_2 all;

type record ApplicationHeaderContent
{};

type record ApplicationBodyContent {
    Set setRequest
};

type record SoapEnvelope {
    SoapHeader header optional,
    SoapBody body
}
with {
variant "name as 'Envelope'";
variant (header) "name as capitalized";
variant (body) "name as capitalized";
};

type record of ApplicationHeaderContent SoapHeader;

type union SoapBody {
    XSD.String fault,
    record of ApplicationBodyContent content
}
with {
variant (fault) "name as capitalized";
variant (content) "untagged";
variant (content[-]) "untagged";
};

}
with {
encode "XML";
variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'";
variant "namespace as 'http://schemas.xmlsoap.org/soap/envelope/' prefix 'SOAP-ENV'";
variant "namespace as 'http://schemas.xmlsoap.org/soap/encoding/' prefix 'SOAP-ENC'";
variant "namespace as 'http://schemas.ericsson.com/cai3g1.1/' prefix 'ns3'";
}
----

The XML encoding/decoding can be accessed via external functions. To encode a value of the SoapEnvelope type (the top-level record type in our example) to XML, or to decode XML data into a value of SoapType, we can use external functions like the following:
[source]
----
module SOAP_ExternalFunctions {

import from SOAP all;

external function enc_SOAP(in SoapEnvelope pdu) return octetstring
with { extension "prototype (convert) encode(XER:XER_EXTENDED)" }

external function dec_SOAP(in octetstring stream) return SoapEnvelope
with { extension "prototype (convert) decode(XER:XER_EXTENDED)" }

}
----

The "prototype (convert)" attribute instructs the compiler to generate a {cpp} implementation for each of the external functions (see section 4.22.4 above). This permits the use of the encoding/decoding functions directly from TTCN-3 code.

In case more sophisticated processing is required (or some form of pre/postprocessing), the encoder/decoder functions can be reimplemented in {cpp}. The basic functionality provided by the compiler can be used as a starting point.

NOTE: In this case all the ``with'' attributes in the example above must be removed from the external function declaration (otherwise the compiler will generate the functions again with the same signature and duplicate symbol errors will appear at link time).

For representing the usage of encoding and decoding we created this demo module that contains one template definition and in the testcase we will apply encoding and decoding.
[source]
----
module demo {

import from SOAP all;
import from SOAP_ExternalFunctions all;

template SoapEnvelope SoapTemplate :=
{
  header := omit,
  body := {
    content := { {
        setRequest := {
          mOType       := "JB007",
          mOId         := {
            elem_list := {
             "<catalog><books count='3'/></catalog>",
             "<catalog><movies count='1'/></catalog>"
            }
          },
          mOAttributes := {
            setMODefinition := {
            }
          },
          extension_ := omit
        }
      } }
  }
}


type component SOAP_CT
{
  var octetstring v_encodedPDU, v_decodePDU;
  var SoapEnvelope v_decodedPDU;
}

testcase tc_encdec() runs on SOAP_CT
{
  v_encodedPDU := enc_SOAP(valueof(SoapTemplate));

  v_decodedPDU := dec_SOAP(v_encodedPDU);

  log("Encoded set request (SoapEnvelope): ", v_encodedPDU);
  log("Decoded set request (SoapEnvelope): ", v_decodedPDU);
}

control
{
  execute(tc_encdec());
}

}
----

The complete demo project is now ready. If running the test case a log file will be generated in which we can find the encoded representation of the value and the decoded variant.

The resulting XML encoding:
[source]
----
<ns3:Envelope xmlns:ns3='http://schemas.ericsson.com/cai3g1.1/'>
  <ns3:Body>
    <ns3:ApplicationBodyContent>
      <ns3:setRequest>
        <ns3:MOType>JB007</ns3:MOType>
        <ns3:MOId>
          <catalog><books count='3'/></catalog>
          <catalog><movies count='1'/></catalog>
        </ns3:MOId>
        <ns3:MOAttributes>
          <ns3:SetMODefinition/>
        </ns3:MOAttributes>
      </ns3:setRequest>
    </ns3:ApplicationBodyContent>
  </ns3:Body>
</ns3:Envelope>
The decoded format (a TTCN-3 value of type SoapEnvelope)

{
  header := omit,
  body := {
    content := { {
        setRequest := {
          mOType       := "JB007",
          mOId         := {
            elem_list := {
             "<catalog><books count='3'/></catalog>",
             "<catalog><movies count='1'/></catalog>"
            }
          },
          mOAttributes := {
            setMODefinition := {
            }
          },
          extension_ := omit
        }
      } }
  }
}
----

[[debug-memory-use-of-record-set-of-types]]
== Debug Memory Use of Record/set of Types

One of the common source of the memory leakage in the TTCN test suite is the ever-growing record/set of’s. In order to help the debug of such issue, the test suite should be compiled with `-DTITAN_MEMORY_DEBUG_SET_RECORD_OF` flag added to `CPPFLAGS` in the Makefile.

That flag activates a WARNING log statement, issued after every 1000th element added to the record/set of.

Example:
[source]
----
module test {

type component test_CT {}
type record of charstring roc

testcase tc_test() runs on test_CT
{
    var roc r:={}
    var integer k

    for(k:=0;k<10001;k:=k+1){
      r[sizeof(r)]:="a";
    }
}

control
{
  execute(tc_test())
}

}
----

Running of the example test above will produce the following log:
[source]
----
MTC@esekilxxen1844: Warning: New size of type @test.roc: 1000
MTC@esekilxxen1844: Warning: New size of type @test.roc: 2000
MTC@esekilxxen1844: Warning: New size of type @test.roc: 3000
MTC@esekilxxen1844: Warning: New size of type @test.roc: 4000
MTC@esekilxxen1844: Warning: New size of type @test.roc: 5000
MTC@esekilxxen1844: Warning: New size of type @test.roc: 6000
MTC@esekilxxen1844: Warning: New size of type @test.roc: 7000
MTC@esekilxxen1844: Warning: New size of type @test.roc: 8000
MTC@esekilxxen1844: Warning: New size of type @test.roc: 9000
MTC@esekilxxen1844: Warning: New size of type @test.roc: 10000
----