Sync with 5.4.0
[deliverable/titan.core.git] / regression_test / slider / dual.ttcn
1 /******************************************************************************
2 * Copyright (c) 2000-2015 Ericsson Telecom AB
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
7 ******************************************************************************/
8 module dual { // straight off 4.21.8 of reference guide
9
10 // PDU types to be sent and received on the ports
11 type record ControlRequest {
12 charstring text
13 }
14
15 type record ControlResponse{
16 charstring text
17 }
18
19 type record ErrorSignal {
20 charstring err
21 }
22
23 type record PDUType1 {
24 charstring text
25 }
26 with { variant "/* dummy */" }
27
28 type record PDUType2 {
29 charstring text
30 }
31 with { variant (text) "FIELDLENGTH(8)" }
32
33 type record of charstring strings
34 with { variant "/* dummy */" }
35
36 type record of octetstring blob
37 with { variant "/* dummy */" }
38
39
40 // the encoder/decoder functions are written in C++
41 external function enc_PDUType1(in PDUType1 par) return octetstring
42 // there was a typo here ------------^ (was lowercase t)
43 with { extension "prototype(convert)" }
44
45 // Same as above, but generated by the compiler
46 external function enc_PDUType1_gen(in PDUType1 par) return octetstring
47 with { extension "prototype(convert) encode(RAW)" }
48
49
50 // another conversion function in C++
51 external function dec_PDUType1(in octetstring stream,
52 out PDUType1 result) return integer
53 with { extension "prototype(backtrack)" }
54
55 // Again, generated by the compiler
56 external function dec_PDUType1_gen(in octetstring stream,
57 out PDUType1 result) return integer
58 with { extension "prototype(backtrack) decode(RAW)" }
59
60 // And now, something completely different! Sliding decoding!
61
62 // Hand-written decoder function
63 external function dec_slider(inout octetstring stream, out PDUType1 result) return integer
64 with { extension "prototype(sliding)" }
65
66 // Compiler-generated
67 external function dec_slider_gen(inout octetstring stream, out PDUType1 result) return integer
68 with { extension "prototype(sliding) decode(RAW) errorbehavior(INCOMPL_MSG:IGNORE, LEN_ERR:IGNORE)" }
69
70 // Compiler-generated
71 external function dec_slider_gen2(inout octetstring stream, out PDUType2 result) return integer
72 with { extension "prototype(sliding) decode(RAW) errorbehavior(INCOMPL_MSG:IGNORE, LEN_ERR:IGNORE)" }
73
74 // Various other prototypes
75 external function dec_blob_fast(in octetstring stream, out blob val)
76 with { extension "prototype(fast) decode(RAW)" }
77
78 external function dec_strings(in octetstring stream) return strings
79 with { extension "prototype(convert) decode(RAW)" }
80
81 external function bk_strings(in octetstring stream, out strings s) return integer
82 with { extension "prototype(backtrack) decode(RAW)" }
83
84 external function slide_strings(inout octetstring strm, out strings val) return integer
85 with { extension "prototype(sliding) decode(RAW)" }
86
87 function bogus(in octetstring i, out ControlRequest o) return integer
88 {
89 // Yes, you can do this.
90 // If you can decode a ControlRequest in TTCN-3 code, go right ahead.
91 // It's more likely to be useful when mapping from one user-defined type
92 // to another (e.g. shuffling fields from one record to another).
93 // Implementing RAW decoding is going to be a bit more tricky...
94 o := { oct2char(i) }; // living dangerously...
95 return 0;
96 }
97 with { extension "prototype(backtrack)" }
98
99
100 /************************************ The ports ************************************/
101
102 // port type PT1 is the external interface of the dual-faced port
103 // with its own Test Port. See section "The purpose of Test Ports" in the API guide.
104 type port PT1 message {
105 out ControlRequest;
106 in ControlResponse;
107 in ErrorSignal;
108 inout octetstring;
109 out PDUType1;
110 } with { extension "provider" }
111
112 // port type PT2 is the internal interface of the dual-faced port
113 // This port is communicating (in)directly with the SUT using the Test Port of PT1.
114 type port PT2 message {
115 in ControlResponse;
116 out ControlRequest;
117 // out ErrorSignal; // this is bogus
118 inout PDUType1, PDUType2;
119 // out octetstring;
120 inout octetstring;
121 in strings, blob;
122 } with { extension "user PT1
123 out(ControlRequest -> ControlRequest: simple; /* no conversion */
124 PDUType1 -> octetstring: function(enc_PDUType1); /* call function */
125 PDUType2 -> octetstring: encode(RAW)) /* call built-in codec */
126
127 /* Multi-target out mapping ???? */
128 out(octetstring -> octetstring : decode(RAW),
129 ControlRequest : function(bogus),
130 - : discard)
131
132 in(ControlResponse -> ControlResponse : simple; /* no conversion */
133 ErrorSignal -> - : discard; /* drop */
134 octetstring -> PDUType1: function(dec_PDUType1), /* call function */
135 PDUType2: decode(RAW), /* built-in decoder */
136 - : discard)"
137 }
138
139 // As above, but uses the generated converter functions
140 type port PT2GEN message {
141 in ControlResponse;
142 out ControlRequest;
143 // out ErrorSignal; // this is bogus
144 inout PDUType1, PDUType2;
145 inout octetstring;
146 in strings, blob;
147 } with { extension "user PT1
148 out(ControlRequest -> ControlRequest: simple; /* no conversion */
149 PDUType1 -> octetstring: function(enc_PDUType1_gen); /* call function */
150 PDUType2 -> octetstring: encode(RAW); /* call built-in codec */
151 octetstring -> PDUType1: function(dec_slider_gen) /* outgoing map with a prototype(sliding) decode(...) !! */
152 )
153
154 in(ControlResponse -> ControlResponse : simple; /* no conversion */
155 ErrorSignal -> - : discard; /* drop */
156 octetstring -> PDUType2: function(dec_slider_gen2) /* call function; prototype(sliding) */
157 , PDUType1: decode(RAW) /* built-in decoder */
158 , strings : function(slide_strings)
159 , blob : decode(RAW)
160 /*, strings : function(bk_strings) /* call function; protoype(backtrack)
161 /* , strings : function(dec_strings) /* call function; protoype(convert) */
162 /* , blob : function(dec_blob_fast) /* call function; protoype(fast) */
163 /* prototype(backtrack) cannot be used when prototype(sliding) is present,
164 although code gen for sliding is not supported */
165 /*, - : discard cannot be used when proto sliding is present */)"
166 }
167
168 type port STRINGPORT message
169 {
170 in strings;
171 }
172 with {
173 extension "user PT1
174 in(octetstring -> strings : function(dec_strings) /* call function; protoype(convert) */
175 ; ControlResponse -> - : discard
176 ; ErrorSignal -> - : discard )"
177 }
178
179 type port FASTPORT message
180 {
181 in blob
182 }
183 with {
184 extension "user PT1
185 in(octetstring -> blob : function(dec_blob_fast) /* call function; protoype(fast) */
186 ; ControlResponse -> - : discard
187 ; ErrorSignal -> - : discard )"
188
189 }
190
191
192
193 type component MTC_CT {
194 // port PT2 MTC_PORT;
195 port PT2GEN MTC_PORT;
196 }
197
198 type component SYSTEM_SCT {
199 port PT1 SYSTEM_PORT;
200 //port PT1 ANOTHER_SYSTEM_PORT;
201 }
202
203 testcase tc_DUALFACED_func () runs on MTC_CT system SYSTEM_SCT
204 {
205 map(mtc:MTC_PORT, system:SYSTEM_PORT);
206 //map(mtc:MTC_PORT, system:ANOTHER_SYSTEM_PORT);
207 // a second (different) mapping completely prevents sending of messages on the port
208
209 // Send in twice the FIELDLENGTH of PDUType2. This should be decoded
210 // as *two* consecutive incoming messages.
211 MTC_PORT.send(PDUType1 : {"type: 1!type: 2!"});
212 /** MTC_PORT is a PT2GEN, a "user" port. It uses the PT1 "provider" port.
213 * It has no user-conrollable parts; no skeleton is generated.
214 * Sending a PDUType1 calls enc_PDUType1_gen to transform it into octetstring
215 * which is the sent through PT1_PROVIDER::otgoing_send.
216 * PT1 is the provder; it is a "real" port with a skeleton.
217 *
218 * PT1_PROVIDER::otgoing_send is written to call PT2GEN::incoming_message
219 * (because it's a fake port; a real one would call incoming_message
220 * from an event handler). PT2GEN is derived from PT1_PROVIDER.
221 * Here the incoming mapping happens.
222 ***/
223 timer t := 3.0;
224 t.start;
225 alt {
226 [] MTC_PORT.receive(PDUType2 : {"type: 1!"}) { setverdict(pass, "got PDU2"); }
227 [] MTC_PORT.receive /* anything else */{ setverdict(fail, "got unknown response"); }
228 [] t.timeout { setverdict(fail, "time-out"); }
229 }
230 t.stop;
231 t.start;
232 alt {
233 [] MTC_PORT.receive(PDUType2 : {"type: 2!"}) { setverdict(pass, "got PDU2"); }
234 [] MTC_PORT.receive /* anything else */{ setverdict(fail, "got unknown response"); }
235 [] t.timeout { setverdict(fail, "time-out"); }
236 }
237 unmap(mtc:MTC_PORT, system:SYSTEM_PORT);
238 }
239
240 testcase tc_DUALFACED_simple () runs on MTC_CT system SYSTEM_SCT
241 {
242 map(mtc:MTC_PORT, system:SYSTEM_PORT);
243
244 MTC_PORT.send(ControlRequest:{ "CReq from simple" });
245 timer t := 3.0;
246 t.start;
247 // When the port gets a ControlRequest which begins with 'C', it sends back a ControlResponse
248 alt {
249 [] MTC_PORT.receive(ControlResponse:?) { setverdict(pass /* , "got response" */); }
250 [] MTC_PORT.receive /* anything else */{ setverdict(fail, "got unknown response"); }
251 [] t.timeout { setverdict(fail, "time-out"); }
252 }
253
254 // v2
255 t.stop;
256 MTC_PORT.send(ControlRequest:{ "Another CReq from simple" });
257 t.start;
258 // Because the text in the ControlRequest does not start with a 'C',
259 // the port sends back an ErrorSignal... which is discarded by the incoming mapping.
260 alt {
261 [] MTC_PORT.receive(ControlResponse:?) { setverdict(fail, "got WRONG response"); }
262 [] MTC_PORT.receive /* anything else */{ setverdict(fail, "got unknown response"); }
263 [else] /* nothing received */ { setverdict(pass); }
264 }
265
266 unmap(mtc:MTC_PORT, system:SYSTEM_PORT);
267 }
268
269 testcase tc_DUALFACED_slid() runs on MTC_CT system SYSTEM_SCT
270 {
271 map(mtc:MTC_PORT, system:SYSTEM_PORT);
272 var PDUType1 p1 := { "Ulysses!" };
273 var PDUType2 p2 := { p1.text };
274 var octetstring output := enc_PDUType1(p1);
275 MTC_PORT.send(output);
276 timer t := 3.0;
277 t.start;
278 //
279 alt {
280 [] MTC_PORT.receive(PDUType2 : p2) { setverdict(pass); }
281 [] MTC_PORT.receive /* anything else */ { setverdict(fail, "got unknown response"); }
282 [] t.timeout { setverdict(fail, "time-out at ", __LINE__); }
283 }
284 t.stop;
285
286 /*** test that sending a message in two parts gets reassembled ***/
287 var integer len := lengthof(output);
288 var integer half_len := len / 2;
289 // Send the first half \\
290 var octetstring first_half := substr(output, 0, half_len);
291 MTC_PORT.send(first_half);
292 t.start;
293 alt {
294 [] MTC_PORT.receive /* anything */ {
295 setverdict(fail, "It wasn't supposed to receive anything yet");
296 }
297 [else] /* nothing received */ { setverdict(pass); }
298 }
299 t.stop;
300
301 // Send the second half \\
302 var octetstring second_half := substr(output, half_len, len - half_len);
303 MTC_PORT.send(second_half);
304 t.start;
305 alt {
306 [] MTC_PORT.receive(PDUType2 : p2) { setverdict(pass); }
307 [] MTC_PORT.receive /* anything else */ { setverdict(fail, "got unknown response"); }
308 [] t.timeout { setverdict(fail, "time-out at ", __LINE__); }
309 }
310
311 unmap(mtc:MTC_PORT, system:SYSTEM_PORT);
312 }
313
314 control {
315 execute( tc_DUALFACED_simple() );
316 execute( tc_DUALFACED_func() );
317 execute( tc_DUALFACED_slid() );
318 }
319
320 }
321 with {
322 encode "RAW";
323 }
This page took 0.069532 seconds and 5 git commands to generate.