Generating Change Request Reports


The process for generating change request reports is slightly different from generating baseline reports. This is because change request information is not held in the version control tool (ClearCase) but rather in the change request and defect tracking toolwhich in this case is IBM Rational ClearQuest. Therefore, to automate the generation of change request reports, an interface to the ClearQuest tool is required. Fortunately, ClearQuest has a powerful API to achieve this. This API can be called from Perl scripts. This section discusses how to use it.

Using Perl and the ClearQuest API

The ClearQuest API is implemented as a Perl package (called CQPerlExt) that is shipped with ClearQuest. You can use this package from any Perl script by referencing it at the top of your script as follows:

Use CQPerlExt;


All the ClearQuest Perl API methods and constants should then be available for you to use. Whenever you create a Perl script for accessing the API, there is a high-level framework, containing several steps that all scripts typically go through:

  • Create a Session or AdminSession object.

  • Log on to a database.

  • Query or manipulate ClearQuest data.

  • End the session.

The primary point of entry into the ClearQuest API is through either a Session or AdminSession object. The difference is that the Session object provides access to user database objects, such as change request records, whereas the AdminSession object provides access to schema repository objects, such as users and databases. Because in this section I will be constructing change request reports, only Session objects will be used. (For examples of using the AdminSession object, see the ClearQuest API reference Web pages that are installed with the product.) To create a Session object, you include a line in your script similar to the following:

my $sessionObj = CQSession::Build();


This creates a Perl variable called $sessionObj that is used to access the rest of the ClearQuest API.

To protect your databases from unauthorized users, ClearQuest requires that you log on to a database before accessing its records. The method to programmatically achieve this is called UserLogon, and it is called as follows:

$sessionObj->UserLogon(login_name, password, database_name, database_set);


The parameters are as follows:

  • login_name A string that represents the user's login name.

  • password A string that represents the user's password.

  • database_name A string that specifies the name of the required user database.

  • database_set A string that specifies the name of the master database. You should set this string to the empty string ("") unless you have more than one database set.

Once you are logged on, you can start querying or manipulating ClearQuest data. To create a change request report, you query existing data. To do this you build a query on a specific entity (or record) type, similar to what you would do when using the ClearQuest client. The difference is that you construct the query programmatically using the API's methods. For example, to return the set of ClearQuest defect records that are in the state Submitted, you would construct the following query:

my $queryDefObj = $sessionObj->BuildQuery("defect"); $queryDefObj->BuildField("id"); $queryDefObj->BuildField("headline"); $queryDefObj->BuildField("state"); my @states = ("Submitted"); my $where = $queryDefObj->BuildFilterOperator($CQPerlExt::CQ_BOOL_OP_EQ); $where->BuildFilter("state", $CQPerlExt::CQ_COMP_OP_EQ,\@states);


To query on ClearQuest records, you need to create a QueryDef object that defines the query to be executed. In this example an object called $queryDefObj is created to query the defect records in the database. You must specify at least one field from the record type that is to be returned in the query's search results. This is done using the BuildField method. In this example the record's id, headline, and state are all returned. Next, you must construct the query expression that the set of records to be returned is to be filtered on. To do this you must first call the BuildFilterOperator method to obtain the first filter in the query expression. From this filter, you can construct additional filters to specify the criteria you want. In this example, only one filter is created, specifying that the state field should be in the Submitted state. Notice that Perl ClearQuest API constants (such as $CQPerlExt::CQ_COMP_OP_EQ) are used to indicate the query's operator. In this case state must equal Submitted. You can use many operator constants, depending on how you want to construct your query.

Once you have defined the query, you can execute it by creating a ResultSet object:

my $resultSetObj = $sessionObj->BuildResultSet($queryDefObj); $resultSetObj->Execute();


In this example an object called $resultSetObj is created (using the query defined previously), and its Execute method is called to execute it.

The ResultSet object contains data structures that organize data from the query into rows and columns. Each row represents a single record, and each column represents one field from that record. After running the query, you can navigate (move) from row to row and from column to column to obtain the data you want, as in the following example:

while (($resultSetObj->MoveNext()) == $CQPerlExt::CQ_SUCCESS) {     $id = $resultSetObj->GetColumnValue(1);     ... }


In this example, the MoveNext method is executed to move down each row of the ResultSet. The while loop is created in such a way that the statements inside it are executed only if more rows need to be returned. To retrieve the value of each record field that the ResultSet contains, you use the GetColumnValue method. In this example, column 1 is retrieved, which maps to the id field. Column 2 maps to the headline field, and so on. As you retrieve each field, you store, manipulate, or print it, depending on how you want to format your change request report. After you finish retrieving the data, you end the session using the following:

CQSession::Unbuild($sessionObj);


Listing 8.4 shows a complete example that creates a basic ClearQuest defect report query.

Listing 8.4. Perl cq_defect_report.pl File

use CQPerlExt; my $sessionObj = CQSession::Build(); $sessionObj->UserLogon("user", "password", "DB",""); my $queryDefObj = $sessionObj->BuildQuery("defect"); $queryDefObj->BuildField("id"); $queryDefObj->BuildField("headline"); $queryDefObj->BuildField("state"); my @states = ("Submitted"); my $where = $queryDefObj->BuildFilterOperator($CQPerlExt::CQ_BOOL_OP_EQ); $where->BuildFilter("state", $CQPerlExt::CQ_COMP_OP_EQ, \@states); my $resultSetObj = $sessionObj->BuildResultSet($queryDefObj); $resultSetObj->Execute(); while (($resultSetObj->MoveNext()) == $CQPerlExt::CQ_SUCCESS) {     $id = $resultSetObj->GetColumnValue(1);     $headline = $resultSetObj->GetColumnValue(2);     $state = $resultSetObj->GetColumnValue(3);     print "$id - $headline ($state)\n"; } CQSession::Unbuild($sessionObj);

Executing Listing 8.4 produces output similar to the following:

>ratlperl cq-defect-query.pl RBPRO00000028 - Incorrect copyright text (Opened) RBPRO00000056 - Crash when changing account details                 (Submitted) RBPRO00000057 - Spelling error in login screen (Assigned) RBPRO00000058 - Formatting overlaps on address form                 (Submitted)


This information should be sufficient to allow you to create basic queries using the ClearQuest API. If you need more information, the ClearQuest API reference Web pages are comprehensive in this regard.

Creating a Consolidated Change Request Report

In the ClearQuest API examples so far, only defect record types have been queried on and reported. In reality, change request reports consist of many different types, such as both enhancement requests and defects. Also, a set of change requests is usually associated at a higher level with a specific project or release. This section walks through how to create a consolidated change request report for a specific release.

One of ClearQuest's more useful capabilities is its support for record type families. A record type family is a grouping of two or more state-based entity (or record) types that have common fields. For example, a defect and an enhancement request both have id, headline, and owner fields. To create a record type family, you use the ClearQuest Designer tool. First open an existing ClearQuest schema, right-click the Record Type Families folder, and select Add. Enter a name for the record type family, such as All_Change_Requests. Open this newly created folder, right-click Members, and select Add. Add each ClearQuest record type that you want to be in this family, such as Defect or Enhancement Request. Finally, double-click Fields and enter the names of the common fields that the members of the record type family share. Figure 8.1 shows an example.

Figure 8.1. ClearQuest Designer All_Change_Requests record type family


Note that you can only add fields to the record type family that are shared by all its members. After you have created a record type family, you can use it to execute a single query across multiple record types:

my $queryDefObj = $sessionObj->BuildQuery("all_change_requests"); $queryDefObj->BuildField("id"); $queryDefObj->BuildField("headline"); $queryDefObj->BuildField("record_type"); my $resultSetObj = $sessionObj->BuildResultSet($queryDefObj); $resultSetObj->Execute();


As soon as all your change request record types are in a record type family, you can start querying on common fields. One of the standard ways to report change requests is by "release." This is a field containing the name of a specific release that the change requests were implemented for, such as Release 1.0 or Release 2.1. To keep release names consistent, you probably want to use a stateless entity type for the release in your schema. For now I will assume that all the change request record types share a common field called Release (as highlighted in Figure 8.1).

The DTRelease Entity Type

The IBM Rational ClearQuest Build and Deployment Tracking capability comes with a predefined release entity type called DTRelease. Rather than creating your own release entity type, you can simply reuse this one. I will discuss Build and Deployment Tracking in detail in Chapters 10 and 11.


To query on a specific release, you then simply build an additional filter using the Build-Filter method:

my @states = ("Submitted", "Assigned", "Opened"); my @release = ("Release 1.0"); my $where = $queryDefObj->BuildFilterOperator($CQPerlExt::CQ_BOOL_OP_AND); $where->BuildFilter("state", $CQPerlExt::CQ_COMP_OP_EQ,\@states); $where->BuildFilter("release", $CQPerlExt::CQ_COMP_OP_LIKE,\@release);


This is an example of a more complicated query in that it has two filters: the states and the release name. The query returns only record data that matches both of these filters. Note also that the operator for the release field is CQ_COMP_OP_LIKE. This means that the release field does not have to match the string supplied exactly; instead, it simply needs to contain it. Listing 8.5 shows a complete example that creates a report for "active" change requests for a specific release.

Listing 8.5. Perl cq_release_report.pl File

use CQPerlExt; my ($release_name) = @ARGV; if ((@ARGV != 1) or ($release_name eq "")) {     die("Error: invalid release name.\n"); } my $sessionObj = CQSession::Build(); $sessionObj->UserLogon("user", "password", "DB",""); my $queryDefObj = $sessionObj->BuildQuery("all_change_requests"); $queryDefObj->BuildField("id"); $queryDefObj->BuildField("headline"); $queryDefObj->BuildField("state"); $queryDefObj->BuildField("record_type"); my @states = ("Submitted", "Assigned", "Opened"); my @release = ("$release_name"); my $where = $queryDefObj->BuildFilterOperator($CQPerlExt::CQ_BOOL_OP_AND); $where->BuildFilter("state", $CQPerlExt::CQ_COMP_OP_EQ, \@states); $where->BuildFilter("release", $CQPerlExt::CQ_COMP_OP_LIKE, \@release); my $resultSetObj = $sessionObj->BuildResultSet($queryDefObj); $resultSetObj->Execute(); print "$release_name active change requests:\n\n"; while (($resultSetObj->MoveNext()) == $CQPerlExt::CQ_SUCCESS) {     $id = $resultSetObj->GetColumnValue(1);     $headline = $resultSetObj->GetColumnValue(2);     $state = $resultSetObj->GetColumnValue(3);     $type = $resultSetObj->GetColumnValue(4);     print "$id - [$type] $headline ($state)\n"; } CQSession::Unbuild($sessionObj);

Executing Listing 8.5 produces output similar to the following:

>ratlperl cq-release_report.pl "Release 1.0" Release 1.0 active change requests: RBPRO00000035 - [EnhancementRequest] Implement Navigation                 (Opened) RBPRO00000056 - [Defect] Crash when changing account details                 (Submitted) RBPRO00000057 - [Defect] Spelling error in login screen                 (Assigned)


Notice that this example also takes a parameter to the script specifying the name of the release to query on. You could use this type of capability to configure the report's output at runtime, especially if you executed it via an Ant script where you might already have the name of the release in one of your properties.

ClearQuest Hooks Database

ClearQuest has a significant number of prewritten sample hooks and scripts. You can find these on the IBM developerWorks Web site at http://www-128.ibm.com/developerworks/rational/library/4236.html.





IBM Rational ClearCase, Ant, and CruiseControl. The Java Developer's Guide to Accelerating and Automating the Build Process
IBM Rational ClearCase, Ant, and CruiseControl: The Java Developers Guide to Accelerating and Automating the Build Process
ISBN: 0321356993
EAN: 2147483647
Year: 2004
Pages: 115
Authors: Kevin A. Lee

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net