ghendricks%novell.com f2ad205bdb Bugzilla 2.22 port
git-svn-id: svn://10.0.0.236/trunk@205092 18797224-902f-48f8-a5cc-f745e15eee43
2006-07-28 22:32:36 +00:00

449 lines
14 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): David Koenig <dkoenig@novell.com>
=head1 NAME
Bugzilla::Testopia::Xml - Testopia Xml object
=head1 DESCRIPTION
This module parsers a XML representation of a Testopia test plan,
test case, test environment, category or build and returns Testopia
objects re
=head1 SYNOPSIS
use Bugzilla::Testopia::Xml;
=cut
package Bugzilla::Testopia::Xml;
#use fields qw(testplans testcases tags categories builds);
use strict;
use Bugzilla::Config;
use Bugzilla::Error;
use Bugzilla::Product;
use Bugzilla::Testopia::Attachment;
use Bugzilla::Testopia::Build;
use Bugzilla::Testopia::Category;
use Bugzilla::Testopia::TestCase;
use Bugzilla::Testopia::TestPlan;
use Bugzilla::Testopia::TestRun;
use Bugzilla::Testopia::TestTag;
use Bugzilla::Testopia::Util;
use Bugzilla::Testopia::XmlTestCase;
use Bugzilla::User;
use Bugzilla::Util;
use Class::Struct;
#
# The Xml structure is used to keep track of all new Testopia objects being created.
#
struct
(
'Bugzilla::Testopia::Xml',
{
attachments => '@',
builds => '@',
categories => '@',
tags => '@',
testenvironments => '@',
testcases => '@',
testplans => '@',
parse_error => '$',
}
);
#TODO: Add this to checksetup
use Text::Diff;
#use base qw(Exporter);
###############################
#### Initialization ####
###############################
=head1 FIELDS
=cut
###############################
#### Methods ####
###############################
=head2 new
Instantiate a new xml object. This takes a single argument
Instantiate a new test plan. This takes a single argument
either a test plan ID or a reference to a hash containing keys
identical to a test plan's fields and desired values.
=cut
#sub new {
# my Bugzilla::Testopia::Xml $self = fields::new(ref($invocant) || $invocant);
# $self->{testplans} = [];
# $self->{testcases} = [];
# $self->{tags} = [];
# $self->{categories} = [];
# $self->{builds} = [];
# return $self;
#}
sub debug_display()
{
my ($self) = @_;
my $attachments_array_ref = $self->attachments;
my $categories_array_ref = $self->categories;
my $testcases_array_ref = $self->testcases;
my $testplans_array_ref = $self->testplans;
foreach my $category ( @$categories_array_ref )
{
bless($category,"Bugzilla::Testopia::Category");
print STDERR "Category: " . $category->name() . "\n";
my $category_id = "null";
$category_id = $category->id() if ( $category->id() );
print STDERR " ID " . $category_id . "\n";
print STDERR " Product ID " . $category->product_id() . "\n";
print STDERR " Description " . $category->description() . "\n";
}
foreach my $testplan ( @$testplans_array_ref )
{
bless($testplan,"Bugzilla::Testopia::TestPlan");
print STDERR "Testplan: " . $testplan->name() . "\n";
my $testplan_id = "null";
$testplan_id = $testplan->id() if ( $testplan->id() );
print STDERR " ID " . $testplan_id . "\n";
my %author = %{$testplan->author()};
my $author_id = $author{"id"};
my $author_login = $author{"login"};
print STDERR " Author " . $author_login . " (id=" . $author_id . ", hash=" . $testplan->author() . ")\n";
print STDERR " Creation Date " . $testplan->creation_date() . "\n";
print STDERR " Description " . $testplan->text() . "\n";
print STDERR " Default Product Version " . $testplan->product_version() . "\n";
print STDERR " Document " . $testplan->text() . "\n";
my %editor = %{$testplan->editor()};
my $editor_id = $editor{"id"};
my $editor_login = $editor{"login"};
print STDERR " Editor " . $editor_login . " (id=" . $editor_id . ", hash=" . $testplan->editor() . ")\n";
print STDERR " Is Active " . $testplan->isactive() . "\n";
print STDERR " Product " . $testplan->product_id() . "\n";
print STDERR " Type " . $testplan->type_id() . "\n";
foreach my $tag ( @{$self->tags} )
{
print STDERR " Tag " . $tag . "\n";
}
my @attachments = @{$testplan->attachments()};
foreach my $attachment (@attachments)
{
my %submitter = %{$testplan->submitter()};
my $author_login = $author{"login"};
print STDERR " Attachment " . $attachment->description() . "\n";
print STDERR " Creation Date " . $attachment->creation_ts(). "\n";
print STDERR " Filename " . $attachment->filename() . "\n";
print STDERR " Mime Type " . $attachment->mime_type(). "\n";
print STDERR " Submitter " . $author_login . "\n";
}
}
foreach my $testcase ( @$testcases_array_ref )
{
bless($testcase,"Bugzilla::Testopia::XmlTestCase");
$testcase->debug_display();
}
}
sub error()
{
my ($self, $message) = @_;
print STDERR $message . "\n";
$self->parse_error("TRUE");
}
sub parse()
{
my ($self, $xml) = @_;
my $twig = XML::Twig->new();
$twig->parse($xml);
my $root = $twig->root;
my $attachments_array_ref = $self->attachments;
my $categories_array_ref = $self->categories;
my $testplans_array_ref = $self->testplans;
my $testcases_array_ref = $self->testcases;
foreach my $twig_category ($root->children('category'))
{
my $product = new Bugzilla::Product({name => $twig_category->field('product')});
if ( ! $product )
{
$self->error("Cannot find product '" . $twig_category->field('product') . "' for category '" . $twig_category->field('name') . "'.");
$self->{"parser_error"} = 1;
next;
}
my $category = new Bugzilla::Testopia::Category
({
name => $twig_category->field('name'),
product_id => $product->id(),
description => $twig_category->field('description'),
});
push @$categories_array_ref, $category;
}
my $testplan = Bugzilla::Testopia::TestPlan->new({ 'name' => 'dummy' });
my %plantype_ids;
my @temparray = @{$testplan->get_plan_types()};
foreach my $arrayelement (@temparray)
{
my %temphash = %{$arrayelement};
$plantype_ids{$temphash{"name"}} = $temphash{"id"};
}
foreach my $twig_testplan ($root->children('testplan'))
{
my $author = $twig_testplan->field('author');
# Bugzilla::User::match returns a array with a user hash. Fields of the hash needed
# are 'id' and 'login'.
my $author_ref = Bugzilla::User::match($author, 1, 0);
my $author_id = -1;
if ( ! $author_ref->[0] )
{
$self->error("Cannot find author '" . $author . "' in test plan '" . $twig_testplan->field('name') . "'.");
}
else
{
my $author_user = $author_ref->[0];
bless($author_user,"Bugzilla::User");
$author_id = $author_user->id();
}
my $editor = $twig_testplan->field('editor');
my $editor_ref = Bugzilla::User::match($editor, 1, 0);
my $editor_id = -1;
if ( ! $editor_ref->[0] )
{
$self->error("Cannot find editor '" . $editor . "' in test plan '" . $twig_testplan->field('name') . "'.");
}
else
{
my $editor_user = $editor_ref->[0];
bless($editor_user,"Bugzilla::User");
$editor_id = $editor_user->id();
}
$testplan = Bugzilla::Testopia::TestPlan->new({
'name' => $twig_testplan->field('name'),
'product_id' => Bugzilla::Testopia::TestPlan::lookup_product_by_name($twig_testplan->field('product')),
'default_product_version' => $twig_testplan->field('productversion'),
'type_id' => $plantype_ids{$twig_testplan->field('type')},
'text' => $twig_testplan->field('document'),
'author_id' => $author_id,
'editor_id' => $editor_id,
'isactive' => $twig_testplan->field('archive'),
'creation_date' => $twig_testplan->field('created')
});
push @$testplans_array_ref, $testplan;
my @tags = $twig_testplan->children('tag');
foreach my $twig_tag (@tags)
{
push @{$self->tags}, $twig_tag->text();
}
my @attachments = $twig_testplan->children('attachment');
foreach my $twig_attachments (@attachments)
{
my $attachment = Bugzilla::Testopia::Attachment->new({
'description' => $twig_attachments->field('description'),
'filename' => $twig_attachments->field('filename'),
'submitter_id' => $twig_attachments->field('submitter'),
'mime_type' => $twig_attachments->field('mimetype'),
'creation_ts' => $twig_attachments->field('created'),
'data' => $twig_attachments->field('data')
});
push @$attachments_array_ref, $attachment;
#$testplan->add_tag($tag->id());
}
}
my $testcase = Bugzilla::Testopia::TestCase->new({ 'name' => 'dummy' });
my %priority_ids;
@temparray = @{$testcase->get_priority_list()};
foreach my $arrayelement (@temparray)
{
my %temphash = %{$arrayelement};
my $longname = $temphash{"name"};
# The long name. "P1 - Urgent"
$priority_ids{$longname} = $temphash{"id"};
# The short name. "P1"
my $shortname = $longname;
$shortname =~ s/ - .*//;
$priority_ids{$shortname} = $temphash{"id"} if ( $longname ne $shortname );
}
foreach my $twig_testcase ($root->children('testcase'))
{
my $author = $twig_testcase->field('author');
# Bugzilla::User::match returns a array with a user hash. Fields of the hash needed
# are 'id' and 'login'.
my $author_ref = Bugzilla::User::match($author, 1, 0);
my $author_id = -1;
if ( ! $author_ref->[0] )
{
$self->error("Cannot find author '" . $author . "' in test case '" . $twig_testcase->field('summary') . "'.");
}
else
{
my $author_user = $author_ref->[0];
bless($author_user,"Bugzilla::User");
$author_id = $author_user->id();
}
my $tester = $twig_testcase->field('defaulttester');
# Bugzilla::User::match returns a array with a user hash. Fields of the hash needed
# are 'id' and 'login'.
my $tester_ref = Bugzilla::User::match($tester, 1, 0);
my $tester_id = -1;
if ( ! $tester_ref->[0] )
{
$self->error("Cannot find default tester '" . $tester . "' in test case '" . $twig_testcase->field('summary') . "'.");
}
else
{
my $tester_user = $tester_ref->[0];
bless($tester_user,"Bugzilla::User");
$tester_id = $tester_user->id();
}
my $status_id = Bugzilla::Testopia::TestCase::lookup_status_by_name($twig_testcase->field('status'));
$self->error("Cannot find status '" . $twig_testcase->field('status') . "' in test case '" . $twig_testcase->field('summary') . "'.") if ( ! defined($status_id) );
my $xml_testcase = new Bugzilla::Testopia::XmlTestCase;
$xml_testcase->testcase(Bugzilla::Testopia::TestCase->new({
'action' => $twig_testcase->field('action'),
'alias' => $twig_testcase->field('alias') || undef,
'arguments' => $twig_testcase->field('arguments'),
'author_id' => $author_id,
#TODO: Blocks
'blocks' => undef,
'case_status_id' => $status_id,
'category_id' => undef,
'creation_date' => $twig_testcase->field('created'),
'default_tester_id' => $tester_id,
#TODO: Depends On
'dependson' => undef,
'effect' => $twig_testcase->field('effect'),
'expectedresults' => $twig_testcase->field('expectedresults'),
'isautomated' => $twig_testcase->field('isautomated'),
'plans' => undef,
'priority_id' => $priority_ids{$twig_testcase->field('priority')},
'requirement' => $twig_testcase->field('requirement'),
'script' => $twig_testcase->field('script'),
'summary' => $twig_testcase->field('summary'),
}));
# Action field is html format.
my $action = $twig_testcase->field('action');
$action =~ s/\n/<br>/g;
$xml_testcase->action($action);
$xml_testcase->category($twig_testcase->field('category'));
# Expectedresults field is html format.
my $expectedresults = $twig_testcase->field('expectedresults');
$expectedresults =~ s/\n/<br>/g;
$xml_testcase->expectedresults($expectedresults);
push @$testcases_array_ref, $xml_testcase;
my @tags = $twig_testcase->children('tag');
foreach my $twig_tag (@tags)
{
$xml_testcase->add_tag($twig_tag->text());
}
#my @components;
#foreach my $id (@comps){
# detaint_natural($id);
# validate_selection($id, 'id', 'components');
# push @components, $id;
#}
#$case->add_component($_) foreach (@components);
}
#TODO Verfication of data.
#Test cases require a category or store will fail.
# Don't really care about the value of parse_error. If it has been defined then a error occurred
# parsing the XML.
if ( ! defined $self->parse_error )
{
# $self->debug_display();
my @testplanarray;
foreach my $testplan ( @{$self->testplans} )
{
my $plan_id = $testplan->store();
$testplan->{'plan_id'} = $plan_id;
foreach my $asciitag ( @{$self->tags} )
{
my $classtag = Bugzilla::Testopia::TestTag->new({'tag_name' => $asciitag});
my $tagid = $classtag->store;
$testplan->{'tag_id'} = $tagid;
$testplan->add_tag($tagid);
}
push @testplanarray, $testplan;
}
foreach my $testcase ( @{$self->testcases} )
{
bless($testcase,"Bugzilla::Testopia::XmlTestCase");
my $result = $testcase->store($testplan->{'author_id'},@testplanarray);
if ( $result ne "" )
{
$self->error($result);
}
}
}
$twig->purge;
}
=head1 TODO
Use Bugzilla::Product and Version in 2.22
=head1 SEE ALSO
Testopia::(TestRun, TestCase, Category, Build, Evnironment)
=head1 AUTHOR
David Koenig <dkoenig@novell.com>
=cut
1;