SimLang * Simulation Language for Autohit

 

This doclet describes the language used to code Sims. All constructs must be in well-formed XML; the compiler will kick out both syntactic and semantic errors.

Sims are executed by a SimVM java object--autohit.SimVM.

SECTIONS Statements Variables General Example local1.sim Example ver1.sim Example

NOTE!  <exec> is not completely implemented.

  Statements

The following are the valid statements for SimLang.  Each is a well-formed XML element.  The statement names and attributes are case sensitive and are all lower-case.

sim  info  name   version  note  code   set  for  while   if  wait  get   header  nv  block   add  verify  seek   exec 


SIM

<sim>  the script </sim>

Wrapper for the entire simulation.


INFO

<info> information section </info>

Wrapper for the information section of a simulation.  The elements therein will be used to for the Sim object header.

<info>
   <name uid="1">A name</name>
   <version num="1"/>
   <note>Text text text</note>
</info>


NAME

<name uid="id text">textual name</name>

An Info element. It can assign an unique ID and textual name to the Sim.  It will be used by the SimVM as the session name, and thus logged, if session name isn't otherwise specified.

  • (attribute) REQUIRED uid = A unique ID.
  • (content) Text name.  It is best if there aren't any spaces, but it will still work.

VERSION

<version num="1"/>

A version number.  Currently, it doesn't do anything.  It could be used by specific VMs.

  • (attribute) REQUIRED num = A version number.

NOTE

<note>narrative text...  etc... etc..</name>

A note.  It is general text that explains the Sim.  It doesn't actually do anything.


CODE

<code>  the code  </code>

Wrapper for the actual code for the simulation.

<code>
   instructions....
</code>


SET

<set name="VariableName" value="a value"/>

This will create and set a variable. If the variable already exists, it will only set the value. The variable will be available as long as it remains in scope. Once it passes from scope, the value is lost forever.

The value may be any sequence that can be specified through text, including escaped binary.  The name can be any string, but it should start with an alpha.

  • (attribute) REQUIRED name = Variable name.
  • (attribute) REQUIRED value = Set the variable to this value.

FOR

<for count="indexVariable" init="initValue">

A for loop.  When the count variable equals "0", the loop will break.   The variable will NOT be automatically decremented.  Also, it must only contain numeric characters or the VM will die from an exception. 

If the variable does not already exist, it will be created.  If the init attribute is present, the variable will be initialized to its value. 

  • (attribute) REQUIRED count = Variable name.  The loop will break when it equals "0".
  • (attribute) OPTIONAL init  = Set the count variable to this value.

<for count="indexVar" init="3">
   ...some code...
   <add name="indexVar" value="-1"/>
</for>

The for block defines a local variable scope.


WHILE

<while e="$aVariable$" value="something">

A while loop. The loop will continue as long as the expression e is textually equal to the expression value, after any operations or variable replacements.

  • (attribute) REQUIRED e = Left-hand expression.
  • (attribute) REQUIRED value  = Right-hand expression.

<while e="$continueVar$" value="1">
   <!-- EEK! endless loop if we don't change the value of continueVar... -->
</while>

The while block defines a local variable scope.


IF

<if e="lh-expression" value="rh expression">

An if block. The block will execute if the expression e is textually equal to the expression value, after any operations or variable replacements.

  • (attribute) REQUIRED e = Left-hand expression.
  • (attribute) REQUIRED value  = Righ-hand expression.

<set name="variableX" value="1"/>
<if e="$variableX" value="2">
   <!-- this will NOT execute -->
</if>
<if e="$variableX" value="1">
   <!-- this will execute -->
</if>

The if block defines a local variable scope.


WAIT

<wait time="1000"/>

This will cause the Sim to wait for the specified time measured in milliseconds.   This will block the VM until the time expires!

  • (attribute) REQUIRED time  = time to wait measured in milliseconds.  MUST be a numeric!

<wait time="1000"/>
<!-- wait a full second -->


GET

<get qs="/cgi-bin/something.pl?id=9876">

Do a query using the registered transport.  The VM will block on this until the query is complete.  The query result will be available for verification instructions until the next get is performed. 

Any instructions within the <get> block are executed before the query is performed.  Therefore, headers and nv's put within the get block will be used for that get.  Also, verification instructions should not be put in the get block!   They should be placed after the get, as the query result will remain valid until the NEXT get query is completed.

  • (attribute) REQUIRED qs = The Query string.  This is transport dependent, but for http it would be the URL without protocol or domain.
  • (content) OPTIONAL <if>, <header>, <nv> or <verify>.   Technically, you can use verification operations, but they will be performed against the previous <get> result.

<get qs="/goat/testsite/doc.html?zip=1">
   <header name="HTTP Header" value="some header used only for this GET">
</get>

The for block defines a local scope for headers and nv's.


HEADER

<header name="HEADER-NAME" value="Some value...."/>

A header element. It is a name/value pair.  Typically, the registered transport will use this as a protocol header element.

As long as it remains in scope, it will be used by any GET.

  • (attribute) REQUIRED name = Field name.
  • (attribute) REQUIRED value  = Field value.

<header name="HTTP Header" value="Used in both GETs below">
<get qs="/goat/testsite/doc.html?zip=1">
   <header name="HTTP Header" value="Used just for THIS get">
</get>
<get qs="/goat/testsite/doc.html?zip=2">


NV

<nv name="SomeName" value="Some value...."/>

An nv element. It is a name/value pair.  Typically, the registered transport will use this as in the body/content of a query.  (For an http transport, it will be encoded a html form name/value element in a POST query.)

As long as it remains in scope, it will be used by any GET.

  • (attribute) REQUIRED name = Field name.
  • (attribute) REQUIRED value  = Field value.

<nv name="HTTP POST content element" value="Used in both GETs below">
<get qs="/goat/testsite/doc.html?zip=1">
   <header name="HTTP POST content element" value="Used just for THIS get">
</get>
<get qs="/goat/testsite/doc.html?zip=2">


BLOCK

<block>  ...scoped block...  </block>

Builds a simple scope block.

<set name="VariableX" value="1"/>
<block>
   <set name="VariableY" value="2"/>
   <!-- Both VariableX and VariableY valid here -->
</block>
<!-- Only VariableX is valid here.  VariableY only valid within the scope of the <block>. -->


ADD

<add name="VariableX" value="100"/>

Add a numeric to a numeric variable.  You can subtract by specifying a negative value.  If the value of the variable or the value attribute are anything other than a pure integer numeric, the VM will fail with a type-mismatch exception.  A pure numeric is a string with only numeric characters and an optional prefix sign character (+ or -).

If the variable is not defined, the VM will fail with a variable-not-found exception.

  • (attribute) REQUIRED name = Variable name to which to add.
  • (attribute) REQUIRED value  = A pure integer numeric value.

<set name="accumulator" value="1"/>
<set name="bad" value="jsjs13213"/>
<add name="accumulator" value="100"/>   <!-- VALID -->
<add name="accumulator" value="42jfd"/> <!-- BAD.  Value isn't pure numeric -->
<add name="bad" value="1"/>              <!-- BAD.   Variable value isn't pure numeric -->


VERIFY

<verify crc="12345678" size="100"> <seek>|<exec><if> </verify>

Build a verification context for the last Response.  This instruciton can optionally check the crc value and size of the Response content.  At the beginning of a verification context, the a seek pointer is set to the beginning of the Resposne content.  All subsiquent seek operations will move forward through the content, starting where the previous seek stopped.

  • (attribute) OPTIONAL crc = A CRC value for the content.
  • (attribute) OPTIONAL size = A size value for the content.
  • (content) OPTIONAL <seek>, <exec>, <if>.

<verify crc="905819271" size="5180">
   <seek string="release"/>
   <seek string="goat!"/>
</verify>


SEEK

<seek string="look for this string"/>

Seek a string in the Response content.  It starts from where a previous seek stopped or the beginning if it is the first seek in a <verify> context.

  • (attribute) REQUIRED string = What to seek.  It should be encoded according to XML 1.0.  Character matching will be performed according to java encoding rules (so, yes, UNICODE is possible).

<verify crc="905819271" size="5180">
   <seek string="release"/>
   <seek string="goat!"/>
</verify>


EXEC

<exec invoke="perl-module"> ...some perl code... </exec>

Invoke some external executable or resource to handle a verification routine.  The actual content of an exec is not defined by SimLang.  Rather, various support modules can be plugged into the system to handle the exec.  The specific modules will define their usage.

All variables will be available to the support module.

  • (attribute) REQUIRED invoke = An invocation specifier.   It tells which module to use.
  • (content) REQUIRED  Code, parameters, or whatever the specific modules expects..

<verify>
   <exec invoke="BASIC">
      10 PRINT "HELLO WORLD"
      20 END
   </exec>
</verify>


  Variables

All variables are tagged with a pre- and postfix '$'. The '$' character is escaped with two consecutive '$$'. A variable name is any alphanumeric AND white space, but it should begin with an alpha. It may contain any character, but if it will be evaluated as a numeric, it should be a trim string containing ONLY numeric characters.

A variable will persist within the scope that it is first set.  Environment variables will persist through ALL execution and are initially set by the implementing VM and/or execution context. The following are a new standard environment vars.

Any variable that begins with a "!" will be given to the registered transport when it is first set.  The transport will see the variable without the "!".   For instance, a variable named "!cookies" will be given to the transport as "cookies," but will still be seen as "!cookies" by the Sim.

Stock Environment Variables

The following variables will be automatically set by the SimVM.  Additional environment variables MAY be set by other Autohit components; such variables are documented by their respective component.

$lastVerify$ = Result of the last verification. "0" if it failed, "1" if it passed.

$transCode$ = Result code value from the last "GET." The possible values are transport specific.


  General Example

The following example shows each instruction.  This Sim doesn't do anything useful.

<?xml version="1.0"?>
<!DOCTYPE sim SYSTEM "file:sim.dtd">
<sim>

<info>
   <name uid="2323">Sim for BORG111</name>
   <version num=1/>
   <note>aaa sss ddd</note>
</info>

<code>
   <set name="Variable" value="10"/>
   <set name="zoat" value="-1"/>
   <set name="zoatAGAIN" value="$zoat$"/>
   <add name="Variable" value="2"/>

   <header name="HTTP Header" value="some header for everything...">

   <get qs="/goat/testsite/doc$zoat$.html?zip=1">
   </get>
   <verify crc="2774091" size="7361">
       <seek string="some text in the doc"/>
       <seek string="keep seeking from where we left off from last seek"/>
   </verify>
   <verify>
      <seek string="start searching from top of te doc, because it is a new verify context"/>
   </verify> 

   <block> <!-- create a scope -->
      <set name="Wibble" value="This var will only be around within this <block>"/>
      <nv name="goat">blah blag form data *zOt*</nv>
   </block> <!-- done with scope -->

   <set name="waitVal" value="10000"/>
   <wait time="1000"/>
   <wait time="$waitVal$"/> <!-- will wait 10,000 ms -->
   <add name="waitVal" value="20000"/>
   <wait time="$waitVal$0"/> <!-- will wait 300,000 ms. 10,000 + 20,000 = 30,000 -->
   <!-- then a '0' is appended to the resolved variable -->
   <for count="countVar" init="10">
      <add name="countVar value="-1"/> <!-- YOU have to decrement a FOR -->
   </for>

   <if e="$zoat$" value="-1">
      <!-- any code here will run, because $zoat$ DOES equal "-1". -->
   </if>

   <set name="continueVar" value="1"/>
   <while e="$continueVar$" value="1">
      <!-- EEK! endless loop if we don't change the value of continueVar... -->
   </while>

   <!-- comments are plain only XML comments... -->

</code>

</sim>

 

  Example - local1.sim

This example can be found in the ./test directory.  It will push a few HTTP hits against a default IIS installation.  It compiles and works.  You can use the Test or HTTP transport.

<?xml version="1.0"?>
<!DOCTYPE sim SYSTEM "file:sim.dtd">
<sim>

    <info>
        <name      uid="1">LOCAL1</name>
        <version   num="1"/>
        <note>Test local hits</note>
                
    </info>
    
    <code>
        
        <!-- Hit a default IIS install -->

        <get qs="/Default.asp"></get>
        <get qs="/iissamples/default/SQUIGGLE.GIF"></get>
        <get qs="/iissamples/default/MSFT.GIF"></get>                
        <get qs="/iissamples/default/nav2.gif"></get>                
        <get qs="/iissamples/default/IISTitle.gif"></get>
        
        <wait time="1500"/>
        <get qs="/iissamples/default/IE.GIF"></get>                
        <get qs="/default.asp"></get>                
        <get qs="/iissamples/default/IISSide.GIF"></get>   
        <get qs="/iissamples/default/IISTitle.gif"></get>        
        <get qs="/iissamples/default/LEARN.asp"></get>
        <get qs="/iissamples/default/IISTitle.gif"></get>
        
        <wait time="2500"/>    
        <get qs="/iissamples/default/samples.asp"></get>

        <wait time="3000"/>
        <get qs="/iissamples/default/IISTitle.gif"></get>
    
    </code>

</sim>

 

  Example - ver1.sim

This is an example of the verification mechanism.

<?xml version="1.0"?>
<!DOCTYPE sim SYSTEM "file:sim.dtd">
<sim>

    <info>
        <name      uid="1">LOCAL1</name>
        <version   num="1"/>
        <note>Test local hits</note>
        
        <!-- Hit the local machine -->
        
    </info>
    
    <code>
               
        <get qs="/Default.asp"></get>
        <get qs="/iissamples/default/SQUIGGLE.GIF"></get>
        <get qs="/iissamples/default/MSFT.GIF"></get>                
        <get qs="/iissamples/default/nav2.gif"></get>                
        <get qs="/iissamples/default/IISTitle.gif"></get>
        
        <wait time="1500"/>
        <get qs="/iissamples/default/IE.GIF"></get>                
        <get qs="/default.asp"></get>                
        <get qs="/iissamples/default/IISSide.GIF"></get>   
        <get qs="/iissamples/default/IISTitle.gif"></get>        
        <get qs="/iissamples/default/LEARN.asp"></get>
        <get qs="/iissamples/default/IISTitle.gif"></get>
        <verify size="21318"></verify>
        
        <wait time="2500"/>    
        <get qs="/iissamples/default/samples.asp"></get>
        <verify crc="905819271" size="5180">
            <seek string="release"/>
            <seek string="goat!"/>
        </verify>
        <verify crc="0">
            <seek string="release"/>
            <seek string="site correctly you must"/>
            <seek string="http://www.microsoft.com/misc/cpyright.htm"/>
        </verify>
        <verify size="1111"></verify>

        <wait time="2000"/>
        <get qs="/iissamples/default/IISTitle.gif"></get>
    
    </code>
    
</sim>