File: fork-01.t

package info (click to toggle)
libzmq-ffi-perl 1.17-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 504 kB
  • sloc: perl: 4,317; sh: 92; ansic: 30; makefile: 27
file content (143 lines) | stat: -rw-r--r-- 3,267 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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
use strict;
use warnings;

use Test::More;
use Test::Warnings;

use ZMQ::FFI qw(ZMQ_REQ);

#
# Test that we guard against trying to clean up context/sockets
# created in a parent process in forked children
#

my $parent_c = ZMQ::FFI->new();
my $parent_s = $parent_c->socket(ZMQ_REQ);

my $parent_s_closed;
my $parent_c_destroyed;

my ($major, $minor) = $parent_c->version;
if ($major == 2) {
    no warnings qw/redefine once/;

    local *ZMQ::FFI::ZMQ2::Socket::zmq_close = sub {
        $parent_s_closed = 1;
    };

    local *ZMQ::FFI::ZMQ2::Context::zmq_term = sub {
        $parent_c_destroyed = 1;
    };

    use warnings;

    pid_test();
}
elsif ($major == 3) {
    no warnings qw/redefine once/;

    local *ZMQ::FFI::ZMQ3::Socket::zmq_close = sub {
        $parent_s_closed = 1;
    };

    local *ZMQ::FFI::ZMQ3::Context::zmq_ctx_destroy = sub {
        $parent_c_destroyed = 1;
    };

    use warnings;

    pid_test();
}
else {
    if ($major == 4 and $minor == 0) {
        no warnings qw/redefine once/;

        local *ZMQ::FFI::ZMQ4::Socket::zmq_close = sub {
            $parent_s_closed = 1;
        };

	local *ZMQ::FFI::ZMQ4::Context::zmq_ctx_term = sub {
	    $parent_c_destroyed = 1;
	};
	
	use warnings;
	
	pid_test();
    }
    else {
	no warnings qw/redefine once/;

        local *ZMQ::FFI::ZMQ4_1::Socket::zmq_close = sub {
            $parent_s_closed = 1;
        };

	local *ZMQ::FFI::ZMQ4_1::Context::zmq_ctx_term = sub {
	    $parent_c_destroyed = 1;
	};
	
	use warnings;
	
	pid_test();
    }
}

sub pid_test {
    my $child_pid = open(FROM_CHILDTEST, '-|') // die "fork failed $!";

    if ($child_pid) {
        # parent process, do test assertions here

        my $result;
        read(FROM_CHILDTEST, $result, 128);

        waitpid $child_pid, 0;

        is $result, 'ok',
            'child process skipped parent ctx/socket cleanup';


        ok $parent_c->_pid == $$, "parent context pid _should_ match parent pid";
        ok $parent_s->_pid == $$, "parent socket pid _should_ match parent pid";

        # explicitly undef ctx/socket created in parent to trigger DEMOLISH/
        # cleanup logic.. then verify that close/destroy _was_ called
        # for ctx/socket created in parent

        undef $parent_s;
        undef $parent_c;

        ok $parent_s_closed, "parent socket closed in parent";
        ok $parent_c_destroyed, "parent context destroyed in parent";
    }
    else {
        # check test expectataions and print 'ok' if successful

        if ( $parent_c->_pid == $$ ) {
            print "parent context pid _should not_ match child pid"; exit;
        }

        if ( $parent_s->_pid == $$ ) {
            print "parent socket pid _should not_ match child pid"; exit;
        }

        # explicitly undef ctx/socket cloned from parent to trigger DEMOLISH/
        # cleanup logic.. then verify that close/destroy _was not_ called
        # for ctx/socket created in parent

        undef $parent_s;
        undef $parent_c;

        if ( $parent_s_closed ) {
            print "parent socket closed in child!"; exit;
        }

        if ( $parent_c_destroyed) {
            print "parent context destroyed in child!"; exit;
        }

        print 'ok';
        exit;
    }
}

done_testing;