Toggle Menu Visibility











Description

State machine primitives are small functions with common prototype, which are being used as state actions in finite state machine based tests.

 

The common interface is as follows:

 

   FSM_STATUS  FUNC_NAME( FSM_TEST * pTestObject, FSM_EVENT nEventMask )

 

where FSM_STATUS is one of the FSM_OK (=0), FSM_ERROR (error code > then 0), FSM_WAIT ( negative number ), pTestObject is pointer to test object containing params, times, surrent state etc. and nEventMask is mask of events which caused the primitive to be called ( bitwise "or" of FSMEVENT_Read, FSMEVENT_Write, FSMEVENT_Exception ).

 

The primitive is expected to return FSM_OK in case it finished its job successfully and the state machine should pass in successful state. FSM_ERROR type value will make the machine assume the failure state of the current state. A FSM_WAIT value means that the job was not finished due to some reason ( for example, not all of the expected data could be received ) and the machine will stay in current state waiting for new events.

 

 

Primitives

 

 

 

 

 

Primitive: InitSock

Description: Initializes the underlying test object ( resolve host if not yet resolved, creates socket, etc. )

 

PROCEDURE InitSock( pTestObject, eventMask )

   rc := DO_SOME_INIT_STUFF_ON_SOCKET( pTestObject->socket )

   IF SUCCESSFUL( rc ) THEN

      RETURN FSM_OK

   ELSE

      RETURN FSM_ERROR

   END IF

END PROCEDURE

 

Primitive: Connect

Description: Connects the underlying test socket to host

 

PROCEDURE Connect( pTestObject, eventMask )

 

   IF pTestObject->CurrentSubState = 0 THEN

      pTestObject->connect( pTestObject->socket )

      pTestObject->CurrentSubState = 1

   ELSE

      IF eventMask & WRITE_EVENT THEN

         IF ERROR( pTestObject->socket ) THEN

            SET_SOME_ERROR_VALUE_AND_DETAILS( pTestObject )

            RETURN FSM_ERROR

         ELSE

            RETURN FSM_OK

         END IF

      END IF

   END IF

 

   RETURN FSM_WAIT

END PROCEDURE

 

Primitive: WriteSock

Description: Writes some data to the socket

 

PROCEDURE WriteSock( pTestObject, eventMask )

 

   IF pTestObject->CurrentSubState = 0 THEN

      pTestObject->Buffer := PREPARE_REQUEST( pTestObject )

      pTestObject->LeftToSend := LENGTH( pTestObject->Buffer )

 

      REGISTER_SOCKET( pTestObject->socket, FSMEVENT_Write | FSMEVENT_Exception )

 

      pTestObject->CurrentSubState = 1

   END IF 

 

   IF eventMask & FSMEVENT_Exception THEN

      RETURN FSM_ERROR

   END IF

 

   sentBytes := send( pTestObject->socket, pTestObject->Buffer, pTestObject->LeftToSend )

 

   IF SOME_ERROR_OCCURRED() THEN

      SET_SOME_ERROR_VALUE_AND_DETAILS( pTestObject )

      RETURN FSM_ERROR

   END IF

 

   pTestObject->LeftToSend -= sentBytes

 

   IF pTestObject->LeftToSend  = 0 THEN

      RETURN FSM_OK

   END IF 

 

   RETURN FSM_WAIT

 

END PROCEDURE

 

Primitive: ReadSock

Description: Reads some data from the socket

 

PROCEDURE ReadSock( pTestObject, eventMask )

 

   IF pTestObject->CurrentSubState = 0 THEN

 

      REGISTER_SOCKET( pTestObject->socket, FSMEVENT_Read | FSMEVENT_Exception ) 

      pTestObject->CurrentSubState = 1

   END IF 

 

   IF eventMask & FSMEVENT_Exception THEN

      RETURN FSM_ERROR

   END IF

 

   rcvdBytes := read( pTestObject->socket, pTestObject->Buffer )

 

   IF SOME_ERROR_OCCURRED() THEN

      SET_SOME_ERROR_VALUE_AND_DETAILS( pTestObject )

      RETURN FSM_ERROR

   END IF

 

   IF rcvdBytes = 0 THEN

      #   Ready for reading event was received but nothing was read

      #   which means that the sent data was received

      IF MATCH_PATTERN( pTestObject->Buffer ) THEN

         RETURN FSM_OK

      ELSE

         RETURN FSM_ERROR

      END IF

   END IF

  

   RETURN FSM_WAIT

 

END PROCEDURE

 

 

Primitive: Close

Description: Shuts down the socket (this causes the TCP to close connection streams in both directions) and then closes sockets (this is very important since if the socket is not closed, it will remain as an entry in file descriptor table of the process, which has a limit of descriptors and when this limit is reached error will be issued on every socket() syscall) 

PROCEDURE Close( pTestObject, eventMask )

   SHUTDOWN(pTestObject->Socket, SHUT_RDWR)

   CLOSE(pTestObject->Socket)

 

   RETURN FSM_OK

END PROCEDURE