SimCon - Fortran Analysis, Engineering & Migration About UsDownloadsPricing Home | SimCom logo
$keywords!
FPT - Fortran Regression Testing - Record and Replay of Program Execution
Consultancy
Migration & Software QA
 
WinFPT & FPT
WinFPT
FPT Summary
 
Error Correction
Hosts
Metrics
Migration
Optimization/Optimisation
QA
Reports
Security
Standardisation  
Updates & Release notes
$keywords!
WinFPT & FPT - Special Issues
Checking Expressions
Continuation Lines
Datapool
File Handling
File Names
Hex Numbers
Program Control
Record/Replay
Tab Format
Tracing Execution
 
Gould-SEL
VMS & Unix
 
Associated Companies
IQS Solutions
 
 
Record/ Replay

The record/replay mechanism is used in regression testing and in migration of Fortran codes.

FPT adds statements to the code to capture all of the data read in to a program and all of the data written out. The changes are made in such a way that the input data can be replayed into the program, replacing interactive interfaces and file I/O.

Imagine that a program is controlled by a long interactive menu. Testing is tedious because the menu items must be entered by hand. The record/replay mechanism allows them to be captured and replayed automatically.

Imagine that a program interacts with a large database file. The database must be set to the same state every time testing is carried out. Record/replay can replace the database by replaying the database inputs so that the program receives the same input data every time.

Every Fortran logical unit, and every sub-progam and memory interface may be selected for replay independently. You can replay the interactive I/O, for example, without replaying some or all of the file I/O.

FPT instruments the user's code to capture and to replay:

File and terminal I/O
The arguments of interface routines
Interfaces to shared memory

For example, click here to see a code example before modification, and

and here to see the changes which FPT makes.

The changes which FPT has made

FPT has inserted an INCLUDE statement for declaration of the variables used to control record and replay.


      INCLUDE 'rr_cmn.fpi'

The control variables, RR_LUN_FOR_REPLAY, RR_OUTPUT_RECORD_F etc. are in COMMON blocks. The file also contains declarations of the control functions such as REPLAY_IO(N,UNIT). This function determines whether the unit is being replayed or not.

The OPEN statement has been enclosed in a test to find whether or not the unit, in this case unit 7, is being replayed.


      IF (.NOT. REPLAY_IO(1,7)) THEN
         OPEN (7,FILE='VISCOSITY.DAT',ACCESS='DIRECT',STATUS='OLD')
      ENDIF

If unit 7 is replayed from the captured data, we don't need to open the file. This means that the original files don't need to be present when the code is first tested.

The read of the viscosity array has been enclosed in a test.


         IF (REPLAY_IO(2,7)) THEN
            READ (RR_LUN_FOR_REPLAY,*)RR_IOSTAT
            READ (RR_LUN_FOR_REPLAY,*)VISCOSITY(I)
         ELSE
            READ (7,REC=I,IOSTAT=RR_IOSTAT)VISCOSITY(I)
         ENDIF

If unit 7 is being replayed, VISCOSITY(I) is read from the replay file. If not, the original READ statement is executed.

FPT inserts code to capture the values from the viscosity file.


         IF (RR_INPUT_RECORD_F) THEN
            WRITE (RR_LUN_TO_RECORD_INPUT,*)RR_IOSTAT
            WRITE (RR_LUN_TO_RECORD_INPUT,*)VISCOSITY(I)
         ENDIF

The original READ statement had an END= destination. This has been replaced by capturing the IOSTAT value in the READ. The IOSTAT is replayed to the variable RR_IOSTAT and this is used to control jumping to the error destination by the statements:


         IF (RR_IOSTAT .NE. 0) THEN
            GOTO 200
         ENDIF

RR_IOSTAT is also replayed from the recorded file, so that the recording behaves in exactly the same way as the original code.

The WRITE statement to unit 1 is modified in a similar way. Once again, the statement is enclosed in a test, and is not executed if unit 1 is being replayed. The file does not need to exist during the initial stages of testing.


      IF (.NOT. REPLAY_IO(3,1)) THEN
         WRITE (1,100)
      ENDIF
      IF (RR_OUTPUT_RECORD_F) THEN
         WRITE (RR_LUN_TO_RECORD_OUTPUT,100)
      ENDIF
100   FORMAT (/,'Viscosity table read successfully')

Note that FPT captures the outputs from the program as well as the inputs. In a migration project, the outputs may be compared on the old and new hosts as a diagnostic tool.


The Extent of the Changes

FPT has re-written so much of this small subroutine that it is almost unrecognisable. This is not typical. It has happened because the subroutine contains almost nothing but I/O statements. Usually, the record/replay process makes very few changes to a large program.

A Shared Memory Location

Many programs have interfaces which are shared memory locations. These may also be instrumented for record and replay. In the code fragment below, VISBUFR is part of a memory block shared between a simulation program and the visual scene generator.


C     Only the visual system knows where the ground is
      RADAR_ALT=-RVISBUF(3)

To instrument this interface, we need to tell FPT that the memory is shared. This is done by annotating a declaration of VISBUFR. The annotation doesn't need to be in the main code body. It can be written in a small template file which is used only by FPT. The annotation would be, for example:


      COMMON /VISBUF/ RVISBUF(20),IVISBUF(200)
C%    Record/replay interface:: RVISBUF

The comment beginning C% has special meaning to FPT.

FPT then modifies the original statement to read:


C     Only the visual system knows where the ground is
C     RADAR_ALT=-RVISBUF(3)
      IF (REPLAY_INTERFACE(1,'RVISBUF')) THEN
         READ (RR_LUN_FOR_REPLAY,*)RVISBUF_TMP(3)
      ELSE
         RVISBUF_TMP(3)=RVISBUF(3)
      ENDIF
      IF (RR_INPUT_RECORD_F) THEN
         WRITE (RR_LUN_TO_RECORD_INPUT,*)RVISBUF_TMP(3)
      ENDIF
      RADAR_ALT=-RVISBUF_TMP(3)

The original statement is commented-out. Note how replay of the specific interface is controlled by the logical function REPLAY_INTERFACE(N,NAME).

FPT has added a new array, RVISBUF_TMP to the code. This has the same bounds and type as the original array RVISBUF and is declared wherever it is needed.

A Sub-Program Interface

Programs may communicate with external devices or other programs through sub-program arguments. To instrument these interfaces, FPT requires a declaration that the sub-program is an interface, and needs either the code of the sub-program, or a template which indicates the INTENT of the arguments - whether they are inputs, outputs or both. Templates may be written in small files outside the main body of the code, which are processed only by FPT. For example:


C     Template for MACRO routine TO_RADALT
C%    Record/replay interface TO_RADALT
      SUBROUTINE TO_RADALT(V,IADD,IE)
C%    INTENT (IN) :: V
C%    INTENT (IN) :: IADD
C%    INTENT (OUT) :: IE
      END

A call to TO_RADALT, for example:


      CALL TO_RADALT(RADAR_ALT,23,ISTAT)

is instrumented to read:


      IF (REPLAY_INTERFACE(2,'TO_RADALT')) THEN
         READ (RR_LUN_FOR_REPLAY,*)ISTAT
      ELSE
         CALL TO_RADALT(RADAR_ALT,23,ISTAT)
      ENDIF
      IF (RR_INPUT_RECORD_F) THEN
         WRITE (RR_LUN_TO_RECORD_INPUT,*)ISTAT
      ENDIF
      IF (RR_OUTPUT_RECORD_F) THEN
         WRITE (RR_LUN_TO_RECORD_OUTPUT,*)RADAR_ALT,23
      ENDIF

Copyright ©1995 to 2008 Software Validation Ltd. All rights reserved.