[bugzilla-gnome-org-extensions] Initial checkin of traceparser code.



commit 17285959dd14e8d1ad33ee1b58f00014d6e17260
Author: Max Kanat-Alexander <mkanat everythingsolved com>
Date:   Thu Jul 30 07:11:12 2009 -0500

    Initial checkin of traceparser code.

 code/db_schema-abstract_schema.pl         |   47 ++++++++
 code/install-requirements.pl              |   35 ++++++
 code/install-update_db.pl                 |   64 +++++++++++
 info.pl                                   |   26 +++++
 lib/TraceParser/Trace.pm                  |  165 +++++++++++++++++++++++++++++
 template/en/global/code-error-errors.html |   13 +++
 6 files changed, 350 insertions(+), 0 deletions(-)
---
diff --git a/code/db_schema-abstract_schema.pl b/code/db_schema-abstract_schema.pl
new file mode 100644
index 0000000..9235340
--- /dev/null
+++ b/code/db_schema-abstract_schema.pl
@@ -0,0 +1,47 @@
+# -*- Mode: perl; indent-tabs-mode: nil -*-
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Bugzilla Traceparser Plugin.
+#
+# The Initial Developer of the Original Code is Canonical Ltd.
+# Portions created by Canonical Ltd. are Copyright (C) 2009
+# Canonical Ltd. All Rights Reserved.
+#
+# Contributor(s):
+#   Max Kanat-Alexander <mkanat bugzilla org>
+
+
+use strict;
+use warnings;
+use Bugzilla;
+
+my $schema = Bugzilla->hook_args->{schema};
+$schema->{trace} = {
+    FIELDS => [
+        id          => {TYPE => 'MEDIUMSERIAL',  NOTNULL => 1, 
+                        PRIMARYKEY => 1},
+        bug_id      => {TYPE => 'INT3',  NOTNULL => 1, 
+                        REFERENCES => {TABLE  => 'bugs',
+                                       COLUMN => 'bug_id',
+                                       DELETE => 'CASCADE'}},
+        type        => {TYPE => 'varchar(255)', NOTNULL => 1},
+        short_stack => {TYPE => 'MEDIUMTEXT', NOTNULL => 1},
+        short_hash  => {TYPE => 'char(22)', NOTNULL => 1},
+        full_hash   => {TYPE => 'char(22)', NOTNULL => 1},
+        has_symbols => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 0},
+        quality     => {TYPE => 'INT3', NOTNULL => 1},
+    ],
+    INDEXES => [
+        trace_short_hash_idx => ['short_hash'],
+        trace_full_hash_idx  => ['full_hash'],
+    ],
+};
diff --git a/code/install-requirements.pl b/code/install-requirements.pl
new file mode 100644
index 0000000..d99d9f6
--- /dev/null
+++ b/code/install-requirements.pl
@@ -0,0 +1,35 @@
+# -*- Mode: perl; indent-tabs-mode: nil -*-
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Bugzilla Traceparser Plugin.
+#
+# The Initial Developer of the Original Code is Canonical Ltd.
+# Portions created by Canonical Ltd. are Copyright (C) 2009
+# Canonical Ltd. All Rights Reserved.
+#
+# Contributor(s):
+#   Max Kanat-Alexander <mkanat bugzilla org>
+
+
+use strict;
+use warnings;
+
+use constant REQUIRED_MODULES => [
+    {
+        package => 'Parse-StackTrace',
+        module  => 'Parse::StackTrace',
+        version => 0.04,
+    },
+];
+
+use constant OPTIONAL_MODULES => [
+];
diff --git a/code/install-update_db.pl b/code/install-update_db.pl
new file mode 100644
index 0000000..3a66f57
--- /dev/null
+++ b/code/install-update_db.pl
@@ -0,0 +1,64 @@
+# -*- Mode: perl; indent-tabs-mode: nil -*-
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Bugzilla Example Plugin.
+#
+# The Initial Developer of the Original Code is Canonical Ltd.
+# Portions created by Canonical Ltd. are Copyright (C) 2009 
+# Canonical Ltd. All Rights Reserved.
+#
+# Contributor(s): 
+#   Max Kanat-Alexander <mkanat bugzilla org>
+
+
+use strict;
+use warnings;
+use Bugzilla;
+use Bugzilla::Install::Util qw(indicate_progress);
+
+use TraceParser::Trace;
+
+use constant IGNORE_FUNCTIONS => qw(
+   __kernel_vsyscall
+   raise
+   abort
+);
+
+my $dbh = Bugzilla->dbh;
+my $has_traces = $dbh->selectrow_array('SELECT 1 FROM trace ' 
+                                        . $dbh->sql_limit('1'));
+if (!$has_traces) {
+    print "Parsing traces from comments...\n";
+    my $total = $dbh->selectrow_array('SELECT COUNT(*) FROM longdescs');
+
+    if ($dbh->isa('Bugzilla::DB::Mysql')) {
+        $dbh->{'mysql_use_result'} = 1;
+    }
+
+    $dbh->bz_start_transaction();
+    my $sth = $dbh->prepare('SELECT bug_id,thetext FROM longdescs');
+    $sth->execute();
+    my $count = 0;
+    while (my ($bug_id, $text) = $sth->fetchrow_array) {
+        $count++;
+        my $trace = TraceParser::Trace->parse_from_text($text);
+        indicate_progress({ current => $count, total => $total, 
+                            every => 100 });
+        next if !$trace;
+        TraceParser::Trace->create({ %$trace, bug_id => $bug_id });
+    }
+    $dbh->bz_commit_transaction();
+
+    if ($dbh->isa('Bugzilla::DB::Mysql')) {
+        $dbh->{'mysql_use_result'} = 0;
+    }
+}
diff --git a/info.pl b/info.pl
new file mode 100644
index 0000000..f119902
--- /dev/null
+++ b/info.pl
@@ -0,0 +1,26 @@
+# -*- Mode: perl; indent-tabs-mode: nil -*-
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Bugzilla Traceparser Plugin
+#
+# The Initial Developer of the Original Code is Canonical Ltd.
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s): 
+#   Max Kanat-Alexander <mkanat bugzilla org>
+
+use strict;
+no warnings qw(void); # Avoid "useless use of a constant in void context"
+{
+    'version' => '0.01',
+};
diff --git a/lib/TraceParser/Trace.pm b/lib/TraceParser/Trace.pm
new file mode 100644
index 0000000..e0aa53a
--- /dev/null
+++ b/lib/TraceParser/Trace.pm
@@ -0,0 +1,165 @@
+# -*- Mode: perl; indent-tabs-mode: nil -*-
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Bugzilla Bug Tracking System.
+#
+# The Initial Developer of the Original Code is Canonical Ltd.
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s): 
+#   Max Kanat-Alexander <mkanat bugzilla org>
+
+package TraceParser::Trace;
+use strict;
+use base qw(Bugzilla::Object);
+
+use Bugzilla::Bug;
+use Bugzilla::Error;
+use Bugzilla::Util;
+
+use Parse::StackTrace;
+use Digest::MD5 qw(md5_base64);
+
+###############################
+####    Initialization     ####
+###############################
+
+use constant DB_COLUMNS => qw(
+    bug_id
+    has_symbols
+    id
+    full_hash
+    short_hash
+    type
+    quality
+);
+
+use constant DB_TABLE => 'trace';
+
+use constant VALIDATORS => {
+    bug_id      => \&_check_bug_id,
+    has_symbols => \&Bugzilla::Object::check_boolean,
+    full_hash   => \&_check_hash,
+    short_hash  => \&_check_hash,
+    short_stack => \&_check_short_stack,
+    type        => \&_check_type,
+    quality     => \&_check_quality,
+};
+
+use constant REQUIRED_CREATE_FIELDS => qw(type full_hash short_hash);
+
+# This is how long a Base64 MD5 Hash is.
+use constant HASH_SIZE => 22;
+
+use constant TRACE_TYPES => ['GDB', 'Python'];
+
+use constant IGNORE_FUNCTIONS => qw(
+   __kernel_vsyscall
+   raise
+   abort
+   ??
+);
+
+################
+# Constructors #
+################
+
+# Returns a hash suitable for passing to create() (without the bug_id
+# argument), or undef if there is no trace in the comment.
+sub parse_from_text {
+    my ($class, $text) = @_;
+    my $trace = Parse::StackTrace->parse(types => TRACE_TYPES, 
+                                         text => $text);
+    return undef if !$trace;
+
+    my @all_functions;
+    my $quality = 0;
+    my $crash_thread = $trace->thread_with_crash || $trace->threads->[0];
+    foreach my $frame (@{ $crash_thread->frames }) {
+        foreach my $item (qw(function args number file line code)) {
+            $quality++ if defined $frame->$item;
+        }
+        my $function = $frame->function;
+        if (defined $function && !grep($_ eq $function, IGNORE_FUNCTIONS)) {
+            push(@all_functions, $frame->function);
+        }
+    }
+
+    my $max_short_stack = $#all_functions > 4 ? 4 : $#all_functions;
+    my @short_stack = @all_functions[0..$max_short_stack];
+    my $full_hash = md5_base64(join(',', @all_functions));
+    my $short_hash = md5_base64(join(',', @short_stack));
+
+    return {
+        has_symbols => 0, # FIXME
+        full_hash   => $full_hash,
+        short_hash  => $short_hash,
+        short_stack => join(', ', @short_stack),
+        type        => ref($trace),
+        quality     => $quality,
+    };
+}
+
+###############################
+####      Accessors      ######
+###############################
+
+sub has_symbols { return $_[0]->{has_symbols}; }
+sub full_hash   { return $_[0]->{full_hash};   }
+sub short_hash  { return $_[0]->{short_hash};  }
+sub short_stack { return $_[0]->{short_stack}; }
+sub type        { return $_[0]->{type};        }
+sub quality     { return $_[0]->{quality};     }
+
+sub bug {
+    my $self = shift;
+    $self->{bug} ||= new Bugzilla::Bug($self->{bug_id});
+    return $self->{bug};
+}
+
+###############################
+###       Validators        ###
+###############################
+
+sub _check_bug_id {
+    my ($self, $bug_id) = @_;
+    return Bugzilla::Bug->check($bug_id)->id;
+}
+
+sub _check_hash {
+    my ($self, $hash) = @_;
+    $hash = trim($hash);
+    ThrowCodeError('traceparser_no_hash') if !$hash;
+    length($hash) == HASH_SIZE
+        or ThrowCodeError('traceparser_bad_hash', { hash => $hash });
+    return $hash;
+}
+
+sub _check_short_stack { return trim($_[1]) || '' }
+
+sub _check_type {
+    my ($invocant, $type) = @_;
+    $type = trim($type);
+    if (!$type)
+        my $class = ref($invocant) || $invocant;
+        ThrowCodeError('param_required', { function => "${class}::create",
+                                           param    => 'type' });
+    }
+    $type =~ /^Parse::StackTrace::Type/
+      or ThrowCodeError('traceparser_bad_type', { type => $type });
+    return $type;
+}
+
+sub _check_quality { return int($_[1]); }
+
+1;
diff --git a/template/en/global/code-error-errors.html b/template/en/global/code-error-errors.html
new file mode 100644
index 0000000..83d6838
--- /dev/null
+++ b/template/en/global/code-error-errors.html
@@ -0,0 +1,13 @@
+[% IF error == "traceparser_bad_hash" %]
+    [% title = "Bad Hash While Parsing Trace" %]
+    There was an error while parsing a stack trace. The following hash
+    is not a valid MD5 hash: [% hash FILTER html %].
+[% ELSIF error == "traceparser_bad_type" %]
+    [% title = "Bad Trace Type" %]
+    The <code>type</code> argument must be a class name starting with
+    <code>Parse::StackTrace::Type</code>.
+[% ELSIF error == "traceparser_no_hash" %]
+    [% title = "Hash Required" %]
+    You must specify a value for both the <code>full_hash</code> and
+    <code>short_hash</code> parameters.
+[% END %]


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]