-#!/usr/bin/perl
+#!/usr/bin/env cqperl
use strict;
use warnings;
use lib "$FindBin::Bin/../lib";
use Clearquest;
+use Clearcase::View;
+use Clearcase::UCM::Activity;
+use Clearcase::UCM::Stream;
+use Clearcase::UCM::Project;
+use Clearcase::UCM::Pvob;
+use DateUtils;
use Display;
+use Logger;
use TimeUtils;
use Utils;
-my ($cq, %opts);
+my ($cq, %opts, $log, $createView, $test_pvob, $test_project);
-sub displayRecord (%) {
+my $status = 0;
+my $project = 'tc.project';
+
+sub displayRecord(%) {
my (%record) = @_;
- display '-' x 79;
+ $log->msg('-' x 79);
- foreach (keys %record) {
- display_nolf "$_: ";
+ for (keys %record) {
+ $log->msg("$_: ", 1);
if (ref $record{$_} eq 'ARRAY') {
- display join ", ", @{$record{$_}};
+ $log->msg(join ", ", @{$record{$_}});
} elsif ($record{$_}) {
- display $record{$_};
+ $log->msg($record{$_});
} else {
- display "<undef>";
+ $log->msg('<undef>');
} # if
- } # foreach
+ } # for
return;
} # displayRecord
-sub displayResults (@) {
+sub displayResults(@) {
my (@records) = @_;
if (@records) {
displayRecord %$_ foreach (@records);
} else {
- display "Did not find any records";
+ $log->msg('Did not find any records');
} # if
return;
} # displayResults
-sub testGetRecord ($$;@) {
+sub GetRecord($$;@) {
my ($table, $key, @fields) = @_;
- my $startTime = time;
-
- display "Testing get table: $table key: $key";
-
- displayRecord $cq->get ($table, $key, @fields);
-
- display_duration $startTime;
+ $log->msg("Gettng table: $table key: $key");
+
+ my %record = $cq->get($table, $key, @fields);
+
+ if ($cq->checkErr) {
+ $log->err($cq->errmsg);
+ } else {
+ displayRecord %record;
+ } # if
- return;
-} # testGetRecord
+ return $cq->error;
+} # GetRecord
-sub testFindRecord ($$;@) {
+sub FindRecord($$;@) {
my ($table, $condition, @fields) = @_;
- my $startTime = time;
+ my $status;
- display "Testing find table: $table condition: $condition";
+ $log->msg("Finding table: $table condition: $condition");
- my ($result, $nbrRecs) = $cq->find ($table, $condition, @fields);
+ my ($result, $nbrRecs) = $cq->find($table, $condition, @fields);
- display "$nbrRecs records qualified";
+ $log->msg("$nbrRecs records qualified");
- while (my %record = $cq->getNext ($result)) {
- displayRecord %record;
+ while (my %record = $cq->getNext($result)) {
+ unless ($cq->error) {
+ # Store away the createView.pl script location
+ $createView = $record{ws_cr_view} if $table eq 'Platform_Options';
+
+ displayRecord %record;
+
+ $status += $cq->error;
+ } # unless
} # while
- display_duration $startTime;
-
- return;
-} # testFindRecord
+ return $status
+} # FindRecord
-sub testModifyRecord ($$;%) {
+sub ModifyRecord($$;%) {
my ($table, $key, %update) = @_;
- my $startTime = time;
-
- display "Testing modify table: $table key: $key";
-
- $cq->modify ($table, $key, undef, \%update);
+ $log->msg("Modifying table: $table key: $key");
- $cq->checkErr;
+ $cq->modify($table, $key, undef, \%update);
- display_duration $startTime;
+ $log->err($cq->errmsg) if $cq->checkErr;
- return;
-} # testModifyRecord
+ return $cq->error;
+} # ModifyRecord
-sub testChangeState ($$) {
- my ($table, $key) = @_;
+sub AssignWOR($) {
+ my ($key) = @_;
- my $startTime = time;
+ my %record = $cq->get('WOR', $key, ('State'));
- my %record = $cq->get ($table, $key, ('State'));
+ return $cq->error if $cq->checkErr("Unable to find WOR where key = $key");
- $cq->checkErr ("Unable to find $table where key = $key");
-
- return if $cq->error;
-
my ($action, %update);
- if ($record{State} eq 'Assigned') {
- $action = 'AdminAssignToSubmit';
- $update{Stability_Issue} = 'User Fault';
- } else {
- $action = 'Assign';
- $update{Stability_Issue} = 'Assert';
+ if ($record{State} ne 'Submitted') {
+ $log->err("Cannot assign $key - not in submitted state");
+
+ return 1;
} # if
+
+ $action = 'Assign';
+ $update{PlannedStart} = Today2SQLDatetime;
+ $update{ucm_project} = $project;
- display "Testing change state table: $table key: $key action: $action";
-
- $cq->modify ($table, $key, $action, \%update);
-
- $cq->checkErr;
-
- display_duration $startTime;
+ $log->msg("Testing change WOR state of $key action: $action");
- return;
-} # testChangeState
+ $cq->modify('WOR', $key, $action, \%update);
-sub testAddRecord ($%) {
- my ($table, %record) = @_;
+ $log->err($cq->errmsg) if $cq->checkErr;
+
+ return $cq->error;
+} # AssignWOR
+
+sub ActivateWOR($) {
+ my ($key) = @_;
- my $startTime = time;
+ my %record = $cq->get('WOR', $key, ('State'));
- display "Testing adding table: $table";
+ return $cq->error if $cq->checkErr("Unable to find WOR where key = $key");
- $cq->add ($table, \%record, qw(Projects VersionStr));
+ my ($action, %update);
- $cq->checkErr;
+ if ($record{State} ne 'Assessing') {
+ $log->err("Cannot activate $key - not in Assessing state");
+
+ return 1;
+ } # if
+
+ $action = 'Activate';
- display_duration $startTime;
+ $log->msg("Testing change WOR state of $key action: $action");
- return;
-} # testAddRecord
+ $cq->modify('WOR', $key, $action);
-sub testDeleteRecord ($$) {
- my ($table, $key) = @_;
-
- my $startTime = time;
+ $log->err($cq->errmsg) if $cq->checkErr;
+
+ return $cq->error;
+} # ActivateWOR
+
+sub AddRecord($$;$$) {
+ my ($table, $record, $ordering, $returnField) = @_;
- display "Testing deleting table: $table key: $key";
+ $returnField ||= 'id';
+
+ $log->msg("Adding table: $table");
- $cq->delete ($table, $key);
+ my $dbid = $cq->add($table, $record, @$ordering);
- $cq->checkErr;
+ if ($cq->checkErr) {
+ $log->err($cq->errmsg);
+
+ return;
+ } else {
+ my %record = $cq->getDBID($table, $dbid, ($returnField));
+
+ return $record{$returnField};
+ } # if
+} # AddRecord
- display_duration $startTime;
+sub DeleteRecord($$) {
+ my ($table, $key) = @_;
- return;
-} # testDeleteRecord
+ $log->msg("Deleting table: $table key: $key");
+
+ $cq->delete($table, $key);
+
+ $log->err($cq->errmsg) if $cq->checkErr;
+
+ return $cq->error;
+} # DeleteRecord
+
+sub CreateWOR() {
+ # Try to add a WOR - the following fields are required and some may need
+ # to be added to stateless records in order for this to succeed. Once you
+ # can add a WOR through the Clearquest client successfully you should be
+ # able to come up with the values of these required fields. There are,
+ # however, sometimes when you need to specify ordering to have some fields
+ # set before other fields.
+ my %WOR = (
+ headline => 'Test WOR',
+ description => 'This is a test WOR created programmatically',
+ project => 'MUOS',
+ RCLC_name => 'Test RCLC',
+ Prod_Arch1 => 'testcode : N/A',
+ work_product_name => '10 - Software',
+ Engr_target => 'Test Engineering Target',
+ work_code_name => 'RAN-RW2',
+ );
+
+ return AddRecord('WOR', \%WOR, ['project', 'Prod_Arch1']);
+} # CreateWOR
+
+sub CreateView($) {
+ my ($WORID) = @_;
+
+ my ($status, @output) = Execute "$createView $WORID 2>&1";
+
+ $log->log($_) for @output;
+
+ return $status;
+} # CreateView
+
+sub Cleanup($) {
+ my ($WORID) = @_;
+
+ my ($status, @output) = (0, ());
+ my $rc = 0;
+
+ # Remove views created
+ my @tags = (
+ "$ENV{USER}_${project}_intview",
+ "$ENV{USER}_${WORID}_devview",
+ );
+
+ for (@tags) {
+ my $view = Clearcase::View->new($_);
+
+ $log->msg('Removing ' . $view->name);
+
+ ($rc, @output) = $view->remove;
+
+ $status++ if $rc;
+
+ $log->log($_) for @output;
+ } # for
+
+ # Remove streams that were created
+ my @streams = (
+ "$ENV{USER}_${WORID}_${project}_dev",
+ );
+
+ for my $stream (@streams) {
+ my $activity = Clearcase::UCM::Activity->new($WORID, $test_pvob);
+
+ $log->msg('Removing ' . $activity->name);
+
+ ($rc, @output) = $activity->remove;
+
+ $status += $rc;
+
+ $log->log($_) for @output;
+
+ # Streams are downshifted
+ my $stream = Clearcase::UCM::Stream->new(lc $stream, $test_pvob);
+
+ $log->msg('Removing ' . $stream->name);
+
+ ($rc, @output) = $stream->remove;
+
+ $log->log($_) for @output;
+
+ $status++ if $rc;
+ } # for
+
+ return $status;
+} # Cleanup
## Main
-GetOptions (
+GetOptions(
\%opts,
usage => sub { Usage },
verbose => sub { set_verbose },
debug => sub { set_debug },
+ 'verbose',
+ 'debug',
+ 'usage',
'get',
'add',
'modify',
my $processStartTime = time;
+# Since we are creating private vobs (to avoid complications with having to
+# know and code the registry password when making public vobs), we'll simply
+# change $Clearcase::VOBTAG_PREFIX
+$Clearcase::VOBTAG_PREFIX = $ENV{TMP} || '/tmp';
+
local $| = 1;
# Translate any options to ones that the lib understands
-$opts{CQ_USERNAME} = delete $opts{username};
-$opts{CQ_PASSWORD} = delete $opts{password};
-$opts{CQ_DATABASE} = delete $opts{database};
-$opts{CQ_DBSET} = delete $opts{dbset};
-$opts{CQ_SERVER} = delete $opts{server};
-$opts{CQ_PORT} = delete $opts{port};
-$opts{CQ_MODULE} = delete $opts{module};
+map {$opts{$_} = $Clearquest::OPTS{$_}} keys %Clearquest::OPTS;
+
+$opts{CQ_USERNAME} = delete $opts{username} if $opts{username};
+$opts{CQ_PASSWORD} = delete $opts{password} if $opts{password};
+$opts{CQ_DATABASE} = delete $opts{database} if $opts{database};
+$opts{CQ_DBSET} = delete $opts{dbset} if $opts{dbset};
+$opts{CQ_SERVER} = delete $opts{server} if $opts{server};
+$opts{CQ_PORT} = delete $opts{port} if $opts{port};
+$opts{CQ_MODULE} = delete $opts{module} if $opts{module};
# If nothing is set then do everything
unless ($opts{get} or
my $startTime = time;
-$cq = Clearquest->new (%opts);
+$log = Logger->new;
+
+$cq = Clearquest->new(%opts);
-display_nolf 'Connecting to Clearquest database ' . $cq->connection;
+$log->msg('Connecting to Clearquest database ' . $cq->connection . '...', 1);
unless ($cq->connect) {
- $cq->checkErr ('Unable to connect to database ' . $cq->connection);
+ $cq->checkErr('Unable to connect to database ' . $cq->connection, undef, $log);
if ($cq->module eq 'client') {
- display 'Unable to connect to server '
- . $cq->server ()
- . ':'
- . $cq->port ();
+ $log->msg('Unable to connect to server ' . $cq->server() . ':' . $cq->port());
} # if
exit $cq->error;
} else {
- display '';
- display_duration $startTime;
+ $log->msg('connected');
+ display_duration $startTime, $log;
} # unless
-$cq->setOpts (emptyStringForUndef => 1);
+$cq->setOpts(emptyStringForUndef => 1);
+# Check a few required stateless records
if ($opts{get}) {
# Get record by key
- testGetRecord 'Project', 'Athena';
+ $status += GetRecord 'Project', 'MUOS- EC';
# Get record by condition
- testFindRecord 'VersionInfo', 'Deprecated = 1';
-
- # Get record by key with field list
- testFindRecord 'VersionInfo', 'VersionStr = 1.0', ('VersionStr', 'Deprecated');
+ $status += FindRecord 'Platform_Options', 'Platform = "Unix"';
# Get record by condition with field list
- testFindRecord 'CategorySub', 'Category="Software"', ('Category', 'CategoryType', 'SubCategory');
+ $status += FindRecord 'Roles', 'Rank = "Supervisor"', ('user_name', 'teams.Name', 'Rank');
} # if
if ($opts{add}) {
- # Add a record
- testAddRecord 'VersionInfo', (
- VersionStr => '2.0',
- Projects => ['Island', '21331', 'Hera'],
- Visibility => 'Nokia Corporation',
+ my %component = (
+ Name => $FindBin::Script,
+ Description => 'This is a test component',
);
+
+ AddRecord('Component', \%component, undef, 'name');
+
+ $status++ if $cq->error;
} # if
if ($opts{modify}) {
# Modify a record
- testModifyRecord ('VersionInfo', '1.0', (
- Deprecated => 1,
- Projects => ['Island', 'Athena'],
- ));
+ my $newDescription = 'This is a modified test component';
+
+ $status += ModifyRecord('Component', $FindBin::Script, (Description => $newDescription));
+
+ # Make sure the modification happened
+ my %component = $cq->get('Component', $FindBin::Script, ('Description'));
+
+ $log->err('Modification of Component.Description failed!')
+ if $component{Description} ne $newDescription;
} # if
+DeleteRecord 'Component', $FindBin::Script if $opts{add};
+
+$log->msg('Enable tc.project for integration with Clearquest');
+
+$test_pvob = Clearcase::UCM::Pvob->new("$Clearcase::VOBTAG_PREFIX/tc.pvob");
+$test_project = Clearcase::UCM::Project->new('tc.project', 'tc.folder', $test_pvob);
+
+my ($rc, @output) = $test_project->change('-force -crmenable XTST1');
+
+$status += $rc;
+
+$log->log($_) for @output;
+
+$log->msg('Create WOR');
+
+my $WORID = CreateWOR;
+
+unless ($WORID) {
+ $status++;
+
+ exit $status;
+} else {
+ $log->msg("Created WOR $WORID");
+} # unless
+
if ($opts{change}) {
- # Change State
- testChangeState 'Defect', 'apd00000034';
+ $status += AssignWOR $WORID;
+ $status += ActivateWOR $WORID;
} # if
-if ($opts{add}) {
- # Delete that record
- testDeleteRecord 'VersionInfo', '2.0';
+$status += CreateView $WORID;
+
+$status += Cleanup($WORID);
+
+if ($status) {
+ $log->err('Clearquest tests FAILED');
+} else {
+ $log->msg('Clearquest tests PASSED');
} # if
-display_nolf 'Total process time ';
+$log->msg('Total process time ', 1);
+
+display_duration $processStartTime, $log;
-display_duration $processStartTime;
+exit $status;