Hi,
I've got the problem that optional steps seem to not be possible in 'interleave' statements.
What I want: accept either BSSMAP Assignment Request or Iu Rab Assignment:
interleave { [g_pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_AssignmentReq) { ... }; [not g_pars.ran_is_geran] BSSAP.receive(tr_RANAP_RabAssReq(rab_sml)) { ... }; [] other {...}; [] complex {...}; [] steps {...}; }
But that's illegal syntax; works for altsteps, but not for interleave. Even in the language spec, there is no token between the interleave braces. How unfortunate.
Options I am considering:
1) moving the optionals into a separate altstep
var default assignment; if (g_pars.ran_is_geran) { assignment := activate(as_BSSMAP_assignment()); } else { assignment := activate(as_RANAP_assignment()); } interleave { [] other {...}; [] complex {...}; [] steps {...}; } deactivate(assignment);
or 2) blatant code dup if (g_pars.ran_is_geran) { interleave { [] BSSAP.receive(tr_BSSMAP_AssignmentReq) { ... }; [] other {...}; [] complex {...}; [] steps {...}; } } else { interleave { [] BSSAP.receive(tr_RANAP_RabAssReq) { ... }; [] other {...}; [] complex {...}; [] steps {...}; } }
3) boolean dance and break
var boolean done1 := false; var boolean done2 := false; var boolean done3 := false; var boolean done4 := false;
interleave { [] BSSAP.receive(tr_BSSMAP_AssignmentReq) { if (not g_pars.ran_is_geran) { setverdict(fail); } done1 := true; if (done1 and done2 and done3 and done4) { break; } }; [] BSSAP.receive(tr_RANAP_RabAssReq(rab_sml)) { if (g_pars.ran_is_geran) { setverdict(fail); } done1 := true; if (done1 and done2 and done3 and done4) { break; } }; [] other { done2 := true; if (done1 and done2 and done3 and done4) { break; } }; [] complex { done3 := true; if (done1 and done2 and done3 and done4) { break; } }; [] steps { done4 := true; if (done1 and done2 and done3 and done4) { break; } }; }
1) is bad because the interleave may exit without having seen an actual assignment at all. Also interacting with local variables isn't allowed in this kind of altstep. Also if there are more optional parts, the side-altsteps become hard to understand. Also the altstep needs to "repeat;" so that it doesn't break the outer interlave, which makes us accept more than one of the optional message.
2) is bad because it is code dup.
3) is bad because of code clutter that is likely to cause weird failure when the interleave is modified. I am already using this method somewhere... but.
Are there other options??
Why is this coming up? I am preparing for a change in osmo-msc during call setup, and I am making the ttcn3 call testing more flexible and cleaning things up. As a result, some more tests are moved to using f_mo_call_establish() instead of copy-pasting it. That makes some Iu tests go from passed to FAIL, because the f_mo_call_establish() is unable to do the above distinguishing between BSSMAP and IU.
We can also choose to ignore those Iu tests that start to fail. But I am curious whether there is a way for optional interleave steps in ttcn3.
Thanks,
~N
Hi Neels,
On Thu, Oct 17, 2019 at 11:51:20PM +0200, Neels Hofmeyr wrote:
I've got the problem that optional steps seem to not be possible in 'interleave' statements.
yes, they are not. The TTCN-3 core language specification explicitly mandates that the guard expression in 'interleave' must be empty. I guess it was done to simplify the transformation from interleave to nested alt (that's what supposedly happens internally) is simpler - or maybe to guarantee it is possible to solve the resulting logic based on nested alt statements at all?
Another sad thing about interleave is that there's no equivalend to altsteps.
What I want: accept either BSSMAP Assignment Request or Iu Rab Assignment:
interleave { [g_pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_AssignmentReq) { ... }; [not g_pars.ran_is_geran] BSSAP.receive(tr_RANAP_RabAssReq(rab_sml)) { ... }; [] other {...}; [] complex {...}; [] steps {...}; }
why not simply have a "var template ..." that is assigned before and then use that variable instead of the template in the receive statement? Probably because it's separate TTCN-3 types (BSSAP vs. RANAP)? I think I read that there's some kind of "ANY" type (called anytype). but have never used it, and I don't know if you can have a "var template anytype". Maybe worth a try?
TTCN3_P.pdf contains a slide about it, important part seems to use the 'with extension anytype' part at the end of the module, listing the types.
Or you could "cheat" and do something like [] BSSAP.receive((tr_BSSMAP_AssignmentReq, tr_RANAP_RabAssReq(rab_sml))) which would accept either of the two in both cases. Not exactly great as the condition would be fulfilled even if you receive BSSAP but are in a 3G scenario (or vice versa).
moving the optionals into a separate altstep
var default assignment; if (g_pars.ran_is_geran) { assignment := activate(as_BSSMAP_assignment()); } else { assignment := activate(as_RANAP_assignment()); } interleave { [] other {...}; [] complex {...}; [] steps {...}; } deactivate(assignment);
possible, and I would say very ttcn3-like
blatant code dup
if (g_pars.ran_is_geran) { interleave { [] BSSAP.receive(tr_BSSMAP_AssignmentReq) { ... }; [] other {...}; [] complex {...}; [] steps {...}; } } else { interleave { [] BSSAP.receive(tr_RANAP_RabAssReq) { ... }; [] other {...}; [] complex {...}; [] steps {...}; } }
easy to read but probably less easy to maintain.
boolean dance and break
var boolean done1 := false; var boolean done2 := false; var boolean done3 := false; var boolean done4 := false;
god forbid.
Are there other options??
you could try to perform the manual conversion of interleave to nested ALT statements? Not sure if that's nicer than any of the other options.
Hi Neels,
On Fri, Oct 18, 2019 at 11:06:30AM +0200, Harald Welte wrote:
why not simply have a "var template ..." that is assigned before and then use that variable instead of the template in the receive statement? Probably because it's separate TTCN-3 types (BSSAP vs. RANAP)? I think I read that there's some kind of "ANY" type (called anytype). but have never used it, and I don't know if you can have a "var template anytype". Maybe worth a try?
TTCN3_P.pdf contains a slide about it, important part seems to use the 'with extension anytype' part at the end of the module, listing the types.
I just gave it a very simple try, and at least "var template anytype foo" still compiles, as do statements like "foo.PDU_BSSAP := tr_BSSMAP_..." and "foo.RANAP_PDU := tr_RANAP_...".
So it should be possible to construct a receive-template variable this way. I haven't used it from an interleave PORT.receive() but don't see why it shouldn't work.