Language Fundamentals

RECORD TYPE

type record MyRecordType
{
  integer
  field1,
  MyOtherRecordType
  field2 optional,
  charstring
  field3
}
type record MyOtherRecordType
{
  bitstring
  field1,
  boolean
  field2
}
type record MyEmptyRecord { }
var integer MyIntegerValue := 1;

const MyOtherRecordType MyOtherRecordValue:=
{
  field1 := '11001'B,
  field2 := true
}

var MyRecordType MyRecordValue :=
{
  field1 := MyIntegerValue,
  field2 := MyOtherRecordValue,
  field3 := "A string"
}

The same value specified with a value list:

MyRecordValue:= {MyIntegerValue, {'11001'B, true}, "A string"};

Referencing fields of type Record:

MyVar2 := MyRecord1.myElement1.myElement2;

OPTIONAL ELEMENTS WITHIN A RECORD

type record MyMessageType { FieldType1 field1, FieldType2 field2 optional, FieldTypeN fieldN }
Optional fields can be omitted using the omit keyword:
MyRecordValue:= {MyIntegerValue, omit , "A string"};

SETS

  • Similar to records but order does not matter

ENUMERATED TYPES

type enumerated MyFirstEnumType {
  Monday, Tuesday, Wednesday, Thursday, Friday
};
type record MyNewRecordType {
  MyFirstEnumType firstField,
  integer
  secondField
};

UNIONS

Similar to the C concept of a union, where only one field can be present in an actual value. e.g. ->

type union MyUnionType
{
  integer number,
  charstring string
};

MODULES, GROUPS & MODULEPAR PARAMETERS

module MyModule {
  modulepar integer TS_Par0, TS_Par1;
  modulepar boolean TS_Par2;
  modulepar hexstring TS_Par3;
  
  // A collection of definitions
  group MyGroup {
    const integer MyConst:= 1;
    :
    type record MyMessageType { ... };
      group MyGroup1 {
      // Sub-group with definitions
      type record AnotherMessageType { ... };
      const boolean MyBoolean := false
    }
  }
  
  // A group of altsteps
  group MyStepLibrary {
    group MyGroup1 {
    //
    altstep MyStep11()
    altstep MyStep12()
    :
    altstep MyStep1n()
    }
    group MyGroup2 {
      altstep MyStep21()
      altstep MyStep22()
      :
      altstep MyStep2n()
    }
  }
  :
  Sub-group with the same name as the sub-group with definitions
  { ... }
  { ... }
  { ... }
  { ... }
  { ... }
  { ... }
}

THE MODULE CONTROL PART SPECIFIES THE EXECUTION ORDER OF THE TEST CASES:

module MyTestSuite
{
  // This module contains definitions ...
  :
  const integer MyConstant := 1;
  type record MyMessageType { ... }
  template MyMessageType MyMessage := { ... }
  :
  function MyFunction1() { ... }
  function MyFunction2() { ... }
  :
  testcase MyTestcase1() runs on MyMTCType { ... }
  testcase MyTestcase2() runs on MyMTCType { ... }
  :
  // ... and a control part so it is executable
  control
  {
    var boolean MyVariable; // local control variable
    :
    execute( MyTestCase1()); // sequential execution of test cases
    execute( MyTestCase2());
    :
  }
}

PORTS

  • In TTCN “Ports” enable communication between test components and between test components and the test system interface
type port MyMessagePortType message
{
  in MsgType1, MsgType2;
  out MsgType3;
  inout integer
}

COMPONENTS

The component type defines which ports are associated with a particular
component. These definitions should be in the module definitions part.
The port names in a component definition are local to the component
(another component can have ports with the same names). But ports
of the same component must have unique names.

Example:

type component MyMTCType
{
  port MyMessagePortType PCO1
}

type component MyPTCType
{
  port MyMessagePortType PCO1, PCO4;
  port MyProcedurePortType PCO2;
  port MyAllMesssagesPortType PCO3
}

TEMPLATE VARIABLES

  • declared using the var template keyword followed by a type identifier and a variable identifier:
template MyRecord MyTempl ( template boolean par_bool ) :=
  { field1 := par_bool, field2 := * }
:
function Myfunc () return template MyRecord {
  var template integer MyVarTemp1 := ?;
  var template MyRecord MyVarTemp2 := { field1 := true, field2 := * },
  MyVarTemp3 := { field1 := ?, field2 := MyVarTemp1 };
  MyVarTemp2 := MyTempl (?);
  :
  return MyVarTemp2
}
  • Templates variables are essentially like regular records but containing in-built matching mechanisms
  • (*) is used to match any value or nothing (omitted)
  • (?) is used to match an value where the value must be present (i.e can take any value other than ‘omitted’)

TEMPLATES

TEMPLATES FOR SENDING MESSAGES:

// Given the message definition
type record MyMessageType
{
  integer field1 optional,
  charstring field2,
  boolean field3
}

// a message template could be:
template MyMessageType MyTemplate:=
{
  field1 := omit,
  field2 := "My string",
  field3 := true
}

// A corresponding send operation could be 

MyPCO.send(MyTemplate);

TEMPLATES FOR RECEIVING MESSAGES:

// Given the message definition
type record MyMessageType
{
  integer field1 optional,
  charstring field2,
  boolean field3
}

// a message template might be:
template MyMessageType MyTemplate:=
{
  field1 := ?,
  field2 := pattern "abc*xyz",
  field3 := true
}

// A corresponding receive operation could be
MyPCO.receive(MyTemplate);

ALT STEPS

  • Used to provide alternative sets of instructions (e.g. receive either message1 or message2 or message3, etc)
type component MyComponentType {
  var integer MyIntVar := 0;
  timer MyTimer;
  port MyPortTypeOne PCO1, PCO2;
  port MyPortTypeTwo PCO3;
}

// Altstep definition using PCO1, PCO2, MyIntVar and MyTimer of MyComponentType
altstep AltSet_A(in integer MyPar1) runs on MyComponentType {
  [] PCO1.receive(MyTemplate(MyPar1, MyIntVar) {
    setverdict(inconc);
  }
  [] PCO2.receive {
    repeat
  }
  [] MyTimer.timeout {
    setverdict(fail);
    stop
  }
}

altstep AnotherAltStep(in integer MyPar1) runs on MyComponentType {
  var integer MyLocalVar := MyFunction();  // local variable
  const float MyFloat := 3.41;   // local constant
  [] PCO1.receive(MyTemplate(MyPar1, MyLocalVar) {
    setverdict(inconc);
  }
  [] PCO2.receive {
    repeat
  }
}

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.