File: detect_memory_leaks.t

package info (click to toggle)
libpromise-xs-perl 0.20-1
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 908 kB
  • sloc: perl: 1,097; ansic: 355; makefile: 3
file content (97 lines) | stat: -rw-r--r-- 2,016 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package t::detect_memory_leaks;

use strict;
use warnings;

use Test::More;
use Test::Deep;
use File::Temp;

use Promise::XS;

SKIP: {
    skip 'Windows, XS, fork, and heap allocation don’t get along.', 1 if $^O eq 'MSWin32';

    local $Promise::XS::DETECT_MEMORY_LEAKS = 1;

    my $deferred = Promise::XS::deferred();

    my $ar = [ $deferred ];
    push @$ar, $ar;

    my $fh = File::Temp::tempfile();

    my $pid = fork or do {
        close STDERR;
        open *STDERR, '>>&=', $fh;

        exit;
    };

    waitpid $pid, 0;

    is(
        (stat $fh)[7],
        0,
        'no warning on leak from subprocess',
    ) or do {
        sysseek $fh, 0, 0;

        my $buf = q<>;
        1 while sysread( $fh, $buf, 512, length $buf );

        diag $buf;
    };

    @$ar = ();
}

#----------------------------------------------------------------------

{
    my @inc_args = map { ( '-I', $_ ) } @INC;

    use File::Spec;
    my ($dir) = File::Spec->splitdir( __FILE__ );
    my $script_path = File::Spec->join( $dir, 'assets', 'deferred_leak.pl' );

    my $got = `"$^X" @inc_args -Mstrict -Mwarnings -MPromise::XS $script_path`;

    warn "CHILD_ERROR: $?" if $?;

    cmp_deeply(
        $got,
        all(
            re( qr<Promise::XS::Deferred=> ),
            re( qr<destr>i ),
        ),
        'warning about deferred object that persists to global destruction',
    );
}

#----------------------------------------------------------------------

{
    my @inc_args = map { ( '-I', $_ ) } @INC;

    use File::Spec;
    my ($dir) = File::Spec->splitdir( __FILE__ );
    my $script_path = File::Spec->join( $dir, 'assets', 'promise_leak.pl' );

    my $got = `$^X @inc_args -Mstrict -Mwarnings -MPromise::XS $script_path`;

    warn "CHILD_ERROR: $?" if $?;

    cmp_deeply(
        $got,
        all(
            re( qr<Promise::XS::Promise=> ),
            re( qr<destr>i ),
        ),
        'warning about promise object that persists to global destruction',
    );
}

done_testing;

1;