Fix incorrect whitespace test outside of checkouts
[dbsrgits/DBIx-Class.git] / t / lib / DBICTest / Util.pm
index 5911f9a..3bcbe89 100644 (file)
@@ -30,13 +30,13 @@ use constant {
 use Config;
 use Carp qw(cluck confess croak);
 use Fcntl qw( :DEFAULT :flock );
-use Scalar::Util qw(blessed refaddr);
+use Scalar::Util qw( blessed refaddr openhandle );
 use DBIx::Class::_Util qw( scope_guard parent_dir mkdir_p );
 
 use base 'Exporter';
 our @EXPORT_OK = qw(
-  dbg stacktrace
-  local_umask tmpdir find_co_root
+  dbg stacktrace class_seems_loaded
+  local_umask slurp_bytes tmpdir find_co_root rm_rf
   visit_namespaces PEEPEENESS
   check_customcond_args
   await_flock DEBUG_TEST_CONCURRENCY_LOCKS
@@ -88,7 +88,21 @@ sub await_flock ($$) {
 
     # "say something" every 10 cycles to work around RT#108390
     # jesus christ our tooling is such a crock of shit :(
-    print "#\n" if not $tries % 10;
+    unless ( $tries % 10 ) {
+
+      # Turning on autoflush is crucial: if stars align just right buffering
+      # will ensure we never actually call write() underneath until the grand
+      # timeout is reached (and that's too long). Reproducible via
+      #
+      # DBICTEST_VERSION_WARNS_INDISCRIMINATELY=1 \
+      # DBICTEST_RUN_ALL_TESTS=1 \
+      # strace -f \
+      # prove -lj10 xt/extra/internals/
+      #
+      select( ( select(\*STDOUT), $|=1 )[0] );
+
+      print "#\n";
+    }
   }
 
   return $res;
@@ -102,7 +116,7 @@ sub local_umask ($) {
     if ! defined wantarray;
 
   my $old_umask = umask($_[0]);
-  die "Setting umask failed: $!" unless defined $old_umask;
+  croak "Setting umask failed: $!" unless defined $old_umask;
 
   scope_guard(sub {
     local ($@, $!, $?);
@@ -246,6 +260,86 @@ EOE
 }
 
 
+sub slurp_bytes ($) {
+  croak "Expecting a file name, not a filehandle" if openhandle $_[0];
+  croak "'$_[0]' is not a readable filename" unless -f $_[0] && -r $_[0];
+  open my $fh, '<:raw', $_[0] or croak "Unable to open '$_[0]': $!";
+  local $/ unless wantarray;
+  <$fh>;
+}
+
+
+sub rm_rf ($) {
+  croak "No valid argument supplied to rm_rf()" unless length "$_[0]";
+
+  return unless -e $_[0];
+
+### I do not trust myself - check for subsuming ( the right way )
+### Avoid things like https://rt.cpan.org/Ticket/Display.html?id=111637
+  require Cwd;
+
+  my ($target, $tmp, $co_tmp) = map {
+
+    my $abs_fn = Cwd::abs_path("$_");
+
+    if ( $^O eq 'MSWin32' and length $abs_fn ) {
+
+      # sometimes we can get a short/longname mix, normalize everything to longnames
+      $abs_fn = Win32::GetLongPathName($abs_fn);
+
+      # Fixup for unixy (as opposed to native) slashes
+      $abs_fn =~ s|\\|/|g;
+    }
+
+    $abs_fn =~ s| (?<! / ) $ |/|x
+      if -d $abs_fn;
+
+    ( $abs_fn =~ /(.+)/s )[0]
+
+  } ( $_[0], tmpdir, find_co_root . 't/var' );
+
+  croak(
+    "Path supplied to rm_rf() '$target' is neither within the local nor the "
+  . "global scratch dirs ( '$co_tmp' and '$tmp' ): REFUSING TO `rm -rf` "
+  . 'at random'
+  ) unless (
+    ( index($target, $co_tmp) == 0 and $target ne $co_tmp )
+      or
+    ( index($target, $tmp) == 0    and $target ne $tmp )
+  );
+###
+
+  require File::Path;
+
+  # do not ask for a recent version, use 1.x API calls
+  File::Path::rmtree([ $target ]);
+}
+
+
+# This is an absolutely horrible thing to do on an end-user system
+# DO NOT use it indiscriminately - ideally under nothing short of ->is_smoker
+# Not added to EXPORT_OK on purpose
+sub can_alloc_MB ($) {
+  my $arg = shift;
+  $arg = 'UNDEF' if not defined $arg;
+
+  croak "Expecting a positive integer, got '$arg'"
+    if $arg !~ /^[1-9][0-9]*$/;
+
+  my ($perl) = $^X =~ /(.+)/;
+  local $ENV{PATH};
+  local $ENV{PERL5LIB} = join ($Config{path_sep}, @INC);
+
+  local ( $!, $^E, $?, $@ );
+
+  system( $perl, qw( -Mt::lib::ANFANG -e ), <<'EOS', $arg );
+$0 = 'malloc_canary';
+my $tail_character_of_reified_megastring = substr( ( join '', map chr, 0..255 ) x (4 * 1024 * $ARGV[0]), -1 );
+EOS
+
+  !!( $? == 0 )
+}
+
 sub stacktrace {
   my $frame = shift;
   $frame++;
@@ -337,4 +431,27 @@ sub visit_namespaces {
   return $visited_count;
 }
 
+#
+# Replicate the *heuristic* (important!!!) implementation found in various
+# forms within Class::Load / Module::Inspector / Class::C3::Componentised
+#
+sub class_seems_loaded ($) {
+
+  croak "Function expects a class name as plain string (no references)"
+    unless defined $_[0] and not length ref $_[0];
+
+  no strict 'refs';
+
+  return 1 if defined ${"$_[0]::VERSION"};
+
+  return 1 if @{"$_[0]::ISA"};
+
+  return 1 if $INC{ (join ('/', split ('::', $_[0]) ) ) . '.pm' };
+
+  ( !!*{"$_[0]::$_"}{CODE} ) and return 1
+    for keys %{"$_[0]::"};
+
+  return 0;
+}
+
 1;