Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package perl-Test-Future-IO-Impl for openSUSE:Factory checked in at 2025-07-21 20:00:14 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/perl-Test-Future-IO-Impl (Old) and /work/SRC/openSUSE:Factory/.perl-Test-Future-IO-Impl.new.8875 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-Test-Future-IO-Impl" Mon Jul 21 20:00:14 2025 rev:2 rq:1294558 version:0.150.0 Changes: -------- --- /work/SRC/openSUSE:Factory/perl-Test-Future-IO-Impl/perl-Test-Future-IO-Impl.changes 2023-05-12 20:35:31.389285708 +0200 +++ /work/SRC/openSUSE:Factory/.perl-Test-Future-IO-Impl.new.8875/perl-Test-Future-IO-Impl.changes 2025-07-21 20:00:52.676528040 +0200 @@ -1,0 +2,12 @@ +Wed Jul 16 05:41:39 UTC 2025 - Tina Müller <timueller+p...@suse.de> + +- updated to 0.150.0 (0.15) + see /usr/share/doc/packages/perl-Test-Future-IO-Impl/Changes + + 0.15 2025-07-15 + [CHANGES] + * Added tests for `send`, `recv` and `recvfrom` methods + * Provide copies of `sysread` and `syswrite` tests named `read` and + `write` + +------------------------------------------------------------------- Old: ---- Test-Future-IO-Impl-0.14.tar.gz New: ---- Test-Future-IO-Impl-0.15.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-Test-Future-IO-Impl.spec ++++++ --- /var/tmp/diff_new_pack.q0rvBq/_old 2025-07-21 20:00:54.192591131 +0200 +++ /var/tmp/diff_new_pack.q0rvBq/_new 2025-07-21 20:00:54.196591297 +0200 @@ -1,7 +1,7 @@ # # spec file for package perl-Test-Future-IO-Impl # -# Copyright (c) 2023 SUSE LLC +# Copyright (c) 2025 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,19 +18,23 @@ %define cpan_name Test-Future-IO-Impl Name: perl-Test-Future-IO-Impl -Version: 0.14 +Version: 0.150.0 Release: 0 +# 0.15 -> normalize -> 0.150.0 +%define cpan_version 0.15 License: Artistic-1.0 OR GPL-1.0-or-later Summary: Acceptance tests for Future::IO implementations URL: https://metacpan.org/release/%{cpan_name} -Source0: https://cpan.metacpan.org/authors/id/P/PE/PEVANS/%{cpan_name}-%{version}.tar.gz +Source0: https://cpan.metacpan.org/authors/id/P/PE/PEVANS/%{cpan_name}-%{cpan_version}.tar.gz Source1: cpanspec.yml BuildArch: noarch BuildRequires: perl BuildRequires: perl-macros -BuildRequires: perl(Module::Build) >= 0.400400 +BuildRequires: perl(Module::Build) >= 0.400.400 BuildRequires: perl(Test2::V0) Requires: perl(Test2::V0) +Provides: perl(Test::Future::IO::Impl) = %{version} +%undefine __perllib_provides %{perl_requires} %description @@ -38,17 +42,17 @@ of Future::IO. %prep -%autosetup -n %{cpan_name}-%{version} +%autosetup -n %{cpan_name}-%{cpan_version} -p1 %build -perl Build.PL installdirs=vendor -./Build build flags=%{?_smp_mflags} +perl Build.PL --installdirs=vendor +./Build build --flags=%{?_smp_mflags} %check ./Build test %install -./Build install destdir=%{buildroot} create_packlist=0 +./Build install --destdir=%{buildroot} --create_packlist=0 %perl_gen_filelist %files -f %{name}.files ++++++ Test-Future-IO-Impl-0.14.tar.gz -> Test-Future-IO-Impl-0.15.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Test-Future-IO-Impl-0.14/.editorconfig new/Test-Future-IO-Impl-0.15/.editorconfig --- old/Test-Future-IO-Impl-0.14/.editorconfig 1970-01-01 01:00:00.000000000 +0100 +++ new/Test-Future-IO-Impl-0.15/.editorconfig 2025-07-15 21:39:50.000000000 +0200 @@ -0,0 +1,4 @@ +root = true + +[*.{pm,pl,t}] +indent_size = 3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Test-Future-IO-Impl-0.14/Changes new/Test-Future-IO-Impl-0.15/Changes --- old/Test-Future-IO-Impl-0.14/Changes 2023-04-25 14:00:49.000000000 +0200 +++ new/Test-Future-IO-Impl-0.15/Changes 2025-07-15 21:39:50.000000000 +0200 @@ -1,5 +1,11 @@ Revision history for Test-Future-IO-Impl +0.15 2025-07-15 + [CHANGES] + * Added tests for `send`, `recv` and `recvfrom` methods + * Provide copies of `sysread` and `syswrite` tests named `read` and + `write` + 0.14 2023-04-25 [CHANGES] * Split from Future-IO distribution diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Test-Future-IO-Impl-0.14/LICENSE new/Test-Future-IO-Impl-0.15/LICENSE --- old/Test-Future-IO-Impl-0.14/LICENSE 2023-04-25 14:00:49.000000000 +0200 +++ new/Test-Future-IO-Impl-0.15/LICENSE 2025-07-15 21:39:50.000000000 +0200 @@ -1,4 +1,4 @@ -This software is copyright (c) 2023 by Paul Evans <leon...@leonerd.org.uk>. +This software is copyright (c) 2025 by Paul Evans <leon...@leonerd.org.uk>. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. @@ -12,7 +12,7 @@ --- The GNU General Public License, Version 1, February 1989 --- -This software is Copyright (c) 2023 by Paul Evans <leon...@leonerd.org.uk>. +This software is Copyright (c) 2025 by Paul Evans <leon...@leonerd.org.uk>. This is free software, licensed under: @@ -270,110 +270,143 @@ That's all there is to it! ---- The Artistic License 1.0 --- +--- The Perl Artistic License 1.0 --- -This software is Copyright (c) 2023 by Paul Evans <leon...@leonerd.org.uk>. +This software is Copyright (c) 2025 by Paul Evans <leon...@leonerd.org.uk>. This is free software, licensed under: - The Artistic License 1.0 + The Perl Artistic License 1.0 -The Artistic License -Preamble -The intent of this document is to state the conditions under which a Package -may be copied, such that the Copyright Holder maintains some semblance of -artistic control over the development of the package, while giving the users of -the package the right to use and distribute the Package in a more-or-less -customary fashion, plus the right to make reasonable modifications. + + + The "Artistic License" + + Preamble + +The intent of this document is to state the conditions under which a +Package may be copied, such that the Copyright Holder maintains some +semblance of artistic control over the development of the package, +while giving the users of the package the right to use and distribute +the Package in a more-or-less customary fashion, plus the right to make +reasonable modifications. Definitions: - - "Package" refers to the collection of files distributed by the Copyright - Holder, and derivatives of that collection of files created through - textual modification. - - "Standard Version" refers to such a Package if it has not been modified, - or has been modified in accordance with the wishes of the Copyright - Holder. - - "Copyright Holder" is whoever is named in the copyright or copyrights for - the package. - - "You" is you, if you're thinking about copying or distributing this Package. - - "Reasonable copying fee" is whatever you can justify on the basis of media - cost, duplication charges, time of people involved, and so on. (You will - not be required to justify it to the Copyright Holder, but only to the - computing community at large as a market that must bear the fee.) - - "Freely Available" means that no fee is charged for the item itself, though - there may be fees involved in handling the item. It also means that - recipients of the item may redistribute it under the same conditions they - received it. + "Package" refers to the collection of files distributed by the + Copyright Holder, and derivatives of that collection of files + created through textual modification. + + "Standard Version" refers to such a Package if it has not been + modified, or has been modified in accordance with the wishes + of the Copyright Holder as specified below. + + "Copyright Holder" is whoever is named in the copyright or + copyrights for the package. + + "You" is you, if you're thinking about copying or distributing + this Package. + + "Reasonable copying fee" is whatever you can justify on the + basis of media cost, duplication charges, time of people involved, + and so on. (You will not be required to justify it to the + Copyright Holder, but only to the computing community at large + as a market that must bear the fee.) + + "Freely Available" means that no fee is charged for the item + itself, though there may be fees involved in handling the item. + It also means that recipients of the item may redistribute it + under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. -2. You may apply bug fixes, portability fixes and other modifications derived -from the Public Domain or from the Copyright Holder. A Package modified in such -a way shall still be considered the Standard Version. - -3. You may otherwise modify your copy of this Package in any way, provided that -you insert a prominent notice in each changed file stating how and when you -changed that file, and provided that you do at least ONE of the following: - - a) place your modifications in the Public Domain or otherwise make them - Freely Available, such as by posting said modifications to Usenet or an - equivalent medium, or placing the modifications on a major archive site - such as ftp.uu.net, or by allowing the Copyright Holder to include your - modifications in the Standard Version of the Package. - - b) use the modified Package only within your corporation or organization. - - c) rename any non-standard executables so the names do not conflict with - standard executables, which must also be provided, and provide a separate - manual page for each non-standard executable that clearly documents how it - differs from the Standard Version. - - d) make other distribution arrangements with the Copyright Holder. - -4. You may distribute the programs of this Package in object code or executable -form, provided that you do at least ONE of the following: - - a) distribute a Standard Version of the executables and library files, - together with instructions (in the manual page or equivalent) on where to - get the Standard Version. - - b) accompany the distribution with the machine-readable source of the Package - with your modifications. - - c) accompany any non-standard executables with their corresponding Standard - Version executables, giving the non-standard executables non-standard - names, and clearly documenting the differences in manual pages (or - equivalent), together with instructions on where to get the Standard - Version. +2. You may apply bug fixes, portability fixes and other modifications +derived from the Public Domain or from the Copyright Holder. A Package +modified in such a way shall still be considered the Standard Version. - d) make other distribution arrangements with the Copyright Holder. +3. You may otherwise modify your copy of this Package in any way, provided +that you insert a prominent notice in each changed file stating how and +when you changed that file, and provided that you do at least ONE of the +following: -5. You may charge a reasonable copying fee for any distribution of this -Package. You may charge any fee you choose for support of this Package. You -may not charge a fee for this Package itself. However, you may distribute this -Package in aggregate with other (possibly commercial) programs as part of a -larger (possibly commercial) software distribution provided that you do not -advertise this Package as a product of your own. - -6. The scripts and library files supplied as input to or produced as output -from the programs of this Package do not automatically fall under the copyright -of this Package, but belong to whomever generated them, and may be sold -commercially, and may be aggregated with this Package. + a) place your modifications in the Public Domain or otherwise make them + Freely Available, such as by posting said modifications to Usenet or + an equivalent medium, or placing the modifications on a major archive + site such as uunet.uu.net, or by allowing the Copyright Holder to include + your modifications in the Standard Version of the Package. + + b) use the modified Package only within your corporation or organization. + + c) rename any non-standard executables so the names do not conflict + with standard executables, which must also be provided, and provide + a separate manual page for each non-standard executable that clearly + documents how it differs from the Standard Version. -7. C or perl subroutines supplied by you and linked into this Package shall not -be considered part of this Package. + d) make other distribution arrangements with the Copyright Holder. + +4. You may distribute the programs of this Package in object code or +executable form, provided that you do at least ONE of the following: + + a) distribute a Standard Version of the executables and library files, + together with instructions (in the manual page or equivalent) on where + to get the Standard Version. + + b) accompany the distribution with the machine-readable source of + the Package with your modifications. + + c) give non-standard executables non-standard names, and clearly + document the differences in manual pages (or equivalent), together + with instructions on where to get the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + +5. You may charge a reasonable copying fee for any distribution of this +Package. You may charge any fee you choose for support of this +Package. You may not charge a fee for this Package itself. However, +you may distribute this Package in aggregate with other (possibly +commercial) programs as part of a larger (possibly commercial) software +distribution provided that you do not advertise this Package as a +product of your own. You may embed this Package's interpreter within +an executable of yours (by linking); this shall be construed as a mere +form of aggregation, provided that the complete Standard Version of the +interpreter is so embedded. + +6. The scripts and library files supplied as input to or produced as +output from the programs of this Package do not automatically fall +under the copyright of this Package, but belong to whoever generated +them, and may be sold commercially, and may be aggregated with this +Package. If such scripts or library files are aggregated with this +Package via the so-called "undump" or "unexec" methods of producing a +binary executable image, then distribution of such an image shall +neither be construed as a distribution of this Package nor shall it +fall under the restrictions of Paragraphs 3 and 4, provided that you do +not represent such an executable image as a Standard Version of this +Package. + +7. C subroutines (or comparably compiled subroutines in other +languages) supplied by you and linked into this Package in order to +emulate subroutines and variables of the language defined by this +Package shall not be considered part of this Package, but are the +equivalent of input as in Paragraph 6, provided these subroutines do +not change the language in any way that would cause it to fail the +regression tests for the language. + +8. Aggregation of this Package with a commercial distribution is always +permitted provided that the use of this Package is embedded; that is, +when no overt attempt is made to make this Package's interfaces visible +to the end user of the commercial distribution. Such use shall not be +construed as a distribution of this Package. -8. The name of the Copyright Holder may not be used to endorse or promote +9. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. -9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -The End + The End diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Test-Future-IO-Impl-0.14/MANIFEST new/Test-Future-IO-Impl-0.15/MANIFEST --- old/Test-Future-IO-Impl-0.14/MANIFEST 2023-04-25 14:00:49.000000000 +0200 +++ new/Test-Future-IO-Impl-0.15/MANIFEST 2025-07-15 21:39:50.000000000 +0200 @@ -1,10 +1,11 @@ +.editorconfig Build.PL Changes lib/Test/Future/IO/Impl.pm +LICENSE MANIFEST This list of files +META.json +META.yml README t/00use.t t/99pod.t -LICENSE -META.yml -META.json diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Test-Future-IO-Impl-0.14/META.json new/Test-Future-IO-Impl-0.15/META.json --- old/Test-Future-IO-Impl-0.14/META.json 2023-04-25 14:00:49.000000000 +0200 +++ new/Test-Future-IO-Impl-0.15/META.json 2025-07-15 21:39:50.000000000 +0200 @@ -4,7 +4,7 @@ "Paul Evans <leon...@leonerd.org.uk>" ], "dynamic_config" : 1, - "generated_by" : "Module::Build version 0.4231", + "generated_by" : "Module::Build version 0.4234", "license" : [ "perl_5" ], @@ -33,7 +33,7 @@ "provides" : { "Test::Future::IO::Impl" : { "file" : "lib/Test/Future/IO/Impl.pm", - "version" : "0.14" + "version" : "0.15" } }, "release_status" : "stable", @@ -42,6 +42,6 @@ "http://dev.perl.org/licenses/" ] }, - "version" : "0.14", - "x_serialization_backend" : "JSON::PP version 4.07" + "version" : "0.15", + "x_serialization_backend" : "JSON::PP version 4.16" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Test-Future-IO-Impl-0.14/META.yml new/Test-Future-IO-Impl-0.15/META.yml --- old/Test-Future-IO-Impl-0.14/META.yml 2023-04-25 14:00:49.000000000 +0200 +++ new/Test-Future-IO-Impl-0.15/META.yml 2025-07-15 21:39:50.000000000 +0200 @@ -6,7 +6,7 @@ configure_requires: Module::Build: '0.4004' dynamic_config: 1 -generated_by: 'Module::Build version 0.4231, CPAN::Meta::Converter version 2.150010' +generated_by: 'Module::Build version 0.4234, CPAN::Meta::Converter version 2.150010' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html @@ -15,7 +15,7 @@ provides: Test::Future::IO::Impl: file: lib/Test/Future/IO/Impl.pm - version: '0.14' + version: '0.15' requires: Errno: '0' IO::Handle: '0' @@ -25,5 +25,5 @@ perl: '5.014' resources: license: http://dev.perl.org/licenses/ -version: '0.14' +version: '0.15' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Test-Future-IO-Impl-0.14/README new/Test-Future-IO-Impl-0.15/README --- old/Test-Future-IO-Impl-0.14/README 2023-04-25 14:00:49.000000000 +0200 +++ new/Test-Future-IO-Impl-0.15/README 2025-07-15 21:39:50.000000000 +0200 @@ -24,7 +24,7 @@ run_tests - run_tests @suitenames + run_tests @suitenames; Runs a collection of tests against Future::IO. It is expected that the caller has already loaded the specific implementation module to be @@ -43,17 +43,37 @@ Tests the Future::IO->connect method. + recv, recvfrom + + Since version 0.15. + + Tests the Future::IO->recv and Future::IO->recvfrom methods. + + send + + Since version 0.15. + + Tests the Future::IO->send method. + sleep Tests the Future::IO->sleep method. - sysread + read, sysread + + Tests the Future::IO->sysread or Future::IO->sysread method. + + These two test suites are identical other than the name of the method + they invoke. The two exist because of the method rename that happened + at Future::IO version 0.17. - Tests the Future::IO->sysread method. + write, syswrite - syswrite + Tests the Future::IO->write or Future::IO->syswrite method. - Tests the Future::IO->syswrite method. + These two test suites are identical other than the name of the method + they invoke. The two exist because of the method rename that happened + at Future::IO version 0.17. waitpid diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Test-Future-IO-Impl-0.14/lib/Test/Future/IO/Impl.pm new/Test-Future-IO-Impl-0.15/lib/Test/Future/IO/Impl.pm --- old/Test-Future-IO-Impl-0.14/lib/Test/Future/IO/Impl.pm 2023-04-25 14:00:49.000000000 +0200 +++ new/Test-Future-IO-Impl-0.15/lib/Test/Future/IO/Impl.pm 2025-07-15 21:39:50.000000000 +0200 @@ -1,9 +1,9 @@ # You may distribute under the terms of either the GNU General Public License # or the Artistic License (the same terms as Perl itself) # -# (C) Paul Evans, 2021 -- leon...@leonerd.org.uk +# (C) Paul Evans, 2021-2025 -- leon...@leonerd.org.uk -package Test::Future::IO::Impl 0.14; +package Test::Future::IO::Impl 0.15; use v5.14; use warnings; @@ -13,7 +13,10 @@ use Errno qw( EINVAL EPIPE ); use IO::Handle; -use Socket qw( pack_sockaddr_in INADDR_LOOPBACK ); +use Socket qw( + pack_sockaddr_in sockaddr_family INADDR_LOOPBACK + AF_INET AF_UNIX SOCK_DGRAM SOCK_STREAM PF_UNSPEC +); use Time::HiRes qw( time ); use Exporter 'import'; @@ -75,7 +78,7 @@ =head2 run_tests - run_tests @suitenames + run_tests @suitenames; Runs a collection of tests against C<Future::IO>. It is expected that the caller has already loaded the specific implementation module to be tested @@ -199,6 +202,185 @@ } } +=head2 recv, recvfrom + +I<Since version 0.15.> + +Tests the C<< Future::IO->recv >> and C<< Future::IO->recvfrom >> methods. + +=cut + +# Getting a read/write socket pair which has working addresses is nontrivial. +# AF_UNIX sockets created by socketpair() literally have no addresses. AF_INET +# sockets would always have an address, but socketpair() can't create +# connected AF_INET pairs on most platforms. Grr. +# We'll make our own socketpair-alike that does. +sub _socketpair_INET_DGRAM +{ + my ( $connected ) = @_; + $connected //= 1; + + require IO::Socket::INET; + + # The IO::Socket constructors are unhelpful to us here; we'll do it ourselves + my $rd = IO::Socket::INET->new + ->socket( AF_INET, SOCK_DGRAM, 0 ) or die "Cannot socket rd - $!"; + $rd->bind( pack_sockaddr_in( 0, INADDR_LOOPBACK ) ) or die "Cannot bind rd - $!"; + + my $wr = IO::Socket::INET->new + ->socket( AF_INET, SOCK_DGRAM, 0 ); + $wr->connect( $rd->sockname ) or die "Cannot connect wr - $!" + if $connected; + + return ( $rd, $wr ); +} + +sub run_recv_test { _run_recv_test( 'recv', 0 ); } +sub run_recvfrom_test { _run_recv_test( 'recvfrom', 1 ); } +sub _run_recv_test +{ + my ( $method, $expect_fromaddr ) = @_; + + # yielding bytes + { + my ( $rd, $wr ) = _socketpair_INET_DGRAM(); + + $wr->autoflush(); + $wr->send( "BYTES" ); + + my $f = Future::IO->$method( $rd, 5 ); + + is( scalar $f->get, "BYTES", "Future::IO->$method yields bytes from socket" ); + # We can't know exactly what address it will be but + my $fromaddr = ( $f->get )[1]; + ok( defined $fromaddr, "Future::IO->$method also yields a fromaddr" ) + if $expect_fromaddr; + is( sockaddr_family( $fromaddr ), AF_INET, "Future::IO->$method fromaddr is valid AF_INET address" ) + if $expect_fromaddr; + } + + # From here onwards we don't need working sockaddr/peeraddr so we can just + # use simpler IO::Socket::UNIX->socketpair instead + + return if $^O eq "MSWin32"; + + require IO::Socket::UNIX; + + # yielding EOF + { + my ( $rd, $wr ) = IO::Socket::UNIX->socketpair( AF_UNIX, SOCK_STREAM, PF_UNSPEC ) + or die "Cannot socketpair() - $!"; + $wr->close; undef $wr; + + my $f = Future::IO->$method( $rd, 1 ); + + is ( [ $f->get ], [], "Future::IO->$method yields nothing on EOF" ); + } + + # can be cancelled + { + my ( $rd, $wr ) = IO::Socket::UNIX->socketpair( AF_UNIX, SOCK_STREAM, PF_UNSPEC ) + or die "Cannot socketpair() - $!"; + + $wr->autoflush(); + $wr->send( "BYTES" ); + + my $f1 = Future::IO->$method( $rd, 3 ); + my $f2 = Future::IO->$method( $rd, 3 ); + + $f1->cancel; + + is( scalar $f2->get, "BYT", "Future::IO->$method can be cancelled" ); + } +} + +=head2 send + +I<Since version 0.15.> + +Tests the C<< Future::IO->send >> method. + +=cut + +sub run_send_test +{ + # success + { + # An unconnected socketpair to prove that ->send used the correct address later on + my ( $rd, $wr ) = _socketpair_INET_DGRAM( 0 ); + + my $f = Future::IO->send( $wr, "BYTES", 0, $rd->sockname ); + + is( scalar $f->get, 5, 'Future::IO->send yields sent count' ); + + $rd->recv( my $buf, 5 ); + is( $buf, "BYTES", 'Future::IO->send sent bytes' ); + } + + # From here onwards we don't need working sockaddr/peeraddr so we can just + # use simpler IO::Socket::UNIX->socketpair instead + + return if $^O eq "MSWin32"; + + require IO::Socket::UNIX; + + # yielding EAGAIN + SKIP: { + $^O eq "MSWin32" and skip "MSWin32 doesn't do EAGAIN properly", 2; + + my ( $rd, $wr ) = IO::Socket::UNIX->socketpair( AF_UNIX, SOCK_STREAM, PF_UNSPEC ) + or die "Cannot socketpair() - $!"; + $wr->blocking( 0 ); + + # Attempt to fill the buffer + $wr->write( "X" x 4096 ) for 1..256; + + my $f = Future::IO->send( $wr, "more" ); + + ok( !$f->is_ready, '$f is still pending' ); + + # Now make some space. We need to drain it quite a lot for mechanisms + # like ppoll() to be happy that the socket is actually writable + $rd->blocking( 0 ); + $rd->read( my $buf, 4096 ) for 1..256; + + is( scalar $f->get, 4, 'Future::IO->send yields written count' ); + } + + # yielding EPIPE + { + my ( $rd, $wr ) = IO::Socket::UNIX->socketpair( AF_UNIX, SOCK_STREAM, PF_UNSPEC ) + or die "Cannot socketpair() - $!"; + $rd->close; undef $rd; + + local $SIG{PIPE} = 'IGNORE'; + + my $f = Future::IO->send( $wr, "BYTES" ); + + ok( !eval { $f->get }, 'Future::IO->send fails on EPIPE' ); + + is( [ $f->failure ], + [ "send: $errstr_EPIPE\n", send => $wr, $errstr_EPIPE ], + 'Future::IO->send failure for EPIPE' ); + } + + # can be cancelled + { + my ( $rd, $wr ) = IO::Socket::UNIX->socketpair( AF_UNIX, SOCK_STREAM, PF_UNSPEC ) + or die "Cannot socketpair() - $!"; + + my $f1 = Future::IO->send( $wr, "BY" ); + my $f2 = Future::IO->send( $wr, "TES" ); + + $f1->cancel; + + is( scalar $f2->get, 3, 'Future::IO->send after cancelled one still works' ); + + $rd->read( my $buf, 3 ); + is( $buf, "TES", 'Cancelled Future::IO->send method did no write bytes' ); + } +} + =head2 sleep Tests the C<< Future::IO->sleep >> method. @@ -232,75 +414,91 @@ }, 0.2, 'Future::IO->alarm( now + 0.2 ) sleeps 0.2 seconds'; } -=head2 sysread +=head2 read, sysread + +Tests the C<< Future::IO->sysread >> or C<< Future::IO->sysread >> method. -Tests the C<< Future::IO->sysread >> method. +These two test suites are identical other than the name of the method they +invoke. The two exist because of the method rename that happened at +C<Future::IO> version 0.17. =cut -sub run_sysread_test +sub run_read_test { _run_read_test( 'read' ); } +sub run_sysread_test { _run_read_test( 'sysread' ); } +sub _run_read_test { - # ->sysread yielding bytes + my ( $method ) = @_; + + # yielding bytes { pipe my ( $rd, $wr ) or die "Cannot pipe() - $!"; $wr->autoflush(); $wr->print( "BYTES" ); - my $f = Future::IO->sysread( $rd, 5 ); + my $f = Future::IO->$method( $rd, 5 ); - is( scalar $f->get, "BYTES", 'Future::IO->sysread yields bytes from pipe' ); + is( scalar $f->get, "BYTES", "Future::IO->$method yields bytes from pipe" ); } - # ->sysread yielding EOF + # yielding EOF { pipe my ( $rd, $wr ) or die "Cannot pipe() - $!"; $wr->close; undef $wr; - my $f = Future::IO->sysread( $rd, 1 ); + my $f = Future::IO->$method( $rd, 1 ); - is( [ $f->get ], [], 'Future::IO->sysread yields nothing on EOF' ); + is( [ $f->get ], [], "Future::IO->$method yields nothing on EOF" ); } # TODO: is there a nice portable way we can test for an IO error? - # ->sysread can be cancelled + # can be cancelled { pipe my ( $rd, $wr ) or die "Cannot pipe() - $!"; $wr->autoflush(); $wr->print( "BYTES" ); - my $f1 = Future::IO->sysread( $rd, 3 ); - my $f2 = Future::IO->sysread( $rd, 3 ); + my $f1 = Future::IO->$method( $rd, 3 ); + my $f2 = Future::IO->$method( $rd, 3 ); $f1->cancel; - is( scalar $f2->get, "BYT", 'Future::IO->sysread can be cancelled' ); + is( scalar $f2->get, "BYT", "Future::IO->$method can be cancelled" ); } } -=head2 syswrite +=head2 write, syswrite -Tests the C<< Future::IO->syswrite >> method. +Tests the C<< Future::IO->write >> or C<< Future::IO->syswrite >> method. + +These two test suites are identical other than the name of the method they +invoke. The two exist because of the method rename that happened at +C<Future::IO> version 0.17. =cut -sub run_syswrite_test +sub run_write_test { _run_write_test( 'write' ); } +sub run_syswrite_test { _run_write_test( 'syswrite' ); } +sub _run_write_test { - # ->syswrite success + my ( $method ) = @_; + + # success { pipe my ( $rd, $wr ) or die "Cannot pipe() - $!"; - my $f = Future::IO->syswrite( $wr, "BYTES" ); + my $f = Future::IO->$method( $wr, "BYTES" ); - is( scalar $f->get, 5, 'Future::IO->syswrite yields written count' ); + is( scalar $f->get, 5, "Future::IO->$method yields written count" ); $rd->read( my $buf, 5 ); - is( $buf, "BYTES", 'Future::IO->syswrite wrote bytes' ); + is( $buf, "BYTES", "Future::IO->$method wrote bytes" ); } - # ->syswrite yielding EAGAIN + # yielding EAGAIN SKIP: { $^O eq "MSWin32" and skip "MSWin32 doesn't do EAGAIN properly", 2; @@ -308,47 +506,47 @@ $wr->blocking( 0 ); # Attempt to fill the pipe - $wr->syswrite( "X" x 4096 ) for 1..256; + $wr->$method( "X" x 4096 ) for 1..256; - my $f = Future::IO->syswrite( $wr, "more" ); + my $f = Future::IO->$method( $wr, "more" ); ok( !$f->is_ready, '$f is still pending' ); # Now make some space $rd->read( my $buf, 4096 ); - is( scalar $f->get, 4, 'Future::IO->syswrite yields written count' ); + is( scalar $f->get, 4, "Future::IO->$method yields written count" ); } - # ->syswrite yielding EPIPE + # yielding EPIPE { pipe my ( $rd, $wr ) or die "Cannot pipe() - $!"; $rd->close; undef $rd; local $SIG{PIPE} = 'IGNORE'; - my $f = Future::IO->syswrite( $wr, "BYTES" ); + my $f = Future::IO->$method( $wr, "BYTES" ); - ok( !eval { $f->get }, 'Future::IO->syswrite fails on EPIPE' ); + ok( !eval { $f->get }, "Future::IO->$method fails on EPIPE" ); is( [ $f->failure ], [ "syswrite: $errstr_EPIPE\n", syswrite => $wr, $errstr_EPIPE ], - 'Future::IO->syswrite failure for EPIPE' ); + "Future::IO->$method failure for EPIPE" ); } - # ->syswrite can be cancelled + # can be cancelled { pipe my ( $rd, $wr ) or die "Cannot pipe() - $!"; - my $f1 = Future::IO->syswrite( $wr, "BY" ); - my $f2 = Future::IO->syswrite( $wr, "TES" ); + my $f1 = Future::IO->$method( $wr, "BY" ); + my $f2 = Future::IO->$method( $wr, "TES" ); $f1->cancel; - is( scalar $f2->get, 3, 'Future::IO->syswrite after cancelled one still works' ); + is( scalar $f2->get, 3, "Future::IO->$method after cancelled one still works" ); $rd->read( my $buf, 3 ); - is( $buf, "TES", 'Cancelled Future::IO->syswrite did not write bytes' ); + is( $buf, "TES", "Cancelled Future::IO->$method did not write bytes" ); } }