2003-03-27 00:07:02 +00:00
|
|
|
#!/usr/bin/perl -wT
|
1998-09-15 21:49:26 +00:00
|
|
|
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
1998-09-01 01:20:36 +00:00
|
|
|
#
|
1999-11-01 23:33:56 +00:00
|
|
|
# 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.
|
|
|
|
#
|
1998-09-01 01:20:36 +00:00
|
|
|
# The Original Code is the Bugzilla Bug Tracking System.
|
1999-11-01 23:33:56 +00:00
|
|
|
#
|
1998-09-01 01:20:36 +00:00
|
|
|
# The Initial Developer of the Original Code is Netscape Communications
|
1999-11-01 23:33:56 +00:00
|
|
|
# Corporation. Portions created by Netscape are
|
|
|
|
# Copyright (C) 1998 Netscape Communications Corporation. All
|
|
|
|
# Rights Reserved.
|
|
|
|
#
|
1998-09-01 01:20:36 +00:00
|
|
|
# Contributor(s): Terry Weissman <terry@mozilla.org>
|
2001-09-03 01:08:05 +00:00
|
|
|
# Matthew Tuck <matty@chariot.net.au>
|
2005-06-15 03:55:00 +00:00
|
|
|
# Max Kanat-Alexander <mkanat@bugzilla.org>
|
2005-06-25 12:10:28 +00:00
|
|
|
# Marc Schumann <wurblzap@gmail.com>
|
1998-09-01 01:20:36 +00:00
|
|
|
|
1998-09-15 21:49:26 +00:00
|
|
|
use strict;
|
1998-09-01 01:20:36 +00:00
|
|
|
|
2002-01-20 01:44:52 +00:00
|
|
|
use lib qw(.);
|
|
|
|
|
2005-08-10 01:30:41 +00:00
|
|
|
require "globals.pl";
|
2002-11-24 19:56:34 +00:00
|
|
|
use Bugzilla::Constants;
|
2005-11-21 19:06:15 +00:00
|
|
|
use Bugzilla::Util;
|
2005-03-15 22:10:14 +00:00
|
|
|
use Bugzilla::User;
|
1998-09-01 01:20:36 +00:00
|
|
|
|
2002-10-05 14:37:52 +00:00
|
|
|
###########################################################################
|
|
|
|
# General subs
|
|
|
|
###########################################################################
|
1998-09-15 21:49:26 +00:00
|
|
|
|
|
|
|
sub Status {
|
|
|
|
my ($str) = (@_);
|
2002-06-28 00:18:32 +00:00
|
|
|
print "$str <p>\n";
|
1998-09-01 01:20:36 +00:00
|
|
|
}
|
|
|
|
|
1998-09-15 21:49:26 +00:00
|
|
|
sub Alert {
|
|
|
|
my ($str) = (@_);
|
2002-06-28 00:18:32 +00:00
|
|
|
Status("<font color=\"red\">$str</font>");
|
1998-09-01 01:20:36 +00:00
|
|
|
}
|
|
|
|
|
1998-09-15 21:49:26 +00:00
|
|
|
sub BugLink {
|
|
|
|
my ($id) = (@_);
|
2002-06-28 00:18:32 +00:00
|
|
|
return "<a href=\"show_bug.cgi?id=$id\">$id</a>";
|
1998-09-01 01:20:36 +00:00
|
|
|
}
|
|
|
|
|
2003-09-02 01:37:55 +00:00
|
|
|
#
|
|
|
|
# Parameter is a list of bug ids.
|
|
|
|
#
|
|
|
|
# Return is a string containing a list of all the bugids, as hrefs,
|
|
|
|
# followed by a link to them all as a buglist
|
|
|
|
sub BugListLinks {
|
|
|
|
my @bugs = @_;
|
|
|
|
|
|
|
|
# Historically, GetBugLink() wasn't used here. I'm guessing this
|
|
|
|
# was because it didn't exist or is too performance heavy, or just
|
|
|
|
# plain unnecessary
|
|
|
|
my @bug_links = map(BugLink($_), @bugs);
|
|
|
|
|
|
|
|
return join(', ',@bug_links) . " <a href=\"buglist.cgi?bug_id=" .
|
|
|
|
join(',',@bugs) . "\">(as buglist)</a>";
|
|
|
|
}
|
|
|
|
|
2002-10-05 14:37:52 +00:00
|
|
|
###########################################################################
|
|
|
|
# Start
|
|
|
|
###########################################################################
|
1998-09-01 01:20:36 +00:00
|
|
|
|
2004-03-27 03:51:44 +00:00
|
|
|
Bugzilla->login(LOGIN_REQUIRED);
|
2002-10-05 14:37:52 +00:00
|
|
|
|
2004-02-29 14:24:06 +00:00
|
|
|
my $cgi = Bugzilla->cgi;
|
2005-02-17 21:57:27 +00:00
|
|
|
my $dbh = Bugzilla->dbh;
|
2005-07-22 05:13:36 +00:00
|
|
|
my $template = Bugzilla->template;
|
2004-02-29 14:24:06 +00:00
|
|
|
|
2002-10-05 14:37:52 +00:00
|
|
|
# Make sure the user is authorized to access sanitycheck.cgi. Access
|
|
|
|
# is restricted to logged-in users who have "editbugs" privileges,
|
|
|
|
# which is a reasonable compromise between allowing all users to access
|
|
|
|
# the script (creating the potential for denial of service attacks)
|
|
|
|
# and restricting access to this installation's administrators (which
|
|
|
|
# prevents users with a legitimate interest in Bugzilla integrity
|
|
|
|
# from accessing the script).
|
|
|
|
UserInGroup("editbugs")
|
2005-03-09 16:18:03 +00:00
|
|
|
|| ThrowUserError("auth_failure", {group => "editbugs",
|
|
|
|
action => "run",
|
|
|
|
object => "sanity_check"});
|
2002-10-05 14:37:52 +00:00
|
|
|
|
2005-03-17 15:14:58 +00:00
|
|
|
print $cgi->header();
|
1998-09-15 21:49:26 +00:00
|
|
|
|
1999-03-03 22:55:36 +00:00
|
|
|
my @row;
|
1999-03-05 17:55:45 +00:00
|
|
|
|
2005-07-22 05:13:36 +00:00
|
|
|
$template->put_header("Bugzilla Sanity Check");
|
1999-10-11 17:14:32 +00:00
|
|
|
|
2002-05-22 09:21:35 +00:00
|
|
|
###########################################################################
|
|
|
|
# Fix vote cache
|
|
|
|
###########################################################################
|
|
|
|
|
2004-02-29 14:24:06 +00:00
|
|
|
if (defined $cgi->param('rebuildvotecache')) {
|
1999-10-11 17:14:32 +00:00
|
|
|
Status("OK, now rebuilding vote cache.");
|
2005-02-17 21:57:27 +00:00
|
|
|
$dbh->bz_lock_tables('bugs WRITE', 'votes READ');
|
2005-02-08 16:51:03 +00:00
|
|
|
SendSQL("UPDATE bugs SET votes = 0");
|
2005-03-16 00:27:15 +00:00
|
|
|
SendSQL("SELECT bug_id, SUM(vote_count) FROM votes " .
|
|
|
|
$dbh->sql_group_by('bug_id'));
|
1999-10-11 17:14:32 +00:00
|
|
|
my %votes;
|
|
|
|
while (@row = FetchSQLData()) {
|
|
|
|
my ($id, $v) = (@row);
|
|
|
|
$votes{$id} = $v;
|
|
|
|
}
|
|
|
|
foreach my $id (keys %votes) {
|
2005-02-08 16:51:03 +00:00
|
|
|
SendSQL("UPDATE bugs SET votes = $votes{$id} WHERE bug_id = $id");
|
1999-10-11 17:14:32 +00:00
|
|
|
}
|
2005-02-17 21:57:27 +00:00
|
|
|
$dbh->bz_unlock_tables();
|
1999-10-12 11:18:29 +00:00
|
|
|
Status("Vote cache has been rebuilt.");
|
1999-10-11 17:14:32 +00:00
|
|
|
}
|
|
|
|
|
2005-06-25 12:10:28 +00:00
|
|
|
###########################################################################
|
|
|
|
# Create missing group_control_map entries
|
|
|
|
###########################################################################
|
|
|
|
|
|
|
|
if (defined $cgi->param('createmissinggroupcontrolmapentries')) {
|
|
|
|
Status(qq{OK, now creating <code>SHOWN</code> member control entries
|
|
|
|
for product/group combinations lacking one.});
|
|
|
|
|
|
|
|
my $na = CONTROLMAPNA;
|
|
|
|
my $shown = CONTROLMAPSHOWN;
|
|
|
|
my $insertsth = $dbh->prepare(
|
|
|
|
qq{INSERT INTO group_control_map (
|
|
|
|
group_id, product_id, entry,
|
|
|
|
membercontrol, othercontrol, canedit
|
|
|
|
)
|
|
|
|
VALUES (
|
|
|
|
?, ?, 0,
|
|
|
|
$shown, $na, 0
|
|
|
|
)});
|
|
|
|
my $updatesth = $dbh->prepare(qq{UPDATE group_control_map
|
|
|
|
SET membercontrol = $shown
|
|
|
|
WHERE group_id = ?
|
|
|
|
AND product_id = ?});
|
|
|
|
my $counter = 0;
|
|
|
|
|
|
|
|
# Find all group/product combinations used for bugs but not set up
|
|
|
|
# correctly in group_control_map
|
|
|
|
my $invalid_combinations = $dbh->selectall_arrayref(
|
|
|
|
qq{ SELECT bugs.product_id,
|
|
|
|
bgm.group_id,
|
|
|
|
gcm.membercontrol,
|
|
|
|
groups.name,
|
|
|
|
products.name
|
|
|
|
FROM bugs
|
|
|
|
INNER JOIN bug_group_map AS bgm
|
|
|
|
ON bugs.bug_id = bgm.bug_id
|
|
|
|
INNER JOIN groups
|
|
|
|
ON bgm.group_id = groups.id
|
|
|
|
INNER JOIN products
|
|
|
|
ON bugs.product_id = products.id
|
|
|
|
LEFT JOIN group_control_map AS gcm
|
|
|
|
ON bugs.product_id = gcm.product_id
|
|
|
|
AND bgm.group_id = gcm.group_id
|
|
|
|
WHERE COALESCE(gcm.membercontrol, $na) = $na
|
|
|
|
} . $dbh->sql_group_by('bugs.product_id, bgm.group_id'));
|
|
|
|
|
|
|
|
foreach (@$invalid_combinations) {
|
|
|
|
my ($product_id, $group_id, $currentmembercontrol,
|
|
|
|
$group_name, $product_name) = @$_;
|
|
|
|
|
|
|
|
$counter++;
|
|
|
|
if (defined($currentmembercontrol)) {
|
|
|
|
Status(qq{Updating <code>NA/<em>xxx</em></code> group control
|
|
|
|
setting for group <em>$group_name</em> to
|
|
|
|
<code>SHOWN/<em>xxx</em></code> in product
|
|
|
|
<em>$product_name</em>.});
|
|
|
|
$updatesth->execute($group_id, $product_id);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Status(qq{Generating <code>SHOWN/NA</code> group control setting
|
|
|
|
for group <em>$group_name</em> in product
|
|
|
|
<em>$product_name</em>.});
|
|
|
|
$insertsth->execute($group_id, $product_id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Status("Repaired $counter defective group control settings.");
|
|
|
|
}
|
|
|
|
|
2005-04-12 17:24:33 +00:00
|
|
|
###########################################################################
|
|
|
|
# Send unsent mail
|
|
|
|
###########################################################################
|
|
|
|
|
2004-02-29 14:24:06 +00:00
|
|
|
if (defined $cgi->param('rescanallBugMail')) {
|
2003-02-09 22:04:25 +00:00
|
|
|
require Bugzilla::BugMail;
|
|
|
|
|
|
|
|
Status("OK, now attempting to send unsent mail");
|
2005-03-11 19:45:03 +00:00
|
|
|
SendSQL("SELECT bug_id FROM bugs
|
|
|
|
WHERE (lastdiffed IS NULL OR lastdiffed < delta_ts) AND
|
2005-11-13 17:32:12 +00:00
|
|
|
delta_ts < now() - " . $dbh->sql_interval(30, 'MINUTE') .
|
2005-03-03 07:19:10 +00:00
|
|
|
" ORDER BY bug_id");
|
2003-02-09 22:04:25 +00:00
|
|
|
my @list;
|
|
|
|
while (MoreSQLData()) {
|
|
|
|
push (@list, FetchOneColumn());
|
|
|
|
}
|
|
|
|
|
|
|
|
Status(scalar(@list) . ' bugs found with possibly unsent mail.');
|
|
|
|
|
|
|
|
foreach my $bugid (@list) {
|
|
|
|
Bugzilla::BugMail::Send($bugid);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scalar(@list) > 0) {
|
|
|
|
Status("Unsent mail has been sent.");
|
|
|
|
}
|
|
|
|
|
2005-07-22 05:13:36 +00:00
|
|
|
$template->put_footer();
|
2003-02-09 22:04:25 +00:00
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
2005-04-12 17:24:33 +00:00
|
|
|
###########################################################################
|
|
|
|
# Remove all references to deleted bugs
|
|
|
|
###########################################################################
|
|
|
|
|
|
|
|
if (defined $cgi->param('remove_invalid_references')) {
|
|
|
|
Status("OK, now removing all references to deleted bugs.");
|
|
|
|
|
|
|
|
$dbh->bz_lock_tables('attachments WRITE', 'bug_group_map WRITE',
|
|
|
|
'bugs_activity WRITE', 'cc WRITE',
|
|
|
|
'dependencies WRITE', 'duplicates WRITE',
|
|
|
|
'flags WRITE', 'keywords WRITE',
|
|
|
|
'longdescs WRITE', 'votes WRITE', 'bugs READ');
|
|
|
|
|
|
|
|
foreach my $pair ('attachments/', 'bug_group_map/', 'bugs_activity/', 'cc/',
|
|
|
|
'dependencies/blocked', 'dependencies/dependson',
|
|
|
|
'duplicates/dupe', 'duplicates/dupe_of',
|
|
|
|
'flags/', 'keywords/', 'longdescs/', 'votes/') {
|
|
|
|
|
|
|
|
my ($table, $field) = split('/', $pair);
|
|
|
|
$field ||= "bug_id";
|
|
|
|
|
|
|
|
my $bug_ids =
|
|
|
|
$dbh->selectcol_arrayref("SELECT $table.$field FROM $table
|
|
|
|
LEFT JOIN bugs ON $table.$field = bugs.bug_id
|
|
|
|
WHERE bugs.bug_id IS NULL");
|
|
|
|
|
|
|
|
if (scalar(@$bug_ids)) {
|
|
|
|
$dbh->do("DELETE FROM $table WHERE $field IN (" . join(',', @$bug_ids) . ")");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$dbh->bz_unlock_tables();
|
|
|
|
Status("All references to deleted bugs have been removed.");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-06-28 00:18:32 +00:00
|
|
|
print "OK, now running sanity checks.<p>\n";
|
1999-10-11 17:14:32 +00:00
|
|
|
|
2002-05-22 09:21:35 +00:00
|
|
|
###########################################################################
|
|
|
|
# Perform referential (cross) checks
|
|
|
|
###########################################################################
|
|
|
|
|
2002-10-05 15:07:16 +00:00
|
|
|
# This checks that a simple foreign key has a valid primary key value. NULL
|
|
|
|
# references are acceptable and cause no problem.
|
|
|
|
#
|
|
|
|
# The first parameter is the primary key table name.
|
|
|
|
# The second parameter is the primary key field name.
|
|
|
|
# Each successive parameter represents a foreign key, it must be a list
|
|
|
|
# reference, where the list has:
|
|
|
|
# the first value is the foreign key table name.
|
|
|
|
# the second value is the foreign key field name.
|
|
|
|
# the third value is optional and represents a field on the foreign key
|
|
|
|
# table to display when the check fails.
|
|
|
|
# the fourth value is optional and is a list reference to values that
|
|
|
|
# are excluded from checking.
|
|
|
|
#
|
|
|
|
# FIXME: The excluded values parameter should go away - the QA contact
|
|
|
|
# fields should use NULL instead - see bug #109474.
|
2004-12-09 09:36:51 +00:00
|
|
|
# The same goes for series; no bug for that yet.
|
2002-10-05 15:07:16 +00:00
|
|
|
|
2002-10-05 14:25:13 +00:00
|
|
|
sub CrossCheck {
|
|
|
|
my $table = shift @_;
|
|
|
|
my $field = shift @_;
|
|
|
|
|
|
|
|
Status("Checking references to $table.$field");
|
|
|
|
|
|
|
|
while (@_) {
|
|
|
|
my $ref = shift @_;
|
|
|
|
my ($refertable, $referfield, $keyname, $exceptions) = @$ref;
|
|
|
|
|
|
|
|
$exceptions ||= [];
|
|
|
|
my %exceptions = map { $_ => 1 } @$exceptions;
|
|
|
|
|
|
|
|
Status("... from $refertable.$referfield");
|
|
|
|
|
|
|
|
SendSQL("SELECT DISTINCT $refertable.$referfield" . ($keyname ? ", $refertable.$keyname" : '') . " " .
|
|
|
|
"FROM $refertable LEFT JOIN $table " .
|
|
|
|
" ON $refertable.$referfield = $table.$field " .
|
|
|
|
"WHERE $table.$field IS NULL " .
|
|
|
|
" AND $refertable.$referfield IS NOT NULL");
|
|
|
|
|
2005-04-12 17:24:33 +00:00
|
|
|
my $has_bad_references = 0;
|
2002-10-05 14:25:13 +00:00
|
|
|
while (MoreSQLData()) {
|
|
|
|
my ($value, $key) = FetchSQLData();
|
|
|
|
if (!$exceptions{$value}) {
|
2005-10-28 10:25:44 +00:00
|
|
|
my $alert = "Bad value "$value" found in $refertable.$referfield";
|
2002-10-05 14:25:13 +00:00
|
|
|
if ($keyname) {
|
|
|
|
if ($keyname eq 'bug_id') {
|
|
|
|
$alert .= ' (bug ' . BugLink($key) . ')';
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$alert .= " ($keyname == '$key')";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Alert($alert);
|
2005-04-12 17:24:33 +00:00
|
|
|
$has_bad_references = 1;
|
2002-10-05 14:25:13 +00:00
|
|
|
}
|
|
|
|
}
|
2005-04-12 17:24:33 +00:00
|
|
|
# References to non existent bugs can be safely removed, bug 288461
|
|
|
|
if ($table eq 'bugs' && $has_bad_references) {
|
|
|
|
print qq{<a href="sanitycheck.cgi?remove_invalid_references=1">Remove invalid references to non existent bugs.</a><p>\n};
|
|
|
|
}
|
2002-10-05 14:25:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-12-09 09:36:51 +00:00
|
|
|
CrossCheck('classifications', 'id',
|
|
|
|
['products', 'classification_id']);
|
|
|
|
|
2000-01-23 04:37:40 +00:00
|
|
|
CrossCheck("keyworddefs", "id",
|
|
|
|
["keywords", "keywordid"]);
|
|
|
|
|
|
|
|
CrossCheck("fielddefs", "fieldid",
|
2004-12-09 09:36:51 +00:00
|
|
|
["bugs_activity", "fieldid"],
|
|
|
|
['profiles_activity', 'fieldid']);
|
2001-09-10 15:20:11 +00:00
|
|
|
|
2002-09-28 18:42:54 +00:00
|
|
|
CrossCheck("flagtypes", "id",
|
|
|
|
["flags", "type_id"]);
|
2000-01-23 04:37:40 +00:00
|
|
|
|
|
|
|
CrossCheck("bugs", "bug_id",
|
|
|
|
["bugs_activity", "bug_id"],
|
2002-09-22 17:15:13 +00:00
|
|
|
["bug_group_map", "bug_id"],
|
2000-01-23 04:37:40 +00:00
|
|
|
["attachments", "bug_id"],
|
|
|
|
["cc", "bug_id"],
|
|
|
|
["longdescs", "bug_id"],
|
|
|
|
["dependencies", "blocked"],
|
|
|
|
["dependencies", "dependson"],
|
2004-12-09 09:36:51 +00:00
|
|
|
['flags', 'bug_id'],
|
2000-01-23 04:37:40 +00:00
|
|
|
["votes", "bug_id"],
|
2001-09-10 15:20:11 +00:00
|
|
|
["keywords", "bug_id"],
|
|
|
|
["duplicates", "dupe_of", "dupe"],
|
|
|
|
["duplicates", "dupe", "dupe_of"]);
|
2000-01-23 04:37:40 +00:00
|
|
|
|
2002-09-22 17:15:13 +00:00
|
|
|
CrossCheck("groups", "id",
|
|
|
|
["bug_group_map", "group_id"],
|
2004-12-09 09:36:51 +00:00
|
|
|
['category_group_map', 'group_id'],
|
2002-09-22 17:15:13 +00:00
|
|
|
["group_group_map", "grantor_id"],
|
|
|
|
["group_group_map", "member_id"],
|
2002-11-24 19:56:34 +00:00
|
|
|
["group_control_map", "group_id"],
|
2002-09-22 17:15:13 +00:00
|
|
|
["user_group_map", "group_id"]);
|
|
|
|
|
2000-01-23 04:37:40 +00:00
|
|
|
CrossCheck("profiles", "userid",
|
2004-12-09 09:36:51 +00:00
|
|
|
['profiles_activity', 'userid'],
|
|
|
|
['profiles_activity', 'who'],
|
2005-12-13 20:14:26 +00:00
|
|
|
['email_setting', 'user_id'],
|
|
|
|
['profile_setting', 'user_id'],
|
2000-07-25 18:58:54 +00:00
|
|
|
["bugs", "reporter", "bug_id"],
|
|
|
|
["bugs", "assigned_to", "bug_id"],
|
2005-03-15 05:20:48 +00:00
|
|
|
["bugs", "qa_contact", "bug_id"],
|
2000-07-25 18:58:54 +00:00
|
|
|
["attachments", "submitter_id", "bug_id"],
|
2004-12-09 09:36:51 +00:00
|
|
|
['flags', 'setter_id', 'bug_id'],
|
|
|
|
['flags', 'requestee_id', 'bug_id'],
|
2000-07-25 18:58:54 +00:00
|
|
|
["bugs_activity", "who", "bug_id"],
|
|
|
|
["cc", "who", "bug_id"],
|
2004-12-09 09:36:51 +00:00
|
|
|
['quips', 'userid'],
|
2000-07-25 18:58:54 +00:00
|
|
|
["votes", "who", "bug_id"],
|
|
|
|
["longdescs", "who", "bug_id"],
|
2001-09-10 15:20:11 +00:00
|
|
|
["logincookies", "userid"],
|
2001-02-22 18:11:29 +00:00
|
|
|
["namedqueries", "userid"],
|
2004-12-09 09:36:51 +00:00
|
|
|
['series', 'creator', 'series_id', ['0']],
|
2001-09-10 15:20:11 +00:00
|
|
|
["watch", "watcher"],
|
|
|
|
["watch", "watched"],
|
2004-12-09 09:36:51 +00:00
|
|
|
['whine_events', 'owner_userid'],
|
2001-09-10 15:20:11 +00:00
|
|
|
["tokens", "userid"],
|
2002-09-22 17:15:13 +00:00
|
|
|
["user_group_map", "user_id"],
|
2004-12-09 09:36:51 +00:00
|
|
|
["components", "initialowner", "name"],
|
2005-03-15 05:20:48 +00:00
|
|
|
["components", "initialqacontact", "name"]);
|
2000-01-23 04:37:40 +00:00
|
|
|
|
2002-08-12 05:43:05 +00:00
|
|
|
CrossCheck("products", "id",
|
|
|
|
["bugs", "product_id", "bug_id"],
|
|
|
|
["components", "product_id", "name"],
|
|
|
|
["milestones", "product_id", "value"],
|
|
|
|
["versions", "product_id", "value"],
|
2002-11-24 19:56:34 +00:00
|
|
|
["group_control_map", "product_id"],
|
2002-09-29 20:14:13 +00:00
|
|
|
["flaginclusions", "product_id", "type_id"],
|
|
|
|
["flagexclusions", "product_id", "type_id"]);
|
2001-09-10 15:20:11 +00:00
|
|
|
|
2005-06-15 03:55:00 +00:00
|
|
|
# Check the former enum types -mkanat@bugzilla.org
|
2005-02-24 22:43:28 +00:00
|
|
|
CrossCheck("bug_status", "value",
|
2005-12-02 20:57:34 +00:00
|
|
|
["bugs", "bug_status", "bug_id"]);
|
2005-02-24 22:43:28 +00:00
|
|
|
|
|
|
|
CrossCheck("resolution", "value",
|
2005-12-02 20:57:34 +00:00
|
|
|
["bugs", "resolution", "bug_id"]);
|
2005-02-24 22:43:28 +00:00
|
|
|
|
|
|
|
CrossCheck("bug_severity", "value",
|
2005-12-02 20:57:34 +00:00
|
|
|
["bugs", "bug_severity", "bug_id"]);
|
2005-02-24 22:43:28 +00:00
|
|
|
|
|
|
|
CrossCheck("op_sys", "value",
|
2005-12-02 20:57:34 +00:00
|
|
|
["bugs", "op_sys", "bug_id"]);
|
2005-02-24 22:43:28 +00:00
|
|
|
|
|
|
|
CrossCheck("priority", "value",
|
2005-12-02 20:57:34 +00:00
|
|
|
["bugs", "priority", "bug_id"]);
|
2005-02-24 22:43:28 +00:00
|
|
|
|
|
|
|
CrossCheck("rep_platform", "value",
|
2005-12-02 20:57:34 +00:00
|
|
|
["bugs", "rep_platform", "bug_id"]);
|
2005-02-24 22:43:28 +00:00
|
|
|
|
2004-12-09 09:36:51 +00:00
|
|
|
CrossCheck('series', 'series_id',
|
|
|
|
['series_data', 'series_id']);
|
|
|
|
|
|
|
|
CrossCheck('series_categories', 'id',
|
|
|
|
['series', 'category']);
|
|
|
|
|
|
|
|
CrossCheck('whine_events', 'id',
|
|
|
|
['whine_queries', 'eventid'],
|
|
|
|
['whine_schedules', 'eventid']);
|
|
|
|
|
2002-05-22 09:21:35 +00:00
|
|
|
###########################################################################
|
2002-10-05 14:14:47 +00:00
|
|
|
# Perform double field referential (cross) checks
|
2002-05-22 09:21:35 +00:00
|
|
|
###########################################################################
|
2002-10-05 14:14:47 +00:00
|
|
|
|
2002-10-05 15:07:16 +00:00
|
|
|
# This checks that a compound two-field foreign key has a valid primary key
|
|
|
|
# value. NULL references are acceptable and cause no problem.
|
|
|
|
#
|
|
|
|
# The first parameter is the primary key table name.
|
|
|
|
# The second parameter is the primary key first field name.
|
|
|
|
# The third parameter is the primary key second field name.
|
|
|
|
# Each successive parameter represents a foreign key, it must be a list
|
|
|
|
# reference, where the list has:
|
|
|
|
# the first value is the foreign key table name
|
|
|
|
# the second value is the foreign key first field name.
|
|
|
|
# the third value is the foreign key second field name.
|
|
|
|
# the fourth value is optional and represents a field on the foreign key
|
|
|
|
# table to display when the check fails
|
|
|
|
|
2002-10-05 14:14:47 +00:00
|
|
|
sub DoubleCrossCheck {
|
|
|
|
my $table = shift @_;
|
|
|
|
my $field1 = shift @_;
|
|
|
|
my $field2 = shift @_;
|
|
|
|
|
|
|
|
Status("Checking references to $table.$field1 / $table.$field2");
|
|
|
|
|
|
|
|
while (@_) {
|
|
|
|
my $ref = shift @_;
|
|
|
|
my ($refertable, $referfield1, $referfield2, $keyname) = @$ref;
|
|
|
|
|
|
|
|
Status("... from $refertable.$referfield1 / $refertable.$referfield2");
|
|
|
|
|
|
|
|
SendSQL("SELECT DISTINCT $refertable.$referfield1, $refertable.$referfield2" . ($keyname ? ", $refertable.$keyname" : '') . " " .
|
|
|
|
"FROM $refertable LEFT JOIN $table " .
|
|
|
|
" ON $refertable.$referfield1 = $table.$field1 " .
|
|
|
|
" AND $refertable.$referfield2 = $table.$field2 " .
|
|
|
|
"WHERE $table.$field1 IS NULL " .
|
|
|
|
" AND $table.$field2 IS NULL " .
|
|
|
|
" AND $refertable.$referfield1 IS NOT NULL " .
|
|
|
|
" AND $refertable.$referfield2 IS NOT NULL");
|
|
|
|
|
|
|
|
while (MoreSQLData()) {
|
|
|
|
my ($value1, $value2, $key) = FetchSQLData();
|
|
|
|
|
2005-10-28 10:25:44 +00:00
|
|
|
my $alert = "Bad values "$value1", "$value2" found in " .
|
2002-10-05 14:14:47 +00:00
|
|
|
"$refertable.$referfield1 / $refertable.$referfield2";
|
|
|
|
if ($keyname) {
|
|
|
|
if ($keyname eq 'bug_id') {
|
|
|
|
$alert .= ' (bug ' . BugLink($key) . ')';
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$alert .= " ($keyname == '$key')";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Alert($alert);
|
|
|
|
}
|
2001-09-10 15:20:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-12-09 09:36:51 +00:00
|
|
|
DoubleCrossCheck('attachments', 'bug_id', 'attach_id',
|
|
|
|
['flags', 'bug_id', 'attach_id'],
|
|
|
|
['bugs_activity', 'bug_id', 'attach_id']);
|
|
|
|
|
2002-10-05 14:14:47 +00:00
|
|
|
DoubleCrossCheck("components", "product_id", "id",
|
2004-12-09 09:36:51 +00:00
|
|
|
["bugs", "product_id", "component_id", "bug_id"],
|
|
|
|
['flagexclusions', 'product_id', 'component_id'],
|
|
|
|
['flaginclusions', 'product_id', 'component_id']);
|
1999-03-03 22:55:36 +00:00
|
|
|
|
2002-10-05 14:14:47 +00:00
|
|
|
DoubleCrossCheck("versions", "product_id", "value",
|
|
|
|
["bugs", "product_id", "version", "bug_id"]);
|
|
|
|
|
|
|
|
DoubleCrossCheck("milestones", "product_id", "value",
|
|
|
|
["bugs", "product_id", "target_milestone", "bug_id"],
|
|
|
|
["products", "id", "defaultmilestone", "name"]);
|
1999-03-03 22:55:36 +00:00
|
|
|
|
2002-05-22 09:21:35 +00:00
|
|
|
###########################################################################
|
|
|
|
# Perform login checks
|
|
|
|
###########################################################################
|
|
|
|
|
2000-01-23 04:37:40 +00:00
|
|
|
Status("Checking profile logins");
|
1998-09-01 01:20:36 +00:00
|
|
|
|
2004-03-25 14:32:18 +00:00
|
|
|
SendSQL("SELECT userid, login_name FROM profiles");
|
1998-09-01 01:20:36 +00:00
|
|
|
|
2000-01-23 04:37:40 +00:00
|
|
|
while (my ($id,$email) = (FetchSQLData())) {
|
2005-11-21 19:06:15 +00:00
|
|
|
validate_email_syntax($email)
|
|
|
|
|| Alert "Bad profile email address, id=$id, <$email>.";
|
2000-01-23 04:37:40 +00:00
|
|
|
}
|
1998-09-01 01:20:36 +00:00
|
|
|
|
2002-05-22 09:21:35 +00:00
|
|
|
###########################################################################
|
|
|
|
# Perform vote/keyword cache checks
|
|
|
|
###########################################################################
|
1998-09-01 01:20:36 +00:00
|
|
|
|
2002-10-05 14:37:52 +00:00
|
|
|
my $offervotecacherebuild = 0;
|
|
|
|
|
|
|
|
sub AlertBadVoteCache {
|
|
|
|
my ($id) = (@_);
|
|
|
|
Alert("Bad vote cache for bug " . BugLink($id));
|
|
|
|
$offervotecacherebuild = 1;
|
|
|
|
}
|
|
|
|
|
2004-07-05 21:19:34 +00:00
|
|
|
SendSQL("SELECT bug_id, votes, keywords FROM bugs " .
|
2000-01-23 04:37:40 +00:00
|
|
|
"WHERE votes != 0 OR keywords != ''");
|
1998-09-01 01:20:36 +00:00
|
|
|
|
1999-10-11 17:14:32 +00:00
|
|
|
my %votes;
|
1998-09-15 21:49:26 +00:00
|
|
|
my %bugid;
|
2000-01-17 11:38:41 +00:00
|
|
|
my %keyword;
|
1998-09-15 21:49:26 +00:00
|
|
|
|
|
|
|
while (@row = FetchSQLData()) {
|
2000-01-23 04:37:40 +00:00
|
|
|
my($id, $v, $k) = (@row);
|
1999-10-11 17:14:32 +00:00
|
|
|
if ($v != 0) {
|
|
|
|
$votes{$id} = $v;
|
|
|
|
}
|
2000-01-17 11:38:41 +00:00
|
|
|
if ($k) {
|
|
|
|
$keyword{$id} = $k;
|
|
|
|
}
|
1999-10-11 17:14:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Status("Checking cached vote counts");
|
2005-03-16 00:27:15 +00:00
|
|
|
SendSQL("SELECT bug_id, SUM(vote_count) FROM votes " .
|
|
|
|
$dbh->sql_group_by('bug_id'));
|
1999-10-11 17:14:32 +00:00
|
|
|
|
|
|
|
while (@row = FetchSQLData()) {
|
|
|
|
my ($id, $v) = (@row);
|
|
|
|
if ($v <= 0) {
|
|
|
|
Alert("Bad vote sum for bug $id");
|
|
|
|
} else {
|
|
|
|
if (!defined $votes{$id} || $votes{$id} != $v) {
|
|
|
|
AlertBadVoteCache($id);
|
|
|
|
}
|
|
|
|
delete $votes{$id};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
foreach my $id (keys %votes) {
|
|
|
|
AlertBadVoteCache($id);
|
1998-09-01 01:20:36 +00:00
|
|
|
}
|
|
|
|
|
1999-10-11 17:14:32 +00:00
|
|
|
if ($offervotecacherebuild) {
|
|
|
|
print qq{<a href="sanitycheck.cgi?rebuildvotecache=1">Click here to rebuild the vote cache</a><p>\n};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-01-17 11:38:41 +00:00
|
|
|
Status("Checking keywords table");
|
|
|
|
|
|
|
|
my %keywordids;
|
|
|
|
SendSQL("SELECT id, name FROM keyworddefs");
|
|
|
|
while (@row = FetchSQLData()) {
|
|
|
|
my ($id, $name) = (@row);
|
|
|
|
if ($keywordids{$id}) {
|
|
|
|
Alert("Duplicate entry in keyworddefs for id $id");
|
|
|
|
}
|
|
|
|
$keywordids{$id} = 1;
|
2000-01-19 19:26:37 +00:00
|
|
|
if ($name =~ /[\s,]/) {
|
2000-01-17 11:38:41 +00:00
|
|
|
Alert("Bogus name in keyworddefs for id $id");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SendSQL("SELECT bug_id, keywordid FROM keywords ORDER BY bug_id, keywordid");
|
|
|
|
my $lastid;
|
|
|
|
my $lastk;
|
|
|
|
while (@row = FetchSQLData()) {
|
|
|
|
my ($id, $k) = (@row);
|
|
|
|
if (!$keywordids{$k}) {
|
|
|
|
Alert("Bogus keywordids $k found in keywords table");
|
|
|
|
}
|
|
|
|
if (defined $lastid && $id eq $lastid && $k eq $lastk) {
|
|
|
|
Alert("Duplicate keyword ids found in bug " . BugLink($id));
|
|
|
|
}
|
|
|
|
$lastid = $id;
|
|
|
|
$lastk = $k;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status("Checking cached keywords");
|
|
|
|
|
|
|
|
my %realk;
|
|
|
|
|
2004-02-29 14:24:06 +00:00
|
|
|
if (defined $cgi->param('rebuildkeywordcache')) {
|
2005-02-17 21:57:27 +00:00
|
|
|
$dbh->bz_lock_tables('bugs write', 'keywords read',
|
|
|
|
'keyworddefs read');
|
2000-01-17 11:38:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SendSQL("SELECT keywords.bug_id, keyworddefs.name " .
|
2005-04-04 21:52:06 +00:00
|
|
|
"FROM keywords " .
|
|
|
|
"INNER JOIN keyworddefs " .
|
|
|
|
" ON keyworddefs.id = keywords.keywordid " .
|
|
|
|
"INNER JOIN bugs " .
|
|
|
|
" ON keywords.bug_id = bugs.bug_id " .
|
2000-01-17 11:38:41 +00:00
|
|
|
"ORDER BY keywords.bug_id, keyworddefs.name");
|
|
|
|
|
2002-10-05 15:07:16 +00:00
|
|
|
my $lastb = 0;
|
2000-01-17 11:38:41 +00:00
|
|
|
my @list;
|
|
|
|
while (1) {
|
2002-10-05 15:07:16 +00:00
|
|
|
my ($b, $k) = FetchSQLData();
|
2002-10-05 15:08:50 +00:00
|
|
|
if (!defined $b || $b != $lastb) {
|
2000-01-17 11:38:41 +00:00
|
|
|
if (@list) {
|
|
|
|
$realk{$lastb} = join(', ', @list);
|
|
|
|
}
|
|
|
|
if (!$b) {
|
|
|
|
last;
|
|
|
|
}
|
|
|
|
$lastb = $b;
|
|
|
|
@list = ();
|
|
|
|
}
|
|
|
|
push(@list, $k);
|
|
|
|
}
|
|
|
|
|
2002-10-05 14:37:52 +00:00
|
|
|
my @badbugs = ();
|
2001-09-03 01:08:05 +00:00
|
|
|
|
2000-01-17 11:38:41 +00:00
|
|
|
foreach my $b (keys(%keyword)) {
|
|
|
|
if (!exists $realk{$b} || $realk{$b} ne $keyword{$b}) {
|
2001-09-03 01:08:05 +00:00
|
|
|
push(@badbugs, $b);
|
2000-01-17 11:38:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
foreach my $b (keys(%realk)) {
|
|
|
|
if (!exists $keyword{$b}) {
|
2001-09-03 01:08:05 +00:00
|
|
|
push(@badbugs, $b);
|
2000-01-17 11:38:41 +00:00
|
|
|
}
|
|
|
|
}
|
2001-09-03 01:08:05 +00:00
|
|
|
if (@badbugs) {
|
|
|
|
@badbugs = sort {$a <=> $b} @badbugs;
|
2003-09-02 01:37:55 +00:00
|
|
|
Alert(scalar(@badbugs) . " bug(s) found with incorrect keyword cache: " .
|
|
|
|
BugListLinks(@badbugs));
|
2004-02-29 14:24:06 +00:00
|
|
|
if (defined $cgi->param('rebuildkeywordcache')) {
|
2000-01-17 11:38:41 +00:00
|
|
|
Status("OK, now fixing keyword cache.");
|
2001-09-03 01:08:05 +00:00
|
|
|
foreach my $b (@badbugs) {
|
2000-01-17 11:38:41 +00:00
|
|
|
my $k = '';
|
|
|
|
if (exists($realk{$b})) {
|
|
|
|
$k = $realk{$b};
|
|
|
|
}
|
2005-02-08 16:51:03 +00:00
|
|
|
SendSQL("UPDATE bugs SET keywords = " . SqlQuote($k) .
|
2000-01-17 11:38:41 +00:00
|
|
|
" WHERE bug_id = $b");
|
|
|
|
}
|
|
|
|
Status("Keyword cache fixed.");
|
|
|
|
} else {
|
|
|
|
print qq{<a href="sanitycheck.cgi?rebuildkeywordcache=1">Click here to rebuild the keyword cache</a><p>\n};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-02-29 14:24:06 +00:00
|
|
|
if (defined $cgi->param('rebuildkeywordcache')) {
|
2005-02-17 21:57:27 +00:00
|
|
|
$dbh->bz_unlock_tables();
|
2001-10-05 15:18:12 +00:00
|
|
|
}
|
2000-01-17 11:38:41 +00:00
|
|
|
|
2001-09-03 01:08:05 +00:00
|
|
|
###########################################################################
|
2002-10-05 13:23:44 +00:00
|
|
|
# General bug checks
|
2001-09-03 01:08:05 +00:00
|
|
|
###########################################################################
|
|
|
|
|
2005-08-13 12:27:04 +00:00
|
|
|
sub BugCheck {
|
2005-06-25 12:10:28 +00:00
|
|
|
my ($middlesql, $errortext, $repairparam, $repairtext) = @_;
|
2002-10-05 13:23:44 +00:00
|
|
|
|
|
|
|
SendSQL("SELECT DISTINCT bugs.bug_id " .
|
|
|
|
"FROM $middlesql " .
|
|
|
|
"ORDER BY bugs.bug_id");
|
|
|
|
|
|
|
|
my @badbugs = ();
|
|
|
|
|
|
|
|
while (@row = FetchSQLData()) {
|
|
|
|
my ($id) = (@row);
|
|
|
|
push (@badbugs, $id);
|
|
|
|
}
|
2003-09-02 01:37:55 +00:00
|
|
|
|
2002-10-05 13:23:44 +00:00
|
|
|
if (@badbugs) {
|
2003-09-02 01:37:55 +00:00
|
|
|
Alert("$errortext: " . BugListLinks(@badbugs));
|
2005-06-25 12:10:28 +00:00
|
|
|
if ($repairparam) {
|
|
|
|
$repairtext ||= 'Repair these bugs';
|
|
|
|
print qq{<a href="sanitycheck.cgi?$repairparam=1">$repairtext</a>.},
|
|
|
|
'<p>';
|
|
|
|
}
|
2002-10-05 13:23:44 +00:00
|
|
|
}
|
2001-09-03 01:08:05 +00:00
|
|
|
}
|
|
|
|
|
2002-10-05 13:23:44 +00:00
|
|
|
Status("Checking resolution/duplicates");
|
2001-09-03 01:08:05 +00:00
|
|
|
|
2005-04-04 21:52:06 +00:00
|
|
|
BugCheck("bugs INNER JOIN duplicates ON bugs.bug_id = duplicates.dupe " .
|
|
|
|
"WHERE bugs.resolution != 'DUPLICATE'",
|
2002-10-05 13:23:44 +00:00
|
|
|
"Bug(s) found on duplicates table that are not marked duplicate");
|
2001-09-03 01:08:05 +00:00
|
|
|
|
2002-10-05 13:23:44 +00:00
|
|
|
BugCheck("bugs LEFT JOIN duplicates ON bugs.bug_id = duplicates.dupe WHERE " .
|
|
|
|
"bugs.resolution = 'DUPLICATE' AND " .
|
|
|
|
"duplicates.dupe IS NULL",
|
|
|
|
"Bug(s) found marked resolved duplicate and not on duplicates table");
|
2001-09-19 15:06:43 +00:00
|
|
|
|
|
|
|
Status("Checking statuses/resolutions");
|
|
|
|
|
|
|
|
my @open_states = map(SqlQuote($_), OpenStates());
|
|
|
|
my $open_states = join(', ', @open_states);
|
|
|
|
|
2002-10-05 13:23:44 +00:00
|
|
|
BugCheck("bugs WHERE bug_status IN ($open_states) AND resolution != ''",
|
|
|
|
"Bugs with open status and a resolution");
|
|
|
|
BugCheck("bugs WHERE bug_status NOT IN ($open_states) AND resolution = ''",
|
|
|
|
"Bugs with non-open status and no resolution");
|
2001-09-19 15:06:43 +00:00
|
|
|
|
|
|
|
Status("Checking statuses/everconfirmed");
|
|
|
|
|
2005-02-08 16:22:26 +00:00
|
|
|
BugCheck("bugs WHERE bug_status = 'UNCONFIRMED' AND everconfirmed = 1",
|
2002-10-05 13:23:44 +00:00
|
|
|
"Bugs that are UNCONFIRMED but have everconfirmed set");
|
|
|
|
# The below list of resolutions is hardcoded because we don't know if future
|
|
|
|
# resolutions will be confirmed, unconfirmed or maybeconfirmed. I suspect
|
2005-06-29 22:18:21 +00:00
|
|
|
# they will be maybeconfirmed, e.g. ASLEEP and REMIND. This hardcoding should
|
2002-10-05 13:23:44 +00:00
|
|
|
# disappear when we have customised statuses.
|
|
|
|
BugCheck("bugs WHERE bug_status IN ('NEW', 'ASSIGNED', 'REOPENED') AND everconfirmed = 0",
|
|
|
|
"Bugs with confirmed status but don't have everconfirmed set");
|
2001-09-19 15:06:43 +00:00
|
|
|
|
|
|
|
Status("Checking votes/everconfirmed");
|
|
|
|
|
2005-04-04 21:52:06 +00:00
|
|
|
BugCheck("bugs INNER JOIN products ON bugs.product_id = products.id " .
|
|
|
|
"WHERE everconfirmed = 0 AND votestoconfirm <= votes",
|
2002-10-05 13:23:44 +00:00
|
|
|
"Bugs that have enough votes to be confirmed but haven't been");
|
2001-09-19 15:06:43 +00:00
|
|
|
|
2002-10-05 14:25:13 +00:00
|
|
|
###########################################################################
|
|
|
|
# Date checks
|
|
|
|
###########################################################################
|
|
|
|
|
|
|
|
sub DateCheck {
|
|
|
|
my $table = shift @_;
|
|
|
|
my $field = shift @_;
|
|
|
|
Status("Checking dates in $table.$field");
|
|
|
|
SendSQL("SELECT COUNT( $field ) FROM $table WHERE $field > NOW()");
|
|
|
|
my $c = FetchOneColumn();
|
|
|
|
if ($c) {
|
|
|
|
Alert("Found $c dates in future");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DateCheck("groups", "last_changed");
|
|
|
|
DateCheck("profiles", "refreshed_when");
|
|
|
|
|
2002-11-24 19:56:34 +00:00
|
|
|
###########################################################################
|
|
|
|
# Control Values
|
|
|
|
###########################################################################
|
|
|
|
|
|
|
|
# Checks for values that are invalid OR
|
|
|
|
# not among the 9 valid combinations
|
|
|
|
Status("Checking for bad values in group_control_map");
|
|
|
|
SendSQL("SELECT COUNT(product_id) FROM group_control_map WHERE " .
|
|
|
|
"membercontrol NOT IN(" . CONTROLMAPNA . "," . CONTROLMAPSHOWN .
|
|
|
|
"," . CONTROLMAPDEFAULT . "," . CONTROLMAPMANDATORY . ")" .
|
|
|
|
" OR " .
|
|
|
|
"othercontrol NOT IN(" . CONTROLMAPNA . "," . CONTROLMAPSHOWN .
|
|
|
|
"," . CONTROLMAPDEFAULT . "," . CONTROLMAPMANDATORY . ")" .
|
|
|
|
" OR " .
|
|
|
|
"( (membercontrol != othercontrol) " .
|
|
|
|
"AND (membercontrol != " . CONTROLMAPSHOWN . ") " .
|
|
|
|
"AND ((membercontrol != " . CONTROLMAPDEFAULT . ") " .
|
|
|
|
"OR (othercontrol = " . CONTROLMAPSHOWN . ")))");
|
|
|
|
my $c = FetchOneColumn();
|
|
|
|
if ($c) {
|
|
|
|
Alert("Found $c bad group_control_map entries");
|
|
|
|
}
|
|
|
|
|
|
|
|
Status("Checking for bugs with groups violating their product's group controls");
|
2003-03-08 08:29:01 +00:00
|
|
|
BugCheck("bugs
|
2005-04-04 21:52:06 +00:00
|
|
|
INNER JOIN bug_group_map
|
|
|
|
ON bugs.bug_id = bug_group_map.bug_id
|
|
|
|
LEFT JOIN group_control_map
|
|
|
|
ON bugs.product_id = group_control_map.product_id
|
2005-06-29 22:03:47 +00:00
|
|
|
AND bug_group_map.group_id = group_control_map.group_id
|
2005-06-25 12:10:28 +00:00
|
|
|
WHERE ((group_control_map.membercontrol = " . CONTROLMAPNA . ")
|
2002-11-24 19:56:34 +00:00
|
|
|
OR (group_control_map.membercontrol IS NULL))",
|
2005-06-25 12:10:28 +00:00
|
|
|
'Have groups not permitted for their products',
|
|
|
|
'createmissinggroupcontrolmapentries',
|
|
|
|
'Permit the missing groups for the affected products
|
|
|
|
(set member control to <code>SHOWN</code>)');
|
2002-11-24 19:56:34 +00:00
|
|
|
|
2003-03-08 08:29:01 +00:00
|
|
|
BugCheck("bugs
|
2005-06-29 22:03:47 +00:00
|
|
|
INNER JOIN group_control_map
|
2005-04-04 21:52:06 +00:00
|
|
|
ON bugs.product_id = group_control_map.product_id
|
2005-06-29 22:03:47 +00:00
|
|
|
INNER JOIN groups
|
|
|
|
ON group_control_map.group_id = groups.id
|
|
|
|
LEFT JOIN bug_group_map
|
|
|
|
ON bugs.bug_id = bug_group_map.bug_id
|
|
|
|
AND group_control_map.group_id = bug_group_map.group_id
|
2005-06-25 12:10:28 +00:00
|
|
|
WHERE group_control_map.membercontrol = " . CONTROLMAPMANDATORY . "
|
2005-06-29 22:03:47 +00:00
|
|
|
AND bug_group_map.group_id IS NULL
|
|
|
|
AND groups.isactive != 0",
|
2002-11-24 19:56:34 +00:00
|
|
|
"Are missing groups required for their products");
|
|
|
|
|
|
|
|
|
2002-03-03 22:06:20 +00:00
|
|
|
###########################################################################
|
|
|
|
# Unsent mail
|
|
|
|
###########################################################################
|
|
|
|
|
|
|
|
Status("Checking for unsent mail");
|
|
|
|
|
|
|
|
@badbugs = ();
|
|
|
|
|
|
|
|
SendSQL("SELECT bug_id " .
|
2005-03-11 19:45:03 +00:00
|
|
|
"FROM bugs WHERE (lastdiffed IS NULL OR lastdiffed < delta_ts) AND " .
|
2005-11-13 17:32:12 +00:00
|
|
|
"delta_ts < now() - " . $dbh->sql_interval(30, 'MINUTE') .
|
2005-03-03 07:19:10 +00:00
|
|
|
" ORDER BY bug_id");
|
2002-03-03 22:06:20 +00:00
|
|
|
|
|
|
|
while (@row = FetchSQLData()) {
|
|
|
|
my ($id) = (@row);
|
|
|
|
push(@badbugs, $id);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (@badbugs > 0) {
|
|
|
|
Alert("Bugs that have changes but no mail sent for at least half an hour: " .
|
2003-09-02 01:37:55 +00:00
|
|
|
BugListLinks(@badbugs));
|
|
|
|
|
2003-02-09 22:04:25 +00:00
|
|
|
print qq{<a href="sanitycheck.cgi?rescanallBugMail=1">Send these mails</a>.<p>\n};
|
2002-03-03 22:06:20 +00:00
|
|
|
}
|
|
|
|
|
2001-09-19 15:06:43 +00:00
|
|
|
###########################################################################
|
|
|
|
# End
|
|
|
|
###########################################################################
|
1999-06-01 20:52:15 +00:00
|
|
|
|
|
|
|
Status("Sanity check completed.");
|
2005-07-22 05:13:36 +00:00
|
|
|
$template->put_footer();
|