Tsert.Com 


Skip to content, navigation.


  • Home
    Main page
  • Products
    Our products
  • Services
    Our services
  • Translation
    Our  translation engine
  • Thinktank
    Topics & Patents
  • Sales
    Cete.cloud
  • Contact
    Contact us!

ITE Script Examples

The examples below provide a general enough look at the features of the tsert script language.

  • A Database Testcase.
  • A Telephony Testcase.
  • A Load Testcase
  • Using another script language
  • A PDU declaration file

A Database Testcase.

TestID: postgres.001

Requirement: Insertion, file:/usr/doc/packages/postgres/query.html

Purpose:
This test verifies the proper insertion of database entry fields.
in postgres SQL. It is an incomplete testcase, shown here for
information purposes.

Modification of tutorial file from postgres distribution.

basics.sql - Tutorial on the basics (table creation and data manipulation)

Copyright (c) 1994, Andrew Yu, University of California

basics.sql,v 1.1 1995/03/09 22:59:28 andrew Exp

Creating a table:
a CREATE TABLE is used to create base tables. POSTGRES SQL has
its own set of built-in types. (Note that keywords are case-
insensitive but identifiers are case-sensitive.)
//----------------------------------------------------
Setup:

// Could alternatively connect to the database directly through a socket.
channel postgres = open \tty /usr/bin/psql "testDB";

var create_weather = "CREATE TABLE weather(city text,
temp_lo int4, temp_hi int4, precip float8, date abstime)\n";

var create_cities = "CREATE TABLE cities(name text, location point)\n";

var prompt = "=>";
var text;

set postgres \delay 30 secs;

send <postgres> create_weather;
recv <postgres> prompt text;
send <postgres> create_cities;
recv <postgres> prompt text;

Begin:
// Inserting data:
// an INSERT statement is used to insert a new row into a table. There
// are several ways you can specify what columns the data should go to.

channel weather = open \file /usr/share/database/weather_data;

record args { city:"", temp_lo:"", temp_hi:"", precip:"", date:"" };

while ([read <weather> args "\t" "\n"]) {
var insert_weather = "INSERT INTO weather VALUES (",
args.city, ", 46, 50, 0.25, ", args.date, ");";

send <postgres> insert_weather;
recv <postgres> prompt text;
}

close weather;

record city_args { city:"", coords:"" };

channel cities = open \file /usr/share/database/city_data;

while ([read <cities> args "\t" "\n"]) {
var insert_cities = "INSERT INTO cities VALUES ('",
city, "', '", coords, "');";

send <postgres> insert_cities;
recv <postgres> prompt text;
}

close cities;

//----------------------------------------------------
// Removing the tables:
// DROP TABLE is used to remove tables.
// After you have done this, you
// can no longer use those tables.
//----------------------------------------------------

send <postgres> "DROP TABLE weather, cities";
recv <postgres> prompt text;
send <postgres> "\\q";

close postgres;

pass "The insertion test succeeded\n";

End:


Another Testcase with MYSQL.

//================================ Testcase ==================================
//
// $Author$
// $Date$
// $Header$
// $Name$
// $Revision$
// $Source$
//
TestID: Miscellaneous_DBase_SqlDriver.tst

Requirement:
Using_the_Default_Tracker, file:$docs/online-help/index-8.html
Using_the_Recorder, file:$docs/online-help/index-8.html

Purpose:

This testcase verifies the proper behaviour of queries generated
by the Tsert-Recorder, using a socket connection to the database.

Setup:

Begin:
record query_rec {
tbl_name:"",
sql_cmd:"",
cmd_type:"",
columns:"",
data_file:"",
format_str:"",
sql_text:""
};

vector sql_queries;
record values;

var recv_mesg, sql_query;
var db_name = "TsertTracking";

channel db, data_channel;

if (![ open db \db \name db_name \host $hostname \port 3306 ])
fail "Connection to database failed.";

if (! db.active())
fail "Connection to database failed.";

sql_queries += query_rec<[
tbl_name:"TestIds";
cmd_type:"data_file";
sql_cmd:"sql_insert";
columns:"TestIds.test_id,TestIds.testid_index,TestIds.suite_index,TestIds.test_purpose";
data_file:"/home/pierre/.tsert/data/TestIds.dat";
format_str:"TestIds_test_id%s;TestIds_testid_index%d;TestIds_suite_index%d;TestIds_test_purpose%s";
sql_text:""
]>;
sql_queries += query_rec<[
tbl_name:"TestIds";
cmd_type:"query";
sql_cmd:"sql_select";
columns:"TestIds.test_id,TestIds.testid_index,TestIds.suite_index,TestIds.test_purpose";
data_file:"";
format_str:"TestIds_test_id%s;TestIds_testid_index%d;TestIds_suite_index%d;TestIds_test_purpose%s";
sql_text:"SELECT DISTINCTROW TestIds.test_id,
TestIds.testid_index,
TestIds.suite_index,
TestIds.test_purpose
FROM TestIds
WHERE TestIds.test_id= 'hello'
AND TestIds.testid_index= 576547657
AND TestIds.suite_index= 43656
AND TestIds.test_purpose= 'purpose' "
]>;
sql_queries += query_rec<[
tbl_name:"TestIds";
cmd_type:"query";
sql_cmd:"sql_delete";
columns:"TestIds.test_id,TestIds.testid_index,TestIds.suite_index,TestIds.test_purpose";
data_file:"";
format_str:"TestIds_test_id%s;TestIds_testid_index%d;TestIds_suite_index%d;TestIds_test_purpose%s";
sql_text:"DELETE FROM TestIds
WHERE TestIds.test_id= 'hello'
AND TestIds.testid_index= 576547657
AND TestIds.suite_index= 43656
AND TestIds.test_purpose= 'purpose' "
]>;
sql_queries += query_rec<[
tbl_name:"TestIds";
cmd_type:"query";
sql_cmd:"sql_select";
columns:"TestIds.test_id,TestIds.testid_index,TestIds.suite_index,TestIds.test_purpose";
data_file:"";
format_str:"TestIds_test_id%s;TestIds_testid_index%d;TestIds_suite_index%d;TestIds_test_purpose%s";
sql_text:"SELECT DISTINCTROW TestIds.test_id,
TestIds.testid_index,
TestIds.suite_index,
TestIds.test_purpose
FROM TestIds
WHERE TestIds.test_id= 'hello'
AND TestIds.testid_index= 576547657
AND TestIds.suite_index= 43656
AND TestIds.test_purpose= 'purpose' "
]>;

var nb_sql_queries = sql_queries.length();
var idx = 0;

while (idx < nb_sql_queries) {
record query = sql_queries[ idx ];

if (query.cmd_type == "data_file") {
var data_file = query.data_file;

if (![ open data_channel \file data_file ])
fail "Opening of test data file failed.";

set values \format query.format_str;

while ([ read <data_channel> * values ]) {
sql_query = db.newQuery( query, values );
if (![ send <db> sql_query ])
fail "Query " + sql_query + "failed.";
}
close data_channel;

} elsif (![ send <db> query.sql_text ]) {
fail "Query " + query.sql_text + "failed.";
}
idx += 1;
}

close db;

pass "Completed testcase successfully.";

End:




A Telephony Testcase.

//================================ Testcase =================================== 
//
// $Author$
// $Date$
// $Header$
// $Name$
// $Revision$
// $Source$
//
// The following `TestId' line must not be changed.
TestID: Miscellaneous_Telephony_Network.tst

Requirement:
Send_Statement, file:$docs/online-help/index-9.html
Recv_Statement, file:$docs/online-help/index-9.html
OnRecv_Statement, file:$docs/online-help/index-9.html

Purpose:

This is just an example testcase. It does not reflect how a
testcase in a ISO methodology based testsuite should be written.
It also does not reflect how a real telephony application would behave.
It simply shows a basic telephony handshake protocol, while
establishing a voice line, between the handset, the phone fsm and
the network (the remote telephone).

This testcase is driven from the remote phone.

Setup:

Begin:
print "Starting handshake telephony protocol...\n";

// This could be declared at a higher level, i.e. in a group level
// declaration.
states {
Idle, Init, Onhook, Offhook, Dialtone,
WaitForRing, Ringing, Busy, VoiceLineEstablished,
Transfer, Forward, Conference, Recall, Hold, Link,
Error
};

var local = "555-USER";
var netw = "NET-WORK";
var fsm = "XXX-XXXX";

var handset = "handset";
var remote = "network";

// All communication is done through the `Phone' channel object.
channel Phone;

open Phone \memory
\encoding network
\delay 5 \secs
\protocol telephonyProtocol;

puts "Phone Channel: ", Phone;

//================================ PHONE ==================================//

// When 'netw' is specified, it signifies that the local phone FSM
// must send the specified pdu message to the remote phone.

proc fsm_send_ring( fsm_channel ) {
puts "remote: ", remote, " ", fsm_channel.active( remote );
puts "handset: ", handset, " ", fsm_channel.active( handset ), "\n";
send <fsm_channel:remote> ringPdu<[ src_addr:fsm; dest_addr:netw ]>;
send <fsm_channel:handset> ringPdu<[ src_addr:fsm; dest_addr:local ]>;
}

proc fsm_send_to_network(fsm_channel, pdu_mesg) {
send <fsm_channel:remote> pdu_mesg<[src_addr:fsm; dest_addr:netw]>;
}

proc phoneFsm() {
var key = 0;
pdu pdu_mesg;

on_recv ( digitsPdu<[ src_addr:netw ]> ) fsm_send_ring( Phone );

on_recv ( offhookPdu<[ src_addr:local ]> | voicePdu<[ src_addr:local ]> )
fsm_send_to_network( Phone, pdu_mesg );

on_recv ( voicePdu<[ src_addr:netw ]> )
send <Phone:handset> pdu_mesg<[src_addr:fsm; dest_addr:local]>;

while ([ recv <Phone:key> * pdu_mesg ]) {
puts "phoneFsm received: ", pdu_mesg;

switch ( pdu_mesg.isa() ) {
when "onhookPdu": {
send <Phone:handset> onhookPdu<[src_addr:fsm; dest_addr:local]>;
send <Phone:remote> onhookPdu<[src_addr:fsm; dest_addr:netw]>;
break;
}
when "voicePdu", "digitsPdu", "offhookPdu":
otherwise: {
soft_fail "Unexpected pdu received.";
break;
}
}
}
puts "phoneFsm exited...\n";
}

//================================ NETWORK ================================//

proc networkFsm() {
pdu pdu_mesg;

// Takes care of the exchanges between the network and the phone fsm.
channel net_channel = Phone.clone( "network" );

puts "Network Channel: ", net_channel;

on_recv ( offhookPdu<[ src_addr:fsm; dest_addr:netw ]> )
send <net_channel> voicePdu<[ src_addr:netw; dest_addr:fsm ]>;

on_recv ( voicePdu<[ src_addr:fsm; dest_addr:netw ]> )
send <net_channel> voicePdu<[ src_addr:netw; dest_addr:fsm ]>;

send <net_channel> digitsPdu<[ src_addr:netw; dest_addr:fsm ]>;

while ([ recv <net_channel> * pdu_mesg ]) {
puts "networkFsm received: ", pdu_mesg;

switch ( pdu_mesg.isa() ) {
when "onhookPdu": break;
otherwise:
}
}
puts "networkFsm exited...\n";
}

//================================= USER ==================================//


proc userFsm() {
pdu pdu_mesg;

// Takes care of the exchanges between the user and the phone fsm.
channel handset = Phone.clone( "handset" );

puts "User Channel: ", handset;

on_recv ( errorPdu<[ src_addr:fsm ]> ) state = Error;
on_recv ( busyPdu<[ src_addr:fsm ]> ) state = Busy;
on_recv ( ringPdu<[ src_addr:fsm ]> )
send <handset> offhookPdu<[ src_addr:local; dest_addr:fsm ]>;
on_recv ( voicePdu<[ src_addr:fsm ]> )
send <handset> voicePdu<[ src_addr:local; dest_addr:fsm ]>;

on_state ( Idle ) puts "UserFsm reached the Idle state.";

// The following assignment statement initiates the testcase.
// For the testcase to succeed, the 'Idle' state must be reached.
state = Init;

while ([recv <handset> * pdu_mesg]) {
puts "userFsm received: ", pdu_mesg;

if (state == Busy || state == Error)
break;

switch ( pdu_mesg.isa() ) {
when "voicePdu": {
state = VoiceLineEstablished;
send <handset> onhookPdu<[ src_addr:local; dest_addr:fsm ]>;
}
when "onhookPdu": {
puts "State = ", state;
if (state != VoiceLineEstablished) {
soft_fail "onhookPdu received because of an error.";
} else {
state = Idle;
}
break;
}
when "ringPdu", "busyPdu", "errorPdu", "offhookPdu":
otherwise: {
soft_fail "Unexpected pdu received.";
break;
}
}
}
close handset;
puts "userFsm exited...\n";
}

thread net, phone, person;

start phone phoneFsm();
start person userFsm();
start net networkFsm();

// Must sleep to prevent this main loop from hogging cpu cycles.
while (person.active() or phone.active() or net.active())
wait 2 \secs;

close Phone;

if (state != Idle)
soft_fail "Final State: ", state;

on_soft_fail ()
fail "Testcase driven from the remote phone does not work.";

pass "Testcase driven from the remote phone works.";

End:

// This section is usually reserved to prepare the SUT for the next test.


Load Testcase with Threads.

TestID: Miscellaneous_load_test.001

Requirement: LoadTest, file:/opt/tsert/requirements.html

Purpose:
This test opens a channel with 50 sessions to a given server.
The number of sessions is increased to 150 by threading the
procedure creating the sessions. It is a simple load test on
a given server application. It is just to demonstrate the
capabilitties of the Tsert language, and is incomplete.

Setup:

Begin:
vector pdus;

pdus += onhookPdu;
pdus += offhookPdu;
pdus += dialtonePdu;
pdus += voicePdu;
pdus += ringPdu;
pdus += busyPdu;
pdus += digitsPdu;
pdus += errorPdu;

proc do_random_query(client, query) {
var key = -1;

if (query >= pdus.length()) {
client.close();
return query;
}

// The query is sent on all sessions of the channel when key equal -1.
// The query should be different every time this function is called.
send pdus[query];

var response;
// The format to look for in responses, may also change.
var expected;

var session = 0;
var count = client.active_sessions();

// Making sure that a response is received from all sessions.
while (count) {
// The expected response may change.
if (not [recv expected response]) {
soft_fail "Did not receive data.";
client.close();
return query;
}
count -= 1;
}
return query + 1;
}

var server_address = ":testServer";

proc create_sessions() {
timer random_send;

// The timer is recycled with a random delay of 1 to 5 secs;
set random_send \loop yes \delay random(1,5) secs;

// Setting up a connection to the server.
// Additionally, a protocol could be associated with the channel.
channel client;

var active = [open client \socket server_address telephonyProtocol];
if ( active ) {
soft_fail "Connection to server '", server_address, " failed.";
return false;
}

var idx = 0;
var count = 50;

while (count) {
// Create 50 sessions by opening an already opened channel.
client.open();
count -= 1;
}

start random_send;

// Trying to simulate the typing of a user at a terminal,
// by randomly sending a query at different time intervals.
//
on_timer (random_send) idx = do_random_query(client, idx);

// Loop until client channel becomes inactive - no active sessions.
while (client.active()) { sleep 1 secs; }

close client, random_send;
}

// By threading 3 create_sessions, 150 sessions are created.
thread 3 create_sessions();

// Loop until all threads finish executing.
while (create_sessions.active()) { sleep 1 secs; }

End:
// If current test failed.
on_soft_fail () fail "Load test failed";

pass "Executed load test successfully.";


A Testcase With Another Script Language.

TestID: expect.001

Requirement: OtherScript, file:/Tsert/Requirement/User/Script.html

Purpose:
This test verifies the proper execution of a user defined script,
written with script language other than the tsert language.

Setup:
if (not is_exec /usr/bin/expect)
fail "Failed Setup - Did not find expect executable\n";

Begin:

run_script %{

#!/usr/bin/expect
# ftp-rfc <rfc-number>
# ftp-rfc -index

# retrieves an rfc (or the index) from uunet

exp_version -exit 5.0

if $argc!=1 {
send_user "usage: ftp-rfc \[#] \[-index]\n"
exit
}

set file "rfc$argv.Z"

set timeout 60
spawn ftp ftp.uu.net
expect "Name*:"
send "anonymous\r"
expect "Password:"
send "expect@nist.gov\r"
expect "ftp>"
send "binary\r"
expect "ftp>"
send "cd inet/rfc\r"
expect "550*ftp>" exit "250*ftp>"
send "get $file\r"
expect "550*ftp>" exit "200*226*ftp>"
close
wait
send_user "\nuncompressing file - wait...\n"
exec uncompress $file

%}

End: // This section is used to prepare the SUT for the next test.


A Pdu Declaration File.

#pdu_decls

// The Pdu declarations file.
//
// The pdu declarations are used to specify the format that incoming
// and outgoing messages must adhere to for proper communication
// between the test entities specified in the test scripts.
// Pdu declarations have group level scoping.
//
protocol testProtocol {
mesg_types {
t_init:0x01,
t_connect:0x02,
t_disconnect:0x03,
t_data:0x04,
t_status:0x05,
t_error:0x06
}

pdu t_init {
header 6 byte {
// field_name length type default_value
mesg_type 1 byte int (1);
src_addr 2 byte int (257);
dest_addr 2 byte int (257);
mesg_len 1 byte int (17);
}
text 11 byte ("INITIATE...");
}

pdu t_connect {
header 6 byte {
mesg_type 1 byte int (2);
src_addr 2 byte int (257);
dest_addr 2 byte int (257);
mesg_len 1 byte int (28) (> 18);
// The mesg length of a t_connect pdu must be greater than 18.
}
// The stop sequence is 2 ESC characters.
// Length = all characters before and including escape sequence.
text "" ("Connected...");
parms_nb 1 byte int (2);

// A set of parms_nb parameters
parameters[ parms_nb ] ("\005HELLO\006BYEBYE") {
length 1 byte int;
value length; // Type is string (any sequence of chars) by default.
}
}

pdu t_disconnect {
header 6 byte {
mesg_type 1 byte int (3);
src_addr 2 byte int (257);
dest_addr 2 byte int (257);
mesg_len 1 byte int (23) (> 7);
}
text "" ("Disconnected...");
}

pdu t_data {
header 6 byte {
mesg_type 1 byte int (4);
src_addr 2 byte int (257);
dest_addr 2 byte int (257);
mesg_len 1 byte int (32) (> 7);
}
text "" ("Text info in pdu t_data.");
}

pdu t_status {
header 6 byte {
mesg_type 1 byte int (5);
src_addr 2 byte int (257);
dest_addr 2 byte int (257);
mesg_len 1 byte int (10);
}
// A Record with fields that have their length in bits cannot exceed
// the size of an int (4 bytes) in length.
status 2 byte ("\017\017") {
err_code 6 bits int (\011);
filler 2 bits int (\003);
status_code 1 byte int (0xff);
}
text 8 byte ("OK .....");
}

pdu t_error {
header 6 byte {
mesg_type 1 byte int (6);
src_addr 2 byte int (257);
dest_addr 2 byte int (257);
mesg_len 1 byte int (8);
}
err_code short (0x00);
}
}

Back to Top

Home
Services
Contract
Sign-In
Register
Products
ITE
Linux
Search
Ferret
ENet
Builder
XTractor
Translation
White-Papers
Sales
Contact Us
 
 
1996-2013Tsert.Com Design: David Kohout