Studio:How to synchronize scripts: Difference between revisions
No edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
If a test scenario requires multiple scripts synchronization between the scripts is required. For example if testing a component requires to simulate a | If a test scenario requires multiple scripts, synchronization between the scripts is required. For example, if testing a component requires you to simulate a dependent component it is sometimes easier to split the task into multiple scripts. One script drives the test, which launches a separate script non-blocking which simulates the dependent component. | ||
The following example shows how communication between two scripts can be achieved using a simple client-server example. The client queries the server for date and time. The server returns a date and time string. | The following example shows how communication between two scripts can be achieved using a simple client-server example. The client queries the server for date and time. The server returns a date and time string. | ||
The interface between the client and server is defined in a SCL file. | The interface between the client and server is defined in a SCL file. In this example the SCL file has two interfaces, one to request information (in the example the date and time string) and a "dummy" function that exists solely to allow us to notify the server script that it should end. | ||
; Note: An alternative to this synchronization technique is shown in the article [[Using Scripts to Simulate Missing Software Units]]. | |||
The server | ==SCL File== | ||
<source lang="c"> | |||
#define MAX_STRING_SIZE 50 | |||
int get_time(char* szTime); | |||
#ifdef _SCL | |||
/* this is the dummy function declaration, used for communication | |||
between the client and server scripts */ | |||
void shutdown(void); | |||
#pragma scl_function(get_time) | |||
#pragma scl_ptr(get_time.szTime, OUT, PRIVATE) | |||
#pragma scl_string(get_time.szTime, MAX_STRING_SIZE) | |||
#pragma scl_function(shutdown) | |||
#endif /* _SCL */ | |||
</source> | |||
==Server Script== | |||
The server script waits for requests, gets the time and returns requests: | |||
<source lang="perl"> | |||
## Used interfaces | |||
my $req = $main::ascript->Functions->Item("get_time")->Owner; | |||
my $shutdown = $main::ascript->Functions->Item("shutdown")->Owner; | |||
## take ownership of required interfaces | |||
$req->Register(); | |||
$shutdown->Register(); | |||
## initialize exit variable | |||
my $end = 0; | |||
## Wait for requests from clients until exit | |||
while ($end == 0) | |||
{ | |||
## Wait for an event | |||
my $event = $main::ascript->WaitForEvent(); | |||
## if the event is a get time request, get the time | |||
## and return | |||
if ($event->Name eq $req->Name) | |||
{ | |||
$req->OutPointers->{szTime} = gmctime(); | |||
$req->{ReturnValue} = 1; | |||
$req->Return(); | |||
} | |||
## Shutdown event. Set the variable to exit the loop | |||
if ($event->Name eq $shutdown->Name) | |||
{ | |||
$shutdown->{ReturnValue} = 1; | |||
$shutdown->Return(); | |||
$end = 1; | |||
} | |||
} | |||
## Unregister ownership | |||
$req->Unregister(); | |||
$shutdown->Unregister(); | |||
</source> | |||
==Client Script== | |||
The client script queries the server. However it also assures that the server is running. To show how scripts can be launched and terminated the client scripts first checks if the server is running. If not it starts the server and waits until the server is ready to accept requests. This is done by waiting until the server has registered the interfaces for script communication. At the end the client script sends a shutdown request to the server to end the server script. | The client script queries the server. However it also assures that the server is running. To show how scripts can be launched and terminated the client scripts first checks if the server is running. If not it starts the server and waits until the server is ready to accept requests. This is done by waiting until the server has registered the interfaces for script communication. At the end the client script sends a shutdown request to the server to end the server script. | ||
<source lang="perl"> | |||
## Check if server is running | |||
if (!($main::ascript->Functions->Item("shutdown")->Owner->IsRegistered)) | |||
{ | |||
## Server not available | |||
## As an option we can start the server here | |||
## This might not be required in all cases but is a good sample | |||
## on how to start another script non-blocking | |||
$main::studio->Workspace->Files->Item("server.pl")->RunNonBlocking(); | |||
## wait for the server to be up | |||
## An easy way is to wait until the server has taken ownership | |||
## of the supported functions | |||
while (!($main::ascript->Functions->Item("shutdown")->Owner->IsRegistered)) | |||
{ | { | ||
$main::ascript->Sleep(100); | |||
} | } | ||
} | |||
## Get a shortcut to the function | |||
my $req = $main::ascript->Functions->Item("get_time")->User; | |||
## Call the function (blocking request to the server) | |||
$req->Call(); | |||
## Check for the return value and display date and time | |||
if ($req->ReturnValue) | |||
{ | |||
$main::ascript->MessageBox($req->OutPointers->szTime, "Current Time"); | |||
} | |||
else | |||
{ | |||
$main::ascript->MessageBox("Server returned Error", "Error"); | |||
} | |||
## Shutdown the server (if required) | |||
$main::ascript->Functions->Item("shutdown")->User->Call(); | |||
</source> | |||
[[Category:Scripting]] | [[Category:Scripting]] |
Revision as of 16:10, 11 March 2008
If a test scenario requires multiple scripts, synchronization between the scripts is required. For example, if testing a component requires you to simulate a dependent component it is sometimes easier to split the task into multiple scripts. One script drives the test, which launches a separate script non-blocking which simulates the dependent component.
The following example shows how communication between two scripts can be achieved using a simple client-server example. The client queries the server for date and time. The server returns a date and time string.
The interface between the client and server is defined in a SCL file. In this example the SCL file has two interfaces, one to request information (in the example the date and time string) and a "dummy" function that exists solely to allow us to notify the server script that it should end.
- Note
- An alternative to this synchronization technique is shown in the article Using Scripts to Simulate Missing Software Units.
SCL File
#define MAX_STRING_SIZE 50
int get_time(char* szTime);
#ifdef _SCL
/* this is the dummy function declaration, used for communication
between the client and server scripts */
void shutdown(void);
#pragma scl_function(get_time)
#pragma scl_ptr(get_time.szTime, OUT, PRIVATE)
#pragma scl_string(get_time.szTime, MAX_STRING_SIZE)
#pragma scl_function(shutdown)
#endif /* _SCL */
Server Script
The server script waits for requests, gets the time and returns requests:
## Used interfaces
my $req = $main::ascript->Functions->Item("get_time")->Owner;
my $shutdown = $main::ascript->Functions->Item("shutdown")->Owner;
## take ownership of required interfaces
$req->Register();
$shutdown->Register();
## initialize exit variable
my $end = 0;
## Wait for requests from clients until exit
while ($end == 0)
{
## Wait for an event
my $event = $main::ascript->WaitForEvent();
## if the event is a get time request, get the time
## and return
if ($event->Name eq $req->Name)
{
$req->OutPointers->{szTime} = gmctime();
$req->{ReturnValue} = 1;
$req->Return();
}
## Shutdown event. Set the variable to exit the loop
if ($event->Name eq $shutdown->Name)
{
$shutdown->{ReturnValue} = 1;
$shutdown->Return();
$end = 1;
}
}
## Unregister ownership
$req->Unregister();
$shutdown->Unregister();
Client Script
The client script queries the server. However it also assures that the server is running. To show how scripts can be launched and terminated the client scripts first checks if the server is running. If not it starts the server and waits until the server is ready to accept requests. This is done by waiting until the server has registered the interfaces for script communication. At the end the client script sends a shutdown request to the server to end the server script.
## Check if server is running
if (!($main::ascript->Functions->Item("shutdown")->Owner->IsRegistered))
{
## Server not available
## As an option we can start the server here
## This might not be required in all cases but is a good sample
## on how to start another script non-blocking
$main::studio->Workspace->Files->Item("server.pl")->RunNonBlocking();
## wait for the server to be up
## An easy way is to wait until the server has taken ownership
## of the supported functions
while (!($main::ascript->Functions->Item("shutdown")->Owner->IsRegistered))
{
$main::ascript->Sleep(100);
}
}
## Get a shortcut to the function
my $req = $main::ascript->Functions->Item("get_time")->User;
## Call the function (blocking request to the server)
$req->Call();
## Check for the return value and display date and time
if ($req->ReturnValue)
{
$main::ascript->MessageBox($req->OutPointers->szTime, "Current Time");
}
else
{
$main::ascript->MessageBox("Server returned Error", "Error");
}
## Shutdown the server (if required)
$main::ascript->Functions->Item("shutdown")->User->Call();