7 =head1 NAME $RCSfile: testclearquest.pl,v $
9 Test the Clearquest libary
11 This script tests various functions of the Clearquest library
19 Andrew DeFaria <Andrew@ClearSCM.com>
27 Mon Nov 12 16:50:44 PST 2012
31 $Date: 2013/03/14 23:39:39 $
37 Usage: testclearquest.pl [-u|sage] [-v|erbose] [-d|ebug]
38 [-get] [-add] [-modify] [-change] [-delete]
39 [-username <username>] [-password <password>]
40 [-database <dbname>] [-dbset <dbset>]
41 [-module] [-server <server>] [-port <port>]
44 -usa|ge: Displays usage
46 -de|bug: Output debug messages
54 -use|rname: Username to open database with (Default: from config file)
55 -p|assword: Password to open database with (Default: from config file)
56 -da|tabase: Database to open (Default: from config file)
57 -db|set: Database Set to use (Default: from config file)
58 -m|odule: Type of Clearquest module to use. Must be one of 'api',
59 'client', or 'rest'. The 'api' module can only be used if
60 Clearquest is installed locally. The 'client' module can only
61 be successful if a corresponding server is running. And the
62 'rest' module can only be used if a CQ Web server has been set
63 up and configured (Default: rest)
64 -s|erver: For module = client or rest this is the name of the server that
65 will be providing the service
66 -p|ort: For module = client, this is the point on the server to talk
72 Options are keep in the cq.conf file in etc. They specify the default options
73 listed below. Or you can export the option name to the env(1) to override the
74 defaults in cq.conf. Finally you can programmatically set the options when you
75 call new by passing in a %parms hash. To specify the %parms hash key remove the
76 CQ_ portion and lc the rest.
78 =for html <blockquote>
84 Clearquest server to talk to (Default: From cq.conf)
88 Port to connect to (Default: From cq.conf)
92 The web host to contact with leading http:// (Default: From cq.conf)
96 Name of database to connect to (Default: From cq.conf)
100 User name to connect as (Default: From cq.conf)
104 Password for CQREST_USERNAME (Default: From cq.conf)
108 Database Set name (Default: From cq.conf)
117 use lib "$FindBin::Bin/../lib";
121 use Clearcase::UCM::Activity;
122 use Clearcase::UCM::Stream;
123 use Clearcase::UCM::Project;
124 use Clearcase::UCM::Pvob;
131 my ($cq, %opts, $log, $createView, $test_pvob, $test_project);
134 my $project = 'tc.project';
136 sub displayRecord(%) {
142 $log->msg("$_: ", 1);
144 if (ref $record{$_} eq 'ARRAY') {
145 $log->msg(join ", ", @{$record{$_}});
146 } elsif ($record{$_}) {
147 $log->msg($record{$_});
149 $log->msg('<undef>');
156 sub displayResults(@) {
160 displayRecord %$_ foreach (@records);
162 $log->msg('Did not find any records');
168 sub GetRecord($$;@) {
169 my ($table, $key, @fields) = @_;
171 $log->msg("Gettng table: $table key: $key");
173 my %record = $cq->get($table, $key, @fields);
176 $log->err($cq->errmsg);
178 displayRecord %record;
184 sub FindRecord($$;@) {
185 my ($table, $condition, @fields) = @_;
189 $log->msg("Finding table: $table condition: $condition");
191 my ($result, $nbrRecs) = $cq->find($table, $condition, @fields);
193 $log->msg("$nbrRecs records qualified");
195 while (my %record = $cq->getNext($result)) {
196 unless ($cq->error) {
197 # Store away the createView.pl script location
198 $createView = $record{ws_cr_view} if $table eq 'Platform_Options';
200 displayRecord %record;
202 $status += $cq->error;
209 sub ModifyRecord($$;%) {
210 my ($table, $key, %update) = @_;
212 $log->msg("Modifying table: $table key: $key");
214 $cq->modify($table, $key, undef, \%update);
216 $log->err($cq->errmsg) if $cq->checkErr;
224 my %record = $cq->get('WOR', $key, ('State'));
226 return $cq->error if $cq->checkErr("Unable to find WOR where key = $key");
228 my ($action, %update);
230 if ($record{State} ne 'Submitted') {
231 $log->err("Cannot assign $key - not in submitted state");
237 $update{PlannedStart} = Today2SQLDatetime;
238 $update{ucm_project} = $project;
240 $log->msg("Testing change WOR state of $key action: $action");
242 $cq->modify('WOR', $key, $action, \%update);
244 $log->err($cq->errmsg) if $cq->checkErr;
252 my %record = $cq->get('WOR', $key, ('State'));
254 return $cq->error if $cq->checkErr("Unable to find WOR where key = $key");
256 my ($action, %update);
258 if ($record{State} ne 'Assessing') {
259 $log->err("Cannot activate $key - not in Assessing state");
264 $action = 'Activate';
266 $log->msg("Testing change WOR state of $key action: $action");
268 $cq->modify('WOR', $key, $action);
270 $log->err($cq->errmsg) if $cq->checkErr;
275 sub AddRecord($$;$$) {
276 my ($table, $record, $ordering, $returnField) = @_;
278 $returnField ||= 'id';
280 $log->msg("Adding table: $table");
282 my $dbid = $cq->add($table, $record, @$ordering);
285 $log->err($cq->errmsg);
289 my %record = $cq->getDBID($table, $dbid, ($returnField));
291 return $record{$returnField};
295 sub DeleteRecord($$) {
296 my ($table, $key) = @_;
298 $log->msg("Deleting table: $table key: $key");
300 $cq->delete($table, $key);
302 $log->err($cq->errmsg) if $cq->checkErr;
308 # Try to add a WOR - the following fields are required and some may need
309 # to be added to stateless records in order for this to succeed. Once you
310 # can add a WOR through the Clearquest client successfully you should be
311 # able to come up with the values of these required fields. There are,
312 # however, sometimes when you need to specify ordering to have some fields
313 # set before other fields.
315 headline => 'Test WOR',
316 description => 'This is a test WOR created programmatically',
318 RCLC_name => 'Test RCLC',
319 Prod_Arch1 => 'testcode : N/A',
320 work_product_name => '10 - Software',
321 Engr_target => 'Test Engineering Target',
322 work_code_name => 'RAN-RW2',
325 return AddRecord('WOR', \%WOR, ['project', 'Prod_Arch1']);
331 my ($status, @output) = Execute "$createView $WORID 2>&1";
333 $log->log($_) for @output;
341 my ($status, @output) = (0, ());
344 # Remove views created
346 "$ENV{USER}_${project}_intview",
347 "$ENV{USER}_${WORID}_devview",
351 my $view = Clearcase::View->new($_);
353 $log->msg('Removing ' . $view->name);
355 ($rc, @output) = $view->remove;
359 $log->log($_) for @output;
362 # Remove streams that were created
364 "$ENV{USER}_${WORID}_${project}_dev",
367 for my $stream (@streams) {
368 my $activity = Clearcase::UCM::Activity->new($WORID, $test_pvob);
370 $log->msg('Removing ' . $activity->name);
372 ($rc, @output) = $activity->remove;
376 $log->log($_) for @output;
378 # Streams are downshifted
379 my $stream = Clearcase::UCM::Stream->new(lc $stream, $test_pvob);
381 $log->msg('Removing ' . $stream->name);
383 ($rc, @output) = $stream->remove;
385 $log->log($_) for @output;
396 usage => sub { Usage },
397 verbose => sub { set_verbose },
398 debug => sub { set_debug },
416 my $processStartTime = time;
418 # Since we are creating private vobs (to avoid complications with having to
419 # know and code the registry password when making public vobs), we'll simply
420 # change $Clearcase::VOBTAG_PREFIX
421 $Clearcase::VOBTAG_PREFIX = $ENV{TMP} || '/tmp';
425 # Translate any options to ones that the lib understands
426 map {$opts{$_} = $Clearquest::OPTS{$_}} keys %Clearquest::OPTS;
428 $opts{CQ_USERNAME} = delete $opts{username} if $opts{username};
429 $opts{CQ_PASSWORD} = delete $opts{password} if $opts{password};
430 $opts{CQ_DATABASE} = delete $opts{database} if $opts{database};
431 $opts{CQ_DBSET} = delete $opts{dbset} if $opts{dbset};
432 $opts{CQ_SERVER} = delete $opts{server} if $opts{server};
433 $opts{CQ_PORT} = delete $opts{port} if $opts{port};
434 $opts{CQ_MODULE} = delete $opts{module} if $opts{module};
436 # If nothing is set then do everything
437 unless ($opts{get} or
443 $opts{get} = $opts{add} = $opts{modify} = $opts{change} = 1;
446 # If we are testing add or delete then toggle on the other one
447 $opts{delete} = 1 if $opts{add};
448 $opts{add} = 1 if $opts{delete};
450 my $startTime = time;
454 $cq = Clearquest->new(%opts);
456 $log->msg('Connecting to Clearquest database ' . $cq->connection . '...', 1);
458 unless ($cq->connect) {
459 $cq->checkErr('Unable to connect to database ' . $cq->connection, undef, $log);
461 if ($cq->module eq 'client') {
462 $log->msg('Unable to connect to server ' . $cq->server() . ':' . $cq->port());
467 $log->msg('connected');
468 display_duration $startTime, $log;
471 $cq->setOpts(emptyStringForUndef => 1);
473 # Check a few required stateless records
476 $status += GetRecord 'Project', 'MUOS- EC';
478 # Get record by condition
479 $status += FindRecord 'Platform_Options', 'Platform = "Unix"';
481 # Get record by condition with field list
482 $status += FindRecord 'Roles', 'Rank = "Supervisor"', ('user_name', 'teams.Name', 'Rank');
487 Name => $FindBin::Script,
488 Description => 'This is a test component',
491 AddRecord('Component', \%component, undef, 'name');
493 $status++ if $cq->error;
498 my $newDescription = 'This is a modified test component';
500 $status += ModifyRecord('Component', $FindBin::Script, (Description => $newDescription));
502 # Make sure the modification happened
503 my %component = $cq->get('Component', $FindBin::Script, ('Description'));
505 $log->err('Modification of Component.Description failed!')
506 if $component{Description} ne $newDescription;
509 DeleteRecord 'Component', $FindBin::Script if $opts{add};
511 $log->msg('Enable tc.project for integration with Clearquest');
513 $test_pvob = Clearcase::UCM::Pvob->new("$Clearcase::VOBTAG_PREFIX/tc.pvob");
514 $test_project = Clearcase::UCM::Project->new('tc.project', 'tc.folder', $test_pvob);
516 my ($rc, @output) = $test_project->change('-force -crmenable XTST1');
520 $log->log($_) for @output;
522 $log->msg('Create WOR');
524 my $WORID = CreateWOR;
531 $log->msg("Created WOR $WORID");
535 $status += AssignWOR $WORID;
536 $status += ActivateWOR $WORID;
539 $status += CreateView $WORID;
541 $status += Cleanup($WORID);
544 $log->err('Clearquest tests FAILED');
546 $log->msg('Clearquest tests PASSED');
549 $log->msg('Total process time ', 1);
551 display_duration $processStartTime, $log;