Repository: lucy-clownfish
Updated Branches:
  refs/heads/master 6bde44eef -> 811d2ef68


Add test_valgrind action for Clownfish compiler

Also skip some tests with leaky exceptions under Valgrind.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/811d2ef6
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/811d2ef6
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/811d2ef6

Branch: refs/heads/master
Commit: 811d2ef68793a4bd09b97c677363caeb2b685948
Parents: 6bde44e
Author: Nick Wellnhofer <[email protected]>
Authored: Mon Jul 28 16:24:56 2014 +0200
Committer: Nick Wellnhofer <[email protected]>
Committed: Mon Jul 28 16:24:56 2014 +0200

----------------------------------------------------------------------
 compiler/perl/buildlib/Clownfish/CFC/Build.pm | 80 ++++++++++++++++++++++
 compiler/perl/t/401-class.t                   | 46 +++++++------
 compiler/perl/t/502-clash.t                   | 20 ++++--
 devel/conf/cfcompiler-perl.supp               | 23 +++++++
 4 files changed, 145 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/811d2ef6/compiler/perl/buildlib/Clownfish/CFC/Build.pm
----------------------------------------------------------------------
diff --git a/compiler/perl/buildlib/Clownfish/CFC/Build.pm 
b/compiler/perl/buildlib/Clownfish/CFC/Build.pm
index 9f9d1f0..c6bf5a3 100644
--- a/compiler/perl/buildlib/Clownfish/CFC/Build.pm
+++ b/compiler/perl/buildlib/Clownfish/CFC/Build.pm
@@ -170,6 +170,86 @@ sub ACTION_code {
     $self->SUPER::ACTION_code;
 }
 
+sub _valgrind_base_command {
+    return
+          "PERL_DESTRUCT_LEVEL=2 LUCY_VALGRIND=1 valgrind "
+        . "--leak-check=yes "
+        . "--show-reachable=yes "
+        . "--dsymutil=yes "
+        . "--suppressions=../../devel/conf/cfcompiler-perl.supp ";
+}
+
+# Run the entire test suite under Valgrind.
+#
+# For this to work, Lucy must be compiled with the LUCY_VALGRIND environment
+# variable set to a true value, under a debugging Perl.
+#
+# A custom suppressions file will probably be needed -- use your judgment.
+# To pass in one or more local suppressions files, provide a comma separated
+# list like so:
+#
+#   $ ./Build test_valgrind --suppressions=foo.supp,bar.supp
+sub ACTION_test_valgrind {
+    my $self = shift;
+    # Debian's debugperl uses the Config.pm of the standard system perl
+    # so -DDEBUGGING won't be detected.
+    die "Must be run under a perl that was compiled with -DDEBUGGING"
+        unless $self->config('ccflags') =~ /-D?DEBUGGING\b/
+               || $^X =~ /\bdebugperl\b/;
+    if ( !$ENV{LUCY_VALGRIND} ) {
+        warn "\$ENV{LUCY_VALGRIND} not true -- possible false positives";
+    }
+    $self->depends_on('code');
+
+    # Unbuffer STDOUT, grab test file names and suppressions files.
+    $|++;
+    my $t_files = $self->find_test_files;    # not public M::B API, may fail
+    my $valgrind_command = $self->_valgrind_base_command;
+
+    if ( my $local_supp = $self->args('suppressions') ) {
+        for my $supp ( split( ',', $local_supp ) ) {
+            $valgrind_command .= "--suppressions=$supp ";
+        }
+    }
+
+    # Iterate over test files.
+    my @failed;
+    for my $t_file (@$t_files) {
+
+        # Run test file under Valgrind.
+        print "Testing $t_file...";
+        die "Can't find '$t_file'" unless -f $t_file;
+        my $command = "$valgrind_command $^X -Mblib $t_file 2>&1";
+        my $output = "\n" . ( scalar localtime(time) ) . "\n$command\n";
+        $output .= `$command`;
+
+        # Screen-scrape Valgrind output, looking for errors and leaks.
+        if (   $?
+            or $output =~ /ERROR SUMMARY:\s+[^0\s]/
+            or $output =~ /definitely lost:\s+[^0\s]/
+            or $output =~ /possibly lost:\s+[^0\s]/
+            or $output =~ /still reachable:\s+[^0\s]/ )
+        {
+            print " failed.\n";
+            push @failed, $t_file;
+            print "$output\n";
+        }
+        else {
+            print " succeeded.\n";
+        }
+    }
+
+    # If there are failed tests, print a summary list.
+    if (@failed) {
+        print "\nFailed "
+            . scalar @failed . "/"
+            . scalar @$t_files
+            . " test files:\n    "
+            . join( "\n    ", @failed ) . "\n";
+        exit(1);
+    }
+}
+
 sub ACTION_dist {
     my $self = shift;
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/811d2ef6/compiler/perl/t/401-class.t
----------------------------------------------------------------------
diff --git a/compiler/perl/t/401-class.t b/compiler/perl/t/401-class.t
index 5a44c57..f137cf4 100644
--- a/compiler/perl/t/401-class.t
+++ b/compiler/perl/t/401-class.t
@@ -57,26 +57,32 @@ my $should_be_foo = 
Clownfish::CFC::Model::Class->fetch_singleton(
 );
 is( $$foo, $$should_be_foo, "fetch_singleton" );
 
-eval { Clownfish::CFC::Model::Class->create(%foo_create_args) };
-like( $@, qr/two classes with name/i,
-      "Can't call create for the same class more than once" );
-eval {
-    Clownfish::CFC::Model::Class->create(
-        parcel     => 'Neato',
-        class_name => 'Other::Foo',
-    );
-};
-like( $@, qr/class name conflict/i,
-      "Can't create classes wth the same final component" );
-eval {
-    Clownfish::CFC::Model::Class->create(
-        parcel     => 'Neato',
-        class_name => 'Bar',
-        nickname   => 'Foo',
-    );
-};
-like( $@, qr/class nickname conflict/i,
-      "Can't create classes wth the same nickname" );
+SKIP: {
+    skip( 'Exceptions leak', 3 )
+        if $ENV{LUCY_VALGRIND};
+
+    eval { Clownfish::CFC::Model::Class->create(%foo_create_args) };
+    like( $@, qr/two classes with name/i,
+          "Can't call create for the same class more than once" );
+
+    eval {
+        Clownfish::CFC::Model::Class->create(
+            parcel     => 'Neato',
+            class_name => 'Other::Foo',
+        );
+    };
+    like( $@, qr/class name conflict/i,
+          "Can't create classes wth the same final component" );
+    eval {
+        Clownfish::CFC::Model::Class->create(
+            parcel     => 'Neato',
+            class_name => 'Bar',
+            nickname   => 'Foo',
+        );
+    };
+    like( $@, qr/class nickname conflict/i,
+          "Can't create classes wth the same nickname" );
+}
 
 my $foo_jr = Clownfish::CFC::Model::Class->create(
     parcel            => 'Neato',

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/811d2ef6/compiler/perl/t/502-clash.t
----------------------------------------------------------------------
diff --git a/compiler/perl/t/502-clash.t b/compiler/perl/t/502-clash.t
index ae64da1..cd875f0 100644
--- a/compiler/perl/t/502-clash.t
+++ b/compiler/perl/t/502-clash.t
@@ -28,7 +28,10 @@ my $dest_dir        = catdir(qw( t cfdest ));
 my $class_clash_dir = catdir(qw( t cfclash class ));
 my $file_clash_dir  = catdir(qw( t cfclash file ));
 
-{
+SKIP: {
+    skip( 'Exceptions leak', 1 )
+        if $ENV{LUCY_VALGRIND};
+
     my $hierarchy = Clownfish::CFC::Model::Hierarchy->new(dest => $dest_dir);
 
     $hierarchy->add_source_dir($base_dir);
@@ -44,7 +47,10 @@ my $file_clash_dir  = catdir(qw( t cfclash file ));
     Clownfish::CFC::Model::Parcel->reap_singletons();
 }
 
-{
+SKIP: {
+    skip( 'Exceptions leak', 1 )
+        if $ENV{LUCY_VALGRIND};
+
     my $hierarchy = Clownfish::CFC::Model::Hierarchy->new(dest => $dest_dir);
 
     $hierarchy->add_source_dir($class_clash_dir);
@@ -78,7 +84,10 @@ my $file_clash_dir  = catdir(qw( t cfclash file ));
 my $foo_dir = catdir(qw( t cfclash foo ));
 my $bar_dir = catdir(qw( t cfclash bar ));
 
-{
+SKIP: {
+    skip( 'Exceptions leak', 1 )
+        if $ENV{LUCY_VALGRIND};
+
     my $hierarchy = Clownfish::CFC::Model::Hierarchy->new(dest => $dest_dir);
 
     $hierarchy->add_source_dir($foo_dir);
@@ -94,7 +103,10 @@ my $bar_dir = catdir(qw( t cfclash bar ));
     Clownfish::CFC::Model::Parcel->reap_singletons();
 }
 
-{
+SKIP: {
+    skip( 'Exceptions leak', 1 )
+        if $ENV{LUCY_VALGRIND};
+
     my $hierarchy = Clownfish::CFC::Model::Hierarchy->new(dest => $dest_dir);
 
     $hierarchy->add_source_dir($bar_dir);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/811d2ef6/devel/conf/cfcompiler-perl.supp
----------------------------------------------------------------------
diff --git a/devel/conf/cfcompiler-perl.supp b/devel/conf/cfcompiler-perl.supp
new file mode 100644
index 0000000..37e44d0
--- /dev/null
+++ b/devel/conf/cfcompiler-perl.supp
@@ -0,0 +1,23 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (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.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+{
+   <XS_DynaLoader_dl_load_file>
+   Memcheck:Leak
+   ...
+   fun:XS_DynaLoader_dl_load_file
+   ...
+}
+

Reply via email to