Commit 4342f24f authored by balaskoa's avatar balaskoa
Browse files

HQ16404 added to Regression_Test_java


Signed-off-by: default avatarbalaskoa <Jeno.Balasko@ericsson.com>
parent b81f81f9
/******************************************************************************
* Copyright (c) 2000-2019 Ericsson Telecom AB
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
*
* Contributors:
* Balasko, Jeno
* Raduly, Csaba
*
******************************************************************************/
module HQ16404 {
type port dummyport message { inout integer } with { extension "internal" }
type component CT{
port dummyport p
}
type record of integer RI;
type union UU
{
integer a,
integer b,
charstring s,
charstring z,
boolean boo
};
testcase notOK() runs on CT { // TYPE 1: template change type
var template integer a;
a:=?;
a:=(a, 1); //Dynamic test case error: Copying an
// uninitialized/unsupported integer template.
// DTE happens because in preparation to transforming itself from AnyValue
// to value list template, the variable "a" has already been freed
// when the time comes to assign it as the first element of the value list.
log(a);
setverdict(pass);
}
testcase permut() runs on CT { // no error
var template integer a := *;
var template RI aa := { permutation (1,2) }
aa := { 1, aa[0], 2 };
log(aa);
setverdict(pass);
}
testcase choice() runs on CT { // TYPE 2: union change alternative
var UU vu := { a := 42 }
vu := { b := vu.a }
// This "self-assignment" is NOT working as expected.
// C++ code: vu.b() = const_cast< const UU&>(vu).a();
// Order of calls:
// const INTEGER& UU::a() const -> returns a reference
// INTEGER& UU::b() -> deletes field_a and creates field_b
// INTEGER& operator=(const INTEGER& other) gets a *freed* "other" object!
// Yay for undefined behavior!
//
// Note that when compiled with clang, UU::b() is called *before* UU::a() const,
// which means that UU::a() throws a DTE (because a is not the selected alternative anymore).
if (ischosen(vu.b)) { setverdict(pass); }
else { setverdict(fail, "b should be chosen"); }
if (isvalue (vu.b)) { setverdict(pass); }
else { setverdict(fail, "b should be bound"); }
if (vu.b == 42) { setverdict(pass); }
else { setverdict(fail, match(vu.b, 42)); }
vu := { s := log2str(vu.b) };
if (ischosen(vu.s)) { setverdict(pass); }
else { setverdict(fail, "s should be chosen"); }
if (isvalue (vu.s)) { setverdict(pass); }
else { setverdict(fail, "s should be bound"); }
if (vu.s == "42") { setverdict(pass); }
else { setverdict(fail, match(vu.s, "42")); }
vu := { b := 42 } // reset again to 42
vu := { s := log2str(vu.b + 1) }; // now try it with an expression instead of a reference
if (ischosen(vu.s)) { setverdict(pass); }
else { setverdict(fail, "s should be chosen"); }
if (isvalue (vu.s)) { setverdict(pass); }
else { setverdict(fail, "s should be bound"); }
if (vu.s == "43") { setverdict(pass); }
else { setverdict(fail, match(vu.s, "43")); }
vu := { boo := ischosen(vu.s) }
if (ischosen(vu.boo)) { setverdict(pass); }
else { setverdict(fail, "boo should be chosen"); }
if (isvalue (vu.boo)) { setverdict(pass); }
else { setverdict(fail, "boo should be bound"); }
if (vu.boo) { setverdict(pass); }
else { setverdict(fail, match(vu.boo, true)); }
vu.s := "Presence";
vu := { boo := ispresent(vu.s) }
if (ischosen(vu.boo)) { setverdict(pass); }
else { setverdict(fail, "boo should be chosen"); }
if (isvalue (vu.boo)) { setverdict(pass); }
else { setverdict(fail, "boo should be bound"); }
if (vu.boo) { setverdict(pass); }
else { setverdict(fail, match(vu.boo, true)); }
}
testcase choice_template() runs on CT { // TYPE 2: union change alternative
var template UU vtu := { a := 42 }
vtu := { b := vtu.a }
// This "self-assignment" is NOT working as expected.
// C++ code: vtu.b() = const_cast< const UU&>(vtu).a();
// Order of calls:
// const INTEGER& UU::a() const -> returns a reference
// INTEGER& UU::b() -> deletes field_a and creates field_b
// INTEGER& operator=(const INTEGER& other) gets a *freed* "other" object!
// Yay for undefined behavior!
//
// Note that when compiled with clang, UU::b() is called *before* UU::a() const,
// which means that UU::a() throws a DTE (because a is not the selected alternative anymore).
if (ischosen(vtu.b)) { setverdict(pass); }
else { setverdict(fail, "b should be chosen"); }
if (isvalue (vtu.b)) { setverdict(pass); }
else { setverdict(fail, "b should be bound"); }
if (valueof(vtu.b) == 42) { setverdict(pass); }
else { setverdict(fail, match(valueof(vtu.b), 42)); }
vtu := { s := log2str(vtu.b) };
if (ischosen(vtu.s)) { setverdict(pass); }
else { setverdict(fail, "s should be chosen"); }
if (isvalue (vtu.s)) { setverdict(pass); }
else { setverdict(fail, "s should be bound"); }
if (valueof(vtu.s) == "42") { setverdict(pass); }
else { setverdict(fail, match(valueof(vtu.s), "42")); }
vtu := { b := 42 } // reset again to 42
vtu := { s := log2str(valueof(vtu.b) + 1) }; // now try it with an expression instead of a reference
if (ischosen(vtu.s)) { setverdict(pass); }
else { setverdict(fail, "s should be chosen"); }
if (isvalue (vtu.s)) { setverdict(pass); }
else { setverdict(fail, "s should be bound"); }
if (valueof(vtu.s) == "43") { setverdict(pass); }
else { setverdict(fail, match(valueof(vtu.s), "43")); }
vtu := { boo := ischosen(vtu.s) }
if (ischosen(vtu.boo)) { setverdict(pass); }
else { setverdict(fail, "boo should be chosen"); }
if (isvalue (vtu.boo)) { setverdict(pass); }
else { setverdict(fail, "boo should be bound"); }
if (valueof(vtu.boo)) { setverdict(pass); }
else { setverdict(fail, match(valueof(vtu.boo), true)); }
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// A for loop contains two assignments. Each can be affected by self-assignment.
testcase loop() runs on CT { // TYPE 2: union change alternative
var UU vu := { a := 43 }
// This loop is not here for its loopyness; we're just interested
// in the initialization and "increment" statements.
// In fact, we only go through this infinite loop twice.
for ( vu := { b := vu.a }; true; vu := { s := int2str(vu.b) } ) {
if (ischosen(vu.a)) { setverdict(fail, "It cannot be a"); }
else {
if (ischosen(vu.b)) { // we passed the init statement
if (isvalue (vu.b)) { setverdict(pass); }
else { setverdict(fail, "b shoudl be bound"); }
}
else if (ischosen(vu.s)) {
// we passed the "increment" statement
if (vu.s == "43") { setverdict(pass); }
else { setverdict(fail, match(vu.s, "43")); }
break; // escape the loop
}
}
}
action(vu);
}
testcase naked_loop() runs on CT { // TYPE 2: union change alternative
var UU vu := { a := 53 }
// This loop is not here for its loopyness; we're just interested
// in the initialization and "increment" statements.
// In fact, we only go through this infinite loop twice.
for ( vu.b := vu.a; true; vu.s := int2str(vu.b) ) {
if (ischosen(vu.a)) { setverdict(fail, "It cannot be a"); }
else {
if (ischosen(vu.b)) { // we passed the init statement
if (isvalue (vu.b)) { setverdict(pass); }
else { setverdict(fail, "b shoudl be bound"); }
}
else if (ischosen(vu.s)) {
// we passed the "increment" statement
if (vu.s == "53") { setverdict(pass); }
else { setverdict(fail, match(vu.s, "53")); }
break; // escape the loop
}
}
}
//action(vu);
}
testcase loop_template() runs on CT { // TYPE 2: union change alternative
var template UU vtu := { a := 63 }
// This loop is not here for its loopyness; we're just interested
// in the initialization and "increment" statements.
// In fact, we only go through this infinite loop twice.
for ( vtu := { b := vtu.a }; true; vtu := { s := int2str(valueof(vtu.b)) } ) {
if (ischosen(vtu.a)) { setverdict(fail, "It cannot be a"); }
else {
if (ischosen(vtu.b)) { // we passed the init statement
if (isvalue (vtu.b)) { setverdict(pass); }
else { setverdict(fail, "b shoudl be bound"); }
}
else if (ischosen(vtu.s)) {
// we passed the "increment" statement
if (valueof(vtu.s) == "63") { setverdict(pass); }
else { setverdict(fail, match(valueof(vtu.s), "63")); }
break; // escape the loop
}
}
}
//action(vtu);
}
testcase naked_loop_template() runs on CT { // TYPE 2: union change alternative
var template UU vtu := { a := 73 }
// This loop is not here for its loopyness; we're just interested
// in the initialization and "increment" statements.
// In fact, we only go through this infinite loop twice.
for ( vtu.b := vtu.a; true; vtu.s := int2str(valueof(vtu.b)) ) {
if (ischosen(vtu.a)) { setverdict(fail, "It cannot be a"); }
else {
if (ischosen(vtu.b)) { // we passed the init statement
if (isvalue (vtu.b)) { setverdict(pass); }
else { setverdict(fail, "b shoudl be bound"); }
}
else if (ischosen(vtu.s)) {
// we passed the "increment" statement
if (valueof(vtu.s) == "73") { setverdict(pass); }
else { setverdict(fail, match(valueof(vtu.s), "73")); }
break; // escape the loop
}
}
}
//action(vtu);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
testcase stringy() runs on CT { // TYPE 2: union change alternative
var UU vu := { s := "manslaughter" };
vu := { z := substr(vu.s, 4, 8) };
if (ischosen(vu.z)) { setverdict(pass); }
else { setverdict(fail, "z should be chosen"); }
if (vu.z == "laughter") { setverdict(pass); }
else { setverdict(fail, "You can't have manslaughter without the laughter"); }
vu.s := "manslaughter";
vu := { z := replace(vu.s, 0, 4, "") }; // self-ref in the first argument
if (ischosen(vu.z)) { setverdict(pass); }
else { setverdict(fail, "z should be chosen"); }
if (vu.z == "laughter") { setverdict(pass); }
else { setverdict(fail, "You can't have manslaughter without the laughter"); }
vu.s := "";
vu := { z := replace("manslaughter", 0, 4, vu.s) }; // self-ref in the fourth argument
if (ischosen(vu.z)) { setverdict(pass); }
else { setverdict(fail, "z should be chosen"); }
if (vu.z == "laughter") { setverdict(pass); }
else { setverdict(fail, "You can't have manslaughter without the laughter"); }
}
testcase named_tlist() runs on CT { // TYPE 2: union change alternative
var UU vu;
var template UU vtu := { a := 47 };
vu := valueof(modifies vtu := { s := int2str(valueof(vtu.a)) });
if (ischosen(vu.s)) { setverdict(pass); }
else { setverdict(fail, "s should be chosen"); }
if (isvalue (vu.s)) { setverdict(pass); }
else { setverdict(fail, "s should be bound"); }
if (vu.s == "47") { setverdict(pass); }
else { setverdict(fail, match(vu.s, "47")); }
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
testcase patterned() runs on CT { // TYPE 2: union change alternative
var template UU vtu := { s := "*laughter" }
vtu := { boo := match("manslaughter", pattern vtu.s) }
if (ischosen(vtu.boo)) { setverdict(pass); }
else { setverdict(fail, "boo should be chosen"); }
if (isvalue (vtu.boo)) { setverdict(pass); }
else { setverdict(fail, "boo should be bound"); }
if (valueof(vtu.boo)) { setverdict(pass); }
else { setverdict(fail, match(valueof(vtu.boo), true)); }
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
altstep as() {
[] any timer.timeout {
setverdict(pass, "altstep called"); // called in a rather roundabout way
}
}
type altstep altstepref()
type union aref {
altstepref a,
default d
}
testcase actimel() runs on CT { // TYPE 2: union change alternative
var aref va := { a := refers(as) }
va := { d := activate( derefers(va.a)() ) }
timer t := 0.42
t.start
p.receive // this would block forever, were it not for the activated default.
// instead, the timer will run out and the altstep will be called.
deactivate(va.d);
// These tests shouls be *after* the receive operation,
// so the setverdict in the altstep can set the verdict reason for pass.
if (ischosen(va.d)) { setverdict(pass); }
else { setverdict(fail, "d should be chosen"); }
if (isvalue (va.d)) { setverdict(pass); }
else { setverdict(fail, "d should be bound"); }
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
type record of charstring ints;
type record vecs {
ints input,
ints output
}
testcase recoff() runs on CT {
var vecs v := { input := { "1", "2", "3" } }
for (var integer i:=0; i < lengthof(v.input); i := i + 1) {
// This code is here to trigger the annoying fact that it's not good enough
// to copy the LHS into a temp, assign the result to the temp, and then
// copy the temp to the LHS. The problem is that the LHS is allowed
// to be unbound, and then the copy to the temp will throw a DTE.
// The right thing(tm) to do is to copy the RHS.
v.output[i] := v.input[i];
}
if (v.output == v.input) { setverdict(pass); }
else { setverdict(fail, match(v.output, v.input)); }
}
control
{
execute(notOK());
execute(permut());
execute(choice());
execute(choice_template());
execute(loop());
execute(naked_loop());
execute(loop_template());
execute(naked_loop_template());
execute(stringy());
execute(named_tlist());
execute(patterned());
execute(actimel());
execute(recoff());
}
} // module
###############################################################################
# Copyright (c) 2000-2019 Ericsson Telecom AB
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v2.0
# which accompanies this distribution, and is available at
# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
#
# Contributors:
# Balasko, Jeno
# Raduly, Csaba
#
###############################################################################
[LOGGING]
LogEventTypes := Detailed
SourceInfoFormat := Single
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment