Developer-Dashboard
view release on metacpan or search on metacpan
integration/blank-env/run-integration.pl view on Meta::CPAN
allow_fail => 1,
);
_assert( $stopped->{exit_code} != 0, 'web service is no longer reachable after dashboard stop' );
print "Blank-environment integration run passed\n";
return 0;
}
# _run_shell($label, $command, %opts)
# Runs one shell command, streams stdout and stderr live, and returns structured command results.
# Input: human label, shell command string, and optional allow_fail flag.
# Output: hash reference with command, stdout, stderr, and exit_code.
sub _run_shell {
my ( $label, $command, %opts ) = @_;
print "==> $label\n";
print " $command\n";
my $stderr_fh = gensym();
my $pid = open3( undef, my $stdout_fh, $stderr_fh, 'sh', '-lc', $command );
my $selector = IO::Select->new( $stdout_fh, $stderr_fh );
my $stdout = '';
my $stderr = '';
my $stdout_fd = fileno($stdout_fh);
my $stderr_fd = fileno($stderr_fh);
while ( my @ready = $selector->can_read ) {
for my $fh (@ready) {
my $buffer = '';
my $read = sysread( $fh, $buffer, 8192 );
if ( !defined $read || $read == 0 ) {
$selector->remove($fh);
close $fh;
next;
}
if ( defined fileno($fh) && fileno($fh) == $stdout_fd ) {
$stdout .= $buffer;
print $buffer;
next;
}
if ( defined fileno($fh) && fileno($fh) == $stderr_fd ) {
$stderr .= $buffer;
print STDERR $buffer;
next;
}
}
}
waitpid( $pid, 0 );
my $exit_code = $? >> 8;
if ( !$opts{allow_fail} && $exit_code != 0 ) {
die "Command failed for [$label] with exit $exit_code\n";
}
return {
command => $command,
exit_code => $exit_code,
stdout => defined $stdout ? $stdout : '',
stderr => defined $stderr ? $stderr : '',
};
}
# _capture_stream_prefix($label, $command, %opts)
# Runs one streaming shell command and records when expected stdout chunks first appear.
# Input: human label, shell command string, expected_chunks array ref, and optional timeout seconds.
# Output: hash reference with stdout, stderr, and matched event timing data.
sub _capture_stream_prefix {
my ( $label, $command, %opts ) = @_;
my $expected = $opts{expected_chunks} || [];
my $timeout = $opts{timeout} || 5;
print "==> $label\n";
print " $command\n";
my $stderr_fh = gensym();
my $pid = open3( undef, my $stdout_fh, $stderr_fh, 'sh', '-lc', $command );
my $selector = IO::Select->new( $stdout_fh, $stderr_fh );
my $stdout = '';
my $stderr = '';
my $stdout_fd = fileno($stdout_fh);
my $stderr_fd = fileno($stderr_fh);
my @events;
my $start = time;
my $deadline = $start + $timeout;
while ( $selector->count && @events < @{$expected} && time < $deadline ) {
my @ready = $selector->can_read(0.25);
next if !@ready;
for my $fh (@ready) {
my $buffer = '';
my $read = sysread( $fh, $buffer, 8192 );
if ( !defined $read || $read == 0 ) {
$selector->remove($fh);
close $fh;
next;
}
if ( defined fileno($fh) && fileno($fh) == $stdout_fd ) {
$stdout .= $buffer;
print $buffer;
while ( @events < @{$expected} && index( $stdout, $expected->[@events] ) >= 0 ) {
push @events, {
chunk => $expected->[@events],
at => time - $start,
};
}
next;
}
if ( defined fileno($fh) && fileno($fh) == $stderr_fd ) {
$stderr .= $buffer;
print STDERR $buffer;
}
}
}
kill 'TERM', $pid;
waitpid( $pid, 0 );
return {
stdout => $stdout,
stderr => $stderr,
events => \@events,
};
}
# _wait_for_http($url, $expected_code)
# Polls a URL until it returns the expected HTTP status code or times out.
( run in 0.849 second using v1.01-cache-2.11-cpan-39bf76dae61 )