Try to avoid strange failures when 1 == 1 doesn't give us PL_sv_yes.
Nicholas Clark [Wed, 21 Jun 2017 20:09:45 +0000 (22:09 +0200)]
The intent of these tests is to confirm that the interpreter variables
PL_sv_undef, PL_sv_no and PL_sv_yes are not reported as part of the size.
It seems that on some older threaded perls with newer versions of
Test::More, we can end up with 1 == 1 not passing PL_sv_yes into
total_size(), presuambly because some code in Test::More has also caused
PL_sv_yes to end up in a pad slot.

The ugly (and possibly fragile) fix seems to be to ensure that our test code
is the first thing to get compiled, by moving the load of Test::More later.

CHANGES
t/basic.t

diff --git a/CHANGES b/CHANGES
index 83514ac..9133d0d 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,7 @@
 Revision history for Perl extension Devel::Size.
 
 0.80_50 2017-06-21 nicholas
+  * Attempt to fix strange 1 == 1 failures on some older threaded perls.
 
 0.80 2015-03-31 nicholas
  [no changes]
index 0dd3e9e..3827601 100644 (file)
--- a/t/basic.t
+++ b/t/basic.t
@@ -1,7 +1,28 @@
 #!/usr/bin/perl -w
 
-use Test::More tests => 30;
 use strict;
+
+# I'm not sure if this is "too hacky to live".
+# It seems that for some newer versions of Test::More on older perls, if the
+# test for total_size(1 == 1) is *after* the load of test more, then the test
+# fails. I infer that something in Test::More is also ending up with PL_sv_yes
+# in a pad temp somewhere, and whatever gets compiled first gets to keep the
+# real one, and everyone afterwards gets forced to have a copy. (For ithreads).
+# And I'm not even sure if this is a bug that was fixed (in the constant code)
+# or a necessary evil that survives, and it's pure chance when it hits.
+sub specials {
+    # Must call direct - avoid all copying:
+    foreach(['undef', total_size(undef)],
+            ['no', total_size(1 == 0)],
+            ['yes', total_size(1 == 1)],
+        ) {
+        my ($name, $size) = @$_;
+        is($size, 0,
+           "PL_sv_$name is interpeter wide, so not counted as part of the structure's size");
+    }
+}
+
+use Test::More tests => 30;
 use Devel::Size qw(size total_size);
 
 can_ok ('Devel::Size', qw/
@@ -99,15 +120,7 @@ cmp_ok (total_size(\&LARGE), '>', 8192,
        'Any intial reference is dereferenced and discarded');
 }
 
-# Must call direct - avoid all copying:
-foreach(['undef', total_size(undef)],
-       ['no', total_size(1 == 0)],
-       ['yes', total_size(1 == 1)],
-       ) {
-    my ($name, $size) = @$_;
-    is($size, 0,
-       "PL_sv_$name is interpeter wide, so not counted as part of the structure's size");
-}
+specials();
 
 {
     # SvOOK stuff