зеркало из https://github.com/mozilla/pjs.git
1014 строки
24 KiB
Perl
1014 строки
24 KiB
Perl
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
|
#
|
|
# The contents of this file are subject to the Mozilla Public
|
|
# License Version 1.1 (the "License"); you may not use this file
|
|
# except in compliance with the License. You may obtain a copy of
|
|
# the License at http://www.mozilla.org/MPL/
|
|
#
|
|
# Software distributed under the License is distributed on an "AS
|
|
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
# implied. See the License for the specific language governing
|
|
# rights and limitations under the License.
|
|
#
|
|
# The Original Code is the Bugzilla Test Runner System.
|
|
#
|
|
# The Initial Developer of the Original Code is Maciej Maczynski.
|
|
# Portions created by Maciej Maczynski are Copyright (C) 2001
|
|
# Maciej Maczynski. All Rights Reserved.
|
|
#
|
|
# Contributor(s): Greg Hendricks <ghendricks@novell.com>
|
|
# Ed Fuentetaja <efuentetaja@acm.org>
|
|
|
|
=head1 NAME
|
|
|
|
Bugzilla::Testopia::TestRun - Testopia Test Run object
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
This module represents a test run in Testopia. A test run is the
|
|
place where most of the work of testing is done. A run is associated
|
|
with a single test plan and multiple test cases through the test
|
|
case-runs.
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
use Bugzilla::Testopia::TestRun;
|
|
|
|
$run = Bugzilla::Testopia::TestRun->new($run_id);
|
|
$run = Bugzilla::Testopia::TestRun->new(\%run_hash);
|
|
|
|
=cut
|
|
|
|
package Bugzilla::Testopia::TestRun;
|
|
|
|
use strict;
|
|
|
|
use Bugzilla::Util;
|
|
use Bugzilla::User;
|
|
use Bugzilla::Constants;
|
|
use Bugzilla::Config;
|
|
use Bugzilla::Testopia::Environment;
|
|
|
|
use base qw(Exporter);
|
|
@Bugzilla::Testopia::TestRun::EXPORT = qw(CalculatePercentCompleted);
|
|
|
|
###############################
|
|
#### Initialization ####
|
|
###############################
|
|
|
|
=head1 FIELDS
|
|
|
|
run_id
|
|
plan_id
|
|
environment_id
|
|
product_version
|
|
build_id
|
|
plan_text_version
|
|
manager_id
|
|
start_date
|
|
stop_date
|
|
summary
|
|
notes
|
|
|
|
=cut
|
|
|
|
use constant DB_COLUMNS => qw(
|
|
test_runs.run_id
|
|
test_runs.plan_id
|
|
test_runs.environment_id
|
|
test_runs.product_version
|
|
test_runs.build_id
|
|
test_runs.plan_text_version
|
|
test_runs.manager_id
|
|
test_runs.start_date
|
|
test_runs.stop_date
|
|
test_runs.summary
|
|
test_runs.notes
|
|
);
|
|
|
|
our $columns = join(", ", DB_COLUMNS);
|
|
|
|
|
|
###############################
|
|
#### Methods ####
|
|
###############################
|
|
|
|
=head2 new
|
|
|
|
Instantiate a new Test Run. This takes a single argument
|
|
either a test run ID or a reference to a hash containing keys
|
|
identical to a test run's fields and desired values.
|
|
|
|
=cut
|
|
|
|
sub new {
|
|
my $invocant = shift;
|
|
my $class = ref($invocant) || $invocant;
|
|
my $self = {};
|
|
bless($self, $class);
|
|
return $self->_init(@_);
|
|
}
|
|
|
|
=head2 _init
|
|
|
|
Private constructor for this object
|
|
|
|
=cut
|
|
|
|
sub _init {
|
|
my $self = shift;
|
|
my ($param) = (@_);
|
|
my $dbh = Bugzilla->dbh;
|
|
|
|
my $id = $param unless (ref $param eq 'HASH');
|
|
my $obj;
|
|
|
|
if (defined $id && detaint_natural($id)) {
|
|
|
|
$obj = $dbh->selectrow_hashref(qq{
|
|
SELECT $columns FROM test_runs
|
|
WHERE run_id = ?}, undef, $id);
|
|
|
|
} elsif (ref $param eq 'HASH'){
|
|
$obj = $param;
|
|
|
|
} else {
|
|
Bugzilla::Error::ThrowCodeError('bad_arg',
|
|
{argument => 'param',
|
|
function => 'Testopia::TestRun::_init'});
|
|
}
|
|
|
|
return undef unless (defined $obj);
|
|
|
|
foreach my $field (keys %$obj) {
|
|
$self->{$field} = $obj->{$field};
|
|
}
|
|
|
|
return $self;
|
|
}
|
|
|
|
=head2 calculate_percent_completed
|
|
|
|
Calculates a percentage from two numbers. Takes the total number
|
|
of IDLE case runs and the number of those that have another status
|
|
and adds them to get a total then takes the percentage.
|
|
|
|
=cut
|
|
|
|
sub calculate_percent_completed {
|
|
|
|
my ($idle, $run) = (@_);
|
|
my $total = $idle + $run;
|
|
my $percent;
|
|
if ($total == 0) {
|
|
$percent = 100;
|
|
} else {
|
|
$percent = $run*100/$total;
|
|
$percent = int($percent + 0.5);
|
|
if (($percent == 100) && ($idle != 0)) {
|
|
#I don't want to see 100% unless every test is run
|
|
$percent = 99;
|
|
}
|
|
}
|
|
return $percent;
|
|
}
|
|
|
|
=head2 add_cc
|
|
|
|
Adds a user to the CC list for this run
|
|
|
|
=cut
|
|
|
|
sub add_cc{
|
|
my $self = shift;
|
|
my ($ccid) = (@_);
|
|
my $dbh = Bugzilla->dbh;
|
|
$dbh->do("INSERT INTO test_run_cc(run_id, who)
|
|
VALUES (?,?)", undef, $self->{'run_id'}, $ccid);
|
|
#TODO: send mail
|
|
return 1;
|
|
}
|
|
|
|
=head2 remove_cc
|
|
|
|
Removes a user from the CC list of this run
|
|
|
|
=cut
|
|
|
|
sub remove_cc{
|
|
my $self = shift;
|
|
my ($ccid) = (@_);
|
|
my $dbh = Bugzilla->dbh;
|
|
$dbh->do("DELETE FROM test_run_cc
|
|
WHERE run_id=? AND who=?",
|
|
undef, $self->{'run_id'}, $ccid);
|
|
#TODO: send mail
|
|
return 1;
|
|
}
|
|
|
|
=head2 add_tag
|
|
|
|
Associates a tag with this test case
|
|
|
|
=cut
|
|
|
|
sub add_tag {
|
|
my $self = shift;
|
|
my ($tag_id) = @_;
|
|
my $dbh = Bugzilla->dbh;
|
|
|
|
$dbh->bz_lock_tables('test_run_tags WRITE');
|
|
my $tagged = $dbh->selectrow_array(
|
|
"SELECT 1 FROM test_run_tags
|
|
WHERE tag_id = ? AND run_id = ?",
|
|
undef, $tag_id, $self->{'run_id'});
|
|
if ($tagged) {
|
|
$dbh->bz_unlock_tables;
|
|
return 1;
|
|
}
|
|
$dbh->do("INSERT INTO test_run_tags VALUES(?,?)",
|
|
undef, $tag_id, $self->{'run_id'});
|
|
$dbh->bz_unlock_tables;
|
|
|
|
return 0;
|
|
}
|
|
|
|
=head2 remove_tag
|
|
|
|
Disassociates a tag from this test case
|
|
|
|
=cut
|
|
|
|
sub remove_tag {
|
|
my $self = shift;
|
|
my ($tag_id) = @_;
|
|
my $dbh = Bugzilla->dbh;
|
|
$dbh->do("DELETE FROM test_run_tags
|
|
WHERE tag_id=? AND run_id=?",
|
|
undef, $tag_id, $self->{'run_id'});
|
|
return;
|
|
}
|
|
|
|
=head2 add_case_run
|
|
|
|
Associates a test case with this run by adding a new row to
|
|
the test_case_runs table
|
|
|
|
=cut
|
|
|
|
sub add_case_run {
|
|
my $self = shift;
|
|
my ($case_id) = @_;
|
|
my $case = Bugzilla::Testopia::TestCase->new($case_id);
|
|
my $caserun = Bugzilla::Testopia::TestCaseRun->new({
|
|
'run_id' => $self->{'run_id'},
|
|
'case_id' => $case_id,
|
|
'assignee' => $case->default_tester->id,
|
|
'case_text_version' => $case->version,
|
|
'build_id' => $self->build->id,
|
|
});
|
|
$caserun->store;
|
|
}
|
|
|
|
=head2 store
|
|
|
|
Stores a test run object in the database. This method is used to store a
|
|
newly created test run. It returns the new ID.
|
|
|
|
=cut
|
|
|
|
sub store {
|
|
my $self = shift;
|
|
my $dbh = Bugzilla->dbh;
|
|
my $timestamp = Bugzilla::Testopia::Util::get_time_stamp();
|
|
$dbh->do("INSERT INTO test_runs ($columns)
|
|
VALUES (?,?,?,?,?,?,?,?,?,?,?)",
|
|
undef, (undef, $self->{'plan_id'}, $self->{'environment_id'},
|
|
$self->{'product_version'}, $self->{'build_id'},
|
|
$self->{'plan_text_version'}, $self->{'manager_id'},
|
|
$timestamp, undef, $self->{'summary'}, $self->{'notes'}));
|
|
my $key = $dbh->bz_last_key( 'test_runs', 'run_id' );
|
|
return $key;
|
|
}
|
|
|
|
=head2 update
|
|
|
|
Updates this test run with new values supplied by the user.
|
|
Accepts a reference to a hash with keys identical to a test run's
|
|
fields and values representing the new values entered.
|
|
Validation tests should be performed on the values
|
|
before calling this method. If a field is changed, a history
|
|
of that change is logged in the test_run_activity table.
|
|
|
|
=cut
|
|
|
|
sub update {
|
|
my $self = shift;
|
|
my ($newvalues) = @_;
|
|
my $dbh = Bugzilla->dbh;
|
|
my $timestamp = Bugzilla::Testopia::Util::get_time_stamp();
|
|
|
|
$dbh->bz_lock_tables('test_runs WRITE', 'test_run_activity WRITE',
|
|
'test_fielddefs READ');
|
|
foreach my $field (keys %{$newvalues}){
|
|
if ($self->{$field} ne $newvalues->{$field}){
|
|
$dbh->do("UPDATE test_runs
|
|
SET $field = ? WHERE run_id = ?",
|
|
undef, ($newvalues->{$field}, $self->{'run_id'}));
|
|
# Update the history
|
|
my $field_id = Bugzilla::Testopia::Util::get_field_id($field, "test_runs");
|
|
$dbh->do("INSERT INTO test_run_activity
|
|
VALUES(?,?,?,?,?,?)",
|
|
undef, ($self->{'run_id'}, $field_id, Bugzilla->user->id,
|
|
$timestamp, $self->{$field}, $newvalues->{$field}));
|
|
$self->{$field} = $newvalues->{$field};
|
|
}
|
|
}
|
|
$dbh->bz_unlock_tables();
|
|
}
|
|
|
|
=head2 update_notes
|
|
|
|
Updates just the notes for this run
|
|
|
|
=cut
|
|
|
|
sub update_notes {
|
|
my $self = shift;
|
|
my ($notes) = @_;
|
|
my $dbh = Bugzilla->dbh;
|
|
$dbh->do("UPDATE test_runs
|
|
SET notes = ? WHERE run_id = ?",
|
|
undef, $notes, $self->{'run_id'});
|
|
}
|
|
|
|
=head2 clone
|
|
|
|
Creates a copy of this test run. Accepts the summary of the new run
|
|
and the build id to use.
|
|
|
|
=cut
|
|
|
|
sub clone {
|
|
my $self = shift;
|
|
my ($summary, $build) = @_;
|
|
my $dbh = Bugzilla->dbh;
|
|
my $timestamp = Bugzilla::Testopia::Util::get_time_stamp();
|
|
$dbh->do("INSERT INTO test_runs ($columns)
|
|
VALUES (?,?,?,?,?,?,?,?,?,?,?)",
|
|
undef, (undef, $self->{'plan_id'}, $self->{'environment_id'},
|
|
$self->{'product_version'}, $build,
|
|
$self->{'plan_text_version'}, $self->{'manager_id'},
|
|
$timestamp, undef, $summary, undef));
|
|
my $key = $dbh->bz_last_key( 'test_runs', 'run_id' );
|
|
return $key;
|
|
}
|
|
|
|
=head2 history
|
|
|
|
Returns a reference to a list of history entries from the
|
|
test_run_activity table.
|
|
|
|
=cut
|
|
|
|
sub history {
|
|
my $self = shift;
|
|
my $dbh = Bugzilla->dbh;
|
|
my $ref = $dbh->selectall_arrayref(
|
|
"SELECT defs.description AS what,
|
|
p.login_name AS who, a.changed, a.oldvalue, a.newvalue
|
|
FROM test_run_activity AS a
|
|
JOIN test_fielddefs AS defs ON a.fieldid = defs.fieldid
|
|
JOIN profiles AS p ON a.who = p.userid
|
|
WHERE a.run_id = ?",
|
|
{'Slice'=>{}}, $self->{'run_id'});
|
|
|
|
foreach my $row (@$ref){
|
|
if ($row->{'what'} eq 'Environment'){
|
|
$row->{'oldvalue'} = $self->lookup_environment($row->{'oldvalue'});
|
|
$row->{'newvalue'} = $self->lookup_environment($row->{'newvalue'});
|
|
}
|
|
elsif ($row->{'what'} eq 'Default Build'){
|
|
$row->{'oldvalue'} = $self->lookup_build($row->{'oldvalue'});
|
|
$row->{'newvalue'} = $self->lookup_build($row->{'newvalue'});
|
|
}
|
|
elsif ($row->{'what'} eq 'Manager'){
|
|
$row->{'oldvalue'} = $self->lookup_manager($row->{'oldvalue'});
|
|
$row->{'newvalue'} = $self->lookup_manager($row->{'newvalue'});
|
|
}
|
|
}
|
|
return $ref;
|
|
}
|
|
|
|
=head2 lookup_environment
|
|
|
|
Takes an ID of the envionment field and returns the value
|
|
|
|
=cut
|
|
|
|
sub lookup_environment {
|
|
my $self = shift;
|
|
my ($id) = @_;
|
|
my $dbh = Bugzilla->dbh;
|
|
my ($value) = $dbh->selectrow_array(
|
|
"SELECT name
|
|
FROM test_environments
|
|
WHERE environment_id = ?",
|
|
undef, $id);
|
|
return $value;
|
|
}
|
|
|
|
=head2 lookup_build
|
|
|
|
Takes an ID of the build field and returns the value
|
|
|
|
=cut
|
|
|
|
sub lookup_build {
|
|
my $self = shift;
|
|
my ($id) = @_;
|
|
my $dbh = Bugzilla->dbh;
|
|
my ($value) = $dbh->selectrow_array(
|
|
"SELECT name
|
|
FROM test_builds
|
|
WHERE build_id = ?",
|
|
undef, $id);
|
|
return $value;
|
|
}
|
|
|
|
=head2 lookup_manager
|
|
|
|
Takes an ID of the manager field and returns the value
|
|
|
|
=cut
|
|
|
|
sub lookup_manager {
|
|
my $self = shift;
|
|
my ($id) = @_;
|
|
my $dbh = Bugzilla->dbh;
|
|
my ($value) = $dbh->selectrow_array(
|
|
"SELECT login_name
|
|
FROM profiles
|
|
WHERE userid = ?",
|
|
undef, $id);
|
|
return $value;
|
|
}
|
|
|
|
=head2 environments
|
|
|
|
Returns a reference to a list of Testopia::Environment objects.
|
|
|
|
=cut
|
|
|
|
sub environments {
|
|
my ($self) = @_;
|
|
my $dbh = Bugzilla->dbh;
|
|
return $self->{'environments'} if exists $self->{'environments'};
|
|
|
|
my $environments =
|
|
$dbh->selectcol_arrayref("SELECT environment_id
|
|
FROM test_environments");
|
|
|
|
my @environments;
|
|
foreach my $id (@{$environments}){
|
|
push @environments, Bugzilla::Testopia::Environment->new($id);
|
|
}
|
|
$self->{'environments'} = \@environments;
|
|
return $self->{'environments'};
|
|
}
|
|
|
|
=head2 get_status_list
|
|
|
|
Returns a list of statuses for a run
|
|
|
|
=cut
|
|
|
|
sub get_status_list {
|
|
my @status = (
|
|
{ 'id' => 0, 'name' => 'Running' },
|
|
{ 'id' => 1, 'name' => 'Stopped' },
|
|
);
|
|
return \@status;
|
|
}
|
|
|
|
=head2 get_distinct_builds
|
|
|
|
Returns a list of build names for use in searches
|
|
|
|
=cut
|
|
|
|
sub get_distinct_builds {
|
|
my $self = shift;
|
|
my $dbh = Bugzilla->dbh;
|
|
my $query = "SELECT build.name AS id, build.name " .
|
|
"FROM test_builds AS build " .
|
|
"JOIN products ON build.product_id = products.id " .
|
|
"LEFT JOIN group_control_map " .
|
|
"ON group_control_map.product_id = products.id ";
|
|
if (Param('useentrygroupdefault')) {
|
|
$query .= "AND group_control_map.entry != 0 ";
|
|
} else {
|
|
$query .= "AND group_control_map.membercontrol = " .
|
|
CONTROLMAPMANDATORY . " ";
|
|
}
|
|
if (%{Bugzilla->user->groups}) {
|
|
$query .= "AND group_id NOT IN(" .
|
|
join(',', values(%{Bugzilla->user->groups})) . ") ";
|
|
}
|
|
$query .= "WHERE group_id IS NULL ORDER BY build.name";
|
|
|
|
my $ref = $dbh->selectall_arrayref($query, {'Slice'=>{}});
|
|
|
|
return $ref;
|
|
}
|
|
|
|
=head2 get_distinct_milestones
|
|
|
|
Returns a list of milestones for use in searches
|
|
|
|
=cut
|
|
|
|
sub get_distinct_milestones {
|
|
my $self = shift;
|
|
my $dbh = Bugzilla->dbh;
|
|
my $ref = $dbh->selectall_arrayref(
|
|
"SELECT DISTINCT value AS id, value as name
|
|
FROM milestones
|
|
ORDER BY sortkey", {'Slice'=>{}});
|
|
|
|
return $ref;
|
|
}
|
|
|
|
=head2 get_environments
|
|
|
|
Returns a list of environments for use in searches
|
|
|
|
=cut
|
|
|
|
sub get_environments {
|
|
my $dbh = Bugzilla->dbh;
|
|
my $ref = $dbh->selectall_arrayref(
|
|
"SELECT environment_id AS id, name
|
|
FROM test_environments
|
|
ORDER BY name",
|
|
{'Slice'=>{}});
|
|
|
|
return $ref;
|
|
}
|
|
|
|
=head2 canedit
|
|
|
|
Returns true if the logged in user has rights to edit this test run.
|
|
|
|
=cut
|
|
|
|
sub canedit {
|
|
my $self = shift;
|
|
return $self->canview
|
|
&& (UserInGroup('managetestplans')
|
|
|| UserInGroup('edittestcases')
|
|
|| UserInGroup('runtests'));
|
|
}
|
|
|
|
=head2 canview
|
|
|
|
Returns true if the logged in user has rights to view this test run.
|
|
|
|
=cut
|
|
|
|
sub canview {
|
|
my $self = shift;
|
|
return $self->{'canview'} if exists $self->{'canview'};
|
|
$self->{'canview'} = Bugzilla::Testopia::Util::can_view_product($self->plan->product_id);
|
|
return $self->{'canview'};
|
|
}
|
|
|
|
=head2 candelete
|
|
|
|
Returns true if the logged in user has rights to delete this test run.
|
|
|
|
=cut
|
|
|
|
sub candelete {
|
|
my $self = shift;
|
|
return $self->canedit && Param('allow-test-deletion');
|
|
}
|
|
|
|
###############################
|
|
#### Accessors ####
|
|
###############################
|
|
|
|
=head1 ACCESSOR METHODS
|
|
|
|
=head2 id
|
|
|
|
Returns the ID for this object
|
|
|
|
=head2 plan_text_version
|
|
|
|
Returns the plan's text version of this run
|
|
|
|
=head2 plan_id
|
|
|
|
Returns the plan idof this run
|
|
|
|
=head2 environment_id
|
|
|
|
Returns the environment id of this run
|
|
|
|
=head2 manager
|
|
|
|
Returns a Bugzilla::User object representing the run's manager
|
|
|
|
=head2 start_date
|
|
|
|
Returns the time stamp of when this run was started
|
|
|
|
=head2 stop_date
|
|
|
|
Returns the time stamp of when this run was completed
|
|
|
|
=head2 summary
|
|
|
|
Returns the summary of this run
|
|
|
|
=head2 notes
|
|
|
|
Returns the notes for this run
|
|
|
|
=head2 product_version
|
|
|
|
Returns the product version of this run
|
|
|
|
=cut
|
|
|
|
sub id { return $_[0]->{'run_id'}; }
|
|
sub plan_text_version { return $_[0]->{'plan_text_version'}; }
|
|
sub plan_id { return $_[0]->{'plan_id'}; }
|
|
sub environment_id { return $_[0]->{'environment_id'}; }
|
|
sub manager { return Bugzilla::User->new($_[0]->{'manager_id'}); }
|
|
sub start_date { return $_[0]->{'start_date'}; }
|
|
sub stop_date { return $_[0]->{'stop_date'}; }
|
|
sub summary { return $_[0]->{'summary'}; }
|
|
sub notes { return $_[0]->{'notes'}; }
|
|
sub product_version { return $_[0]->{'product_version'}; }
|
|
|
|
=head2 plan
|
|
|
|
Returns the Testopia::TestPlan object of the plan this run
|
|
is assoceated with
|
|
|
|
=cut
|
|
|
|
sub plan {
|
|
my $self = shift;
|
|
return $self->{'plan'} if exists $self->{'plan'};
|
|
$self->{'plan'} = Bugzilla::Testopia::TestPlan->new($self->{'plan_id'});
|
|
return $self->{'plan'};
|
|
}
|
|
|
|
=head2 tags
|
|
|
|
Returns a reference to a list of Testopia::TestTag objects
|
|
associated with this run
|
|
|
|
=cut
|
|
|
|
sub tags {
|
|
my ($self) = @_;
|
|
my $dbh = Bugzilla->dbh;
|
|
return $self->{'tags'} if exists $self->{'tags'};
|
|
my $tagids = $dbh->selectcol_arrayref("SELECT tag_id
|
|
FROM test_run_tags
|
|
WHERE run_id = ?",
|
|
undef, $self->{'run_id'});
|
|
my @tags;
|
|
foreach my $t (@{$tagids}){
|
|
push @tags, Bugzilla::Testopia::TestTag->new($t);
|
|
}
|
|
$self->{'tags'} = \@tags;
|
|
return $self->{'tags'};
|
|
}
|
|
|
|
=head2 environment
|
|
|
|
Returns the Testopia::Environment object of the environment
|
|
this run is assoceated with
|
|
|
|
=cut
|
|
|
|
sub environment {
|
|
my $self = shift;
|
|
return $self->{'environment'} if exists $self->{'environment'};
|
|
$self->{'environment'} = Bugzilla::Testopia::Environment->new($self->{'environment_id'});
|
|
return $self->{'environment'};
|
|
|
|
}
|
|
|
|
=head2 build
|
|
|
|
Returns the Testopia::Build object of the plan this run
|
|
is assoceated with
|
|
|
|
=cut
|
|
|
|
sub build {
|
|
my $self = shift;
|
|
return $self->{'build'} if exists $self->{'build'};
|
|
$self->{'build'} = Bugzilla::Testopia::Build->new($self->{'build_id'});
|
|
return $self->{'build'};
|
|
|
|
}
|
|
|
|
=head2 runtime
|
|
|
|
Returns the total time the run took to complete
|
|
|
|
=cut
|
|
|
|
sub runtime {
|
|
|
|
}
|
|
|
|
=head2 bugs
|
|
|
|
Returns a reference to a list of Bugzilla::Bug objects associated
|
|
with this run
|
|
|
|
=cut
|
|
|
|
sub bugs {
|
|
my $self = shift;
|
|
my $dbh = Bugzilla->dbh;
|
|
return $self->{'bugs'} if exists $self->{'bugs'};
|
|
my $ref = $dbh->selectcol_arrayref(
|
|
"SELECT bug_id
|
|
FROM test_case_bugs b
|
|
JOIN test_case_runs r ON r.case_run_id = b.case_run_id
|
|
WHERE r.run_id = ?",
|
|
undef, $self->{'run_id'});
|
|
my @bugs;
|
|
foreach my $id (@{$ref}){
|
|
push @bugs, Bugzilla::Bug->new($id, Bugzilla->user->id);
|
|
}
|
|
$self->{'bugs'} = \@bugs;
|
|
return $self->{'bugs'};
|
|
}
|
|
|
|
=head2 cc
|
|
|
|
Returns a reference to a list of Bugzilla::User objects
|
|
on the CC list of this run
|
|
|
|
=cut
|
|
|
|
sub cc {
|
|
my $self = shift;
|
|
return $self->{'cc'} if exists $self->{'cc'};
|
|
my $dbh = Bugzilla->dbh;
|
|
my $ref = $dbh->selectcol_arrayref(
|
|
"SELECT who FROM test_run_cc
|
|
WHERE run_id=?", undef, $self->{'run_id'});
|
|
my @cc;
|
|
foreach my $id (@{$ref}){
|
|
push @cc, Bugzilla::User->new($id);
|
|
}
|
|
$self->{'cc'} = \@cc;
|
|
return $self->{'cc'};
|
|
}
|
|
|
|
=head2 cases
|
|
|
|
Returns a reference to a list of Testopia::TestCase objects
|
|
associated with this run
|
|
|
|
=cut
|
|
|
|
sub cases {
|
|
my $self = shift;
|
|
return $self->{'cases'} if exists $self->{'cases'};
|
|
my @cases;
|
|
foreach my $cr (@{$self->current_caseruns}){
|
|
push @cases, Bugzilla::Testopia::TestCase->new($cr->id);
|
|
}
|
|
$self->{'cases'} = \@cases;
|
|
return $self->{'cases'};
|
|
|
|
}
|
|
|
|
=head2 case_count
|
|
|
|
Returns a count of the test cases associated with this run
|
|
|
|
=cut
|
|
|
|
sub case_count {
|
|
my $self = shift;
|
|
return scalar @{$self->cases};
|
|
}
|
|
|
|
=head2 idle_count
|
|
|
|
Returns a count of the number of case-runs in this run with a status
|
|
of IDLE
|
|
|
|
=cut
|
|
|
|
sub idle_count {
|
|
my $self = shift;
|
|
my $dbh = Bugzilla->dbh;
|
|
|
|
my ($count) = $dbh->selectrow_array(
|
|
"SELECT COUNT(*)
|
|
FROM test_case_runs cr
|
|
JOIN test_case_run_status cs
|
|
ON cr.case_run_status_id = cs.case_run_status_id
|
|
WHERE cs.name = ? AND cr.run_id = ? AND cr.iscurrent = 1",
|
|
undef, ('IDLE', $self->{'run_id'}));
|
|
|
|
$self->{'idle_count'} = $count;
|
|
return $self->{'idle_count'};
|
|
}
|
|
|
|
=head2 passed_count
|
|
|
|
Returns a count of the number of case-runs in this run with a status
|
|
of PASSED
|
|
|
|
=cut
|
|
|
|
sub passed_count {
|
|
my $self = shift;
|
|
my $dbh = Bugzilla->dbh;
|
|
|
|
my ($count) = $dbh->selectrow_array(
|
|
"SELECT COUNT(*)
|
|
FROM test_case_runs cr
|
|
JOIN test_case_run_status cs
|
|
ON cr.case_run_status_id = cs.case_run_status_id
|
|
WHERE cs.name = ? AND cr.run_id = ? AND cr.iscurrent = 1",
|
|
undef, ('PASSED', $self->{'run_id'}));
|
|
|
|
$self->{'passed_count'} = $count;
|
|
return $self->{'passed_count'};
|
|
}
|
|
|
|
=head2 failed_count
|
|
|
|
Returns a count of the number of case-runs in this run with a status
|
|
of FAILED
|
|
|
|
=cut
|
|
|
|
sub failed_count {
|
|
my $self = shift;
|
|
my $dbh = Bugzilla->dbh;
|
|
|
|
my ($count) = $dbh->selectrow_array(
|
|
"SELECT COUNT(*)
|
|
FROM test_case_runs cr
|
|
JOIN test_case_run_status cs
|
|
ON cr.case_run_status_id = cs.case_run_status_id
|
|
WHERE cs.name = ? AND cr.run_id = ? AND cr.iscurrent = 1",
|
|
undef, ('FAILED', $self->{'run_id'}));
|
|
|
|
$self->{'failed_count'} = $count;
|
|
return $self->{'failed_count'};
|
|
}
|
|
|
|
=head2 running_count
|
|
|
|
Returns a count of the number of case-runs in this run with a status
|
|
of RUNNING
|
|
|
|
=cut
|
|
|
|
sub running_count {
|
|
my $self = shift;
|
|
my $dbh = Bugzilla->dbh;
|
|
|
|
my ($count) = $dbh->selectrow_array(
|
|
"SELECT COUNT(*)
|
|
FROM test_case_runs cr
|
|
JOIN test_case_run_status cs
|
|
ON cr.case_run_status_id = cs.case_run_status_id
|
|
WHERE cs.name = ? AND cr.run_id = ? AND cr.iscurrent = 1",
|
|
undef, ('RUNNING', $self->{'run_id'}));
|
|
|
|
$self->{'running_count'} = $count;
|
|
return $self->{'running_count'};
|
|
}
|
|
|
|
=head2 paused_count
|
|
|
|
Returns a count of the number of case-runs in this run with a status
|
|
of PAUSED
|
|
|
|
=cut
|
|
|
|
sub paused_count {
|
|
my $self = shift;
|
|
my $dbh = Bugzilla->dbh;
|
|
|
|
my ($count) = $dbh->selectrow_array(
|
|
"SELECT COUNT(*)
|
|
FROM test_case_runs cr
|
|
JOIN test_case_run_status cs
|
|
ON cr.case_run_status_id = cs.case_run_status_id
|
|
WHERE cs.name = ? AND cr.run_id = ? AND cr.iscurrent = 1",
|
|
undef, ('PAUSED', $self->{'run_id'}));
|
|
|
|
$self->{'paused_count'} = $count;
|
|
return $self->{'paused_count'};
|
|
}
|
|
|
|
=head2 blocked_count
|
|
|
|
Returns a count of the number of case-runs in this run with a status
|
|
of BLOCKED
|
|
|
|
=cut
|
|
|
|
sub blocked_count {
|
|
my $self = shift;
|
|
my $dbh = Bugzilla->dbh;
|
|
|
|
my ($count) = $dbh->selectrow_array(
|
|
"SELECT COUNT(*)
|
|
FROM test_case_runs cr
|
|
JOIN test_case_run_status cs
|
|
ON cr.case_run_status_id = cs.case_run_status_id
|
|
WHERE cs.name = ? AND cr.run_id = ? AND cr.iscurrent = 1",
|
|
undef, ('BLOCKED', $self->{'run_id'}));
|
|
|
|
$self->{'blocked_count'} = $count;
|
|
return $self->{'blocked_count'};
|
|
}
|
|
|
|
=head2 percent_complete
|
|
|
|
Returns a number representing the percentage of case-runs
|
|
that have a status vs. those with a status of IDLE
|
|
|
|
=cut
|
|
|
|
sub percent_complete {
|
|
my $self = shift;
|
|
my $notrun = $self->idle_count + $self->running_count + $self->paused_count;
|
|
my $run = $self->passed_count + $self->failed_count + $self->blocked_count;
|
|
$self->{'percent_complete'} = calculate_percent_completed($notrun, $run);
|
|
return $self->{'percent_complete'};
|
|
}
|
|
|
|
=head2 current_caseruns
|
|
|
|
Returns a reference to a list of TestCaseRun objects that are the
|
|
current case-runs on this run
|
|
|
|
=cut
|
|
|
|
sub current_caseruns {
|
|
my $self = shift;
|
|
my $dbh = Bugzilla->dbh;
|
|
return $self->{'current_caseruns'} if exists $self->{'current_caseruns'};
|
|
my $ref = $dbh->selectcol_arrayref(
|
|
"SELECT case_run_id FROM test_case_runs
|
|
WHERE run_id=? AND iscurrent=1", undef,
|
|
$self->{'run_id'});
|
|
my @caseruns;
|
|
|
|
foreach my $id (@{$ref}){
|
|
push @caseruns, Bugzilla::Testopia::TestCaseRun->new($id);
|
|
}
|
|
$self->{'current_caseruns'} = \@caseruns;
|
|
return $self->{'current_caseruns'};
|
|
}
|
|
|
|
=head2 case_id_list
|
|
|
|
Returns a list of case_id's from the current case runs.
|
|
|
|
=cut
|
|
|
|
sub case_id_list {
|
|
my $self = shift;
|
|
my @ids;
|
|
foreach my $c (@{$self->current_caseruns}){
|
|
push @ids, $c->case_id;
|
|
}
|
|
|
|
return join(",", @ids);
|
|
}
|
|
|
|
=head1 SEE ALSO
|
|
|
|
Testopia::(TestPlan, TestCase, Category, Build, Environment)
|
|
|
|
=head1 AUTHOR
|
|
|
|
Greg Hendricks <ghendricks@novell.com>
|
|
|
|
=cut
|
|
|
|
1;
|