Toolboxcategory cloud |
ViewsPersonal toolsClearCase Trigger to Update TestTrackFrom Seapine LabsWorks with TestTrack 2008.2.1 Works with ClearCase 7.0.1
[edit] OverviewThis article outlines how to create a trigger in ClearCase, which calls a script that updates TestTrack. This was all developed and tested against TT 2008.2 and ClearCase 7.0.1.
[edit] ClearCase Integration ScriptThe script we'll be using is written in Java. Java is good because it's used on a variety of platforms. I'm not going to review the actual source, but it's not overly complex if you understand a little bit of Java. [edit] Script mattersThis script does not take any parameters. The values it needs are either hard coded or gathered from ClearCase environment variables. The hard coded values are:
[edit] Java CodeBelow is the java code for the script. You will need to use the TestTrack SOAP classes available here. If you would like to generate your own TestTrack SOAP classes (if you are using a different version of TestTrack), follow this NetBeans Tutorial. If you do create your own classes, you may need to change the import of testtrack_Interface to the name of the package you create to hold the classes.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package cctrigger;
import testtrack_Interface.*;//<---May need to be changed if you use your own TestTrack classes
import java.util.*;
import java.text.*;
import java.io.*;
/**
*
* @author Cremerf
*/
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
//SOAP vars
//hard coded
String soapSrv = "http://localhost/scripts/ttsoapcgi.exe";
String ttUser = "soap";
String ttPass = "passoap";
String ttProject = "Sample Project";
//If you want to pass them as args, it would look like this.
/*
* String soapSrv = args[0];
String ttUser = args[1];
String ttPass = args[2];
String ttProject = args[3];
*
* You may also want to use an if statement to ensure the correct number of parameters
* are passed.
*
* */
//ClearCase env vars
String sccFile = System.getenv("CLEARCASE_PN");
String chkComments = System.getenv("CLEARCASE_COMMENT");
String scmVersion = System.getenv("CLEARCASE_ID_STR");
//Hard coded vars for testing outside of trigger environment (debugging).
//String sccFile = "V:\\file.test";
// String chkComments = "<:7:>";
// String scmVersion = "5";
//Vars assigned during program execution
long ttCookie = 0;
String strDNum = "";
long ttDNum = 0;
//Get fixed date - not available as a ClearCase env var, so we'll have to use current date & time
//All lines may not be needed, but this works, so why change it?
Calendar cal=Calendar.getInstance();
try
{
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
String d = dateFormat.format(date);
cal.setTime(date);
}
catch (Exception e)
{
eLogger(e.getMessage());
}
try
{
//Parse the comments
strDNum = parseComments(chkComments);
ttDNum = Integer.parseInt(strDNum);
//TestTrack SOAP interaction
//Define soap object
TtsoapcgiPortType_Stub ttSoap = (TtsoapcgiPortType_Stub)(new Ttsoapcgi_Impl().getTtsoapcgi());
//Set the URL
ttSoap._setProperty(javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY, soapSrv);
//Get list of projects and select one we need
CProject ttCProject = new CProject();
CProject[] ttCProjects = ttSoap.getProjectList(ttUser, ttPass);
for (int i=0;i < ttCProjects.length; i++)
{
if (ttCProjects[i].getDatabase().getName().equals(ttProject))
{
ttCProject = ttCProjects[i];
}
}
if (ttCProject != null)
{
//if we found project for user, lets log in
//ttCookie = ttSoap.databaseLogon(ttProject, ttUser, ttPass); <---- Deprecated, but depending on your xml serializer
//the projectLogon may return an error. databaseLogon may work in that instance
ttCookie = ttSoap.projectLogon(ttCProject,ttUser,ttPass);
//Create a defect object and set it to the defect we are attaching to
CDefect ttDefect = new CDefect();
ttDefect = ttSoap.editDefect(ttCookie, ttDNum, "", false);
//Get the list of SCC files the defect may have
CSCCFileRecord[] ttSCCFiles = ttDefect.getPSCCFileList();
int fileCount = 0;
//If the list already contains files
//If it does, we have to rebuild the array of SCCFiles objects and add our file
//We can not just add our file to the end of the list.
if (ttSCCFiles != null)
{
//Get the number of files
fileCount= ttSCCFiles.length;
//check to see if file exists
boolean sccFileExists = false;
for (int i = 0;i < fileCount; i++)
{
if (ttSCCFiles[i].getMstrFileName().equals(sccFile))
{
//if the file has already been attached, we will just append the new version
ttSCCFiles[i].setMstrFixedRevision(ttSCCFiles[i].getMstrFixedRevision() + "," + scmVersion);
sccFileExists = true;
}
}
if (sccFileExists == false)
{
CSCCFileRecord[] ttNSCCFiles = new CSCCFileRecord[fileCount + 1];
for (int i = 0; i < fileCount; i++)
{
ttNSCCFiles[i] = new CSCCFileRecord();
ttNSCCFiles[i].setMdateFixedTimestamp(ttSCCFiles[i].getMdateFixedTimestamp());
ttNSCCFiles[i].setMstrFileName(ttSCCFiles[i].getMstrFileName());
ttNSCCFiles[i].setMstrFixedRevision(ttSCCFiles[i].getMstrFixedRevision());
}
ttNSCCFiles[fileCount] = new CSCCFileRecord();
ttNSCCFiles[fileCount].setMstrFileName(sccFile);
ttNSCCFiles[fileCount].setMstrFixedRevision(scmVersion);
if (cal != null)
{
ttNSCCFiles[fileCount].setMdateFixedTimestamp(cal);
}
ttDefect.setPSCCFileList(ttNSCCFiles);
}
}
else
{
CSCCFileRecord[] ttNSCCFiles = new CSCCFileRecord[fileCount + 1];
ttNSCCFiles[fileCount] = new CSCCFileRecord();
ttNSCCFiles[fileCount].setMstrFileName(sccFile);
ttNSCCFiles[fileCount].setMstrFixedRevision(scmVersion);
if (cal != null)
{
ttNSCCFiles[fileCount].setMdateFixedTimestamp(cal);
}
ttDefect.setPSCCFileList(ttNSCCFiles);
}
ttSoap.saveDefect(ttCookie, ttDefect);
ttSoap.databaseLogoff(ttCookie);
}
}
catch(Exception fcc)
{
eLogger(fcc.getMessage());
}
}
//Method to log errors - change path of file to store it somewhere else
private static void eLogger(String log)
{
try
{
FileWriter outFile = new FileWriter("c:\\logger.txt");
PrintWriter out = new PrintWriter(outFile);
out.append("The following error was encountered:");
out.append(log);
out.close();
}
catch (IOException ef)
{
ef.printStackTrace();
}
}
private static String parseComments(String scmComments)
{
String dNum = "";
int startPos = scmComments.indexOf("<:");
int endPos = scmComments.indexOf(":>");
dNum = scmComments.substring(startPos + 2, endPos);
return dNum;
}
}
[edit] Create ClearCase TriggerNow that we understand how to the script works, we can create a trigger in ClearCase.
cleartool mktrtype -c "Attach to Defect" -element -all -postop checkin -execwin "C:\Program Files\Java\jre1.6.0_07\bin\java.exe -jar C:\dist\CCTrigger.jar" TTATTACH
Please refer to the ClearCase documentation for clear understanding on all of the options used and how to possibly change them to customize this for your own needs.
[edit] Debuggin/Using the TriggerTo debug the code above, hard code the variables that depend on the environment variables. The sample code above already has this commented out for your use. To debug the code when it runs as a trigger, create a method similar to the eLogger() method to log messages throughtout the code, these messages can help you see how far your code got before the error occurred. The reason I suggest using a separate method, is because the method overwrites the file, so the message you log will be overwritten by the message from the Exception. Here is a sample use case:
Now you should have a file linked to defect #1 in your TestTrack project, on the SCC tab. If you've configure ClearCase integration within TestTrack, you should be able to perform ClearCase commands on that file from within TestTrack as well.
|
|


