Opentest-AddingTEEs

From AragoWiki

Jump to: navigation, search

back to Opentest's home

In order to service a request the dispatcher will eventually need to use the services provided by one or more Test Execution Engines (TEE) present in the framework. To successfully add a TEE to the framework it is necessary that the TEE registers with the appropriate services in the Test Master Controller (TMC) layer and that it is able to comply with the interface defined for TEEs in the system. This section describes the steps necessary to successfully add a TEE to the framework.

Contents

TEE Adapter

The TMC layer of the framework has been designed as a couple of STAF services, Dispatcher and Resource Manager, therefore any interaction between the TEE and the TMC layer is done through STAF calls. For this reason it is essential that when a new TEE is added to the framework it is done so as a STAF service that is required to:

  1. Register at start-up with the Resource Manager.
  2. Unregister at shutdown with the Resource Manager.
  3. Implement the interface defined in Test Execution Engines (TEE) Interface

TEE Registration

At startup a TEE must inform the TMC layer of its presence in the system, to do so the TEE Adapter must:

  1. Register with the Resource Manager by submitting a successful "ADD TYPE <TEE service Name> NAME <TEE Machine> CAPABILITIES <hardware assets>" to the Resource Manager service in the TMC Machine.
    • The TMC machine is the machine name or IP address of the machine where the Dispatcher is Running. This information must be known by the user and can be saved in the STAF configuration file by setting a shared variable that is read at start-up.
    • The Resource Manager service is the name given to the resource manager service when it was registered in the TMC machine. This information is saved in the TMC machine in a shared variable called STAF/TMC/ResMgr, when the service is registering with STAF is should obtain the value of this variable by submitting a "GET SHARED VAR STAF/TMC/ResMgr" request to the VAR service in the TMC machine.
    • <TEE service Name> is the name given to the TEE service when registering with STAF.
    • <TEE Machine> is the name or IP address where the TEE resides this information can be obtain during service initialization by performing STAFUtil.resolveInitVar("{STAF/TMC/Machine}",) call.
    • <hardware assets> specifies the hardware assets associated with this TEE. This information can be saved in the STAF configuration file by setting a shared variable that is read at start-up.

The steps shown before can be implemented in a java staf service as follows:

In the STAF.cfg file enter add the following line
set shared var staf/tmc/machine=<TMC machine or IP addr> 
service add service <service name> library jstaf execute <path to tee jar file> parms <optional parameters>

For example, for the TEE Adapter:

set shared var staf/tmc/machine=158.218.103.6
service add service vatf@1 library jstaf execute C:\myJar\TeeAdapter.jar params "txtype=xslt requesttxpath=C:/mydir/afile.xsl requesttxpath=C:/mydir/afile.xsl resultpath=C:\vatf_results.xml hwassets=[dm355,nand2k]"

In the Initialization function defined by staf for the TEE service add:

//Obtaining the TEE service name
this.teeServiceName = info.name;

//Creating a STAFHandle for the Service
teeServiceHandle = new STAFHandle("STAF/Service/" + info.name);

//Obtaining the TEE's machine name 
STAFResult res = STAFUtil.resolveInitVar("{STAF/Config/Machine}", teeServiceHandle);
if (res.rc != STAFResult.Ok) return res;
teeMachine = res.result;

//Obtaining the root and temp data directories
String endOfPath = "/";
if(info.writeLocation.endsWith("\\") || info.writeLocation.endsWith("/"))endOfPath="";
rootDataDir = info.writeLocation.replaceAll("\\\\","/") + endOfPath;
tempDataDir = rootDataDir + "tmp";
File tmpDir = new File(tempDataDir);
if(!tmpDir.exists() && !tmpDir.mkdirs())throw new Exception("Unable to create data directory " + tempDataDir);

//Obtaining the TMC machine name or IP address
res = STAFUtil.resolveInitVar("{STAF/TMC/Machine}", teeServiceHandle);
if (res.rc != STAFResult.Ok) return res;
this.tmcMachine = res.result;

//Obtaining the TEE test scripts root directory
res = STAFUtil.resolveInitVar("{"+ this.teeServiceName +"/STAF/TEE/test_scripts_root}", teeServiceHandle);
if (res.rc == STAFResult.Ok){
  this.testRootDir = res.result;
}
else
{
  this.testRootDir = null;
}

//Obtaining the System's line separator
res = STAFUtil.resolveInitVar("{STAF/Config/Sep/Line}", teeServiceHandle);
if (res.rc != STAFResult.Ok) return res;
this.lineSeparator = res.result;

// Obtaining the name of the Resource Manager service from the TMC Machine
res = this.teeServiceHandle.submit2(this.tmcMachine,"VAR","GET SHARED VAR STAF/TMC/ResMgr");
if (res.rc != STAFResult.Ok) return res;
this.tmcResMgr = res.result;

//Parsing the parameters passed during service registration
Hashtable <String, String> regParams = getParms(info.parms);

//Obtaining TEE service configuration info
if(!regParams.containsKey("txtype") || !regParams.containsKey("requesttxfile") || !regParams.containsKey("resulttxfile") || !regParams.containsKey("hwassets"))throw new Exception("Missing required txType, requesttxfile, resulttxfile or hwassets registration parameter.Check parms option");
this.hwAssets = regParams.get("hwassets");
String description = "";
if(regParams.containsKey("description"))description = " DESCRIPTION " + "\""+ regParams.get("description") + "\"";
// Registering with the resource manager
STAFResult resMgrRegRes = teeServiceHandle.submit2(this.tmcMachine,this.tmcResMgr,"ADD TYPE \""+this.teeServiceName+"\" NAME \""+this.teeMachine+"\" CAPABILITIES \""+this.hwAssets+"\"" + description);
if (resMgrRegRes.rc != STAFResult.Ok) return resMgrRegRes;

// Loading the tx type and transformation files 
this.txType = regParams.get("txtype").trim();
res = STAFUtil.resolveInitVar(regParams.get("requesttxfile"), teeServiceHandle);
if(res.rc != STAFResult.Ok)return res;
File reqTxFile = getTxFile(new File(res.result));
if(reqTxFile!=null){
  this.teeRequestTxFile = reqTxFile;
  this.reqTxPath = res.result;
}
else throw new Exception("Unable to access requesttxfile "+regParams.get("requesttxfile"));
res = STAFUtil.resolveInitVar(regParams.get("resulttxfile"), teeServiceHandle);
if(res.rc != STAFResult.Ok)return res;
File resTxFile = getTxFile(new File(res.result));
if(resTxFile!=null)
{
  this.teeResultTxFile = resTxFile;
  this.resTxPath = res.result;
}
else throw new Exception("Unable to access resulttxfile "+regParams.get("resulttxfile"));

//Obtaining the location of the xml results file generated by the TEE, if any
if(regParams.containsKey("resultpath"))
{
  res = STAFUtil.resolveInitVar(regParams.get("resultpath"), teeServiceHandle);
  if(res.rc != STAFResult.Ok)return res;
  this.xmlResultsPath=res.result.replaceAll("\\\\", "/");
}
//Obtaining the name of the monitor service
res = this.teeServiceHandle.submit2(this.tmcMachine,"VAR","GET SHARED VAR STAF/TMC/Monitor");
if (res.rc == STAFResult.Ok)
{
  this.tmcMonitor = res.result;
  STAFResult monitorServiceCheck = this.teeServiceHandle.submit2("LOCAL","SERVICE","QUERY SERVICE "+this.tmcMonitor);
  if(monitorServiceCheck.rc != 0)
  {
    STAFResult varResult = this.teeServiceHandle.submit2("LOCAL","VAR","SET SHARED VAR \"auto/Tee/Monitor="+this.tmcMonitor+"\"");
    if(varResult.rc != STAFResult.Ok)return varResult;
    STAFResult monRegRes = this.teeServiceHandle.submit2("LOCAL","SERVICE","ADD SERVICE " + this.tmcMonitor + " LIBRARY STAFMon");
    if(monRegRes.rc != STAFResult.Ok)return monRegRes;
  }
}

TEE Un-registration

At shutdown a TEE must inform the TMC layer that it will no longer be present in the system, to do so the TEE Adapter must:

  1. Unregister with the Resource Manager by submitting a successful "DELETE TYPE <TEE service Name> NAME <TEE Machine> CONFIRM"
    • <TEE service Name> is the name given to the TEE service when registering with STAF.
    • <TEE Machine> is the name or IP address where the TEE resides.

The steps shown before can be implemented in a java staf service as follows:

In the termination function defined by staf for the TEE service add:
this.teeServiceHandle.submit2(this.tmcMachine,this.tmcResMgr,"DELETE  TYPE "+this.teeServiceName+" NAME "+this.teeMachine+" CONFIRM");

TEE Adapter Implementation

A TEE service can be implemented in any language supported by STAF (C/C++, Java, etc) for more information about STAF service development refer to Staf Service Developer's Guide . The TEE adapter must implement the interface defined in Test Execution Engines (TEE) Interface, this interface requires the TEE service to support a "Run <xml test data file> [FORCECOPY]" command which is used by the dispatcher to send a test request to the TEE service. The sequence of events between the dispatcher and the TEE during a request is as follows:

  1. For each software asset needed for the tests the Dispatcher sets a STAF variable <service name>/auto/sw_assets/<asset name> in the TEE that points to the location of the asset in the Dispatcher's cache.
  2. The dispatcher sets the <service name>/auto/TEE/test_scripts_root in the TEE to value specified in the build Information of the test. If supported by the TEE this value is used to specify the version of the test scripts that will be used for the tests.
  3. The Dispatcher sends a "Run <xml test data file> [FORCECOPY]" (defined at Test Execution Engines (TEE) Interface) command to the TEE service.
  4. The TEE service copies the assets specified in 1 locally. Although it is not required, ideally the TEE service should keep a local cache with the assets it has copied in previous iterations and copy only the assets not present in its cache unless the FORCECOPY flag is specified.
  5. The TEE service gets the <xml test data file> and runs the tests.
  6. The TEE service returns a STAF result with a Map class than contains a resultsfile entry pointing to the xml results file generated by the TEE service.

An example template of a "Run <xml test data file> [FORCECOPY]" implementation in java could be:

//Checking that the requesting service has the required trust level
STAFResult trustResult = STAFUtil.validateTrust(3, this.teeServiceName, "Run", this.teeMachine, info);
if (trustResult.rc != STAFResult.Ok) return trustResult;

//Checking that the run request has the correct structure
STAFCommandParseResult parsedRequest = getParser("run").parse(info.request);
if(parsedRequest.rc != STAFResult.Ok) return new STAFResult(STAFResult.InvalidRequestString, parsedRequest.errorBuffer);

//Copying the xml test data
String teeReqFile = STAFUtil.resolveRequestVar(parsedRequest.optionValue("run"),this.teeServiceHandle,info.requestNumber).result;
String localTestRequest = this.tempDataDir+"/tee_req_" + String.valueOf(new Date().getTime())+ ".xml";
STAFResult copyReqResult = submit2(this.tmcMachine,"FS", "COPY FILE "+teeReqFile +" TOFILE "+localTestRequest);
if(copyReqResult.rc != STAFResult.Ok) return copyReqResult;

//Obtaining the location of the software assets specified for this test session, and copying to the cache if necessary
STAFResult varResult = this.teeServiceHandle.submit2("local","var","list shared");
if(varResult.rc == STAFResult.Ok)
{
  Map varMap = (Map) varResult.resultObj;
  Set mapKeys = varMap.keySet();
  for(Iterator resIter = mapKeys.iterator(); resIter.hasNext();)
  {
    String currentKey = (String) resIter.next();
    if(currentKey.trim().toLowerCase().startsWith("auto/sw_assets/"))
    {
      String currentAssetLocation = (String)varMap.get(currentKey);
      if(currentAssetLocation.startsWith("/"))currentAssetLocation=currentAssetLocation.replaceFirst("/","");
      int baseDirindex = currentAssetLocation.toLowerCase().indexOf("sw_assets");
      String localAsset = this.cacheRootDir;
		
      if(baseDirindex > -1)
      {
      String assetLocSubString = currentAssetLocation.substring(baseDirindex+9);
      if(assetLocSubString.startsWith("/"))assetLocSubString=assetLocSubString.replaceFirst("/","");
      localAsset+=assetLocSubString;
      }
      else localAsset+=currentAssetLocation;
      File localFile = new File(localAsset);
      if(!(localFile.exists()) || parsedRequest.optionTimes("FORCECOPY") != 0)
      {
        localFile.getParentFile().mkdirs();
        STAFResult copySoftwareRes = this.teeServiceHandle.submit2(this.tmcMachine,"FS","COPY FILE \""+currentAssetLocation+"\" TOFILE \""+localAsset+"\"");
        if(copySoftwareRes.rc != STAFResult.Ok) return copySoftwareRes;
      }
      STAFResult varSetRes = this.teeServiceHandle.submit2("LOCAL","VAR","SET SHARED VAR \""+currentKey+"="+localAsset+"\"");
      if(varSetRes.rc != STAFResult.Ok) return varSetRes; 
    }
  }
}
else return varResult;

//Setting the test scripts that will be used to the appropriate version.		
STAFResult testScriptVarRes = this.teeServiceHandle.submit2("LOCAL","VAR","GET SHARED VAR auto/TEE /test_scripts_root");
if(testScriptVarRes.rc == STAFResult.Ok)
{
  String[] testScriptRootInfo = testScriptVarRes.result.trim().split("://");
  String testScriptRootType = testScriptRootInfo[0].trim().toLowerCase();
  String testScriptRootSetupInfo = testScriptRootInfo[1].trim();
  TestScriptHelper testScriptHelp;
  if(testScriptRootType.equals("clearcase"))testScriptHelp = new ClearCaseHelper(this.teeServiceHandle, "automation_teeadapter", this.tempDataDir, this.adLogger);
  else testScriptHelp = null;
  String teeScriptDrive = null;
  if(testScriptHelp != null)
  {
    try 
    {
      teeScriptDrive = testScriptHelp.setTestDir(testScriptRootSetupInfo);
    } catch (Exception e)
    {
      String eTrace = e.toString()+"\n";
      StackTraceElement[] eStack = e.getStackTrace();
      for(int i =0; i < eStack.length; i++)eTrace+=eStack[i].toString()+"\n";
    }
  }
  if(teeScriptDrive != null)
  {
    STAFResult teeScriptsRes = submit2("LOCAL","VAR","SET SHARED VAR \"auto/TEE/test_scripts_root="+teeScriptDrive+"\"");
  }
 }
	
 String resultFile = "";
 //TEE Specific execution code goes here
        .
        .
        .
        .

 //Sending the result message to the Dispatcher		
 STAFMarshallingContext runMC = new STAFMarshallingContext();
 runMC.setMapClassDefinition(runMapClass);
 Map resultMap = runMapClass.createInstance();
 resultMap.put("resultsfile", resultFile.replaceAll("\\\\","/"));
 runMC.setRootObject(resultMap);
 return new STAFResult(STAFResult.Ok,runMC.marshall());

TEE Adapter Implementation Example

An example implementation of a TEE Adapter can be found at TEEAdapter source. This TEE adapter was developed to integrate VATF into the framework.

Personal tools