ETSI's Bug Tracker - Ext Pack: Config & Deployment Support (ES 202 781)
View Issue Details

ID | Project | Category | View Status | Date Submitted | Last Update
0005810 | Ext Pack: Config & Deployment Support (ES 202 781) | New Feature | public | 24-11-2010 17:12 | 04-06-2012 06:08

Reporter | Elisabet Wahlgren |
Assigned To | Gyorgy Rethy |
Priority | low | Severity | feature | Reproducibility | N/A
Status | closed | Resolution | no change required |
Platform |  | OS |  | OS Version |
Product Version |  |
Target Version |  | Fixed in Version |  |
Clause Reference(s) | 21, Configuration operations
Source (company - Author) | Ericsson AB - Elisabet Wahlgren
TS version |

Summary | 0005810: Blocking configuration operation on PTC

Description

The project I am working in currently uses TTCN-3 in a way that requires PTC configuration to be done in a serial manner (yes, I know the abbreviation PTC stands for Parallel Test Component, but parallel execution is rarely used in our current project). The code is literally littered with statement sequences of the form
componentRef.start(function());
componentRef.done;
in such amounts that I began searching for a blocking function execution operation, perhaps "execute", so that the required functionality could be expressed as
componentRef.execute(function());
which would improve readability a lot.
Our test environment involves a rather large number of component types for handling all the protocols that our SUT is using, and there is a lot of code written using the current component and data type structures.
Is this abuse of TTCN-3? Or might there be rationales for introducing a blocking configuration operation?

Steps To Reproduce |
Additional Information |
Tags | No tags attached.
Relationships |
Attached Files | CR5810.doc (1,989,120) 01-12-2010 13:59 http://oldforge.etsi.org/mantis/file_download.php?file_id=2457&type=bug example_code_from_CR_submitter.zip (2,045) 29-06-2011 14:07 http://oldforge.etsi.org/mantis/file_download.php?file_id=2523&type=bug CHCR_TRAF_RestartTestcases.ttcn (146,545) 20-07-2011 17:26 http://oldforge.etsi.org/mantis/file_download.php?file_id=2562&type=bug

Issue History
Date Modified | Username | Field | Change
24-11-2010 17:12 | Elisabet Wahlgren | New Issue |
24-11-2010 17:12 | Elisabet Wahlgren | Clause Reference(s) | => 21, Configuration operations
24-11-2010 17:12 | Elisabet Wahlgren | Source (company - Author) | => Ericsson AB - Elisabet Wahlgren
29-11-2010 15:29 | Jacob Wieland - Spirent | Note Added: 0009831 |
30-11-2010 09:34 | Ina Schieferdecker | Project | TTCN-3 Change Requests => Ext Pack: Config & Deployment Support (ES 202 781)
30-11-2010 17:33 | Gyorgy Rethy | Note Added: 0009869 |
30-11-2010 17:33 | Gyorgy Rethy | Assigned To | => Jacob Wieland - Spirent
30-11-2010 17:33 | Gyorgy Rethy | Status | new => assigned
30-11-2010 17:34 | Gyorgy Rethy | Project | Ext Pack: Config & Deployment Support (ES 202 781) => Part 01: TTCN-3 Core Language
01-12-2010 13:54 | Jacob Wieland - Spirent | File Added: CR5810.doc |
01-12-2010 13:59 | Jacob Wieland - Spirent | File Deleted: CR5810.doc |
01-12-2010 13:59 | Jacob Wieland - Spirent | File Added: CR5810.doc |
01-12-2010 14:00 | Jacob Wieland - Spirent | Note Added: 0009897 |
01-12-2010 14:00 | Jacob Wieland - Spirent | Assigned To | Jacob Wieland - Spirent => Jens Grabowski
03-12-2010 11:00 | Gyorgy Rethy | Target Version | => Edition 4.3.2 (interim)
03-12-2010 12:38 | Jens Grabowski | Note Added: 0009936 |
03-12-2010 15:02 | Elisabet Wahlgren | Note Added: 0009938 |
03-12-2010 15:06 | Elisabet Wahlgren | Note Edited: 0009938 |
03-12-2010 15:11 | Jens Grabowski | Note Added: 0009939 |
03-12-2010 15:37 | Elisabet Wahlgren | Note Deleted: 0009938 |
24-05-2011 19:28 | Gyorgy Rethy | Priority | normal => low
25-05-2011 13:37 | Jacob Wieland - Spirent | Note Added: 0010049 |
27-05-2011 13:35 | Elisabet Wahlgren | Note Added: 0010101 |
27-05-2011 13:57 | Jacob Wieland - Spirent | Note Added: 0010102 |
29-06-2011 13:57 | Gyorgy Rethy | Assigned To | Jens Grabowski => Jacob Wieland - Spirent
29-06-2011 14:04 | Gyorgy Rethy | Note Added: 0010144 |
29-06-2011 14:07 | Gyorgy Rethy | File Added: example_code_from_CR_submitter.zip |
01-07-2011 13:51 | Jacob Wieland - Spirent | Note Added: 0010177 |
01-07-2011 13:55 | Jacob Wieland - Spirent | Assigned To | Jacob Wieland - Spirent => Gyorgy Rethy
18-07-2011 16:49 | Elisabet Wahlgren | Note Added: 0010228 |
19-07-2011 11:19 | Jacob Wieland - Spirent | Note Added: 0010229 |
20-07-2011 17:26 | Elisabet Wahlgren | File Added: CHCR_TRAF_RestartTestcases.ttcn |
20-07-2011 17:44 | Elisabet Wahlgren | Note Added: 0010230 |
21-07-2011 10:01 | Jacob Wieland - Spirent | Note Added: 0010231 |
28-07-2011 10:24 | Elisabet Wahlgren | Note Added: 0010232 |
28-07-2011 11:06 | Elisabet Wahlgren | Note Edited: 0010232 |
27-09-2011 14:04 | Gyorgy Rethy | Target Version | Edition 4.3.2 (interim) => Edition 4.4.1
30-11-2011 10:24 | Gyorgy Rethy | Note Added: 0010424 |
30-11-2011 11:27 | Elisabet Wahlgren | Note Added: 0010438 |
30-11-2011 13:03 | Gyorgy Rethy | Note Added: 0010442 |
30-11-2011 14:25 | Elisabet Wahlgren | Note Added: 0010446 |
30-11-2011 16:11 | Gyorgy Rethy | Status | assigned => closed
30-11-2011 16:11 | Gyorgy Rethy | Note Added: 0010450 |
30-11-2011 16:11 | Gyorgy Rethy | Resolution | open => no change required
30-11-2011 16:11 | Gyorgy Rethy | Fixed in Version | => Edition 4.4.1
04-06-2012 06:08 | Ina Schieferdecker | Project | Part 01: TTCN-3 Core Language => Ext Pack: Config & Deployment Support (ES 202 781)

Notes

(0009831)
Jacob Wieland - Spirent
29-11-2010 15:29

The proposal has merit. Especially, for this construct the restriction that the started function may have no out-parameters can be lifted as then it is clear when exactly these variables get their new values. The ptc-execute could also have the return value of the executed function as its result.
Thus, if you had:
function f(inout integer x) runs on C return integer {
x := ...;
return ...;
}
then you could do:
var C ptc := C.create alive;
...
var integer x, y;
...
x := ptc.execute(f(y));

(0009869)
Gyorgy Rethy
30-11-2010 17:33

STF discussion 30-11-2010: make sense also to allow inout parameters (passing back the parameter value when the called function is finished). Text to be proposed.

(0009897)
Jacob Wieland - Spirent
01-12-2010 14:00

please proofread and add operational semantics

(0009936)
Jens Grabowski
03-12-2010 12:38

On the discussion of the CR and the resolution proposal from J. Wieland:
I (Jens) am sorry, but the CR and the resolution do somehow not fit.
The CR asks for some sort of shorthand for
componentRef.start(function());
componentRef.done;
Even this CR needs further information: Shall a default be activated in the background, e.g., to supervise the test execution by means of a test case timer?
Jacob's proposal introduces an execute PTC operation
- with time supervision and
- with inout parameters.
First of all, if a default is activated in the background, the solution will not match the intention of the CR.
Inout parameters seems to force the strange restriction that the component started by an execute PTC-operation can only be stopped by itself but not be stopped by any other component, even not by the MTC.
If it is stopped by some other component or the time supervision exceeded, the test run will end with a test case error.
I (Jens) doubt that such a behaviour really is wanted by the CR and that we really want such a behaviour ...
Personally, I (Jens) am against inout parameters for a special case only that in addition implies a very severe runtime restriction (i.e., the component can only be stopped by itself). If we want to have inout-parameters, this should be bound to the start operation itself.
My (Jens) proposal is to ask for some clarification first and then to look into Jacob's proposal again.
Answer from Jacob:
I (Jacob) also think that we need more information regarding the context of the intended statement, i.e. are there default alternatives active or not, is it desired that execution in the starting component continues even if componentRef is stopped before finishing, etc.
The semantics I (Jacob) assigned in my proposal is basically the same semantics as that of the existing execute statement for test cases. Of course, there you don't have the possibility that a testcase can be stopped from another control part.
Either way, if you take my proposal or simply go with the just-syntactic-sugar route, both is fine with me. Allowing effect of out parameters in the syntactic-sugar variant would of course be inconsistent with the normal start statement.
Overall summary:
The STF will ask for further information before reconsidering the proposal from Jacob. The resolution of this CR is shifted to the next year (or new STF).

(0009939)
Jens Grabowski
03-12-2010 15:11

Dear Elisabet Wahlgren,
sorry, Mantis is not an open discussion forum and I will not start a discussion about the CR here. Mantis shall only reflect the status of the CRs. The request for further information as well as further discussion will be done offline via Email. However, I do not have your Email. Please do me a favour and send me an Email to grabowski@informatik.uni-goettingen.de
Best regards
Jens Grabowski

(0010049)
Jacob Wieland - Spirent
25-05-2011 13:37

From the example that was given to the STF, it seems clear that not the
pattern
p.start(...)
p.done;
is really the problem that makes the code 'littered' (I would rather say, unreadable), but the use of indexed/dotted notation expressions over and over again.
The usual approach to this problem would be to extract the re-used common (lengthy) sub-expressions of the statements into variables and then use these
variables instead. If the expressions are used are lvalues,
this refactoring needs to be done by introducing a new function with out/inout parameters (which are instantiated with the lengthy lvalue-expressions when calling that function).
For example:
vg_iscSessions[p_index.iscInit].componentRef.start(ISCv2_SessionFunctions.f_
s_isc_INVITE(vg_continue,
vg_iscSessions[p_index.iscInit].dialogList[p_index.iscInitDialog],
vl_sdpInvite, p_parInvite.addHeaderInviteSend, -,
p_parInvite.deleteHeaderInviteSend));
f_cto_waitForReturnResult({ctIsc :=
vg_iscSessions[p_index.iscInit].componentRef}, vg_continue);
vg_iscSessions[p_index.iscInit].componentRef.start(ISCv2_SessionFunctions.f_
r_isc_100Trying(vg_continue,
vg_iscSessions[p_index.iscInit].dialogList[p_index.iscInitDialog],
p_par100.addHeader, -, -, p_par100.deleteHeader));
f_cto_waitForReturnResult({ctIsc :=
vg_iscSessions[p_index.iscInit].componentRef}, vg_continue);
Would be rewritten to:
var ... componentRef := vg_iscSessions[p_index.iscInit].componentRef;
var ... dialogList :=
vg_iscSessions[p_index.iscInit].dialogList[p_index.iscInitDialog];
var ... wrappedComponentRef := {ctIsc := componentRef}
componentRef.start(ISCv2_SessionFunctions.f_s_isc_INVITE(vg_continue,
dialogList, vl_sdpInvite, p_parInvite.addHeaderInviteSend, -,
p_parInvite.deleteHeaderInviteSend));
f_cto_waitForReturnResult(wrappedComponentRef, vg_continue);
componentRef.start(ISCv2_SessionFunctions.f_r_isc_100Trying(vg_continue,
dialogList, p_par100.addHeader, -, -, p_par100.deleteHeader));
f_cto_waitForReturnResult(wrappedComponentRef, vg_continue);

(0010101)
Elisabet Wahlgren
27-05-2011 13:35

Thanks for supporting the view of our code as littered on the verge of unreadability! But we seem to need even more brilliant advice to do away with our quest for an "execute" operation, the lack of which seems to add an orthogonal degree of obfuscation to TTCN-3 code. What would you do with the following function:
function f_auto_configureCharging()
runs on DEFAULT_MTC_CT
{
vg_dn := "MtasCharging=0,applicationName=MtasFunction" & ",nodeName=jambala";
// Offline Orig Node Level
vg_ldap.start(f_gen_LdapCheckValue(vg_dn,"mtasChargingOriginatingOffline","0",compareTrue));
vg_ldap.done;
vg_ldap.start(f_gen_setMtasChargingParameter("mtasChargingOriginatingOffline","1"));
vg_ldap.done;
// Online Orig Node Level
vg_ldap.start(f_gen_LdapCheckValue(vg_dn,"mtasChargingOriginatingOnline","0",compareTrue));
vg_ldap.done;
vg_ldap.start(f_gen_setMtasChargingParameter("mtasChargingOriginatingOnline","1"));
vg_ldap.done;
// Offline Term Node Level
vg_ldap.start(f_gen_LdapCheckValue(vg_dn,"mtasChargingTerminatingOffline","0",compareTrue));
vg_ldap.done;
vg_ldap.start(f_gen_setMtasChargingParameter("mtasChargingTerminatingOffline","1"));
vg_ldap.done;
// Online Term Node Level
vg_ldap.start(f_gen_LdapCheckValue(vg_dn,"mtasChargingTerminatingOnline","0",compareTrue));
vg_ldap.done;
vg_ldap.start(f_gen_setMtasChargingParameter("mtasChargingTerminatingOnline","1"));
vg_ldap.done;
vg_ldap.start(f_gen_removeChargingDeactDests());
vg_ldap.done;
vg_ldap.start(f_gen_setMtasChargingParameter("mtasChargingDefaultCdfAddress",SIP_CommonDefinitions.tsp_ccfRealm1));
vg_ldap.done;
// Charging Profile - "Charging"
vg_ldap.start(f_gen_addMtasChargingProf("Charging","3","3",false,false,true)); // offline/online enabled
vg_ldap.done;
}
11 lines too many here? We have tens of thousands of those.

(0010102)
Jacob Wieland - Spirent
27-05-2011 13:57

We still think that you are mainly choosing the wrong approach here.
First of all, if you have repetitive code, you should put it in a separate function. This way you would get rid of almost half your 11 lines.
function f_...()
runs on DEFAULT_MTC_CT
{
vg_ldap.start(f_gen_LdapCheckValue(vg_dn,"mtasChargingOriginatingOffline","0",compareTrue));
vg_ldap.done;
}
Also, if you only have single-threaded calls on the same ptc, why then not define the function as running on the PTC and simply call the functions one after the other. There you have a blocking operation and you get rid of the pattern.
In your example, this would look like this:
function f_auto_configureCharging()
runs on DEFAULT_MTC_CT
{
vg_dn := "MtasCharging=0,applicationName=MtasFunction" & ",nodeName=jambala";
// Offline Orig Node Level
vg_ldap.start(configure(...)) // to transmit the correct variable values to the ptc.
vg_ldap.done;
vg_ldap.start(f());
}
function f() runs on <PtcType> {
f_gen_LdapCheckValue(vg_dn,"mtasChargingOriginatingOffline","0",compareTrue);
f_gen_setMtasChargingParameter("mtasChargingOriginatingOffline","1");
// Online Orig Node Level
f_gen_LdapCheckValue(vg_dn,"mtasChargingOriginatingOnline","0",compareTrue);
f_gen_setMtasChargingParameter("mtasChargingOriginatingOnline","1");
// Offline Term Node Level
f_gen_LdapCheckValue(vg_dn,"mtasChargingTerminatingOffline","0",compareTrue);
f_gen_setMtasChargingParameter("mtasChargingTerminatingOffline","1");
// Online Term Node Level
f_gen_LdapCheckValue(vg_dn,"mtasChargingTerminatingOnline","0",compareTrue);
f_gen_setMtasChargingParameter("mtasChargingTerminatingOnline","1");
f_gen_removeChargingDeactDests();
f_gen_setMtasChargingParameter("mtasChargingDefaultCdfAddress",
SIP_CommonDefinitions.tsp_ccfRealm1);
// Charging Profile - "Charging"
f_gen_addMtasChargingProf("Charging","3","3",false,false,true);
// offline/online enabled
}
I agree with Jens Grabowski, though, that further discussions should be done by mail.
Just write to stf430@etsi.org or wieland@testingtech.com or to Jens Grabowski (address above)

(0010144)
Gyorgy Rethy
29-06-2011 14:04

As agreed during the STF discussion, the problem can be solved by the language instruments existing today: functions started on the different "PTC" types, with runs on clauses using the relevant PTC type are defined today; the MTC type can be defined as extending all PTC component types; thus, all functions started on a PTC today could also be simply called on the MTC and using the relevant "subpart" of the MTC only. This allows compile time checking of the called functions (as all of them do have the needed runs on clause), would solve the problem of returning a value and would result even a simpler syntax than proposed in the example code.

(0010177)
Jacob Wieland - Spirent
01-07-2011 13:51

Since you've explained it already fully and the resulting code would not look different from sweetercode.txt or like function f() in my last comment, I don't know what to do here anymore.

(0010228)
Elisabet Wahlgren
18-07-2011 16:49

Thank you for your suggestions for usage of existing language instruments. However, declaring an MTC incorporating all PTC variables would seem to preclude the possibility of requesting parallel execution of functions on components. As stated in my original request, we use it rarely (currently), but it is needed.

(0010229)
Jacob Wieland - Spirent
19-07-2011 11:19

We cannot imagine a setting with your highly restricted testing-style (where, as I understood it, the code flow shall reflect the test flow, basically) where you would need a ptc which is also a member of this flow. Of course, you can still have any number of ptcs beside the MTC which are not part of the flow, but with the known drawbacks of explicit synchronization.
Since you yourself already are saying that you use this only rarely, it should not be a problem to then use one of the other suggested workarounds (or even the start/done pairing) in those rare places as well.

(0010230)
Elisabet Wahlgren
20-07-2011 17:44

A real-world example of our (ab)use of the TTCN-3 language was just uploaded to your site. For example, testcase TC_CHCR_DYN0030 orders parallel execution of a function on two test components of a type, ISC session component simulating a SIP call end, that we most often use in serial execution. The testcase causes an application process to die in mid-call, which is intended to result in BYE messages sent to both call ends, and where the order in which they receive this BYE message is not important.
Using PTCs, even if they were used only for serial execution, enables data access restriction (cf private class variables) that decreases the risk of undesired interferences. Your recommendation to include all variables required in the MTC instead makes all data globally accessible, which I believe is not always to be desired. Some programming languages nowadays pride themselves by not allowing global variables at all! However, I believe you do require them, but trying to minimize them is wise.
Your alternative suggestion to declare two-line functions to avoid the start-done sequence I also believe many programmers would hold counter to good coding style. Reasonable function lengths - not too small, not too lengthy - has been shown to correlate with readability and maintainability - conducive to quality.
So, what is the views of the TTCN-3 core language group on coding styles? Is this important in any respect for language usability and code maintainability?

(0010231)
Jacob Wieland - Spirent
21-07-2011 10:01

The problem here, I think, is that you are confusing different concepts.
It seems that you view a 'component' in TTCN-3 like an 'object' in an object-oriented language while in actuality it is more on the lines of a 'thread' in an imperative one and pretty much works the same way (i.e. you have to join it explicitely and somehow use communication/synchronization mechanisms to get results from it and have to deal with it not finishing etc.).
Your argument about the visibility of variables is void, since, if you continue to declare your functions to work only on a certain kind of component and then let the MTC (or other driving component) extend the different component types, the function still can only access those fields defined for its component type. This way, you get the best of both worlds. The only drawback is that you cannot have different component variables of the same name anymore, but that could be seen as a bad style anyway.
Basically, you can define your 'component'-functions pretty much the same way as before, but only have to define the 'driving' function differently. And, as I said, if using ptcs is the exception instead of the rule (as you have stated more than once), then using start/done in those few places cannot hurt. Also, it is not bad style, it is just explicit which is true for most things in TTCN-3. Also, if you want to receive different messages in any order, you could also use the interleave-construct instead of ptcs, again alleviating the need for ptcs.
To my knowledge, TTCN-3 is not designed in a way that you can write down things as short as possible, often opting for the more explicit way. I think it was deemed that this would yield more understandable code as implicit knowledge would not be necessary to understand it - leaving nothing open to interpretation - which is good practice when writing down standardized test suites, I guess.

(0010232)
Elisabet Wahlgren
28-07-2011 10:24 (edited on: 28-07-2011 11:06)

It seems my code examples have not been conducive to clarifying the data structures we are using to model our test environment. We use not just one instance of a component type â€“ in which case your suggestion to define an MTC extending all component types ever used would work fine- but in the general case we use an array of for example ISC session components, to model a varying number of participants in the many call scenarios handled by a Multimedia Application Server, as well as for example SDP data arrays per each ISC session component. I would upload some definition files if you require more clarification as to our data structure needs, or perhaps the above, together with the code examples already given, are enough to trigger your structural imagination. So, your suggestion is no solution for us. We really need these data array structures to be able to write general code.
My confusion as regards the concept of component in TTCN-3 may not be overwhelming. I am not alone in viewing the function of a component as a way to enable data isolation, as well as a means of threaded execution for simulation of parallel component interaction with a SUT. Yes, as stated already in my initial CR entry, I realize the â€œabnormalityâ€ of using a concept, introduced to enable simulation of parallel execution, for serial execution. But doesTTCN-3 provides other means of data isolation than use of different component types?
Your suggest that providing only â€œthe more explicit wayâ€ of defining operations is preferable in a language used to write standardized test suites (I donâ€™t know if our test suites can be described as â€œstandardizedâ€ â€“ is this important?). I think you disregard the fact that the creation and maintenance of a collection of test suites for a reasonably complex product is in fact a large scale programming project, in grave need of good language constructs to be able to produce readable and maintainable test code.
I do not today realize for what more narrow purposes TTCN-3 was created. It seems we may have chosen the wrong tool for our type of automated testing. I think originally it was considered an advantage to use the same tool as other testing instances, to benefit from concerted efforts for creating common test port types, etc. But a general purpose programming language with proven useful constructs would probably serve us better â€“ what do you think?

(0010424)
Gyorgy Rethy
30-11-2011 10:24

As a compromise solution, a blocking start could be discussed, where the blocking nature is explicitly identified: MyNewPTC.start(MyFirstBehaviour(),block); it could also be allowed to write MyNewPTC.start(MyFirstBehaviour(),noblock); where "noblock" would be the default. The disadvantage is that block would be a new keyword, but I couldn't find a suitable existing keyword.

(0010438)
Elisabet Wahlgren
30-11-2011 11:27

Thank you for your attention to this matter. You have probably already discussed and rejected the existing "execute" keyword (to be exclusively used for testcases?). If you are introducing new keywords anyway, would you consider "exec"?

(0010442)
Gyorgy Rethy
30-11-2011 13:03

The point is that if there will be two different ways of starting PTC behaviour, it shall be visible explicitly, which one is blocking and which one is non-blocking. Nor execute, neither exec hints this information, thus most of the users would simply confuse the semantics of the two operations. For this reason, none of them would be a good solution.

(0010446)
Elisabet Wahlgren
30-11-2011 14:25

Thank you for the explanation. This view of the abilities of the TTCN-3 user community is rather depressing.
Has TTCN-3 really been designed for users without any learning capacities? Could then a user really be expected to understand the need for the "execute" keyword in connection with running (I will not use the e-word) a testcase? What about execution "on components" per se - why would this be possible to understand? How come a TTCN-3 user is expected to understand the alt/altstep functionality - very special constructs for alternative execution paths that would seem to require some form of abstract thinking.
I am very surprised by the suggestion that it would be too advanced, causing confusion, to be required to distinguish between blocking and non-blocking function execution on components by using different keywords. And, after all, exec() is a rather common method of function execution in a lot of code circumstances (system calls from scripts or other programming languages, C, Erlang, etc), and for someone completely new to programming, who would have to learn a lot starting to use TTCN-3 anyway, it would be good to understand some more about execution alternatives.

(0010450)
Gyorgy Rethy
30-11-2011 16:11

STF decision 30-11-2011: don't change the standard as the use case can be solved using existing language features in several ways. Introducing a new keyword (and a new syntax and semantics) or re-using execute() would be inappropriate and complicate the language unnecessary.