diff --git a/dist.ini b/dist.ini index eeafb0167..8647d533f 100644 --- a/dist.ini +++ b/dist.ini @@ -75,7 +75,7 @@ Crypt::Eksblowfish::Bcrypt = 0 Cwd = 0 DBI = 0 DBIx::Class::UUIDColumns = 0 -DBIx::QuickDB = 0.000020 +DBIx::QuickDB = 0.000034 Data::Dumper = 0 DateTime = 0 DateTime::Format::MySQL = 0 diff --git a/lib/App/Yath/Command/run.pm b/lib/App/Yath/Command/run.pm index 7e1b95372..b13c28820 100644 --- a/lib/App/Yath/Command/run.pm +++ b/lib/App/Yath/Command/run.pm @@ -215,6 +215,8 @@ sub stop_plugins_and_renderers { my $exit ||= $auditor->exit_value; $_->client_finalize(settings => $settings, auditor => $auditor, exit => \$exit) for @$plugins; + $_->exit_hook($auditor) for reverse @$renderers; + return $exit || $alt_exit; } diff --git a/lib/App/Yath/Command/start.pm b/lib/App/Yath/Command/start.pm index 274555d94..a7586a9ff 100644 --- a/lib/App/Yath/Command/start.pm +++ b/lib/App/Yath/Command/start.pm @@ -183,6 +183,7 @@ sub become_collector { ); my $collector = $self->collector(); + my $exit = $collector->process($pid); remove_tree($settings->harness->workdir, {safe => 1, keep_root => 0}) diff --git a/lib/App/Yath/Command/test.pm b/lib/App/Yath/Command/test.pm index 5495af149..d6cb57d3c 100644 --- a/lib/App/Yath/Command/test.pm +++ b/lib/App/Yath/Command/test.pm @@ -144,6 +144,8 @@ sub become_collector { $self->start_plugins_and_renderers(); + my $collector = $self->collector; + my $exit = $self->SUPER::become_collector($pid); return $self->stop_plugins_and_renderers($exit); diff --git a/lib/App/Yath/Renderer.pm b/lib/App/Yath/Renderer.pm index 96366c764..4640b9aa9 100644 --- a/lib/App/Yath/Renderer.pm +++ b/lib/App/Yath/Renderer.pm @@ -40,6 +40,8 @@ sub step { } sub signal { } sub finish { } +sub exit_hook {} + sub weight { 0 } 1; diff --git a/lib/App/Yath/Renderer/DB.pm b/lib/App/Yath/Renderer/DB.pm index 4aad2c85a..fae1251ab 100644 --- a/lib/App/Yath/Renderer/DB.pm +++ b/lib/App/Yath/Renderer/DB.pm @@ -31,7 +31,7 @@ include_options( 'App::Yath::Options::Yath', 'App::Yath::Options::DB', 'App::Yath::Options::Publish', - 'App::Yath::Options::WebClient', + 'App::Yath::Options::WebClient' => [qw/url/], ); sub start { @@ -82,7 +82,7 @@ sub render_event { local $SIG{PIPE} = sub { warn "Caught SIGPIPE while writing to the database"; $spipe++; - $self->{+STOPPED} = 'SIGPIPE'; + $self->{+STOPPED} = ['SIGPIPE']; close($self->{+WRITE_PIPE}); $self->{+WRITE_PIPE} = undef; }; diff --git a/lib/App/Yath/Renderer/Server.pm b/lib/App/Yath/Renderer/Server.pm index 1775adb1c..b8ab692da 100644 --- a/lib/App/Yath/Renderer/Server.pm +++ b/lib/App/Yath/Renderer/Server.pm @@ -2,6 +2,88 @@ package App::Yath::Renderer::Server; use strict; use warnings; +our $VERSION = '2.000000'; + +use App::Yath::Schema::Util qw/schema_config_from_settings/; +use App::Yath::Server; + +use parent 'App::Yath::Renderer::DB'; +use Test2::Harness::Util::HashBase qw{ + [qw/ephemeral/], +); + +sub start { + my $self = shift; + + my $settings = $self->settings; + my $ephemeral = $settings->server->ephemeral; + unless ($ephemeral) { + $ephemeral = 'Auto'; + $settings->server->ephemeral($ephemeral); + } + + my $config = $self->{+CONFIG} //= schema_config_from_settings($settings, ephemeral => $ephemeral); + + my $qdb_params = { + single_user => 1, + single_run => 1, + no_upload => 1, + email => undef, + }; + + my $server = $self->{+SERVER} //= App::Yath::Server->new(schema_config => $config, $settings->webserver->all, qdb_params => $qdb_params); + $server->start_server(no_importers => 1); + + sleep 1; + + $ENV{YATH_URL} = "http://" . $settings->webserver->host . ":" . $settings->webserver->port . "/"; + print "\nYath URL: $ENV{YATH_URL}\n\n"; + + $settings->db->config($ENV{YATH_DB_CONFIG}) if $ENV{YATH_DB_CONFIG}; + $settings->db->driver($ENV{YATH_DB_DRIVER}) if $ENV{YATH_DB_DRIVER}; + $settings->db->name($ENV{YATH_DB_NAME}) if $ENV{YATH_DB_NAME}; + $settings->db->user($ENV{YATH_DB_USER}) if $ENV{YATH_DB_USER}; + $settings->db->pass($ENV{YATH_DB_PASS}) if $ENV{YATH_DB_PASS}; + $settings->db->dsn($ENV{YATH_DB_DSN}) if $ENV{YATH_DB_DSN}; + $settings->db->host($ENV{YATH_DB_HOST}) if $ENV{YATH_DB_HOST}; + $settings->db->port($ENV{YATH_DB_PORT}) if $ENV{YATH_DB_PORT}; + $settings->db->socket($ENV{YATH_DB_SOCKET}) if $ENV{YATH_DB_SOCKET}; + + $self->SUPER::start(); +} + +sub exit_hook { + my $self = shift; + + $self->SUPER::exit_hook(@_); + + print "\nYath URL: $ENV{YATH_URL}\n\n"; + print "Press ENTER/RETURN to stop server and exit\n"; + my $x = ; + + delete $self->{+SERVER}; + delete $self->{+CONFIG}; + + return; +} + +1; + +__END__ use Carp qw/croak/; use App::Yath::Server; diff --git a/lib/App/Yath/Server.pm b/lib/App/Yath/Server.pm index 729255c3f..6d43170df 100644 --- a/lib/App/Yath/Server.pm +++ b/lib/App/Yath/Server.pm @@ -120,7 +120,7 @@ sub start_ephemeral_db { my $qdb_args; if ($schema_type eq 'Auto') { - $qdb_args = {drivers => [qdb_driver('PostgreSQL'), qdb_driver('MySQL')]}; + $qdb_args = {drivers => [qdb_driver('PostgreSQL'), qdb_driver('MariaDB'), qdb_driver('MySQL'), qdb_driver('Percona'), qdb_driver('SQLite')]}; $schema_type = undef; } else { diff --git a/lib/Test2/Harness/Collector.pm b/lib/Test2/Harness/Collector.pm index 757bb012d..a4e693b25 100644 --- a/lib/Test2/Harness/Collector.pm +++ b/lib/Test2/Harness/Collector.pm @@ -772,6 +772,8 @@ sub _process { push @$handles => [$stderr->rh, sub { $last_event = time; $self->handle_event(stderr => $stderr, $broken) }, eof => sub { $broken->{$stderr} || $stderr->eof }, name => 'stderr'] unless $self->{+MERGE_OUTPUTS}; + my %timeout_warns; + ipc_loop( handles => $handles, sigchild => sub { $reap->(0) }, @@ -814,8 +816,29 @@ sub _process { if (defined $exited) { for my $h (@$handles) { my ($x, $y, %params) = @$h; - return 0 unless $params{eof}->(); + + my $timeout; + if (my $delta = int(time - $last_event)) { + $timeout = 1 if $delta > 10; + + unless ($timeout) { + if ($timeout_warns{main}) { + my $countdown = int(10 - $delta); + unless ($timeout_warns{$countdown}) { + warn " $countdown...\n"; + $timeout_warns{$countdown} = 1; + } + } + else { + warn "Testing looks complete, but a filehandle is still open (Did a plugin or renderer fork without an exec?), will timeout in 10 seconds...\n"; + $timeout_warns{main} = 1; + } + } + } + + return 0 unless $params{eof}->() || $timeout; } + return 1 if !$auditor; return 1 if $auditor->has_plan; return 1 if $exit; # If the exit value is not true we do not wait for post-exit timeout