ElementaryBlock Element/en

Aus expecco Wiki (Version 2.x)
Zur Navigation springen Zur Suche springen

Introduction[Bearbeiten]

An elementary block provides the basic functionality of an expecco testsuite. It is used to model basic calculations or logical combinations, or to query and control external devices. These can be local or remote processes as well as hardware devices that are attached by some kind of hardware interface.

The behavior of an elementary block is defined by one of the following:

  • a piece of textual program code, which is written in a particular programming language, which executes inside expecco
  • a piece of code, written in Groovy, which executes on the local system or inside the system under test itself
  • a piece of code, written in VisualBasic Script, which executes in a separate process (requires extra licensed plugin)
  • a call to a DLL (shared library) function
  • a call to an external program (script)
  • a remote procedure or service call (SOAP, XML-RPC, SunRPC)

Expecco provides built in language interpreters and compilers for two scripting languages: the built In Smalltalk and a built in JavaScript-like scripting language. When such an elementary block is executed, the script code runs inside the expecco process. These support high level symbolic debugging including single-step, breakpoints or inspection of variables. The debugger even allows for code changes to be done to the running program (for example, while the program is stopped at a breakpoint). These internal scripts are transparently and automatically compiled into machine code when first executed (just in time compilation).

Additional built In scripting languages (Ruby and Lisp) are being prepared.

Other scripting languages (Perl, TCL, Python, etc.) can be called via external script interpreters. It is also possible to call existing command line scripts (Shell under Unix or Windows+cygwin, Batch under Windows).

With the Java Bridge extension plugin, elementary blocks can also be written in Groovy, which is a scripting language with a syntax similar to Java, and which is transparently (and dynamically) compiled to Java bytecode, to be executed inside the system under test or on the expecco host or on any other such configured machine in the local network . Groovy blocks are useful to define callbacks, subclasses of existing classes or to set up complicated Java objects inside the tested Java application. When such a block is executed, the script code runs inside a JavaVM, which can be either a local one, dedicated to script execution, or on the target system (the system under test). More detail is found in the Expecco API Documentation.

With the VisualBasic Plugin, elementary blocks can be written in the VisualBasic Script syntax and are executed in an external VisualBasic interpreter. This may run on the local host (the one n which expecco runs) or optionally on a remote host. The host on which the script engine executes must be a Windows host. For Unix/Linux users, this means that at least a virtual machine with a Windows system must be setup and reachable.

The source code is usually edited in the code editor. It is interpreted according to the used language’s syntax at runtime. For the builtin languages Smalltalk and JavaScript, it is possible to switch the syntax pattern for already implemented blocks, causing the code to be automatically converted to that particular syntax style. The values of data pins can be directly accessed (read and write) in the code using the pin's name. The external interface of an elementary block (e.g. number of pins) is defined in the schema editor.

Notice that the standard library as delivered already contains a number of useful elementary blocks for a wide range of applications. So that the need to define your own elementary blocks is often limited to special interfacing or specialized processing of data.

Smalltalk and JavaScript Block Examples[Bearbeiten]

Here is a block to compute the minimum and maximum values of a mathematical function over a range of x-values. It is especially flexible, as the name of the function can be passed as an argument (for example: 'sin', 'cos' or 'arcTan'). The block's definition is:

Min max elementaryBlock.jpg

and its code could be written in Smalltalk as:

execute
    |fn minY maxY y|

    fn := functionName value asSymbol.

    (x0 value) to:(x1 value) by:(dX value) do:[:x |
        y := x perform:fn.
        minY := minY isNil ifTrue:[y] ifFalse:[ minY min:y ].
        maxY := maxY isNil ifTrue:[y] ifFalse:[ maxY max:y ].
    ].

    min value:minY.
    max value:maxY.

or in JavaScript as:

execute() {
    var fn, minY, maxY, x, y;

    fn = functionName.value().asSymbol();
    for (x = x0.value(); x <= x1.value(); x += dX.value()) {
        y = x.perform(fn);
        minY = (minY.isNil()) ? y : minY.min(y);
        maxY = (maxY.isNil()) ? y : maxY.max(y);
    }
    min.value(minY);
    max.value(maxY);
 }

(notice the use of the "perform"-function, to call a function by name)


Of course, as usual, there are multiple ways to write the same function; an experienced Smalltalker would write:

execute
    |fn minMax|

    fn := functionName value asSymbol.

    minMax := ((x0 value) to:(x1 value) by:(dX value))
                  collect:[:x | x perform:fn])
                      minMax.
    min value:minMax first.
    max value:minMax second.

and a JavaScript programmer might prefer:

execute() {
    var fn, minY, maxY, x, y;

    fn = functionName.value;
    for (x = x0.value; x <= x1.value; x += dX.value) {
        y = x.perform(fn.asSymbol());
        minY = (minY == null) ? y : Math.min(minY,y);
        maxY = (maxY == null) ? y : Math.max(maxY,y);
    }
    min.value(minY);
    max.value(maxY);
 }


The block could be used to calculate the min/max of the sine function in the range 0..1 as follows:

Min max in use with sine.jpg

Groovy Blocks[Bearbeiten]

A Groovy block's code is executed in a Java Virtual Machine (either locally or in a remote system). It is described in more detail in the Expecco API documentation on Groovy .

VisualBasic Script Blocks[Bearbeiten]

A VisualBasic Script block's code is executed by a scripting host (see Microsoft documentation on Visual Basic). It is described in more detail in the Expecco API documentation on VisualBasic and the  VisualBasic Plugin documentation.

Shell Script Blocks[Bearbeiten]

Under Unix operating systems (incl. Linux, Solaris etc.) or Windows with Cygwin installed (or any similar shell implementation which is bash/ksh compatible), you can also execute shell-script blocks. For example, here is a script to read its input, filter all lines beginning with some pattern, sort them, and pass them on as output:

grep "^xx" | sort

of course, arbitrarily commands can be called (even programs with their own GUI). Under Windows, make sure that you have installed an appropriate shell emulator, and that it is either found along the PATH, or that you have specified the sh-path in the expecco-settings dialog (in "External Tools" - "Shell Path"). Shell Script blocks provide the standard output and standard error at their output pins as text, so you may have to read and analyze that further.

Batch Script Blocks[Bearbeiten]

These are similar to shell scripts, but use the Windows-batch file syntax. These cannot be executed on Unix systems, so your tests become OS-dependent, if you use them. The example code below would check out some source code from a cvs repository and start a build:

REM
REM batch file script (windows only)
REM
echo Checking out...
cvs co myProgram
cd myProgram
echo Building...
make

Batch Script blocks provide the standard output and standard error at their output pins as text, so you may have to read and analyze that further.

DLL-Calls[Bearbeiten]

DLL-call blocks define an interface to a function which is contained inside a DLL (Dynamic Link Library). For a dll-call to be possible, the functions attributes have to be entered into the dll-call editor. These are:

  • name of the dll (for example: "user32.dll"). If the DLL-name has no extension (".dll"/".so"), an OS-specific extension is added by expecco. For portability, it is better to only provide the base name here.
  • the name of the function within the dll
  • the calltype (WINAPI or C-Call).
  • the number and types of the arguments
  • the type of the return value.

In addition, it is possible to specifiy that the dll-call is to be executed by a separate API-call thread. This avoids a blocking of the expecco user interface and other executing activities, for long running dll-calls.

If the called function is a C++ function or C++ wrapper function, the compiler may have arbitrarily mangelt the name; usually a prefix or suffix, or both are added to the plain function's name. As this name mangeling is very OS- and compiler-specific, no automatic name generation can be done by expecco, and you will have to find out the name yourself, and paste it into the "C++ Name" field. Use any of your system's symbol-table listing tool ("nm", "dllWalker" etc.) to find out that name.

If your testsuite is planned to be portable across operating systems (i.e. it should run under both Windows- and Unix test machines), you will need both a windows DLL ("foo.dll") and a unix shared library object ("foo.so" or "foo.dylib"). Because the filename extensions are OS-specific, it is recommended to enter the basename without suffix into the "DLL name" field. Expecco will fill in the extension as used by the OS (however, if your dll uses a non-standard extension, you will have to provide it).

DLL Mapping[Bearbeiten]

Expecco (actually Smalltalk) maintains a DLL-name mapping table, which translates DLL-library names on an individual per-DLL basis. Thus, it is possible to control which DLL is actually used by DLL call blocks. The mapping is very useful, if multiple versions of a DLL are present (e.g. use "foo" in the DLL call block, and define a mapping of "foo" to "foo.vsnX") or to control from which location a library is to be loaded (e.g. define a mapping from "foo" to "/mylibs/libraries/foo.so").

The StandardLibrary contains a block "Define DLL Mapping", which can be used to modify this mapping table.  

SOAP-Calls[Bearbeiten]

These blocks define a remote procedure call via the SOAP protocol. SOAP blocks are normally generated automatically, by importing a wsdl service description. For more information, please refer to the WSDL Import Plugin description.

 

XML-RPC-Calls[Bearbeiten]

These blocks define XML-RPC remote procedure calls. XML-RPC is a very light-weight and low-overhead XML-based protocol, which is supported by many service oriented applications (among them, expecco and expeccoNET themself). For an XML-RPC call, the following information is mandatory:

There are 3 alternative ways, to specify the URL:

  • hardwired as a string in the blocks specification (not recommended)
  • via an environment variable
  • via a pin value (freeze or dynamic)
Hardwired Service URL[Bearbeiten]

Because this is very unflexible, it should be only used for very constant URLs, or while exploring a service interface. For this, type the URL into the block's specification form.

Specifying the Service URL via an Environment Variable[Bearbeiten]

Use a macro-replacement pattern such as "%(RPC_HOST)" in the URL field (as above). This will be replaced by a corresponding variable name from the reachable environment variable named accordingly. You can either specify a full URL (i.e. host, port and path) or a partial URL using this mechanism. For example, you can also provide the URL via 3 separate environment variables, by entering: "%(RPC_HOST):%(RPC_PORT)/%(RPC_PATH)". A runtime error will be reported, if the variable expansion leads to an invalid URL. However, if a missing expansion leads to a valid URL, no error is reported. This allows for optional fields to be added to the URL, for example as in: "%(JIRA_HOST)%(OPTIONAL_RPC_PORT)/jira/rpc/xmlrpc".

Providing the URL via an Input Pin[Bearbeiten]

Add an input pin with the (obligatory) name "url", and deliver it a string value. This is the most flexible way, as the URL value can be dynamically generated by any other block, or be provided via a pin-freeze value. If a url-pin is present, but not connected, it is ignored and the above variable mechanism is used. Otherwise, the pin-value takes precedence over any value in the specification.


See Also[Bearbeiten]

For a list of already existing blocks, see Standard Library
For the programmer API for the built in languages see: Expecco API
For information on the functions avaliable in the built-in classes, please refer to the [Smalltalk/X Online Documentation] and especially the [Class Reference]. For example, some of the mathematical functions are described [here] and String processing functions are found [here] and [here].



Copyright © 2014-2024 eXept Software AG