Sync with 5.4.0
[deliverable/titan.core.git] / regression_test / HQ16404 / HQ16404.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 HQ16404 {
9
10 type port dummyport message { inout integer } with { extension "internal" }
11
12 type component CT{
13 port dummyport p
14 }
15
16 type record of integer RI;
17
18 type union UU
19 {
20 integer a,
21 integer b,
22 charstring s,
23 charstring z,
24 boolean boo
25 };
26
27
28 testcase notOK() runs on CT { // TYPE 1: template change type
29 var template integer a;
30 a:=?;
31 a:=(a, 1); //Dynamic test case error: Copying an
32 // uninitialized/unsupported integer template.
33 // DTE happens because in preparation to transforming itself from AnyValue
34 // to value list template, the variable "a" has already been freed
35 // when the time comes to assign it as the first element of the value list.
36 log(a);
37 setverdict(pass);
38 }
39
40 testcase permut() runs on CT { // no error
41 var template integer a := *;
42 var template RI aa := { permutation (1,2) }
43 aa := { 1, aa[0], 2 };
44 log(aa);
45 setverdict(pass);
46 }
47
48 testcase choice() runs on CT { // TYPE 2: union change alternative
49 var UU vu := { a := 42 }
50
51 vu := { b := vu.a }
52 // This "self-assignment" is NOT working as expected.
53 // C++ code: vu.b() = const_cast< const UU&>(vu).a();
54 // Order of calls:
55 // const INTEGER& UU::a() const -> returns a reference
56 // INTEGER& UU::b() -> deletes field_a and creates field_b
57 // INTEGER& operator=(const INTEGER& other) gets a *freed* "other" object!
58 // Yay for undefined behavior!
59 //
60 // Note that when compiled with clang, UU::b() is called *before* UU::a() const,
61 // which means that UU::a() throws a DTE (because a is not the selected alternative anymore).
62
63 if (ischosen(vu.b)) { setverdict(pass); }
64 else { setverdict(fail, "b should be chosen"); }
65 if (isvalue (vu.b)) { setverdict(pass); }
66 else { setverdict(fail, "b should be bound"); }
67 if (vu.b == 42) { setverdict(pass); }
68 else { setverdict(fail, match(vu.b, 42)); }
69
70 vu := { s := log2str(vu.b) };
71 if (ischosen(vu.s)) { setverdict(pass); }
72 else { setverdict(fail, "s should be chosen"); }
73 if (isvalue (vu.s)) { setverdict(pass); }
74 else { setverdict(fail, "s should be bound"); }
75 if (vu.s == "42") { setverdict(pass); }
76 else { setverdict(fail, match(vu.s, "42")); }
77
78 vu := { b := 42 } // reset again to 42
79 vu := { s := log2str(vu.b + 1) }; // now try it with an expression instead of a reference
80 if (ischosen(vu.s)) { setverdict(pass); }
81 else { setverdict(fail, "s should be chosen"); }
82 if (isvalue (vu.s)) { setverdict(pass); }
83 else { setverdict(fail, "s should be bound"); }
84 if (vu.s == "43") { setverdict(pass); }
85 else { setverdict(fail, match(vu.s, "43")); }
86
87 vu := { boo := ischosen(vu.s) }
88 if (ischosen(vu.boo)) { setverdict(pass); }
89 else { setverdict(fail, "boo should be chosen"); }
90 if (isvalue (vu.boo)) { setverdict(pass); }
91 else { setverdict(fail, "boo should be bound"); }
92 if (vu.boo) { setverdict(pass); }
93 else { setverdict(fail, match(vu.boo, true)); }
94
95 vu.s := "Presence";
96 vu := { boo := ispresent(vu.s) }
97 if (ischosen(vu.boo)) { setverdict(pass); }
98 else { setverdict(fail, "boo should be chosen"); }
99 if (isvalue (vu.boo)) { setverdict(pass); }
100 else { setverdict(fail, "boo should be bound"); }
101 if (vu.boo) { setverdict(pass); }
102 else { setverdict(fail, match(vu.boo, true)); }
103 }
104
105 testcase choice_template() runs on CT { // TYPE 2: union change alternative
106 var template UU vtu := { a := 42 }
107
108 vtu := { b := vtu.a }
109 // This "self-assignment" is NOT working as expected.
110 // C++ code: vtu.b() = const_cast< const UU&>(vtu).a();
111 // Order of calls:
112 // const INTEGER& UU::a() const -> returns a reference
113 // INTEGER& UU::b() -> deletes field_a and creates field_b
114 // INTEGER& operator=(const INTEGER& other) gets a *freed* "other" object!
115 // Yay for undefined behavior!
116 //
117 // Note that when compiled with clang, UU::b() is called *before* UU::a() const,
118 // which means that UU::a() throws a DTE (because a is not the selected alternative anymore).
119
120 if (ischosen(vtu.b)) { setverdict(pass); }
121 else { setverdict(fail, "b should be chosen"); }
122 if (isvalue (vtu.b)) { setverdict(pass); }
123 else { setverdict(fail, "b should be bound"); }
124 if (valueof(vtu.b) == 42) { setverdict(pass); }
125 else { setverdict(fail, match(valueof(vtu.b), 42)); }
126
127 vtu := { s := log2str(vtu.b) };
128 if (ischosen(vtu.s)) { setverdict(pass); }
129 else { setverdict(fail, "s should be chosen"); }
130 if (isvalue (vtu.s)) { setverdict(pass); }
131 else { setverdict(fail, "s should be bound"); }
132 if (valueof(vtu.s) == "42") { setverdict(pass); }
133 else { setverdict(fail, match(valueof(vtu.s), "42")); }
134
135 vtu := { b := 42 } // reset again to 42
136 vtu := { s := log2str(valueof(vtu.b) + 1) }; // now try it with an expression instead of a reference
137 if (ischosen(vtu.s)) { setverdict(pass); }
138 else { setverdict(fail, "s should be chosen"); }
139 if (isvalue (vtu.s)) { setverdict(pass); }
140 else { setverdict(fail, "s should be bound"); }
141 if (valueof(vtu.s) == "43") { setverdict(pass); }
142 else { setverdict(fail, match(valueof(vtu.s), "43")); }
143
144 vtu := { boo := ischosen(vtu.s) }
145 if (ischosen(vtu.boo)) { setverdict(pass); }
146 else { setverdict(fail, "boo should be chosen"); }
147 if (isvalue (vtu.boo)) { setverdict(pass); }
148 else { setverdict(fail, "boo should be bound"); }
149 if (valueof(vtu.boo)) { setverdict(pass); }
150 else { setverdict(fail, match(valueof(vtu.boo), true)); }
151
152 vtu.s := omit;
153 vtu := { boo := ispresent(vtu.s) }
154 if (ischosen(vtu.boo)) { setverdict(pass); }
155 else { setverdict(fail, "boo should be chosen"); }
156 if (isvalue (vtu.boo)) { setverdict(pass); }
157 else { setverdict(fail, "boo should be bound"); }
158 if (not valueof(vtu.boo)) { setverdict(pass); }
159 else { setverdict(fail, match(valueof(vtu.boo), false)); }
160 }
161
162 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
163
164 // A for loop contains two assignments. Each can be affected by self-assignment.
165 testcase loop() runs on CT { // TYPE 2: union change alternative
166 var UU vu := { a := 43 }
167 // This loop is not here for its loopyness; we're just interested
168 // in the initialization and "increment" statements.
169 // In fact, we only go through this infinite loop twice.
170 for ( vu := { b := vu.a }; true; vu := { s := int2str(vu.b) } ) {
171 if (ischosen(vu.a)) { setverdict(fail, "It cannot be a"); }
172 else {
173 if (ischosen(vu.b)) { // we passed the init statement
174 if (isvalue (vu.b)) { setverdict(pass); }
175 else { setverdict(fail, "b shoudl be bound"); }
176 }
177 else if (ischosen(vu.s)) {
178 // we passed the "increment" statement
179 if (vu.s == "43") { setverdict(pass); }
180 else { setverdict(fail, match(vu.s, "43")); }
181 break; // escape the loop
182 }
183 }
184 }
185 action(vu);
186 }
187
188 testcase naked_loop() runs on CT { // TYPE 2: union change alternative
189 var UU vu := { a := 53 }
190 // This loop is not here for its loopyness; we're just interested
191 // in the initialization and "increment" statements.
192 // In fact, we only go through this infinite loop twice.
193 for ( vu.b := vu.a; true; vu.s := int2str(vu.b) ) {
194 if (ischosen(vu.a)) { setverdict(fail, "It cannot be a"); }
195 else {
196 if (ischosen(vu.b)) { // we passed the init statement
197 if (isvalue (vu.b)) { setverdict(pass); }
198 else { setverdict(fail, "b shoudl be bound"); }
199 }
200 else if (ischosen(vu.s)) {
201 // we passed the "increment" statement
202 if (vu.s == "53") { setverdict(pass); }
203 else { setverdict(fail, match(vu.s, "53")); }
204 break; // escape the loop
205 }
206 }
207 }
208 //action(vu);
209 }
210
211 testcase loop_template() runs on CT { // TYPE 2: union change alternative
212 var template UU vtu := { a := 63 }
213 // This loop is not here for its loopyness; we're just interested
214 // in the initialization and "increment" statements.
215 // In fact, we only go through this infinite loop twice.
216 for ( vtu := { b := vtu.a }; true; vtu := { s := int2str(valueof(vtu.b)) } ) {
217 if (ischosen(vtu.a)) { setverdict(fail, "It cannot be a"); }
218 else {
219 if (ischosen(vtu.b)) { // we passed the init statement
220 if (isvalue (vtu.b)) { setverdict(pass); }
221 else { setverdict(fail, "b shoudl be bound"); }
222 }
223 else if (ischosen(vtu.s)) {
224 // we passed the "increment" statement
225 if (valueof(vtu.s) == "63") { setverdict(pass); }
226 else { setverdict(fail, match(valueof(vtu.s), "63")); }
227 break; // escape the loop
228 }
229 }
230 }
231 //action(vtu);
232 }
233
234 testcase naked_loop_template() runs on CT { // TYPE 2: union change alternative
235 var template UU vtu := { a := 73 }
236 // This loop is not here for its loopyness; we're just interested
237 // in the initialization and "increment" statements.
238 // In fact, we only go through this infinite loop twice.
239 for ( vtu.b := vtu.a; true; vtu.s := int2str(valueof(vtu.b)) ) {
240 if (ischosen(vtu.a)) { setverdict(fail, "It cannot be a"); }
241 else {
242 if (ischosen(vtu.b)) { // we passed the init statement
243 if (isvalue (vtu.b)) { setverdict(pass); }
244 else { setverdict(fail, "b shoudl be bound"); }
245 }
246 else if (ischosen(vtu.s)) {
247 // we passed the "increment" statement
248 if (valueof(vtu.s) == "73") { setverdict(pass); }
249 else { setverdict(fail, match(valueof(vtu.s), "73")); }
250 break; // escape the loop
251 }
252 }
253 }
254 //action(vtu);
255 }
256
257 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
258
259 testcase stringy() runs on CT { // TYPE 2: union change alternative
260 var UU vu := { s := "manslaughter" };
261 vu := { z := substr(vu.s, 4, 8) };
262 if (ischosen(vu.z)) { setverdict(pass); }
263 else { setverdict(fail, "z should be chosen"); }
264 if (vu.z == "laughter") { setverdict(pass); }
265 else { setverdict(fail, "You can't have manslaughter without the laughter"); }
266
267 vu.s := "manslaughter";
268 vu := { z := replace(vu.s, 0, 4, "") }; // self-ref in the first argument
269 if (ischosen(vu.z)) { setverdict(pass); }
270 else { setverdict(fail, "z should be chosen"); }
271 if (vu.z == "laughter") { setverdict(pass); }
272 else { setverdict(fail, "You can't have manslaughter without the laughter"); }
273
274 vu.s := "";
275 vu := { z := replace("manslaughter", 0, 4, vu.s) }; // self-ref in the fourth argument
276 if (ischosen(vu.z)) { setverdict(pass); }
277 else { setverdict(fail, "z should be chosen"); }
278 if (vu.z == "laughter") { setverdict(pass); }
279 else { setverdict(fail, "You can't have manslaughter without the laughter"); }
280 }
281
282 testcase named_tlist() runs on CT { // TYPE 2: union change alternative
283 var UU vu;
284 var template UU vtu := { a := 47 };
285 vu := valueof(modifies vtu := { s := int2str(valueof(vtu.a)) });
286 if (ischosen(vu.s)) { setverdict(pass); }
287 else { setverdict(fail, "s should be chosen"); }
288 if (isvalue (vu.s)) { setverdict(pass); }
289 else { setverdict(fail, "s should be bound"); }
290 if (vu.s == "47") { setverdict(pass); }
291 else { setverdict(fail, match(vu.s, "47")); }
292 }
293
294 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
295
296 testcase patterned() runs on CT { // TYPE 2: union change alternative
297 var template UU vtu := { s := "*laughter" }
298 vtu := { boo := match("manslaughter", pattern vtu.s) }
299
300 if (ischosen(vtu.boo)) { setverdict(pass); }
301 else { setverdict(fail, "boo should be chosen"); }
302 if (isvalue (vtu.boo)) { setverdict(pass); }
303 else { setverdict(fail, "boo should be bound"); }
304 if (valueof(vtu.boo)) { setverdict(pass); }
305 else { setverdict(fail, match(valueof(vtu.boo), true)); }
306 }
307
308 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
309
310 altstep as() {
311 [] any timer.timeout {
312 setverdict(pass, "altstep called"); // called in a rather roundabout way
313 }
314 }
315
316 type altstep altstepref()
317
318 type union aref {
319 altstepref a,
320 default d
321 }
322
323 testcase actimel() runs on CT { // TYPE 2: union change alternative
324 var aref va := { a := refers(as) }
325 va := { d := activate( derefers(va.a)() ) }
326 timer t := 0.42
327 t.start
328 p.receive // this would block forever, were it not for the activated default.
329 // instead, the timer will run out and the altstep will be called.
330 deactivate(va.d);
331 // These tests shouls be *after* the receive operation,
332 // so the setverdict in the altstep can set the verdict reason for pass.
333 if (ischosen(va.d)) { setverdict(pass); }
334 else { setverdict(fail, "d should be chosen"); }
335 if (isvalue (va.d)) { setverdict(pass); }
336 else { setverdict(fail, "d should be bound"); }
337 }
338
339 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
340
341 type record of charstring ints;
342 type record vecs {
343 ints input,
344 ints output
345 }
346
347 testcase recoff() runs on CT {
348 var vecs v := { input := { "1", "2", "3" } }
349 for (var integer i:=0; i < lengthof(v.input); i := i + 1) {
350 // This code is here to trigger the annoying fact that it's not good enough
351 // to copy the LHS into a temp, assign the result to the temp, and then
352 // copy the temp to the LHS. The problem is that the LHS is allowed
353 // to be unbound, and then the copy to the temp will throw a DTE.
354 // The right thing(tm) to do is to copy the RHS.
355 v.output[i] := v.input[i];
356 }
357 if (v.output == v.input) { setverdict(pass); }
358 else { setverdict(fail, match(v.output, v.input)); }
359 }
360
361 control
362 {
363 execute(notOK());
364 execute(permut());
365 execute(choice());
366 execute(choice_template());
367 execute(loop());
368 execute(naked_loop());
369 execute(loop_template());
370 execute(naked_loop_template());
371 execute(stringy());
372 execute(named_tlist());
373 // execute(patterned());
374 execute(actimel());
375 execute(recoff());
376 }
377
378 } // module
This page took 0.05113 seconds and 5 git commands to generate.