From 8ec8da0491ad89604700b3e29a227966f6d84ba1 Mon Sep 17 00:00:00 2001 From: Perl Tidy Date: Wed, 5 Dec 2018 15:38:52 -0500 Subject: no bug - reformat all the code using the new perltidy rules --- xt/lib/Bugzilla/Test/Search.pm | 1492 +++++++++++++++++++++------------------- 1 file changed, 769 insertions(+), 723 deletions(-) (limited to 'xt/lib/Bugzilla/Test/Search.pm') diff --git a/xt/lib/Bugzilla/Test/Search.pm b/xt/lib/Bugzilla/Test/Search.pm index 2666455e8..b1651916e 100644 --- a/xt/lib/Bugzilla/Test/Search.pm +++ b/xt/lib/Bugzilla/Test/Search.pm @@ -73,8 +73,8 @@ use Scalar::Util qw(blessed); ############### sub new { - my ($class, $options) = @_; - return bless { options => $options }, $class; + my ($class, $options) = @_; + return bless {options => $options}, $class; } ############# @@ -82,198 +82,212 @@ sub new { ############# sub options { return $_[0]->{options} } -sub option { return $_[0]->{options}->{$_[1]} } +sub option { return $_[0]->{options}->{$_[1]} } sub num_tests { - my ($self) = @_; - my @top_operators = $self->top_level_operators; - my @all_operators = $self->all_operators; - my $top_operator_tests = $self->_total_operator_tests(\@top_operators); - my $all_operator_tests = $self->_total_operator_tests(\@all_operators); - - my @fields = $self->all_fields; - - # Basically, we run TESTS_PER_RUN tests for each field/operator combination. - my $top_combinations = $top_operator_tests * scalar(@fields); - my $all_combinations = $all_operator_tests * scalar(@fields); - # But we also have ORs, for which we run combinations^2 tests. - my $join_tests = $self->option('long') - ? ($top_combinations * $all_combinations) : 0; - # And AND tests, which means we run 2x $join_tests; - $join_tests = $join_tests * 2; - # Also, because of NOT tests and Normal tests, we run 3x $top_combinations. - my $basic_tests = $top_combinations * 3; - my $operator_field_tests = ($basic_tests + $join_tests) * TESTS_PER_RUN; - - # Then we test each field/operator combination for SQL injection. - my @injection_values = INJECTION_TESTS; - my $sql_injection_tests = scalar(@fields) * scalar(@top_operators) - * scalar(@injection_values) * NUM_SEARCH_TESTS; - - # This @{ [] } thing is the only reasonable way to get a count out of a - # constant array. - my $special_tests = scalar(@{ [SPECIAL_PARAM_TESTS, CUSTOM_SEARCH_TESTS] }) - * TESTS_PER_RUN; - - return $operator_field_tests + $sql_injection_tests + $special_tests; + my ($self) = @_; + my @top_operators = $self->top_level_operators; + my @all_operators = $self->all_operators; + my $top_operator_tests = $self->_total_operator_tests(\@top_operators); + my $all_operator_tests = $self->_total_operator_tests(\@all_operators); + + my @fields = $self->all_fields; + + # Basically, we run TESTS_PER_RUN tests for each field/operator combination. + my $top_combinations = $top_operator_tests * scalar(@fields); + my $all_combinations = $all_operator_tests * scalar(@fields); + + # But we also have ORs, for which we run combinations^2 tests. + my $join_tests + = $self->option('long') ? ($top_combinations * $all_combinations) : 0; + + # And AND tests, which means we run 2x $join_tests; + $join_tests = $join_tests * 2; + + # Also, because of NOT tests and Normal tests, we run 3x $top_combinations. + my $basic_tests = $top_combinations * 3; + my $operator_field_tests = ($basic_tests + $join_tests) * TESTS_PER_RUN; + + # Then we test each field/operator combination for SQL injection. + my @injection_values = INJECTION_TESTS; + my $sql_injection_tests + = scalar(@fields) + * scalar(@top_operators) + * scalar(@injection_values) + * NUM_SEARCH_TESTS; + + # This @{ [] } thing is the only reasonable way to get a count out of a + # constant array. + my $special_tests + = scalar(@{[SPECIAL_PARAM_TESTS, CUSTOM_SEARCH_TESTS]}) * TESTS_PER_RUN; + + return $operator_field_tests + $sql_injection_tests + $special_tests; } sub _total_operator_tests { - my ($self, $operators) = @_; - - # Some operators have more than one test. Find those ones and add - # them to the total operator tests - my $extra_operator_tests; - foreach my $operator (@$operators) { - my $tests = TESTS->{$operator}; - next if !$tests; - my $extra_num = scalar(@$tests) - 1; - $extra_operator_tests += $extra_num; - } - return scalar(@$operators) + $extra_operator_tests; + my ($self, $operators) = @_; + + # Some operators have more than one test. Find those ones and add + # them to the total operator tests + my $extra_operator_tests; + foreach my $operator (@$operators) { + my $tests = TESTS->{$operator}; + next if !$tests; + my $extra_num = scalar(@$tests) - 1; + $extra_operator_tests += $extra_num; + } + return scalar(@$operators) + $extra_operator_tests; } sub all_operators { - my ($self) = @_; - if (not $self->{all_operators}) { - - my @operators; - if (my $limit_operators = $self->option('operators')) { - @operators = split(',', $limit_operators); - } - else { - @operators = sort (keys %{ Bugzilla::Search::OPERATORS() }); - } - # "substr" is just a backwards-compatibility operator, same as "substring". - @operators = grep { $_ ne 'substr' } @operators; - $self->{all_operators} = \@operators; + my ($self) = @_; + if (not $self->{all_operators}) { + + my @operators; + if (my $limit_operators = $self->option('operators')) { + @operators = split(',', $limit_operators); + } + else { + @operators = sort (keys %{Bugzilla::Search::OPERATORS()}); } - return @{ $self->{all_operators} }; + + # "substr" is just a backwards-compatibility operator, same as "substring". + @operators = grep { $_ ne 'substr' } @operators; + $self->{all_operators} = \@operators; + } + return @{$self->{all_operators}}; } sub all_fields { - my $self = shift; - if (not $self->{all_fields}) { - $self->_create_custom_fields(); - my @fields = @{ Bugzilla->fields }; - @fields = sort { $a->name cmp $b->name } @fields; - $self->{all_fields} = \@fields; - } - return @{ $self->{all_fields} }; + my $self = shift; + if (not $self->{all_fields}) { + $self->_create_custom_fields(); + my @fields = @{Bugzilla->fields}; + @fields = sort { $a->name cmp $b->name } @fields; + $self->{all_fields} = \@fields; + } + return @{$self->{all_fields}}; } sub top_level_operators { - my ($self) = @_; - if (!$self->{top_level_operators}) { - my @operators; - my $limit_top = $self->option('top-operators'); - if ($limit_top) { - @operators = split(',', $limit_top); - } - else { - @operators = $self->all_operators; - } - $self->{top_level_operators} = \@operators; + my ($self) = @_; + if (!$self->{top_level_operators}) { + my @operators; + my $limit_top = $self->option('top-operators'); + if ($limit_top) { + @operators = split(',', $limit_top); } - return @{ $self->{top_level_operators} }; + else { + @operators = $self->all_operators; + } + $self->{top_level_operators} = \@operators; + } + return @{$self->{top_level_operators}}; } sub text_fields { - my ($self) = @_; - my @text_fields = grep { $_->type == FIELD_TYPE_TEXTAREA - or $_->type == FIELD_TYPE_FREETEXT } $self->all_fields; - @text_fields = map { $_->name } @text_fields; - push(@text_fields, qw(short_desc status_whiteboard bug_file_loc see_also)); - return @text_fields; + my ($self) = @_; + my @text_fields + = grep { $_->type == FIELD_TYPE_TEXTAREA or $_->type == FIELD_TYPE_FREETEXT } + $self->all_fields; + @text_fields = map { $_->name } @text_fields; + push(@text_fields, qw(short_desc status_whiteboard bug_file_loc see_also)); + return @text_fields; } sub bugs { - my $self = shift; - $self->{bugs} ||= [map { $self->_create_one_bug($_) } (1..NUM_BUGS)]; - return @{ $self->{bugs} }; + my $self = shift; + $self->{bugs} ||= [map { $self->_create_one_bug($_) } (1 .. NUM_BUGS)]; + return @{$self->{bugs}}; } # Get a numbered bug. sub bug { - my ($self, $number) = @_; - return ($self->bugs)[$number - 1]; + my ($self, $number) = @_; + return ($self->bugs)[$number - 1]; } sub admin { - my $self = shift; - if (!$self->{admin_user}) { - my $admin = create_user("admin"); - Bugzilla::Install::make_admin($admin); - $self->{admin_user} = $admin; - } - # We send back a fresh object every time, to make sure that group - # memberships are always up-to-date. - return new Bugzilla::User($self->{admin_user}->id); + my $self = shift; + if (!$self->{admin_user}) { + my $admin = create_user("admin"); + Bugzilla::Install::make_admin($admin); + $self->{admin_user} = $admin; + } + + # We send back a fresh object every time, to make sure that group + # memberships are always up-to-date. + return new Bugzilla::User($self->{admin_user}->id); } sub nobody { - my $self = shift; - $self->{nobody} ||= Bugzilla::Group->create({ name => "nobody-" . random(), - description => "Nobody", isbuggroup => 1 }); - return $self->{nobody}; + my $self = shift; + $self->{nobody} + ||= Bugzilla::Group->create({ + name => "nobody-" . random(), description => "Nobody", isbuggroup => 1 + }); + return $self->{nobody}; } + sub everybody { - my ($self) = @_; - $self->{everybody} ||= create_group('To The Limit'); - return $self->{everybody}; + my ($self) = @_; + $self->{everybody} ||= create_group('To The Limit'); + return $self->{everybody}; } sub bug_create_value { - my ($self, $number, $field) = @_; - $field = $field->name if blessed($field); - if ($number == 6 and $field ne 'alias') { - $number = 1; - } - my $extra_values = $self->_extra_bug_create_values->{$number}; - if (exists $extra_values->{$field}) { - return $extra_values->{$field}; - } - return $self->_bug_create_values->{$number}->{$field}; + my ($self, $number, $field) = @_; + $field = $field->name if blessed($field); + if ($number == 6 and $field ne 'alias') { + $number = 1; + } + my $extra_values = $self->_extra_bug_create_values->{$number}; + if (exists $extra_values->{$field}) { + return $extra_values->{$field}; + } + return $self->_bug_create_values->{$number}->{$field}; } + sub bug_update_value { - my ($self, $number, $field) = @_; - $field = $field->name if blessed($field); - if ($number == 6 and $field ne 'alias') { - $number = 1; - } - return $self->_bug_update_values->{$number}->{$field}; + my ($self, $number, $field) = @_; + $field = $field->name if blessed($field); + if ($number == 6 and $field ne 'alias') { + $number = 1; + } + return $self->_bug_update_values->{$number}->{$field}; } # Values used to create the bugs. sub _bug_create_values { - my $self = shift; - return $self->{bug_create_values} if $self->{bug_create_values}; - my %values; - foreach my $number (1..NUM_BUGS) { - $values{$number} = $self->_create_field_values($number, 'for create'); - } - $self->{bug_create_values} = \%values; - return $self->{bug_create_values}; + my $self = shift; + return $self->{bug_create_values} if $self->{bug_create_values}; + my %values; + foreach my $number (1 .. NUM_BUGS) { + $values{$number} = $self->_create_field_values($number, 'for create'); + } + $self->{bug_create_values} = \%values; + return $self->{bug_create_values}; } + # Values as they existed on the bug, at creation time. Used by the # changedfrom tests. sub _extra_bug_create_values { - my $self = shift; - $self->{extra_bug_create_values} ||= { map { $_ => {} } (1..NUM_BUGS) }; - return $self->{extra_bug_create_values}; + my $self = shift; + $self->{extra_bug_create_values} ||= {map { $_ => {} } (1 .. NUM_BUGS)}; + return $self->{extra_bug_create_values}; } # Values used to update the bugs after they are created. sub _bug_update_values { - my $self = shift; - return $self->{bug_update_values} if $self->{bug_update_values}; - my %values; - foreach my $number (1..NUM_BUGS) { - $values{$number} = $self->_create_field_values($number); - } - $self->{bug_update_values} = \%values; - return $self->{bug_update_values}; + my $self = shift; + return $self->{bug_update_values} if $self->{bug_update_values}; + my %values; + foreach my $number (1 .. NUM_BUGS) { + $values{$number} = $self->_create_field_values($number); + } + $self->{bug_update_values} = \%values; + return $self->{bug_update_values}; } ############################## @@ -281,8 +295,8 @@ sub _bug_update_values { ############################## sub random { - $_[0] ||= FIELD_SIZE; - generate_random_password(@_); + $_[0] ||= FIELD_SIZE; + generate_random_password(@_); } # We need to use a custom timestamp for each create() and update(), @@ -290,53 +304,55 @@ sub random { # for the entire transaction, and we need each created bug to have # its own creation_ts and delta_ts. sub timestamp { - my ($day, $second) = @_; - return DateTime->new( - year => 2037, - month => 1, - day => $day, - hour => 12, - minute => $second, - second => 0, - # We make it floating because the timezone doesn't matter for our uses, - # and we want totally consistent behavior across all possible machines. - time_zone => 'floating', - ); + my ($day, $second) = @_; + return DateTime->new( + year => 2037, + month => 1, + day => $day, + hour => 12, + minute => $second, + second => 0, + + # We make it floating because the timezone doesn't matter for our uses, + # and we want totally consistent behavior across all possible machines. + time_zone => 'floating', + ); } sub create_keyword { - my ($number) = @_; - return Bugzilla::Keyword->create({ - name => "$number-keyword-" . random(), - description => "Keyword $number" }); + my ($number) = @_; + return Bugzilla::Keyword->create({ + name => "$number-keyword-" . random(), description => "Keyword $number" + }); } sub create_user { - my ($prefix) = @_; - my $user_name = $prefix . '-' . random(15) . "@" . random(12) - . "." . random(3); - my $user_realname = $prefix . '-' . random(); - my $user = Bugzilla::User->create({ - login_name => $user_name, - realname => $user_realname, - cryptpassword => '*', + my ($prefix) = @_; + my $user_name = $prefix . '-' . random(15) . "@" . random(12) . "." . random(3); + my $user_realname = $prefix . '-' . random(); + my $user + = Bugzilla::User->create({ + login_name => $user_name, realname => $user_realname, cryptpassword => '*', }); - return $user; + return $user; } sub create_group { - my ($prefix) = @_; - return Bugzilla::Group->create({ - name => "$prefix-group-" . random(), description => "Everybody $prefix", - userregexp => '.*', isbuggroup => 1 }); + my ($prefix) = @_; + return Bugzilla::Group->create({ + name => "$prefix-group-" . random(), + description => "Everybody $prefix", + userregexp => '.*', + isbuggroup => 1 + }); } sub create_legal_value { - my ($field, $number) = @_; - my $type = Bugzilla::Field::Choice->type($field); - my $field_name = $field->name; - return $type->create({ value => "$number-$field_name-" . random(), - is_open => 0 }); + my ($field, $number) = @_; + my $type = Bugzilla::Field::Choice->type($field); + my $field_name = $field->name; + return $type->create({value => "$number-$field_name-" . random(), is_open => 0 + }); } ######################### @@ -344,22 +360,22 @@ sub create_legal_value { ######################### sub _create_custom_fields { - my ($self) = @_; - return if !$self->option('add-custom-fields'); - - while (my ($type, $name) = each %{ CUSTOM_FIELDS() }) { - my $exists = new Bugzilla::Field({ name => $name }); - next if $exists; - Bugzilla::Field->create({ - name => $name, - type => $type, - description => "Search Test Field $name", - enter_bug => 1, - custom => 1, - buglist => 1, - is_mandatory => 0, - }); - } + my ($self) = @_; + return if !$self->option('add-custom-fields'); + + while (my ($type, $name) = each %{CUSTOM_FIELDS()}) { + my $exists = new Bugzilla::Field({name => $name}); + next if $exists; + Bugzilla::Field->create({ + name => $name, + type => $type, + description => "Search Test Field $name", + enter_bug => 1, + custom => 1, + buglist => 1, + is_mandatory => 0, + }); + } } ######################## @@ -367,221 +383,232 @@ sub _create_custom_fields { ######################## sub _create_field_values { - my ($self, $number, $for_create) = @_; - my $dbh = Bugzilla->dbh; - - Bugzilla->set_user($self->admin); - - my @selects = grep { $_->is_select } $self->all_fields; - my %values; - foreach my $field (@selects) { - next if $field->is_abnormal; - $values{$field->name} = create_legal_value($field, $number)->name; + my ($self, $number, $for_create) = @_; + my $dbh = Bugzilla->dbh; + + Bugzilla->set_user($self->admin); + + my @selects = grep { $_->is_select } $self->all_fields; + my %values; + foreach my $field (@selects) { + next if $field->is_abnormal; + $values{$field->name} = create_legal_value($field, $number)->name; + } + + my $group = create_group($number); + $values{groups} = [$group->name]; + + $values{'keywords'} = create_keyword($number)->name; + + foreach my $field (qw(assigned_to qa_contact reporter cc)) { + $values{$field} = create_user("$number-$field")->login; + } + + my $classification = Bugzilla::Classification->create( + {name => "$number-classification-" . random()}); + $classification = $classification->name; + + my $version = "$number-version-" . random(); + my $milestone = "$number-tm-" . random(15); + my $product = Bugzilla::Product->create({ + name => "$number-product-" . random(), + description => 'Created by t/search.t', + defaultmilestone => $milestone, + classification => $classification, + version => $version, + allows_unconfirmed => 1, + }); + foreach my $item ($group, $self->nobody) { + $product->set_group_controls($item, + {membercontrol => CONTROLMAPSHOWN, othercontrol => CONTROLMAPNA}); + } + + # $product->update() is called lower down. + my $component = Bugzilla::Component->create({ + product => $product, + name => "$number-component-" . random(), + initialowner => create_user("$number-defaultowner")->login, + initialqacontact => create_user("$number-defaultqa")->login, + initial_cc => [create_user("$number-initcc")->login], + description => "Component $number" + }); + + $values{'product'} = $product->name; + $values{'component'} = $component->name; + $values{'target_milestone'} = $milestone; + $values{'version'} = $version; + + foreach my $field ($self->text_fields) { + + # We don't add a - after $field for the text fields, because + # if we do, fulltext searching for short_desc pulls out + # "short_desc" as a word and matches it in every bug. + my $value = "$number-$field" . random(); + if ($field eq 'bug_file_loc' or $field eq 'see_also') { + $value = "http://$value-" . random(3) . "/show_bug.cgi?id=$number"; } - - my $group = create_group($number); - $values{groups} = [$group->name]; - - $values{'keywords'} = create_keyword($number)->name; - - foreach my $field (qw(assigned_to qa_contact reporter cc)) { - $values{$field} = create_user("$number-$field")->login; + $values{$field} = $value; + } + $values{'tag'} = ["$number-tag-" . random()]; + + my @date_fields = grep { $_->type == FIELD_TYPE_DATETIME } $self->all_fields; + foreach my $field (@date_fields) { + + # We use 03 as the month because that differs from our creation_ts, + # delta_ts, and deadline. (It's nice to have recognizable values + # for each field when debugging.) + my $second = $for_create ? $number : $number + 1; + $values{$field->name} = "2037-03-0$number 12:34:0$second"; + } + + $values{alias} = "$number-alias-" . random(12); + + # Prefixing the original comment with "description" makes the + # lesserthan and greaterthan tests behave predictably. + my $comm_prefix = $for_create ? "description-" : ''; + $values{comment} = "$comm_prefix$number-comment-" . random() . ' ' . random(); + + my @flags; + my $setter = create_user("$number-setters.login_name"); + my $requestee = create_user("$number-requestees.login_name"); + $values{set_flags} = _create_flags($number, $setter, $requestee); + + my $month = $for_create ? "12" : "02"; + $values{'deadline'} = "2037-$month-0$number"; + my $estimate_times = $for_create ? 10 : 1; + $values{estimated_time} = $estimate_times * $number; + + $values{attachment} = _get_attach_values($number, $for_create); + + # Some things only happen on the first bug. + if ($number == 1) { + + # We use 6 as the prefix for the extra values, because bug 6's values + # don't otherwise get used (since bug 6 is created as a clone of + # bug 1). This also makes sure that our greaterthan/lessthan + # tests work properly. + my $extra_group = create_group(6); + $product->set_group_controls($extra_group, + {membercontrol => CONTROLMAPSHOWN, othercontrol => CONTROLMAPNA}); + $values{groups} = [$values{groups}->[0], $extra_group->name]; + my $extra_keyword = create_keyword(6); + $values{keywords} = [$values{keywords}, $extra_keyword->name]; + my $extra_cc = create_user("6-cc"); + $values{cc} = [$values{cc}, $extra_cc->login]; + my @multi_selects + = grep { $_->type == FIELD_TYPE_MULTI_SELECT } $self->all_fields; + + foreach my $field (@multi_selects) { + my $new_value = create_legal_value($field, 6); + my $name = $field->name; + $values{$name} = [$values{$name}, $new_value->name]; } - - my $classification = Bugzilla::Classification->create( - { name => "$number-classification-" . random() }); - $classification = $classification->name; - - my $version = "$number-version-" . random(); - my $milestone = "$number-tm-" . random(15); - my $product = Bugzilla::Product->create({ - name => "$number-product-" . random(), - description => 'Created by t/search.t', - defaultmilestone => $milestone, - classification => $classification, - version => $version, - allows_unconfirmed => 1, - }); - foreach my $item ($group, $self->nobody) { - $product->set_group_controls($item, - { membercontrol => CONTROLMAPSHOWN, - othercontrol => CONTROLMAPNA }); - } - # $product->update() is called lower down. - my $component = Bugzilla::Component->create({ - product => $product, name => "$number-component-" . random(), - initialowner => create_user("$number-defaultowner")->login, - initialqacontact => create_user("$number-defaultqa")->login, - initial_cc => [create_user("$number-initcc")->login], - description => "Component $number" }); - - $values{'product'} = $product->name; - $values{'component'} = $component->name; - $values{'target_milestone'} = $milestone; - $values{'version'} = $version; - - foreach my $field ($self->text_fields) { - # We don't add a - after $field for the text fields, because - # if we do, fulltext searching for short_desc pulls out - # "short_desc" as a word and matches it in every bug. - my $value = "$number-$field" . random(); - if ($field eq 'bug_file_loc' or $field eq 'see_also') { - $value = "http://$value-" . random(3) - . "/show_bug.cgi?id=$number"; - } - $values{$field} = $value; + push(@{$values{'tag'}}, "6-tag-" . random()); + } + + # On bug 5, any field that *can* be left empty, *is* left empty. + if ($number == 5) { + my @set_fields + = grep { $_->type == FIELD_TYPE_SINGLE_SELECT } $self->all_fields; + @set_fields = map { $_->name } @set_fields; + push(@set_fields, qw(short_desc version reporter)); + foreach my $key (keys %values) { + delete $values{$key} unless grep { $_ eq $key } @set_fields; } - $values{'tag'} = ["$number-tag-" . random()]; - - my @date_fields = grep { $_->type == FIELD_TYPE_DATETIME } $self->all_fields; - foreach my $field (@date_fields) { - # We use 03 as the month because that differs from our creation_ts, - # delta_ts, and deadline. (It's nice to have recognizable values - # for each field when debugging.) - my $second = $for_create ? $number : $number + 1; - $values{$field->name} = "2037-03-0$number 12:34:0$second"; - } - - $values{alias} = "$number-alias-" . random(12); + } - # Prefixing the original comment with "description" makes the - # lesserthan and greaterthan tests behave predictably. - my $comm_prefix = $for_create ? "description-" : ''; - $values{comment} = "$comm_prefix$number-comment-" . random() - . ' ' . random(); + $product->update(); - my @flags; - my $setter = create_user("$number-setters.login_name"); - my $requestee = create_user("$number-requestees.login_name"); - $values{set_flags} = _create_flags($number, $setter, $requestee); - - my $month = $for_create ? "12" : "02"; - $values{'deadline'} = "2037-$month-0$number"; - my $estimate_times = $for_create ? 10 : 1; - $values{estimated_time} = $estimate_times * $number; - - $values{attachment} = _get_attach_values($number, $for_create); - - # Some things only happen on the first bug. - if ($number == 1) { - # We use 6 as the prefix for the extra values, because bug 6's values - # don't otherwise get used (since bug 6 is created as a clone of - # bug 1). This also makes sure that our greaterthan/lessthan - # tests work properly. - my $extra_group = create_group(6); - $product->set_group_controls($extra_group, - { membercontrol => CONTROLMAPSHOWN, - othercontrol => CONTROLMAPNA }); - $values{groups} = [$values{groups}->[0], $extra_group->name]; - my $extra_keyword = create_keyword(6); - $values{keywords} = [$values{keywords}, $extra_keyword->name]; - my $extra_cc = create_user("6-cc"); - $values{cc} = [$values{cc}, $extra_cc->login]; - my @multi_selects = grep { $_->type == FIELD_TYPE_MULTI_SELECT } - $self->all_fields; - foreach my $field (@multi_selects) { - my $new_value = create_legal_value($field, 6); - my $name = $field->name; - $values{$name} = [$values{$name}, $new_value->name]; - } - push(@{ $values{'tag'} }, "6-tag-" . random()); - } - - # On bug 5, any field that *can* be left empty, *is* left empty. - if ($number == 5) { - my @set_fields = grep { $_->type == FIELD_TYPE_SINGLE_SELECT } - $self->all_fields; - @set_fields = map { $_->name } @set_fields; - push(@set_fields, qw(short_desc version reporter)); - foreach my $key (keys %values) { - delete $values{$key} unless grep { $_ eq $key } @set_fields; - } - } - - $product->update(); - - return \%values; + return \%values; } # Flags sub _create_flags { - my ($number, $setter, $requestee) = @_; + my ($number, $setter, $requestee) = @_; - my $flagtypes = _create_flagtypes($number); + my $flagtypes = _create_flagtypes($number); - my %flags; - foreach my $type (qw(a b)) { - $flags{$type} = _get_flag_values(@_, $flagtypes->{$type}); - } - return \%flags; + my %flags; + foreach my $type (qw(a b)) { + $flags{$type} = _get_flag_values(@_, $flagtypes->{$type}); + } + return \%flags; } sub _create_flagtypes { - my ($number) = @_; - my $dbh = Bugzilla->dbh; - my $name = "$number-flag-" . random(); - my $desc = "FlagType $number"; - - my %flagtypes; - foreach my $target (qw(a b)) { - $dbh->do("INSERT INTO flagtypes + my ($number) = @_; + my $dbh = Bugzilla->dbh; + my $name = "$number-flag-" . random(); + my $desc = "FlagType $number"; + + my %flagtypes; + foreach my $target (qw(a b)) { + $dbh->do( + "INSERT INTO flagtypes (name, description, target_type, is_requestable, is_requesteeble, is_multiplicable, cc_list) - VALUES (?,?,?,1,1,1,'')", - undef, $name, $desc, $target); - my $id = $dbh->bz_last_key('flagtypes', 'id'); - $dbh->do('INSERT INTO flaginclusions (type_id) VALUES (?)', - undef, $id); - my $flagtype = new Bugzilla::FlagType($id); - $flagtypes{$target} = $flagtype; - } - return \%flagtypes; + VALUES (?,?,?,1,1,1,'')", undef, $name, $desc, $target + ); + my $id = $dbh->bz_last_key('flagtypes', 'id'); + $dbh->do('INSERT INTO flaginclusions (type_id) VALUES (?)', undef, $id); + my $flagtype = new Bugzilla::FlagType($id); + $flagtypes{$target} = $flagtype; + } + return \%flagtypes; } sub _get_flag_values { - my ($number, $setter, $requestee, $flagtype) = @_; - - my @set_flags; - if ($number <= 2) { - foreach my $value (qw(? - + ?)) { - my $flag = { type_id => $flagtype->id, status => $value, - setter => $setter, flagtype => $flagtype }; - push(@set_flags, $flag); - } - $set_flags[0]->{requestee} = $requestee->login; - } - else { - @set_flags = ({ type_id => $flagtype->id, status => '+', - setter => $setter, flagtype => $flagtype }); + my ($number, $setter, $requestee, $flagtype) = @_; + + my @set_flags; + if ($number <= 2) { + foreach my $value (qw(? - + ?)) { + my $flag = { + type_id => $flagtype->id, + status => $value, + setter => $setter, + flagtype => $flagtype + }; + push(@set_flags, $flag); } - return \@set_flags; + $set_flags[0]->{requestee} = $requestee->login; + } + else { + @set_flags = ({ + type_id => $flagtype->id, + status => '+', + setter => $setter, + flagtype => $flagtype + }); + } + return \@set_flags; } # Attachments sub _get_attach_values { - my ($number, $for_create) = @_; - - my $boolean = $number == 1 ? 1 : 0; - if ($for_create) { - $boolean = !$boolean ? 1 : 0; - } - my $ispatch = $for_create ? 'ispatch' : 'is_patch'; - my $isobsolete = $for_create ? 'isobsolete' : 'is_obsolete'; - my $isprivate = $for_create ? 'isprivate' : 'is_private'; - my $mimetype = $for_create ? 'mimetype' : 'content_type'; - - my %values = ( - description => "$number-attach_desc-" . random(), - filename => "$number-filename-" . random(), - $ispatch => $boolean, - $isobsolete => $boolean, - $isprivate => $boolean, - $mimetype => "text/x-$number-" . random(), - ); - if ($for_create) { - $values{data} = "$number-data-" . random() . random(); - } - return \%values; + my ($number, $for_create) = @_; + + my $boolean = $number == 1 ? 1 : 0; + if ($for_create) { + $boolean = !$boolean ? 1 : 0; + } + my $ispatch = $for_create ? 'ispatch' : 'is_patch'; + my $isobsolete = $for_create ? 'isobsolete' : 'is_obsolete'; + my $isprivate = $for_create ? 'isprivate' : 'is_private'; + my $mimetype = $for_create ? 'mimetype' : 'content_type'; + + my %values = ( + description => "$number-attach_desc-" . random(), + filename => "$number-filename-" . random(), + $ispatch => $boolean, + $isobsolete => $boolean, + $isprivate => $boolean, + $mimetype => "text/x-$number-" . random(), + ); + if ($for_create) { + $values{data} = "$number-data-" . random() . random(); + } + return \%values; } ################ @@ -589,194 +616,209 @@ sub _get_attach_values { ################ sub _create_one_bug { - my ($self, $number) = @_; - my $dbh = Bugzilla->dbh; + my ($self, $number) = @_; + my $dbh = Bugzilla->dbh; + + # We need bug 6 to have a unique alias that is not a clone of bug 1's, + # so we get the alias separately from the other parameters. + my $alias = $self->bug_create_value($number, 'alias'); + my $update_alias = $self->bug_update_value($number, 'alias'); + + # Otherwise, make bug 6 a clone of bug 1. + my $real_number = $number; + $number = 1 if $number == 6; + + my $reporter = $self->bug_create_value($number, 'reporter'); + Bugzilla->set_user(Bugzilla::User->check($reporter)); + + # We create the bug with one set of values, and then we change it + # to have different values. + my %params = %{$self->_bug_create_values->{$number}}; + $params{alias} = $alias; + + # There are some things in bug_create_values that shouldn't go into + # create(). + delete @params{qw(attachment set_flags tag)}; + + my ($status, $resolution, $see_also) + = delete @params{qw(bug_status resolution see_also)}; + + # All the bugs are created with everconfirmed = 0. + $params{bug_status} = 'UNCONFIRMED'; + my $bug = Bugzilla::Bug->create(\%params); + + # These are necessary for the changedfrom tests. + my $extra_values = $self->_extra_bug_create_values->{$number}; + foreach my $field ( + qw(comments remaining_time percentage_complete + keyword_objects everconfirmed dependson blocked + groups_in classification actual_time) + ) + { + $extra_values->{$field} = $bug->$field; + } + $extra_values->{reporter_accessible} = $number == 1 ? 0 : 1; + $extra_values->{cclist_accessible} = $number == 1 ? 0 : 1; + + if ($number == 5) { + + # Bypass Bugzilla::Bug--we don't want any changes in bugs_activity + # for bug 5. + $dbh->do( + 'UPDATE bugs SET qa_contact = NULL, reporter_accessible = 0, + cclist_accessible = 0 WHERE bug_id = ?', undef, + $bug->id + ); + $dbh->do('DELETE FROM cc WHERE bug_id = ?', undef, $bug->id); + my $ts = '1970-01-01 00:00:00'; + $dbh->do( + 'UPDATE bugs SET creation_ts = ?, delta_ts = ? + WHERE bug_id = ?', undef, $ts, $ts, $bug->id + ); + $dbh->do('UPDATE longdescs SET bug_when = ? WHERE bug_id = ?', + undef, $ts, $bug->id); + $bug->{creation_ts} = $ts; + $extra_values->{see_also} = []; + } + else { + # Manually set the creation_ts so that each bug has a different one. + # + # Also, manually update the resolution and bug_status, because + # we want to see both of them change in bugs_activity, so we + # have to start with values for both (and as of the time when I'm + # writing this test, Bug->create doesn't support setting resolution). + # + # Same for see_also. + my $timestamp = timestamp($number, $number - 1); + my $creation_ts = $timestamp->ymd . ' ' . $timestamp->hms; + $bug->{creation_ts} = $creation_ts; + $dbh->do('UPDATE longdescs SET bug_when = ? WHERE bug_id = ?', + undef, $creation_ts, $bug->id); + $dbh->do( + 'UPDATE bugs SET creation_ts = ?, bug_status = ?, + resolution = ? WHERE bug_id = ?', undef, $creation_ts, $status, + $resolution, $bug->id + ); + $dbh->do('INSERT INTO bug_see_also (bug_id, value, class) VALUES (?,?,?)', + undef, $bug->id, $see_also, 'Bugzilla::BugUrl::Bugzilla'); + $extra_values->{see_also} = $bug->see_also; - # We need bug 6 to have a unique alias that is not a clone of bug 1's, - # so we get the alias separately from the other parameters. - my $alias = $self->bug_create_value($number, 'alias'); - my $update_alias = $self->bug_update_value($number, 'alias'); + # All the tags must be created as the admin user, so that the + # admin user can find them, later. + my $original_user = Bugzilla->user; + Bugzilla->set_user($self->admin); + my $tags = $self->bug_create_value($number, 'tag'); + $bug->add_tag($_) foreach @$tags; + $extra_values->{tags} = $tags; + Bugzilla->set_user($original_user); - # Otherwise, make bug 6 a clone of bug 1. - my $real_number = $number; - $number = 1 if $number == 6; + if ($number == 1) { - my $reporter = $self->bug_create_value($number, 'reporter'); - Bugzilla->set_user(Bugzilla::User->check($reporter)); - - # We create the bug with one set of values, and then we change it - # to have different values. - my %params = %{ $self->_bug_create_values->{$number} }; - $params{alias} = $alias; - - # There are some things in bug_create_values that shouldn't go into - # create(). - delete @params{qw(attachment set_flags tag)}; - - my ($status, $resolution, $see_also) = - delete @params{qw(bug_status resolution see_also)}; - # All the bugs are created with everconfirmed = 0. - $params{bug_status} = 'UNCONFIRMED'; - my $bug = Bugzilla::Bug->create(\%params); - - # These are necessary for the changedfrom tests. - my $extra_values = $self->_extra_bug_create_values->{$number}; - foreach my $field (qw(comments remaining_time percentage_complete - keyword_objects everconfirmed dependson blocked - groups_in classification actual_time)) - { - $extra_values->{$field} = $bug->$field; + # Bug 1 needs to start off with reporter_accessible and + # cclist_accessible being 0, so that when we change them to 1, + # that change shows up in bugs_activity. + $dbh->do( + 'UPDATE bugs SET reporter_accessible = 0, + cclist_accessible = 0 WHERE bug_id = ?', undef, $bug->id + ); + + # Bug 1 gets three comments, so that longdescs.count matches it + # uniquely. The third comment is added in the middle, so that the + # last comment contains all of the important data, like work_time. + $bug->add_comment("1-comment-" . random(100)); } - $extra_values->{reporter_accessible} = $number == 1 ? 0 : 1; - $extra_values->{cclist_accessible} = $number == 1 ? 0 : 1; - - if ($number == 5) { - # Bypass Bugzilla::Bug--we don't want any changes in bugs_activity - # for bug 5. - $dbh->do('UPDATE bugs SET qa_contact = NULL, reporter_accessible = 0, - cclist_accessible = 0 WHERE bug_id = ?', - undef, $bug->id); - $dbh->do('DELETE FROM cc WHERE bug_id = ?', undef, $bug->id); - my $ts = '1970-01-01 00:00:00'; - $dbh->do('UPDATE bugs SET creation_ts = ?, delta_ts = ? - WHERE bug_id = ?', undef, $ts, $ts, $bug->id); - $dbh->do('UPDATE longdescs SET bug_when = ? WHERE bug_id = ?', - undef, $ts, $bug->id); - $bug->{creation_ts} = $ts; - $extra_values->{see_also} = []; + + my %update_params = %{$self->_bug_update_values->{$number}}; + my %reverse_map = reverse %{Bugzilla::Bug->FIELD_MAP}; + foreach my $db_name (keys %reverse_map) { + next if $db_name eq 'comment'; + next if $db_name eq 'status_whiteboard'; + if (exists $update_params{$db_name}) { + my $update_name = $reverse_map{$db_name}; + $update_params{$update_name} = delete $update_params{$db_name}; + } } - else { - # Manually set the creation_ts so that each bug has a different one. - # - # Also, manually update the resolution and bug_status, because - # we want to see both of them change in bugs_activity, so we - # have to start with values for both (and as of the time when I'm - # writing this test, Bug->create doesn't support setting resolution). - # - # Same for see_also. - my $timestamp = timestamp($number, $number - 1); - my $creation_ts = $timestamp->ymd . ' ' . $timestamp->hms; - $bug->{creation_ts} = $creation_ts; - $dbh->do('UPDATE longdescs SET bug_when = ? WHERE bug_id = ?', - undef, $creation_ts, $bug->id); - $dbh->do('UPDATE bugs SET creation_ts = ?, bug_status = ?, - resolution = ? WHERE bug_id = ?', - undef, $creation_ts, $status, $resolution, $bug->id); - $dbh->do('INSERT INTO bug_see_also (bug_id, value, class) VALUES (?,?,?)', - undef, $bug->id, $see_also, 'Bugzilla::BugUrl::Bugzilla'); - $extra_values->{see_also} = $bug->see_also; - - # All the tags must be created as the admin user, so that the - # admin user can find them, later. - my $original_user = Bugzilla->user; - Bugzilla->set_user($self->admin); - my $tags = $self->bug_create_value($number, 'tag'); - $bug->add_tag($_) foreach @$tags; - $extra_values->{tags} = $tags; - Bugzilla->set_user($original_user); - - if ($number == 1) { - # Bug 1 needs to start off with reporter_accessible and - # cclist_accessible being 0, so that when we change them to 1, - # that change shows up in bugs_activity. - $dbh->do('UPDATE bugs SET reporter_accessible = 0, - cclist_accessible = 0 WHERE bug_id = ?', - undef, $bug->id); - # Bug 1 gets three comments, so that longdescs.count matches it - # uniquely. The third comment is added in the middle, so that the - # last comment contains all of the important data, like work_time. - $bug->add_comment("1-comment-" . random(100)); - } - - my %update_params = %{ $self->_bug_update_values->{$number} }; - my %reverse_map = reverse %{ Bugzilla::Bug->FIELD_MAP }; - foreach my $db_name (keys %reverse_map) { - next if $db_name eq 'comment'; - next if $db_name eq 'status_whiteboard'; - if (exists $update_params{$db_name}) { - my $update_name = $reverse_map{$db_name}; - $update_params{$update_name} = delete $update_params{$db_name}; - } - } - - my ($new_status, $new_res) = - delete @update_params{qw(status resolution)}; - # Bypass the status workflow. - $bug->{bug_status} = $new_status; - $bug->{resolution} = $new_res; - $bug->{everconfirmed} = 1 if $number == 1; - - # add/remove/set fields. - $update_params{keywords} = { set => $update_params{keywords} }; - $update_params{groups} = { add => $update_params{groups}, - remove => $bug->groups_in }; - my @cc_remove = map { $_->login } @{ $bug->cc_users }; - my $cc_new = $update_params{cc}; - my @cc_add = ref($cc_new) ? @$cc_new : ($cc_new); - # We make the admin an explicit CC on bug 1 (but not on bug 6), so - # that we can test the %user% pronoun properly. - if ($real_number == 1) { - push(@cc_add, $self->admin->login); - } - $update_params{cc} = { add => \@cc_add, remove => \@cc_remove }; - my $see_also_remove = $bug->see_also; - my $see_also_add = [$update_params{see_also}]; - $update_params{see_also} = { add => $see_also_add, - remove => $see_also_remove }; - $update_params{comment} = { body => $update_params{comment} }; - $update_params{work_time} = $number; - # Setting work_time kills the remaining_time, so we need to - # preserve that. We add 8 because that produces an integer - # percentage_complete for bug 1, which is necessary for - # accurate "equals"-type searching. - $update_params{remaining_time} = $number + 8; - $update_params{reporter_accessible} = $number == 1 ? 1 : 0; - $update_params{cclist_accessible} = $number == 1 ? 1 : 0; - $update_params{alias} = $update_alias; - - $bug->set_all(\%update_params); - my $flags = $self->bug_create_value($number, 'set_flags')->{b}; - $bug->set_flags([], $flags); - $timestamp->set(second => $number); - $bug->update($timestamp->ymd . ' ' . $timestamp->hms); - $extra_values->{flags} = $bug->flags; - - # It's not generally safe to do update() multiple times on - # the same Bug object. - $bug = new Bugzilla::Bug($bug->id); - my $update_flags = $self->bug_update_value($number, 'set_flags')->{b}; - $_->{status} = 'X' foreach @{ $bug->flags }; - $bug->set_flags($bug->flags, $update_flags); - if ($number == 1) { - my $comment_id = $bug->comments->[-1]->id; - $bug->set_comment_is_private({ $comment_id => 1 }); - } - $bug->update($bug->delta_ts); - - my $attach_create = $self->bug_create_value($number, 'attachment'); - my $attachment = Bugzilla::Attachment->create({ - bug => $bug, - creation_ts => $creation_ts, - %$attach_create }); - # Store for the changedfrom tests. - $extra_values->{attachments} = - [new Bugzilla::Attachment($attachment->id)]; - - my $attach_update = $self->bug_update_value($number, 'attachment'); - $attachment->set_all($attach_update); - # In order to keep the mimetype on the ispatch attachment, - # we need to bypass the validator. - $attachment->{mimetype} = $attach_update->{content_type}; - my $attach_flags = $self->bug_update_value($number, 'set_flags')->{a}; - $attachment->set_flags([], $attach_flags); - $attachment->update($bug->delta_ts); + + my ($new_status, $new_res) = delete @update_params{qw(status resolution)}; + + # Bypass the status workflow. + $bug->{bug_status} = $new_status; + $bug->{resolution} = $new_res; + $bug->{everconfirmed} = 1 if $number == 1; + + # add/remove/set fields. + $update_params{keywords} = {set => $update_params{keywords}}; + $update_params{groups} + = {add => $update_params{groups}, remove => $bug->groups_in}; + my @cc_remove = map { $_->login } @{$bug->cc_users}; + my $cc_new = $update_params{cc}; + my @cc_add = ref($cc_new) ? @$cc_new : ($cc_new); + + # We make the admin an explicit CC on bug 1 (but not on bug 6), so + # that we can test the %user% pronoun properly. + if ($real_number == 1) { + push(@cc_add, $self->admin->login); + } + $update_params{cc} = {add => \@cc_add, remove => \@cc_remove}; + my $see_also_remove = $bug->see_also; + my $see_also_add = [$update_params{see_also}]; + $update_params{see_also} = {add => $see_also_add, remove => $see_also_remove}; + $update_params{comment} = {body => $update_params{comment}}; + $update_params{work_time} = $number; + + # Setting work_time kills the remaining_time, so we need to + # preserve that. We add 8 because that produces an integer + # percentage_complete for bug 1, which is necessary for + # accurate "equals"-type searching. + $update_params{remaining_time} = $number + 8; + $update_params{reporter_accessible} = $number == 1 ? 1 : 0; + $update_params{cclist_accessible} = $number == 1 ? 1 : 0; + $update_params{alias} = $update_alias; + + $bug->set_all(\%update_params); + my $flags = $self->bug_create_value($number, 'set_flags')->{b}; + $bug->set_flags([], $flags); + $timestamp->set(second => $number); + $bug->update($timestamp->ymd . ' ' . $timestamp->hms); + $extra_values->{flags} = $bug->flags; + + # It's not generally safe to do update() multiple times on + # the same Bug object. + $bug = new Bugzilla::Bug($bug->id); + my $update_flags = $self->bug_update_value($number, 'set_flags')->{b}; + $_->{status} = 'X' foreach @{$bug->flags}; + $bug->set_flags($bug->flags, $update_flags); + if ($number == 1) { + my $comment_id = $bug->comments->[-1]->id; + $bug->set_comment_is_private({$comment_id => 1}); } + $bug->update($bug->delta_ts); - # Values for changedfrom. - $extra_values->{creation_ts} = $bug->creation_ts; - $extra_values->{delta_ts} = $bug->creation_ts; + my $attach_create = $self->bug_create_value($number, 'attachment'); + my $attachment + = Bugzilla::Attachment->create({ + bug => $bug, creation_ts => $creation_ts, %$attach_create + }); - return new Bugzilla::Bug($bug->id); + # Store for the changedfrom tests. + $extra_values->{attachments} = [new Bugzilla::Attachment($attachment->id)]; + + my $attach_update = $self->bug_update_value($number, 'attachment'); + $attachment->set_all($attach_update); + + # In order to keep the mimetype on the ispatch attachment, + # we need to bypass the validator. + $attachment->{mimetype} = $attach_update->{content_type}; + my $attach_flags = $self->bug_update_value($number, 'set_flags')->{a}; + $attachment->set_flags([], $attach_flags); + $attachment->update($bug->delta_ts); + } + + # Values for changedfrom. + $extra_values->{creation_ts} = $bug->creation_ts; + $extra_values->{delta_ts} = $bug->creation_ts; + + return new Bugzilla::Bug($bug->id); } ################################### @@ -792,44 +834,45 @@ sub _create_one_bug { # field, which we store more efficiently, in an array, and then we re-populate # the Test_Results in Test::Builder at the end of the test. sub clean_test_history { - my ($self) = @_; - return if !$self->option('long'); - my $builder = Test::More->builder; - my $current_test = $builder->current_test; - - # I don't use details() because I don't want to copy the array. - my $results = $builder->{Test_Results}; - my $check_test = $current_test - 1; - while (my $result = $results->[$check_test]) { - last if !$result; - $self->test_success($check_test, $result->{ok}); - $check_test--; - } - - # Truncate the test history array, but retain the current test number. - $builder->{Test_Results} = []; - $builder->{Curr_Test} = $current_test; + my ($self) = @_; + return if !$self->option('long'); + my $builder = Test::More->builder; + my $current_test = $builder->current_test; + + # I don't use details() because I don't want to copy the array. + my $results = $builder->{Test_Results}; + my $check_test = $current_test - 1; + while (my $result = $results->[$check_test]) { + last if !$result; + $self->test_success($check_test, $result->{ok}); + $check_test--; + } + + # Truncate the test history array, but retain the current test number. + $builder->{Test_Results} = []; + $builder->{Curr_Test} = $current_test; } sub test_success { - my ($self, $index, $status) = @_; - $self->{test_success}->[$index] = $status; - return $self->{test_success}; + my ($self, $index, $status) = @_; + $self->{test_success}->[$index] = $status; + return $self->{test_success}; } sub repopulate_test_results { - my ($self) = @_; - return if !$self->option('long'); - $self->clean_test_history(); - # We create only two hashes, for memory efficiency. - my %ok = ( ok => 1 ); - my %not_ok = ( ok => 0 ); - my @results; - foreach my $success (@{ $self->{test_success} }) { - push(@results, $success ? \%ok : \%not_ok); - } - my $builder = Test::More->builder; - $builder->{Test_Results} = \@results; + my ($self) = @_; + return if !$self->option('long'); + $self->clean_test_history(); + + # We create only two hashes, for memory efficiency. + my %ok = (ok => 1); + my %not_ok = (ok => 0); + my @results; + foreach my $success (@{$self->{test_success}}) { + push(@results, $success ? \%ok : \%not_ok); + } + my $builder = Test::More->builder; + $builder->{Test_Results} = \@results; } ########## @@ -842,13 +885,13 @@ sub repopulate_test_results { # have to re-run the value-translation code every time (which can be pretty # slow). sub value_translation_cache { - my ($self, $field_test, $value) = @_; - return if !$self->option('long'); - my $test_name = $field_test->name; - if (@_ == 3) { - $self->{value_translation_cache}->{$test_name} = $value; - } - return $self->{value_translation_cache}->{$test_name}; + my ($self, $field_test, $value) = @_; + return if !$self->option('long'); + my $test_name = $field_test->name; + if (@_ == 3) { + $self->{value_translation_cache}->{$test_name} = $value; + } + return $self->{value_translation_cache}->{$test_name}; } # When doing AND/OR tests, the value for transformed_value_was_equal @@ -856,13 +899,13 @@ sub value_translation_cache { # if we pull our values from the value_translation_cache. So we need # to also cache the values for transformed_value_was_equal. sub was_equal_cache { - my ($self, $field_test, $number, $value) = @_; - return if !$self->option('long'); - my $test_name = $field_test->name; - if (@_ == 4) { - $self->{tvwe_cache}->{$test_name}->{$number} = $value; - } - return $self->{tvwe_cache}->{$test_name}->{$number}; + my ($self, $field_test, $number, $value) = @_; + return if !$self->option('long'); + my $test_name = $field_test->name; + if (@_ == 4) { + $self->{tvwe_cache}->{$test_name}->{$number} = $value; + } + return $self->{tvwe_cache}->{$test_name}->{$number}; } ############# @@ -870,133 +913,136 @@ sub was_equal_cache { ############# sub run { - my ($self) = @_; - my $dbh = Bugzilla->dbh; - - # We want backtraces on any "die" message or any warning. - # Otherwise it's hard to trace errors inside of Bugzilla::Search from - # reading automated test run results. - local $SIG{__WARN__} = \&Carp::cluck; - local $SIG{__DIE__} = \&Carp::confess; - - $dbh->bz_start_transaction(); - - # Some parameters need to be set in order for the tests to function - # properly. - my $everybody = $self->everybody; - my $params = Bugzilla->params; - local $params->{'useclassification'} = 1; - local $params->{'useqacontact'} = 1; - local $params->{'usebugaliases'} = 1; - local $params->{'usetargetmilestone'} = 1; - local $params->{'mail_delivery_method'} = 'None'; - local $params->{'timetrackinggroup'} = $everybody->name; - local $params->{'insidergroup'} = $everybody->name; - - $self->_setup_bugs(); - - # Even though _setup_bugs set us as an admin, we want to be sure at - # this point that we have an admin with refreshed group memberships. - Bugzilla->set_user($self->admin); - foreach my $test (CUSTOM_SEARCH_TESTS) { - my $custom_test = new Bugzilla::Test::Search::CustomTest($test, $self); - $custom_test->run(); - } - foreach my $test (SPECIAL_PARAM_TESTS) { - my $operator_test = - new Bugzilla::Test::Search::OperatorTest($test->{operator}, $self); - my $field = Bugzilla::Field->check($test->{field}); - my $special_test = new Bugzilla::Test::Search::FieldTestNormal( - $operator_test, $field, $test); - $special_test->run(); - } - foreach my $operator ($self->top_level_operators) { - my $operator_test = - new Bugzilla::Test::Search::OperatorTest($operator, $self); - $operator_test->run(); - } - - # Rollbacks won't get rid of bugs_fulltext entries, so we do that ourselves. - my @bug_ids = map { $_->id } $self->bugs; - my $bug_id_string = join(',', @bug_ids); - $dbh->do("DELETE FROM bugs_fulltext WHERE bug_id IN ($bug_id_string)"); - $dbh->bz_rollback_transaction(); - $self->repopulate_test_results(); + my ($self) = @_; + my $dbh = Bugzilla->dbh; + + # We want backtraces on any "die" message or any warning. + # Otherwise it's hard to trace errors inside of Bugzilla::Search from + # reading automated test run results. + local $SIG{__WARN__} = \&Carp::cluck; + local $SIG{__DIE__} = \&Carp::confess; + + $dbh->bz_start_transaction(); + + # Some parameters need to be set in order for the tests to function + # properly. + my $everybody = $self->everybody; + my $params = Bugzilla->params; + local $params->{'useclassification'} = 1; + local $params->{'useqacontact'} = 1; + local $params->{'usebugaliases'} = 1; + local $params->{'usetargetmilestone'} = 1; + local $params->{'mail_delivery_method'} = 'None'; + local $params->{'timetrackinggroup'} = $everybody->name; + local $params->{'insidergroup'} = $everybody->name; + + $self->_setup_bugs(); + + # Even though _setup_bugs set us as an admin, we want to be sure at + # this point that we have an admin with refreshed group memberships. + Bugzilla->set_user($self->admin); + foreach my $test (CUSTOM_SEARCH_TESTS) { + my $custom_test = new Bugzilla::Test::Search::CustomTest($test, $self); + $custom_test->run(); + } + foreach my $test (SPECIAL_PARAM_TESTS) { + my $operator_test + = new Bugzilla::Test::Search::OperatorTest($test->{operator}, $self); + my $field = Bugzilla::Field->check($test->{field}); + my $special_test + = new Bugzilla::Test::Search::FieldTestNormal($operator_test, $field, $test); + $special_test->run(); + } + foreach my $operator ($self->top_level_operators) { + my $operator_test = new Bugzilla::Test::Search::OperatorTest($operator, $self); + $operator_test->run(); + } + + # Rollbacks won't get rid of bugs_fulltext entries, so we do that ourselves. + my @bug_ids = map { $_->id } $self->bugs; + my $bug_id_string = join(',', @bug_ids); + $dbh->do("DELETE FROM bugs_fulltext WHERE bug_id IN ($bug_id_string)"); + $dbh->bz_rollback_transaction(); + $self->repopulate_test_results(); } # This makes a few changes to the bugs after they're created--changes # that can only be done after all the bugs have been created. sub _setup_bugs { - my ($self) = @_; - $self->_setup_dependencies(); - $self->_set_bug_id_fields(); - $self->_protect_bug_6(); + my ($self) = @_; + $self->_setup_dependencies(); + $self->_set_bug_id_fields(); + $self->_protect_bug_6(); } + sub _setup_dependencies { - my ($self) = @_; - my $dbh = Bugzilla->dbh; - - # Set up depedency relationships between the bugs. - # Bug 1 + 6 depend on bug 2 and block bug 3. - my $bug2 = $self->bug(2); - my $bug3 = $self->bug(3); - foreach my $number (1,6) { - my $bug = $self->bug($number); - my @original_delta = ($bug2->delta_ts, $bug3->delta_ts); - Bugzilla->set_user($bug->reporter); - $bug->set_dependencies([$bug2->id], [$bug3->id]); - $bug->update($bug->delta_ts); - # Setting dependencies changed the delta_ts on bug2 and bug3, so - # re-set them back to what they were before. However, we leave - # the correct update times in bugs_activity, so that the changed* - # searches still work right. - my $set_delta = $dbh->prepare( - 'UPDATE bugs SET delta_ts = ? WHERE bug_id = ?'); - foreach my $row ([$original_delta[0], $bug2->id], - [$original_delta[1], $bug3->id]) - { - $set_delta->execute(@$row); - } + my ($self) = @_; + my $dbh = Bugzilla->dbh; + + # Set up depedency relationships between the bugs. + # Bug 1 + 6 depend on bug 2 and block bug 3. + my $bug2 = $self->bug(2); + my $bug3 = $self->bug(3); + foreach my $number (1, 6) { + my $bug = $self->bug($number); + my @original_delta = ($bug2->delta_ts, $bug3->delta_ts); + Bugzilla->set_user($bug->reporter); + $bug->set_dependencies([$bug2->id], [$bug3->id]); + $bug->update($bug->delta_ts); + + # Setting dependencies changed the delta_ts on bug2 and bug3, so + # re-set them back to what they were before. However, we leave + # the correct update times in bugs_activity, so that the changed* + # searches still work right. + my $set_delta = $dbh->prepare('UPDATE bugs SET delta_ts = ? WHERE bug_id = ?'); + foreach + my $row ([$original_delta[0], $bug2->id], [$original_delta[1], $bug3->id]) + { + $set_delta->execute(@$row); } + } } sub _set_bug_id_fields { - my ($self) = @_; - # BUG_ID fields couldn't be set before, because before we create bug 1, - # we don't necessarily have any valid bug ids.) - my @bug_id_fields = grep { $_->type == FIELD_TYPE_BUG_ID } - $self->all_fields; - foreach my $number (1..NUM_BUGS) { - my $bug = $self->bug($number); - $number = 1 if $number == 6; - next if $number == 5; - my $other_bug = $self->bug($number + 1); - Bugzilla->set_user($bug->reporter); - foreach my $field (@bug_id_fields) { - $bug->set_custom_field($field, $other_bug->id); - $bug->update($bug->delta_ts); - } + my ($self) = @_; + + # BUG_ID fields couldn't be set before, because before we create bug 1, + # we don't necessarily have any valid bug ids.) + my @bug_id_fields = grep { $_->type == FIELD_TYPE_BUG_ID } $self->all_fields; + foreach my $number (1 .. NUM_BUGS) { + my $bug = $self->bug($number); + $number = 1 if $number == 6; + next if $number == 5; + my $other_bug = $self->bug($number + 1); + Bugzilla->set_user($bug->reporter); + foreach my $field (@bug_id_fields) { + $bug->set_custom_field($field, $other_bug->id); + $bug->update($bug->delta_ts); } + } } sub _protect_bug_6 { - my ($self) = @_; - my $dbh = Bugzilla->dbh; - - Bugzilla->set_user($self->admin); - - # Put bug6 in the nobody group. - my $nobody = $self->nobody; - # We pull it newly from the DB to be sure it's safe to call update() - # on. - my $bug6 = new Bugzilla::Bug($self->bug(6)->id); - $bug6->add_group($nobody); - $bug6->update($bug6->delta_ts); - - # Remove the admin (and everybody else) from the $nobody group. - $dbh->do('DELETE FROM group_group_map - WHERE grantor_id = ? OR member_id = ?', undef, - $nobody->id, $nobody->id); + my ($self) = @_; + my $dbh = Bugzilla->dbh; + + Bugzilla->set_user($self->admin); + + # Put bug6 in the nobody group. + my $nobody = $self->nobody; + + # We pull it newly from the DB to be sure it's safe to call update() + # on. + my $bug6 = new Bugzilla::Bug($self->bug(6)->id); + $bug6->add_group($nobody); + $bug6->update($bug6->delta_ts); + + # Remove the admin (and everybody else) from the $nobody group. + $dbh->do( + 'DELETE FROM group_group_map + WHERE grantor_id = ? OR member_id = ?', undef, $nobody->id, + $nobody->id + ); } 1; -- cgit v1.2.3-24-g4f1b