<commit_before>package t::Util;

use strict;
use warnings;
use Digest::MD5 qw(md5_hex);
use File::Temp qw(tempfile);
use Net::EmptyPort qw(check_port empty_port);
use POSIX ":sys_wait_h";
use Scope::Guard qw(scope_guard);

use base qw(Exporter);
our @EXPORT = qw(spawn_server spawn_h2o md5_file prog_exists openssl_can_negotiate);

# spawns a child process and returns a guard object that kills the process when destroyed
sub spawn_server {
    my %args = @_;
    my $pid = fork;
    die "fork failed:$!"
        unless defined $pid;
    if ($pid != 0) {
        if ($args{is_ready}) {
            while (! $args{is_ready}->()) {
                sleep 1;
                die "server died"
                    if waitpid($pid, WNOHANG) == $pid;
            }
        }
        return scope_guard(sub {
            if (kill 'TERM', $pid) {
                while (waitpid($pid, 0) != $pid) {
                }
            }<commit_msg>report the details of server start /stop (#56, merge branch 'kazuho/issues/test-timeout')<commit_after>package t::Util;

use strict;
use warnings;
use Digest::MD5 qw(md5_hex);
use File::Temp qw(tempfile);
use Net::EmptyPort qw(check_port empty_port);
use POSIX ":sys_wait_h";
use Scope::Guard qw(scope_guard);
use Time::HiRes qw(sleep);

use base qw(Exporter);
our @EXPORT = qw(spawn_server spawn_h2o md5_file prog_exists openssl_can_negotiate);

# spawns a child process and returns a guard object that kills the process when destroyed
sub spawn_server {
    my %args = @_;
    my $pid = fork;
    die "fork failed:$!"
        unless defined $pid;
    if ($pid != 0) {
        print STDERR "spawning $args{argv}->[0]... ";
        if ($args{is_ready}) {
            while (1) {
                if ($args{is_ready}->()) {
                    print STDERR "done\n";
                    last;
                }
                if (waitpid($pid, WNOHANG) == $pid) {
                    die "server failed to start (got $?)\n";
                }
                sleep 0.1;
            }
        }
        return scope_guard(sub {
            print STDERR "killing $args{argv}->[0]... ";
            if (kill 'TERM', $pid) {
                my $i = 0;
                while (1) {
                    if (waitpid($pid, WNOHANG) == $pid) {
                        print STDERR "killed (got $?)\n";
                        last;
                    }
                    if ($i++ == 100) {
                        print STDERR "failed to kill the process, continuing anyways\n";
                        last;
                    }
                    sleep 0.1;
                }
            } else {
                print STDERR "no proc? ($!)\n";
            }
{'fraction_non_alphanumeric': 0.12248696947133283, 'fraction_numerical': 0.00967982129560685, 'mean_word_length': 1.6291585127201567, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1134395', 'n_tokens_mistral': 867, 'n_tokens_neox': 814, 'n_words': 235}