source: trunk/ETSI-Testsuites/ETSI_auto_IOT/adapter/validation/LibCommon/LibCommon_Sync.ttcn

Last change on this file was 22, checked in by rings, 14 years ago
  • Property svn:executable set to *
File size: 56.7 KB
Line 
1/**
2 *  @author   ETSI
3 *  @version  $URL: svn+ssh://vcs.etsi.org/TTCN3/LIB/Ttcn3LibCommon/trunk/ttcn/LibCommon_Sync.ttcn $
4 *            $Id: LibCommon_Sync.ttcn 34 2009-05-25 13:12:29Z deshpande $
5 *  @desc     This module implements _one_ generic synchronization mechanism
6 *            for TTCN-3 test cases with one or more test components.
7 *            Key concept is here that one test component acts as a
8 *            synchronization server which listens and triggers one or more
9 *            synchronization clients. It is recomended to use the MTC always as
10 *            the synchronization server but in theory also a PTC can act as such
11 *            a server.<br><br>
12 *            This synchronization is used by calling a function on
13 *            the server test component to wait for a desired amount of clients
14 *            to notify the server that they have reached a specific synchronization
15 *            point. Each client test component must call another
16 *            function to perform this notification.<br><br>
17 *            In the event that a client is not able to reach a synchronization
18 *            point the server sends out a signal to all clients to abort the
19 *            test case. This signal is a STOP message which can be caught by
20 *            a test component default which in turn can then run a proper
21 *            shut down behavior based on the current state of the test
22 *            component. <br><br>
23 *            Note that this synchronization mechanism can also be used
24 *            in a special mode called "self synchronization" when a test case
25 *            only has one test component. Here, the test component in essence
26 *            acts as a server and client at the same time. The main benefit of
27 *            using self synchoronization is that the same shutdown mechanisms
28 *            can also be reused fomr the multi component test cases. <br><br>
29 *            This module contains a lot of TTCN-3 definitions. It has been
30 *            structured into tree main groups to help the user to identify
31 *            quickly relevant TTCN-3 definitions. For rookie users of this
32 *            module basicUserRelevantDefinitions should offer all the needed
33 *            definitions. Advanced users can consider use of definitions in
34 *            advancedUserRelevantDefinitions. Finally, internalDefinitions
35 *            are definitions which are required for the module to work
36 *            properly but do not need to be used in your code. Remember that
37 *            the main motiviation of this sychronization module is to offer
38 *            are _simple_ user interface. Practice has shown that when writing
39 *            actual test component behavior _only a handful_ of functions
40 *            usually wind up being used! Also check the synchronization examples
41 *            module for example uses of this synchronization mechanism.<br><br>
42 *            The invocation of the sync functions is also closely tied
43 *            to the verdict control functions which should also be reviewed
44 *            prior to using this module. <br><br>
45 *            This module has been derived from EtsiCommon_Synchronization
46 *            which was created in ETSIs STF256/276. It has been kept
47 *            intentionally separate to avoid conflicts with future ETSI
48 *            test suite releases.
49 *  @see      LibCommon_Sync.basicUserRelevantDefinitions
50 *  @see      LibCommon_Sync.advancedUserRelevantDefinitions
51 *  @remark   End users should be aware that any changes made to the  in
52 *            definitions this module may be overwritten in future releases.
53 *            End users are encouraged to contact the distributers of this
54 *            module regarding their modifications or additions so that future
55 *            updates will include your changes.
56 */
57module LibCommon_Sync {
58
59  //Common
60  import from LibCommon_BasicTypesAndValues { type UInt } ;
61  import from LibCommon_AbstractData all;
62  import from LibCommon_VerdictControl all;
63
64  group stringStack {
65
66    type record StringStack {
67      UInt        stackSize,
68      StringItems stringItems
69    }
70
71    type record of charstring StringItems;
72
73    /**
74     * @desc    Constant which can be used to initialize a
75     *          string stack. A string stack can be intialized by
76     *          assigning this value in the variable declariation.
77     *          An alternative is to call the initlialization function.
78     * @see     LibCommon_AbstractData.f_initStringStack
79     * @remark  Note that an initlialized stack stack is not
80     *          necessarily the same as an empty string stack.
81     *          An empty tring stack as 0 zero elements but may
82     *          have a non empty list of (empty) items.
83     */
84    const StringStack c_initStringStack := { 0, {} }
85
86    /**
87     * @desc    The invocation of this function will initialize
88     *          a string stack to an empty string stack.
89     *          An alternative is to initlialize a stack using a
90     *          constant value.
91     * @see     LibCommon_AbstractData.c_initStringStack
92     * @param   p_stack String stack to be initialized.
93     */
94    function f_initStringStack ( inout StringStack p_stack ) {
95      p_stack := c_initStringStack
96    }
97
98    /**
99     * @desc    This function checks if a string stack is empty.
100     * @param   p_stack String stack to be checked.
101     * @return  true if empty, false if not empty
102     */
103    function f_isStringStackEmpty ( inout StringStack p_stack )
104    return boolean {
105      if ( p_stack.stackSize == 0 ) {return true}
106      else {return false}
107    }
108
109    /**
110     * @desc    This function checks if a given string is on the
111     *          string stack.
112     * @param   p_stack String stack where the string item
113     *          is to be looked for.
114     * @param   p_item  String to be checked for.
115     * @return  true if found, false if not found
116     */
117    function f_isItemOnStringStack ( inout StringStack p_stack,
118                       in    charstring  p_item )
119    return boolean {
120      var integer i;
121      for (i := 0; i < p_stack.stackSize; i := i+1 ) {
122        if ( p_stack.stringItems[i] == p_item ) {
123          return true;
124        }
125      }
126      return false;
127    }
128
129    /**
130     * @desc    This function checks if a given string is on the
131     *          string stack.
132     * @param   p_stack String stack where the string item
133     *          is to be looked for.
134     * @param   p_item  String item on top of the stack.
135     * @return  false if stack is empty, true otherwise
136     */
137    function f_peekStringStackTop ( inout StringStack p_stack,
138                    out   charstring  p_item)
139    return boolean {
140      if (p_stack.stackSize == 0) {
141        p_item := "f_peekTopStringStack: String stack is empty!";
142        return false;
143      }
144      p_item := p_stack.stringItems[p_stack.stackSize-1];
145      return true;
146    }
147
148
149    /**
150     * @desc    This function puts a string to the top of a
151     *          string stack.
152     * @param   p_stack String stack to which the string item
153     *          is to be added.
154     * @param   p_item  String to be added.
155     */
156    function f_pushStringStack ( inout StringStack p_stack,
157                   in    charstring  p_item ) {
158      p_stack.stringItems[p_stack.stackSize] := p_item;
159      p_stack.stackSize := p_stack.stackSize + 1;
160    }
161
162    /**
163     * @desc    This function removes the string from the top of a
164     *          string stack. If the stack is empty nothing is done
165     * @param   p_stack String stack from which the top string item
166     *          is to be removed.
167     */
168    function f_popStringStack ( inout StringStack p_stack ) {
169            if ( p_stack.stackSize > 0 ) {
170        p_stack.stackSize := p_stack.stackSize-1;
171        // "delete" top stack item to be safe
172        // Note: due to record of index the "old top" is size-1!
173        p_stack.stringItems[p_stack.stackSize] := "";
174      }
175    }
176
177  } // end group stringStack
178
179  group basicUserRelevantDefinitions {
180
181    group importantSyncTypeDefinitions {
182
183      group compTypeRelated {
184
185        /**
186         * @desc  This type is used to be the base of any synchronization
187         *        behavior which is to be executed on a sync server
188         *        component. The test component which acts as a
189         *        sync server in a test case must NOT directly use
190         *        this component type in its runs on clause!
191         *        Note that server synchronization functions may be
192         *        invoked by a test component as long as its
193         *        component type is type compatible to this component
194         *        type definition!
195         */
196        type component BaseSyncComp {
197          port  SyncPort syncPort;
198          timer tc_sync := PX_TSYNC_TIME_LIMIT;
199        }
200
201        /**
202         * @desc  This type is used to define any synchronization
203         *        behavior which is to be executed on a sync server
204         *        component. The test component which acts as a
205         *        sync server in a test case may  - but does
206         *        not have to - directly use this component type its
207         *        runs on clause.
208         *        Note that server synchronization functions may be
209         *        invoked by a test component as long as its
210         *        component type is type compatible to this component
211         *        type definition!
212         */
213        type component ServerSyncComp {
214          timer tc_shutDown := PX_TSHUT_DOWN_TIME_LIMIT;
215          // definitions for BaseSyncComp
216          port  SyncPort syncPort;
217          timer tc_sync := PX_TSYNC_TIME_LIMIT;
218        } with { extension "extends BaseSyncComp" }
219
220        /**
221         * @desc  This type is used to define any synchronization
222         *        behavior which is to be executed on a sync client
223         *        component. The test component(s) which act as a
224         *        sync client in a test case may  - but do not have
225         *        to - directly use this component type their runs
226         *        on clause.
227         *        Note that server synchronization functions may be
228         *        invoked by a test component as long as its
229         *        component type is type compatible to this component
230         *        type definition!
231         */
232        type component ClientSyncComp {
233          var StringStack v_stateStack:= c_initStringStack;
234          // definitions for BaseSyncComp
235          port  SyncPort syncPort;
236          timer tc_sync := PX_TSYNC_TIME_LIMIT;
237        } with { extension "extends BaseSyncComp" }
238
239        /**
240         * @desc  This type is used to define any synchronization
241         *        behavior which is relevant to non-concurrent test
242         *        cases.
243         *        Note that self synchronization functions may be
244         *        invoked by a test component as long as its
245         *        component type is type compatible to this component
246         *        type definition!
247         *        Note also that this type is type compatible to the
248         *        ClientSyncComp type so that shutdown altsteps from
249         *        concurrent test cases can also be reused in single
250         *        component test cases!
251         * @see   LibCommon_Sync.ClientSyncComp
252         */
253        type component SelfSyncComp {
254          port SyncPort syncSendPort;
255          // definitions for ClientSyncComp
256          var StringStack v_stateStack:= c_initStringStack;
257          port SyncPort syncPort;
258          timer tc_sync := PX_TSYNC_TIME_LIMIT;
259        } with { extension "extends ClientSyncComp" }
260
261        /**
262         * @desc  This port type must be imported into test suites
263         *        when defining test component types which are
264         *        type compatible to a synchronization component
265         *        type
266         * @see   LibCommon_Sync.SelfSyncComp
267         * @see   LibCommon_Sync.ServerSyncComp
268         * @see   LibCommon_Sync.ClientSyncComp
269         */
270        type port SyncPort message { inout SyncCmd }
271
272      } // end compTypeRelated
273
274      group standardSyncPointNames {
275        const charstring c_prDone := "preambleDone";
276        const charstring c_poDone := "postambleDone";
277        const charstring c_tbDone := "testBodyDone";
278        const charstring c_initDone := "initDone";
279      }
280
281    } // end group importantSyncTypeDefinitions
282
283    group syncCompTestConfiguration {
284
285      /**
286       *  @desc   Calls self connect function if invoking
287       *         component is the MTC or otherwise connects the client
288       *         the server. This function allows to implement preambles
289       *         in a way that they can be used by test components
290       *         in both non-concurrent as well as concurrent test
291       *         cases!
292       * @remark This function should _not_ be called if the MTC
293       *         acts as a client (and not a server) in a concurrent
294       *         test case. In this case f_connect4ClientSync
295       *         should be used instead.
296       * @see    LibCommon_Sync.f_connect4SelfSync
297       * @see    LibCommon_Sync.f_connect4ClientSync
298       */
299      function f_connect4SelfOrClientSync()
300      runs on SelfSyncComp {
301        if ( self == mtc ) {
302          f_connect4SelfSync();
303        } else {
304          f_connect4ClientSync();
305        }
306      }
307
308      /**
309       * @desc   Calls self connect function if the invoking
310       *         component is the MTC or otherwise disconnects the client
311       *         from the server. This function allows to implement
312       *         postambles in a way that they can be used in both
313       *         non-concurrent as well as concurrent test cases.
314       * @remark This function should _not_ be called if the MTC
315       *         acts as a client (and not a server) in a concurrent
316       *         test case. In this case f_disconnect4ClientSync
317       *         should be used instead.
318       * @see    LibCommon_Sync.f_disconnect4SelfSync
319       * @see    LibCommon_Sync.f_disconnect4ClientSync
320       */
321      function f_disconnect4SelfOrClientSync()
322      runs on SelfSyncComp {
323        if ( self == mtc ) {
324          f_disconnect4SelfSync();
325        } else {
326          f_disconnect4ClientSync();
327        }
328      }
329
330    } // end group syncCompTestConfiguration
331
332    group syncFunctions {
333
334      /**
335       * @desc   Implements synchronization of 2 clients from server side
336       *         on one or more synchronization points.
337       *         If problem occurs, then server sends STOP to all clients.
338       *         Waits for PX_TSYNC_TIME_LIMIT to let clients
339       *         finish executing their behavior until this
340       *         synchronization point. After passing all synchronization
341       *         points successfuly the server waits for all clients
342       *         to stop.
343       *         See f_serverSyncClientsTimed for overwriting this
344       *         the timing constraint!
345       *         This function sets the server component verdict.
346       * @remark The use of this function requires prior connection  of
347       *         the server sync ports!
348       * @see    LibCommon_Sync.f_connect4SelfOrClientSync
349       * @see    LibCommon_Sync.PX_TSYNC_TIME_LIMIT
350       * @see    LibCommon_Sync.f_serverSyncClientsTimed
351       * @see    LibCommon_Sync.f_serverWaitForAllClientsToStop
352       * @param  p_syncPointIds list of synchronization point name/ids
353       */
354      function f_serverSync2ClientsAndStop( in SyncPointList p_syncPointIds )
355      runs on ServerSyncComp {
356        var integer i, v_noOfSyncIds := sizeof(p_syncPointIds);
357        for ( i := 0; i < v_noOfSyncIds; i := i+1 ) {
358          f_serverSyncClientsTimed(2,p_syncPointIds[i], PX_TSYNC_TIME_LIMIT);
359        }
360        f_serverWaitForAllClientsToStop();
361      }
362
363      /**
364       * @desc   Implements synchronization of 3 clients from server side
365       *         on one or more synchronization points.
366       *         If problem occurs, then server sends STOP to all clients.
367       *         Waits for PX_TSYNC_TIME_LIMIT to let clients
368       *         finish executing their behavior until this
369       *         synchronization point. After passing all synchronization
370       *         points successfuly the server waits for all clients
371       *         to stop.
372       *         See f_serverSyncClientsTimed for overwriting this
373       *         the timing constraint!
374       *         This function sets the server component verdict.
375       * @remark The use of this function requires prior connection  of
376       *         the server sync ports!
377       * @see    LibCommon_Sync.f_connect4SelfOrClientSync
378       * @see    LibCommon_Sync.PX_TSYNC_TIME_LIMIT
379       * @see    LibCommon_Sync.f_serverSyncClientsTimed
380       * @see    LibCommon_Sync.f_serverWaitForAllClientsToStop
381       * @param  p_syncPointIds list of synchronization point name/ids
382       */
383      function f_serverSync3ClientsAndStop( in SyncPointList p_syncPointIds )
384      runs on ServerSyncComp {
385        var integer i, v_noOfSyncIds := sizeof(p_syncPointIds);
386        for ( i := 0; i < v_noOfSyncIds; i := i+1 ) {
387          f_serverSyncClientsTimed(3,p_syncPointIds[i], PX_TSYNC_TIME_LIMIT);
388        }
389        f_serverWaitForAllClientsToStop();
390      }
391
392      /**
393       * @desc   Implements synchronization of 4 clients from server side
394       *         on one or more synchronization points.
395       *         If problem occurs, then server sends STOP to all clients.
396       *         Waits for PX_TSYNC_TIME_LIMIT to let clients
397       *         finish executing their behavior until this
398       *         synchronization point. After passing all synchronization
399       *         points successfuly the server waits for all clients
400       *         to stop.
401       *         See f_serverSyncClientsTimed for overwriting this
402       *         the timing constraint!
403       *         This function sets the server component verdict.
404       * @remark The use of this function requires prior connection  of
405       *         the server sync ports!
406       * @see    LibCommon_Sync.f_connect4SelfOrClientSync
407       * @see    LibCommon_Sync.PX_TSYNC_TIME_LIMIT
408       * @see    LibCommon_Sync.f_serverSyncClientsTimed
409       * @see    LibCommon_Sync.f_serverWaitForAllClientsToStop
410       * @param  p_syncPointIds list of synchronization point name/ids
411       */
412      function f_serverSync4ClientsAndStop( in SyncPointList p_syncPointIds )
413      runs on ServerSyncComp {
414        var integer i, v_noOfSyncIds := sizeof(p_syncPointIds);
415        for ( i := 0; i < v_noOfSyncIds; i := i+1 ) {
416          f_serverSyncClientsTimed(4,p_syncPointIds[i], PX_TSYNC_TIME_LIMIT);
417        }
418        f_serverWaitForAllClientsToStop();
419      }
420
421      /**
422       * @desc   Implements synchronization of N clients from server side
423       *         on one or more synchronization points.
424       *         If problem occurs, then server sends STOP to all clients.
425       *         Waits for PX_TSYNC_TIME_LIMIT to let clients
426       *         finish executing their behavior until this
427       *         synchronization point. After passing all synchronization
428       *         points successfuly the server waits for all clients
429       *         to stop.
430       *         See f_serverSyncClientsTimed for overwriting this
431       *         the timing constraint!
432       *         This function sets the server component verdict.
433       * @remark The use of this function requires prior connection  of
434       *         the server sync ports!
435       * @see    LibCommon_Sync.f_connect4SelfOrClientSync
436       * @see    LibCommon_Sync.PX_TSYNC_TIME_LIMIT
437       * @see    LibCommon_Sync.f_serverSyncClientsTimed
438       * @see    LibCommon_Sync.f_serverWaitForAllClientsToStop
439       * @param  p_numClients number of synchronization clients
440       * @param  p_syncPointIds list of synchronization point name/ids
441       */
442      function f_serverSyncNClientsAndStop (
443        in integer p_numClients,
444        in SyncPointList p_syncPointIds )
445      runs on ServerSyncComp {
446        var integer i, v_noOfSyncIds := sizeof(p_syncPointIds);
447        for ( i := 0; i < v_noOfSyncIds; i := i+1 ) {
448          f_serverSyncClientsTimed (
449                p_numClients,
450                p_syncPointIds[i],
451                PX_TSYNC_TIME_LIMIT );
452        }
453        f_serverWaitForAllClientsToStop();
454      }
455
456      /**
457       * @desc   Implements synchronization of 2 clients and 1 UT from server side
458       *         on one or more synchronization points.
459       *         If problem occurs, then server sends STOP to all clients.
460       *         Waits for PX_TSYNC_TIME_LIMIT to let clients
461       *         finish executing their behavior until this
462       *         synchronization point. After passing all synchronization
463       *         points successfuly the server waits for all clients
464       *         to stop.
465       *         See f_serverSyncClientsTimed for overwriting this
466       *         the timing constraint!
467       *         This function sets the server component verdict.
468       * @remark The use of this function requires prior connection  of
469       *         the server sync ports!
470       * @see    LibCommon_Sync.f_connect4SelfOrClientSync
471       * @see    LibCommon_Sync.PX_TSYNC_TIME_LIMIT
472       * @see    LibCommon_Sync.f_serverSyncClientsTimed
473       * @see    LibCommon_Sync.f_serverWaitForAllClientsToStop
474       * @param  p_syncPointIds list of synchronization point name/ids
475       */
476      function f_serverSync2ClientsUtAndStop( in SyncPointList p_syncPointIds )
477      runs on ServerSyncComp {
478        var integer i, v_noOfSyncIds := sizeof(p_syncPointIds);
479        for ( i := 0; i < v_noOfSyncIds; i := i+1 ) {
480          f_serverSyncClientsTimed(3,p_syncPointIds[i], PX_TSYNC_TIME_LIMIT);
481        }
482        f_serverWaitForAllClientsToStop();
483      }
484
485      /**
486       * @desc   Calls either self synchronization function if
487       *         invoking component is the MTC, otherwise
488       *         calls client synchronization. After that it
489       *         sets the verdict based on the specified return code.
490       *         This function allows to implement TTCN-3 functions
491       *         in a way that they can be used in both non-concurrent
492       *         as well as concurrent test cases.
493       * @remark This function should _not_ be called if the MTC
494       *         acts as a client (and not a server) in a concurrent
495       *         test case. In this case f_clientSyncAndVerdict
496       *         should be used instead.
497       * @param  p_syncPoint Synchronization point name/id
498       * @param  p_ret Current behavior execution status
499       * @see    LibCommon_Sync.f_clientSyncAndVerdict
500       * @see    LibCommon_VerdictControl.f_setVerdict
501       */
502      function f_selfOrClientSyncAndVerdict( in charstring p_syncPoint,
503                           in FncRetCode p_ret)
504      runs on SelfSyncComp {
505        if ( self == mtc ) {
506          // then assume we are running non-conurrent test case
507          f_selfSyncAndVerdict(p_syncPoint, p_ret);
508        } else {
509          f_clientSyncAndVerdict(p_syncPoint, p_ret);
510        }
511      }
512
513      /**
514       * @desc   Calls either self synchronization function if
515       *         invoking component is the MTC, otherwise
516       *         calls client synchronization. After that it
517       *         sets a preamble specific verdict based on the
518       *         specified return code.
519       *         This function allows to implement TTCN-3 functions
520       *         in a way that they can be used in both non-concurrent
521       *         as well as concurrent test cases.
522       * @remark This function should _not_ be called if the MTC
523       *         acts as a client (and not a server) in a concurrent
524       *         test case. In this case f_clientSyncAndVerdict
525       *         should be used instead.
526       * @param  p_syncPoint Synchronization point name/id
527       * @param  p_ret Current behavior execution status
528       * @see    LibCommon_Sync.f_clientSyncAndVerdict
529       * @see    LibCommon_VerdictControl.f_setVerdictPreamble
530       */
531      function f_selfOrClientSyncAndVerdictPR( in charstring p_syncPoint,
532                             in FncRetCode p_ret)
533      runs on SelfSyncComp {
534        if ( self == mtc ) {
535          // then assume we are running non-conurrent test case
536          f_selfSyncAndVerdictPreamble(p_syncPoint, p_ret);
537        } else {
538          f_clientSyncAndVerdictPreamble(p_syncPoint, p_ret);
539        }
540      }
541
542    } // end group syncFunctions
543
544    group syncCompStateHandling {
545
546      /**
547       *
548       * @desc   This function updates the state (stack) of a
549       *         sync client or self sync component. This stack is
550       *         key in the shutdown handling of test components.
551       *         It adds the new state name to the top of the
552       *         sync component stack of states.
553       *         The state will only be added in case of a current
554       *         execution status of e_success.
555       * @param  p_newSyncCompState Name of state which was attempted to be reached.
556       * @param  p_ret Current behavior execution status
557       * @remark If the state of component changes this function must be
558       *         _at least_ called from your test suite prior to f_selfSync
559       *         or f_clientSync which is the only definite place for the
560       *         shutdown default invocation!
561       * @see    LibCommon_Sync.a_dummyShutDown
562       * @see    LibCommon_Sync.f_selfSync
563       * @see    LibCommon_Sync.f_clientSync
564       */
565      function f_addSyncCompState(in charstring p_newSyncCompState,
566                    in FncRetCode p_ret)
567      runs on ClientSyncComp {
568        if ( p_ret == e_success ) {
569          if ( f_isItemOnStringStack(v_stateStack,p_newSyncCompState) ) {
570              log("**** f_addSyncCompState: WARNING: Attempt to add state which is already on sync state stack! No additition done.****");
571          } else {
572              f_pushStringStack(v_stateStack,p_newSyncCompState);
573          }
574        }
575      } // end function f_addSyncCompState
576
577      /**
578       *
579       * @desc   This function returns the top state on the sync
580       *         state stack of a sync client or self sync
581       *         component and removes it from the stack
582       *         This function cna be used, e.g., in a while
583       *         statement within a postamble or shutdown
584       *         implementation
585       * @param  p_state State on top of the state stack.
586       * @return false if state stack is empty, true otherwise
587       * @see    LibCommon_Sync.a_dummyShutDown
588       */
589      function f_getTopSyncCompState( out charstring p_state )
590      runs on ClientSyncComp
591      return boolean {
592        if ( not f_peekStringStackTop(v_stateStack,p_state) ) {
593          p_state := "IDLE";
594          return false;
595        }
596        f_popStringStack(v_stateStack);
597        return true;
598      } // end function f_getTopSyncCompState
599
600      /*
601       * @desc  This function removes the last state on the state stack
602       *        of a sync client or self sync component.
603       *        This stack is key in the shutdown handling of test
604       *        components.
605       * @see   LibCommon_Sync.a_dummyShutDown
606       */
607      function f_popSyncCompState()
608      runs on ClientSyncComp {
609        f_popStringStack(v_stateStack);
610      } // end function f_popSyncCompState
611
612      /**
613       *
614       * @desc   This function returns the top state on the sync state
615       *         stack of a sync client or self sync component. It
616       *         does not remove it from the stack
617       *         This stack is key in the shutdown handling of test
618       *         components.
619       * @param  p_state  State on top of the state stack.
620       * @return false if state stack is empty, true otherwise
621       * @see    LibCommon_Sync.a_dummyShutDown
622       */
623      function f_peekTopSyncCompState(out charstring p_state)
624      runs on ClientSyncComp
625      return boolean {
626        return f_peekStringStackTop(v_stateStack,p_state);
627      } // end function f_peekTopSyncCompState
628
629      /**
630       * @desc  This function checks if the sync state stack
631       *        of a sync client or self sync component is empty.
632       *        This stack is key in the shutdown handling of test
633       *        components.
634       * @see   LibCommon_Sync.a_dummyShutDown
635       */
636      function f_isSyncCompStateStackEmpty()
637      runs on ClientSyncComp
638      return boolean {
639        return f_isStringStackEmpty(v_stateStack);
640      } // end function f_isSyncCompStateStackEmpty
641
642    } // end group syncCompStateHandling
643
644    group exampleShutDownAltstep {
645
646      /**
647       * @desc   This is an example of a shutdown altstep which can be
648       *         used as a "template" for a interface specific shutdown
649       *         altstep or possily as a first temporary solution in
650       *         test case development.<br><br>
651       *         This altstep shall be activated as a default as the
652       *         first statement in each test case function which drives
653       *         an interface, i.e., in MTC behavior of single component
654       *         and in each client behavior of multi component test
655       *         cases.<br>
656       *         The required behavior from this altstep is to:<br><br>
657       *           1) expect the STOP either via the test component
658       *              syncPort<br><br>
659       *           2) upon its arrival it should shut down the SUT
660       *              gracefully based on the current component state<br><br>
661       *         The current component state should have been
662       *         previously kept uptodate from a test suite via the
663       *         f_addSyncCompState function. This default will then be
664       *         (automatically) invoked either from within f_selfSync
665       *         or f_clientSync.<br>
666       *         Note that shutdown defaults can be written as
667       *         _interface specific_ - they do not need to be test case
668       *         or test component specific! See another example of a
669       *         shutdown altstep in the sync module.
670       * @see    LibCommon_Sync.f_addSyncCompState
671       * @see    LibCommon_Sync.f_selfSync
672       * @see    LibCommon_Sync.f_clientSync
673       * @see    LibCommon_SyncExamples.a_exampleShutDown
674       * @remark Your application specific shutdown altstep
675       *         implementation(s) should _not_ be defined in this
676       *         module but as part of your test suite or application specific
677       *         modules.
678       */
679      altstep a_dummyShutDown()
680      runs on SelfSyncComp {
681        []  syncPort.receive(m_syncServerStop){
682            var charstring v_state := "";
683            tc_sync.stop;
684            log("**** a_dummyShutDown: Test component received STOP signal from sync server - going to IDLE state ****");
685            while ( f_getTopSyncCompState(v_state) ) {
686              if ( v_state == "x" ) {
687                // then do something
688              } else if ( v_state == "y" ) {
689                // then do something else
690              }
691            } // end while
692            f_disconnect4SelfOrClientSync();
693            // unmap/disconnect more if needed
694            log("**** a_dummyShutDown: -> Test component stopping itself now! ****") ;
695            stop ;
696          }
697      } // end altstep a_dummyShutDown
698
699    } // end group exampleShutDownAltstep
700
701  } // end group basicUserRelevantDefinitions
702
703  group advancedUserRelevantDefinitions {
704
705    group serverRelated {
706
707      /**
708       * @desc   Implements synchronization of "n" clients from server
709       *         side. If a problem occurs, then server sends STOP to
710       *         all clients. Waits for PX_TSYNC_TIME_LIMIT to let
711       *         clients finish executing their behavior until this
712       *         synchronization point. See f_serverSyncClientsTimed for
713       *         overwriting this later timing constraint!
714       *         This function sets the server component verdict.
715       * @remark The use of this function requires prior connection  of
716       *         the server sync port!
717       * @see    LibCommon_Sync.f_connect4SelfOrClientSync
718       * @see    LibCommon_Sync.PX_TSYNC_TIME_LIMIT
719       * @see    LibCommon_Sync.f_serverSyncClientsTimed
720       * @param  p_noOfClients number of clients to be synchronized
721       * @param  p_syncId synchronization point name/id
722       */
723      function f_serverSyncClients( in UInt p_noOfClients, in charstring p_syncId )
724      runs on ServerSyncComp {
725        f_serverSyncClientsTimed(p_noOfClients,p_syncId, PX_TSYNC_TIME_LIMIT);
726      }
727
728      /**
729       * @desc   Handles synchronization of clients from server side.
730       *         If problem occurs, then server sends STOP to all clients.
731       *         This function sets the server verdict.
732       * @remark The use of this function requires prior connection of
733       *         the server sync ports!
734       * @param  p_NoOfClients number of clients to be synchronized
735       * @param  p_syncId synchronization point name/id
736       * @param  p_execTimeLimit time limit given to all clients to finish the execution
737       *         of their behavior up to this synchronization point
738       * @see    LibCommon_Sync.f_connect4SelfOrClientSync
739       */
740      function f_serverSyncClientsTimed(  in UInt     p_NoOfClients,
741                        in charstring   p_syncId,
742                        float       p_execTimeLimit )
743      runs on ServerSyncComp {
744
745        var integer v_noOfRecvdSyncMsgs := 0;
746        var boolean v_stopClients := false;
747        var ClientSyncCompList v_clientRefs := {};
748        var ClientSyncComp v_clientRef;
749
750        if ( p_syncId == c_prDone ) {
751          log("**** f_serverSyncClientsTimed: Sync server now starting PREAMBLE synchronization ... ****") ;
752        } else if ( p_syncId == c_tbDone ) {
753          log("**** f_serverSyncClientsTimed: Sync server now starting TEST BODY synchronization ... ****") ;
754        } else if ( p_syncId == c_initDone ) {
755          log("**** f_serverSyncClientsTimed: Sync server now starting UPPER TESTER synchronization ... ****") ;
756        } else {
757          log("**** f_serverSyncClientsTimed: Sync server now starting handling of next synchronization point ... ****") ;
758        }
759        tc_sync.start(p_execTimeLimit) ;
760        alt{
761          []  syncPort.receive(m_syncClientReady(p_syncId)) -> sender v_clientRef {
762                v_clientRefs[v_noOfRecvdSyncMsgs] := v_clientRef;
763              v_noOfRecvdSyncMsgs := v_noOfRecvdSyncMsgs + 1;
764              if ( v_noOfRecvdSyncMsgs != p_NoOfClients ) { repeat; }
765            }
766          []  syncPort.receive(m_syncClientStop) -> sender v_clientRef {
767              log("**** f_serverSyncClientsTimed: Sync server received STOP signal from a client - server will wait for all clients to reach their next synchronization point and then stop them! ****") ;
768              v_stopClients := true;
769                v_clientRefs[v_noOfRecvdSyncMsgs] := v_clientRef;
770              v_noOfRecvdSyncMsgs := v_noOfRecvdSyncMsgs + 1;
771              if ( v_noOfRecvdSyncMsgs != p_NoOfClients ) { repeat; }
772            }
773          []  syncPort.receive(m_syncClientReady(?)) -> sender v_clientRef {
774              log("**** f_serverSyncClientsTimed: Sync server received client sync message with incorrect synchronization point id which is currently not handled - server will stop all clients! ****") ;
775              v_stopClients := true;
776                v_clientRefs[v_noOfRecvdSyncMsgs] := v_clientRef; }
777          []  syncPort.receive(SyncCmd :? ) {
778              log("**** f_serverSyncClientsTimed: Sync server received (invalid) sync message from other sync server - server will stop all clients! ****") ;
779              v_stopClients := true; }
780          []  any port.receive {
781              // leave it to be ok to receive anything else
782              // in case that the user has added any non-sync ports to
783              // his/her server component type definition!
784              }
785          []  tc_sync.timeout{
786              log("**** f_serverSyncClientsTimed: A client is not responding within specified time limit - sync server is sending stop to all clients! ****");
787              v_stopClients := true; }
788        } //end alt
789        tc_sync.stop ;
790        if ( v_stopClients ) {
791          setverdict(inconc);
792          // then send out STOP sync msg
793          f_serverSendToAllClients(v_clientRefs, m_syncServerStop);
794          f_serverWaitForAllClientsToShutDown(); // function will never return!
795        } else {
796          setverdict(pass);
797          // then send out READY sync msg
798          f_serverSendToAllClients(v_clientRefs, m_syncServerReady(p_syncId));
799          if ( p_syncId == c_prDone ) {
800            log("**** f_serverSyncClientsTimed: Sync server successfully passed PREAMBLE synchronization point. ****") ;
801          } else if ( p_syncId == c_tbDone ) {
802            log("**** f_serverSyncClientsTimed: Sync server successfully passed TEST BODY synchronization point. ****") ;
803          } else {
804            log("**** f_serverSyncClientsTimed: Sync server successfully passed synchronization point. ****") ;
805          }
806        }
807      } // end function f_serverSyncClientsTimed
808
809      /**
810       * @desc  This function is intended only for use on the sync
811       *        server component in concurrent TTCN-3 test cases.
812       *        It waits for all components to finish execution within
813       *        the PX_TSYNC_TIME_LIMIT. If a timeout occurs
814       *        the server will stop all clients.
815       *        This function sets the server component verdict.
816       */
817      function f_serverWaitForAllClientsToStop()
818      runs on ServerSyncComp {
819        tc_sync.start;
820        alt {
821          [] all component.done {
822              tc_sync.stop;
823              log("**** f_serverWaitForAllClientsToStop: All sync clients have finished their execution. Sync server now terminating test case. ****") ;
824            }
825          [] tc_sync.timeout {
826              log("**** f_serverWaitForAllClientsToStop: Not all sync clients have finshed execution within the sync time limit. Sync server will stop test case! ****") ;
827            }
828        } // end alt
829        setverdict(pass);
830          stop;
831      } // end function f_serverWaitForAllClientsToStop
832
833    } // end group serverRelated
834
835    group clientRelated {
836
837      /**
838       * @desc  This function creates the connection needed to
839       *        execute client synchronization functions
840       * @see   LibCommon_Sync.f_clientSync
841       * @see   LibCommon_Sync.f_clientSendStop
842       */
843      function f_connect4ClientSync()
844      runs on ClientSyncComp {
845        connect(self:syncPort, mtc:syncPort);
846      }// end function f_connect4ClientSync
847
848      /**
849       * @desc  This function removes the connection needed
850       *        to execute client synchronization functions
851       * @see   LibCommon_Sync.f_clientSync
852       * @see   LibCommon_Sync.f_clientSendStop
853       */
854      function f_disconnect4ClientSync()
855      runs on ClientSyncComp {
856        disconnect(self:syncPort, mtc:syncPort);
857      }// end function f_disconnect4ClientSync
858
859      /**
860       * @desc   This function combines client verdict setting with its
861       *         synchronization for use after or within a preamble
862       *         implementation.
863       *         Note that such preambles can _not_ be reused in non-
864       *         concurrent test cases.
865       *         This function sets the client component verdict.
866       * @remark The use of this function requires prior connection
867       *         of the client sync port!
868       * @see    LibCommon_Sync.f_connect4ClientSync
869       * @see    LibCommon_Sync.f_connect4SelfOrClientSync
870       * @see    LibCommon_VerdictControl.f_setVerdictPreamble
871       * @param  p_syncId Synchronization point name/id
872       * @param  p_ret Current behavior execution status
873       */
874      function f_clientSyncAndVerdictPreamble(in charstring p_syncId ,
875                          FncRetCode p_ret )
876      runs on ClientSyncComp {
877        f_setVerdictPreamble(p_ret);
878        f_clientSync(p_syncId,p_ret);
879      }
880
881      /**
882       * @desc   This function combines client verdict setting with its
883       *         synchronization for use,e.g, after or within a
884       *         test body implementation.
885       *         Note that such premables can _not_ be reused in non-
886       *         concurrent test cases. This can be achieved by using
887       *         the f_selfOrClientSyncAndVerdict function instead.
888       *         This function sets the client component verdict.
889       * @param  p_syncId Synchronization point name/id
890       * @param  p_ret Current behavior execution status
891       * @remark The use of this function requires prior connection
892       *         of the client sync port!
893       * @see    LibCommon_Sync.f_connect4ClientSync
894       * @see    LibCommon_Sync.f_connect4SelfOrClientSync
895       * @see    LibCommon_VerdictControl.f_setVerdict
896       * @see    LibCommon_Sync.f_selfOrClientSyncAndVerdict
897       */
898      function f_clientSyncAndVerdict(in charstring p_syncId,
899                      in FncRetCode p_ret )
900      runs on ClientSyncComp {
901        f_setVerdict(p_ret);
902        f_clientSync(p_syncId,p_ret);
903      }
904
905      /**
906       * @desc   This function combines client verdict setting with its
907       *         synchronization for use after or within a
908       *         postamble implementation.
909       *         Note that such prostambles can _not_ be reused in non-
910       *         concurrent test cases.
911       *         This function sets the client component verdict.
912       * @remark The use of this function requires prior connection
913       *         of the client sync port!
914       * @see    LibCommon_Sync.f_connect4ClientSync
915       * @see    LibCommon_Sync.f_connect4SelfOrClientSync
916       * @see    LibCommon_VerdictControl.f_setVerdictPostamble
917       * @param  p_syncId Synchronization point name/id
918       * @param  p_ret Current behavior execution status
919       */
920      function f_clientSyncAndVerdictPostamble(in charstring p_syncId ,
921                           in FncRetCode p_ret )
922      runs on ClientSyncComp {
923        f_setVerdictPostamble(p_ret);
924        f_clientSync(p_syncId,p_ret);
925      }
926
927      /**
928       * @desc   This function handles synchronization of a sync client
929       *         with the server. In case of successful execution it sends
930       *         a READY message to the server and waits the READY back.
931       *         The time used for waiting is defined by PX_TSYNC_TIME_LIMIT.
932       *         In case of a non successful execution status it
933       *         sends a STOP message to the server.
934       *         In both cases the receipt of a STOP message or no
935       *         response from the server it will trigger the shutdown
936       *         default (if activated).
937       *         This function will set only the client verdict to INCONC
938       *         (and stop its execution) if no STOP response is received
939       *         from the server within the PX_TSYNC_TIME_LIMIT
940       *         or if no shutdown default is activated. In all other
941       *         cases the client verdict is NOT set.
942       * @param  p_syncId Synchronization point name/id
943       * @param  p_ret Current behavior execution status
944       * @remark The use of this function requires prior connection
945       *         of the client sync port!
946       * @see    LibCommon_Sync.f_connect4ClientSync
947       * @see    LibCommon_Sync.f_connect4SelfOrClientSync
948       * @see    LibCommon_Sync.PX_TSYNC_TIME_LIMIT
949       * @see    LibCommon_Sync.a_dummyShutDown
950       * @see    LibCommon_Sync.f_clientSendStop
951       * @return Updated execution status
952       */
953      function f_clientSync(  in charstring p_syncId ,
954                  in FncRetCode p_ret )
955      runs on ClientSyncComp
956      return FncRetCode{
957
958        if (p_ret == e_success){
959          syncPort.send(m_syncClientReady(p_syncId));
960          tc_sync.start;
961          alt{
962            [] syncPort.receive(m_syncServerReady(p_syncId)){
963                tc_sync.stop ; }
964            [] tc_sync.timeout{
965                log("**** f_clientSync: Sync client did not receive message from sync server within the specified time limit - sync client will ask sync server to stop test case! ****") ;
966                f_clientSendStop(); } // function will not return!
967          } //end alt
968        } //end if
969        else {
970          log("**** f_clientSync: Execution status indicates that execution of test component behavior was not successful - sync client will ask sync server to stop test case! ****") ;
971          f_clientSendStop(); // function will not return!
972        }
973        if ( p_syncId == c_prDone ) {
974          log("**** f_clientSync: Sync client successfully passed PREAMBLE synchronization point. ****") ;
975        } else if ( p_syncId == c_tbDone ) {
976          log("**** f_clientSync: Sync client successfully passed TEST BODY synchronization point. ****") ;
977        } else {
978          log("**** f_clientSync: Sync client successfully passed synchronization point. ****") ;
979        }
980        return e_success ;
981
982      } // end function f_clientSync
983
984      /**
985       * @desc   This function can be used to request the shutdown a
986       *         multi component test case _prior_ to reaching a
987       *         synchronization point. It sends a STOP message to
988       *         the sync server and awaits then the STOP from the server
989       *         which will trigger the shutdown default (if activated).
990       *         This function will set the server verdict to INCONC (and
991       *         stop the test case) if no shutdown default is activated.
992       *         This function will set only the client verdict to INCONC
993       *         (and stop its execution) if no STOP response is received
994       *         from the server within the PX_TSYNC_TIME_LIMIT
995       *         or if no shutdown default is activated. In all other
996       *         cases the client verdict is NOT set.
997       * @remark The use of this function requires prior connection
998       *         of the client sync port!
999       * @see    LibCommon_Sync.f_connect4ClientSync
1000       * @see    LibCommon_Sync.f_connect4SelfOrClientSync
1001       * @see    LibCommon_Sync.PX_TSYNC_TIME_LIMIT
1002       * @see    LibCommon_Sync.a_dummyShutDown
1003       */
1004      function f_clientSendStop()
1005      runs on ClientSyncComp {
1006        log("**** f_clientSendStop: Sync client requesting from server to stop test case (including itself). ****") ;
1007        syncPort.send(m_syncClientStop) ;
1008        tc_sync.start;
1009        alt{
1010          [] tc_sync.timeout{
1011              log("**** f_clientSendStop: Stopping sync client without shutdown - either no shutdown default active or no stop received from server. ****") ;
1012              setverdict(inconc);
1013              stop ;
1014             }
1015        }//end alt
1016        tc_sync.stop;
1017        stop; // stop here if shutdown default does not stop
1018      }
1019
1020    } // end group clientRelated
1021
1022  } // end group advancedUserRelevantDefinitions
1023
1024  group otherSyncModuleDefinitions {
1025
1026    group syncModuleparams {
1027      /**
1028       *
1029       * @desc  Default time limit for a sync client to reach a
1030       *        synchronization point
1031       */
1032      modulepar {float PX_TSYNC_TIME_LIMIT := 120.0}
1033
1034      /*
1035       * @desc  Default time limit for a sync client to finish
1036       *        its execution of the shutdown default
1037       */
1038      modulepar {float PX_TSHUT_DOWN_TIME_LIMIT := 120.0}
1039    }
1040
1041    group otherSyncTypes {
1042
1043      type record of charstring SyncPointList;
1044
1045      type record of ClientSyncComp ClientSyncCompList;
1046
1047    } // end group otherSyncTypes
1048
1049    group otherSelfSyncRelatedDefinitions {
1050
1051      /**
1052       * @desc  This function creates the connection needed to
1053       *        execute self sync functions
1054       * @see   LibCommon_Sync.f_selfSync
1055       * @see   LibCommon_Sync.f_selfSyncStop
1056       */
1057      function f_connect4SelfSync()
1058      runs on SelfSyncComp {
1059        connect(self:syncSendPort, self:syncPort);
1060      }// end function f_connect4SelfSync
1061
1062      /**
1063       * @desc  This function removes the connection needed
1064       *        to execute self sync functions
1065       * @see   LibCommon_Sync.f_selfSync
1066       * @see   LibCommon_Sync.f_selfSyncStop
1067       */
1068      function f_disconnect4SelfSync()
1069      runs on SelfSyncComp {
1070        disconnect(self:syncSendPort, self:syncPort);
1071      }// end function f_disconnect4SelfSync
1072
1073      /**
1074       * @desc  This function combines MTC verdict setting with self
1075       *        synchronization for use after and possibly in the test body
1076       * @param p_syncId Synchronization point name/id
1077       * @param p_ret Current behavior execution status
1078       * @see   LibCommon_VerdictControl.f_setVerdict
1079       * @see   LibCommon_Sync.f_selfSync
1080       * @see   LibCommon_Sync.a_dummyShutDown
1081       */
1082      function f_selfSyncAndVerdict(  in charstring p_syncId,
1083                      in FncRetCode p_ret )
1084      runs on SelfSyncComp {
1085        f_setVerdict(p_ret);
1086        f_selfSync(p_syncId,p_ret);
1087      }
1088
1089      /**
1090       * @desc  This function combines MTC verdict setting with self
1091       *        synchronization for use after the preamble.
1092       * @param p_syncId Synchronization point name/id
1093       * @param p_ret Current behavior execution status
1094       * @see   LibCommon_VerdictControl.f_setVerdictPreamble
1095       * @see   LibCommon_Sync.f_selfSync
1096       */
1097      function f_selfSyncAndVerdictPreamble(  in charstring p_syncId,
1098                          in FncRetCode p_ret )
1099      runs on SelfSyncComp {
1100        f_setVerdictPreamble(p_ret);
1101        f_selfSync(p_syncId,p_ret);
1102      }
1103
1104      /**
1105       * @desc  This function combines MTC verdict setting with self
1106       *        synchronization for use after the postamble.
1107       * @param p_syncId Synchronization point name/id
1108       * @param p_ret Current behavior execution status
1109       * @see   LibCommon_VerdictControl.f_setVerdictPostamble
1110       * @see   LibCommon_Sync.f_selfSync
1111       */
1112      function f_selfSyncAndVerdictPostamble( in charstring p_syncId ,
1113                          in FncRetCode p_ret )
1114      runs on SelfSyncComp {
1115        f_setVerdictPostamble(p_ret);
1116        f_selfSync(p_syncId,p_ret);
1117      }
1118
1119      /**
1120       * @desc   This function synchronizes a MTC with itself. In case
1121       *         of a non successful execution status it sends a STOP
1122       *         message to itself and invokes that way the
1123       *         shutdown default (if activated).
1124       *         This function will set the server verdict to INCONC (and
1125       *         stop the test case) if no shutdown default is activated.
1126       *         Otherwise no verdict is set.
1127       * @remark Sync ports should be connected prior to the invocation
1128       *         of this function!
1129       * @param  p_syncId Synchronization point name/id
1130       * @param  p_ret Current behavior execution status
1131       * @return Updated execution status
1132       * @see    LibCommon_Sync.f_connect4SelfSync
1133       * @see    LibCommon_Sync.a_dummyShutDown
1134       */
1135      function f_selfSync(  in charstring p_syncId ,
1136                  in FncRetCode p_ret )
1137      runs on SelfSyncComp
1138      return FncRetCode{
1139        if (p_ret != e_success){
1140          f_selfSyncStop() ; // function will not return!
1141        }
1142        if ( p_syncId == c_prDone ) {
1143          log("**** f_selfSync: Successfully passed PREAMBLE synchronization point. ****") ;
1144        } else if ( p_syncId == c_tbDone ) {
1145          log("**** f_selfSync: Successfully passed TEST BODY synchronization point. ****") ;
1146        } else {
1147          log("**** f_selfSync: Successfully passed synchronization point. ****") ;
1148        }
1149        return e_success ;
1150      }// end function f_selfSync
1151
1152      /**
1153       * @desc   This function can be used to shut down a test case _prior_
1154       *         to reaching a synchronization point. it sends a STOP
1155       *         message to itself and invokes that way the
1156       *         shutdown default (if activated).
1157       *         This function will set the server verdict to INCONC (and
1158       *         stop the test case) if no shutdown default is activated.
1159       *         Otherwise no verdict is set.
1160       * @remark  Sync ports should be connected prior to the invocation
1161       *          of this function!
1162       * @see     LibCommon_Sync.f_connect4SelfSync
1163       */
1164      function f_selfSyncStop()
1165      runs on SelfSyncComp {
1166
1167        log("**** f_selfSyncStop: MTC requests to stop test case (itself). ****") ;
1168        syncSendPort.send(m_syncServerStop) ; // this MUST be _server_ for the default to catch!
1169        tc_sync.start(PX_TSYNC_TIME_LIMIT);
1170        alt{
1171          [] tc_sync.timeout{
1172              log("**** f_selfSyncStop: Stopping MTC without shutdown - either no shutdown default active or missing syncPort connection ****") ;
1173              setverdict(inconc);
1174              stop ;
1175             }
1176        }//end alt
1177        tc_sync.stop;
1178        stop; // if shutdown default is not activated or if it does not stop
1179      } // end function f_selfSyncStop
1180
1181    } // end group otherSelfSyncRelatedDefinitions
1182
1183    /**
1184     *
1185     * @desc The sychronization protocol is conceptually based on
1186     *       named synchronization. Each synchronization point
1187     *       has it own specific synchronization message. This
1188     *       makes each synchronization unique, and allows, e.g., to
1189     *       ensure that a server synchronizes only clients which have
1190     *       reached the same synchronization point.
1191     */
1192    group syncProtocolDefinition {
1193
1194      type union SyncCmd {
1195        ClientReady clientReady,
1196        ServerReady serverReady,
1197        ClientStop  clientStop,
1198        ServerStop  serverStop
1199      }
1200
1201      type record ClientReady {
1202        charstring syncPointId
1203      }
1204
1205      type record ServerReady {
1206        charstring syncPointId
1207      }
1208
1209      type record ClientStop {}
1210
1211      type record ServerStop {}
1212
1213    } // end group syncProtocolDefinition
1214
1215    group syncMessages {
1216      template SyncCmd m_syncClientReady( template charstring p_syncId ) := {
1217        clientReady := { p_syncId }
1218      }
1219
1220      template SyncCmd m_syncServerReady( template charstring p_syncId ) := {
1221        serverReady := { p_syncId }
1222      }
1223
1224      template SyncCmd m_syncClientStop := {
1225        clientStop := {}
1226      }
1227
1228      template SyncCmd m_syncServerStop := {
1229        serverStop := {}
1230      }
1231
1232    } // end group syncMessages
1233
1234    group otherSyncFunctions {
1235
1236      /**
1237       * @desc  Makes server send a sync message to all known clients
1238       * @param p_clientRefs List of client references to which the message is to be send
1239       * @param p_syncCmd The actual synchronization message to be sent out
1240       */
1241      function f_serverSendToAllClients(  in ClientSyncCompList p_clientRefs,
1242                        in template SyncCmd p_syncCmd)
1243      runs on ServerSyncComp {
1244        var integer i:=0;
1245        for (i:=0; i< sizeof(p_clientRefs); i:=i+1 ){
1246          syncPort.send(p_syncCmd) to p_clientRefs[i];
1247        }
1248      } // end function f_serverSendToAllClients
1249
1250      /**
1251       * @desc  This function is intended only for use on server in concurrent
1252       *        TTCN-3 test cases. It waits for all components to shut down
1253       *        within the PX_TSHUT_DOWN_TIME_LIMIT. If a timeout occurs
1254       *        it aborts the test case (no matter how far clients got with their
1255       *        shutdown).
1256       *        This function sets the server verdict.
1257       */
1258      function f_serverWaitForAllClientsToShutDown()
1259      runs on ServerSyncComp {
1260
1261        tc_shutDown.start(PX_TSHUT_DOWN_TIME_LIMIT);
1262        alt {
1263          [] all component.done {
1264            tc_shutDown.stop;
1265            log("**** f_serverWaitForAllClientsToShutDown: All components have properly shut down. Sync server will now terminate the test case. ****") ;
1266             }
1267          [] tc_shutDown.timeout {
1268            log("**** f_serverWaitForAllClientsToShutDown: Not all clients have properly shutdown within the shut down time limit. Sync server will now terminate test case! ****") ;
1269             }
1270        } // end alt
1271        // cover case that shut down default is NOT activated
1272        setverdict(inconc);
1273          mtc.stop;
1274      } // end function f_serverWaitForAllClientsToShutDown
1275
1276    } // end group otherSyncFunctions
1277
1278  } // end group otherSyncDefinitions
1279
1280} // end module LibCommon_Sync
Note: See TracBrowser for help on using the repository browser.