mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Merge branch 'PHP-8.1'
This commit is contained in:
@@ -2764,101 +2764,113 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
|
||||
#endif
|
||||
|
||||
bool orig_record_errors = EG(record_errors);
|
||||
if (ce->ce_flags & ZEND_ACC_IMMUTABLE) {
|
||||
if (is_cacheable) {
|
||||
if (zend_inheritance_cache_get && zend_inheritance_cache_add) {
|
||||
zend_class_entry *ret = zend_inheritance_cache_get(ce, parent, traits_and_interfaces);
|
||||
if (ret) {
|
||||
if (traits_and_interfaces) {
|
||||
free_alloca(traits_and_interfaces, use_heap);
|
||||
}
|
||||
zv = zend_hash_find_known_hash(CG(class_table), key);
|
||||
Z_CE_P(zv) = ret;
|
||||
return ret;
|
||||
|
||||
if (ce->ce_flags & ZEND_ACC_IMMUTABLE && is_cacheable) {
|
||||
if (zend_inheritance_cache_get && zend_inheritance_cache_add) {
|
||||
zend_class_entry *ret = zend_inheritance_cache_get(ce, parent, traits_and_interfaces);
|
||||
if (ret) {
|
||||
if (traits_and_interfaces) {
|
||||
free_alloca(traits_and_interfaces, use_heap);
|
||||
}
|
||||
|
||||
/* Make sure warnings (such as deprecations) thrown during inheritance
|
||||
* will be recoreded in the inheritance cache. */
|
||||
zend_begin_record_errors();
|
||||
} else {
|
||||
is_cacheable = 0;
|
||||
zv = zend_hash_find_known_hash(CG(class_table), key);
|
||||
Z_CE_P(zv) = ret;
|
||||
return ret;
|
||||
}
|
||||
proto = ce;
|
||||
|
||||
/* Make sure warnings (such as deprecations) thrown during inheritance
|
||||
* will be recorded in the inheritance cache. */
|
||||
zend_begin_record_errors();
|
||||
} else {
|
||||
is_cacheable = 0;
|
||||
}
|
||||
/* Lazy class loading */
|
||||
ce = zend_lazy_class_load(ce);
|
||||
zv = zend_hash_find_known_hash(CG(class_table), key);
|
||||
Z_CE_P(zv) = ce;
|
||||
} else if (ce->ce_flags & ZEND_ACC_FILE_CACHED) {
|
||||
/* Lazy class loading */
|
||||
ce = zend_lazy_class_load(ce);
|
||||
ce->ce_flags &= ~ZEND_ACC_FILE_CACHED;
|
||||
zv = zend_hash_find_known_hash(CG(class_table), key);
|
||||
Z_CE_P(zv) = ce;
|
||||
proto = ce;
|
||||
}
|
||||
|
||||
if (CG(unlinked_uses)) {
|
||||
zend_hash_index_del(CG(unlinked_uses), (zend_long)(zend_uintptr_t) ce);
|
||||
}
|
||||
|
||||
orig_linking_class = CG(current_linking_class);
|
||||
CG(current_linking_class) = is_cacheable ? ce : NULL;
|
||||
|
||||
if (ce->ce_flags & ZEND_ACC_ENUM) {
|
||||
/* Only register builtin enum methods during inheritance to avoid persisting them in
|
||||
* opcache. */
|
||||
zend_enum_register_funcs(ce);
|
||||
}
|
||||
|
||||
if (parent) {
|
||||
if (!(parent->ce_flags & ZEND_ACC_LINKED)) {
|
||||
add_dependency_obligation(ce, parent);
|
||||
zend_try {
|
||||
if (ce->ce_flags & ZEND_ACC_IMMUTABLE) {
|
||||
/* Lazy class loading */
|
||||
ce = zend_lazy_class_load(ce);
|
||||
zv = zend_hash_find_known_hash(CG(class_table), key);
|
||||
Z_CE_P(zv) = ce;
|
||||
} else if (ce->ce_flags & ZEND_ACC_FILE_CACHED) {
|
||||
/* Lazy class loading */
|
||||
ce = zend_lazy_class_load(ce);
|
||||
ce->ce_flags &= ~ZEND_ACC_FILE_CACHED;
|
||||
zv = zend_hash_find_known_hash(CG(class_table), key);
|
||||
Z_CE_P(zv) = ce;
|
||||
}
|
||||
zend_do_inheritance(ce, parent);
|
||||
}
|
||||
if (ce->num_traits) {
|
||||
zend_do_bind_traits(ce, traits_and_interfaces);
|
||||
}
|
||||
if (ce->num_interfaces) {
|
||||
/* Also copy the parent interfaces here, so we don't need to reallocate later. */
|
||||
uint32_t num_parent_interfaces = parent ? parent->num_interfaces : 0;
|
||||
zend_class_entry **interfaces = emalloc(
|
||||
sizeof(zend_class_entry *) * (ce->num_interfaces + num_parent_interfaces));
|
||||
|
||||
if (num_parent_interfaces) {
|
||||
memcpy(interfaces, parent->interfaces,
|
||||
sizeof(zend_class_entry *) * num_parent_interfaces);
|
||||
if (CG(unlinked_uses)) {
|
||||
zend_hash_index_del(CG(unlinked_uses), (zend_long)(zend_uintptr_t) ce);
|
||||
}
|
||||
memcpy(interfaces + num_parent_interfaces, traits_and_interfaces + ce->num_traits,
|
||||
sizeof(zend_class_entry *) * ce->num_interfaces);
|
||||
|
||||
zend_do_implement_interfaces(ce, interfaces);
|
||||
} else if (parent && parent->num_interfaces) {
|
||||
zend_do_inherit_interfaces(ce, parent);
|
||||
}
|
||||
if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT))
|
||||
&& (ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))
|
||||
) {
|
||||
zend_verify_abstract_class(ce);
|
||||
}
|
||||
if (ce->ce_flags & ZEND_ACC_ENUM) {
|
||||
zend_verify_enum(ce);
|
||||
}
|
||||
orig_linking_class = CG(current_linking_class);
|
||||
CG(current_linking_class) = is_cacheable ? ce : NULL;
|
||||
|
||||
/* Normally Stringable is added during compilation. However, if it is imported from a trait,
|
||||
* we need to explicilty add the interface here. */
|
||||
if (ce->__tostring && !(ce->ce_flags & ZEND_ACC_TRAIT)
|
||||
if (ce->ce_flags & ZEND_ACC_ENUM) {
|
||||
/* Only register builtin enum methods during inheritance to avoid persisting them in
|
||||
* opcache. */
|
||||
zend_enum_register_funcs(ce);
|
||||
}
|
||||
|
||||
if (parent) {
|
||||
if (!(parent->ce_flags & ZEND_ACC_LINKED)) {
|
||||
add_dependency_obligation(ce, parent);
|
||||
}
|
||||
zend_do_inheritance(ce, parent);
|
||||
}
|
||||
if (ce->num_traits) {
|
||||
zend_do_bind_traits(ce, traits_and_interfaces);
|
||||
}
|
||||
if (ce->num_interfaces) {
|
||||
/* Also copy the parent interfaces here, so we don't need to reallocate later. */
|
||||
uint32_t num_parent_interfaces = parent ? parent->num_interfaces : 0;
|
||||
zend_class_entry **interfaces = emalloc(
|
||||
sizeof(zend_class_entry *) * (ce->num_interfaces + num_parent_interfaces));
|
||||
|
||||
if (num_parent_interfaces) {
|
||||
memcpy(interfaces, parent->interfaces,
|
||||
sizeof(zend_class_entry *) * num_parent_interfaces);
|
||||
}
|
||||
memcpy(interfaces + num_parent_interfaces, traits_and_interfaces + ce->num_traits,
|
||||
sizeof(zend_class_entry *) * ce->num_interfaces);
|
||||
|
||||
zend_do_implement_interfaces(ce, interfaces);
|
||||
} else if (parent && parent->num_interfaces) {
|
||||
zend_do_inherit_interfaces(ce, parent);
|
||||
}
|
||||
if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT))
|
||||
&& (ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))
|
||||
) {
|
||||
zend_verify_abstract_class(ce);
|
||||
}
|
||||
if (ce->ce_flags & ZEND_ACC_ENUM) {
|
||||
zend_verify_enum(ce);
|
||||
}
|
||||
|
||||
/* Normally Stringable is added during compilation. However, if it is imported from a trait,
|
||||
* we need to explicilty add the interface here. */
|
||||
if (ce->__tostring && !(ce->ce_flags & ZEND_ACC_TRAIT)
|
||||
&& !zend_class_implements_interface(ce, zend_ce_stringable)) {
|
||||
ZEND_ASSERT(ce->__tostring->common.fn_flags & ZEND_ACC_TRAIT_CLONE);
|
||||
ce->ce_flags |= ZEND_ACC_RESOLVED_INTERFACES;
|
||||
ce->num_interfaces++;
|
||||
ce->interfaces = perealloc(ce->interfaces,
|
||||
sizeof(zend_class_entry *) * ce->num_interfaces, ce->type == ZEND_INTERNAL_CLASS);
|
||||
ce->interfaces[ce->num_interfaces - 1] = zend_ce_stringable;
|
||||
do_interface_implementation(ce, zend_ce_stringable);
|
||||
}
|
||||
ZEND_ASSERT(ce->__tostring->common.fn_flags & ZEND_ACC_TRAIT_CLONE);
|
||||
ce->ce_flags |= ZEND_ACC_RESOLVED_INTERFACES;
|
||||
ce->num_interfaces++;
|
||||
ce->interfaces = perealloc(ce->interfaces,
|
||||
sizeof(zend_class_entry *) * ce->num_interfaces, ce->type == ZEND_INTERNAL_CLASS);
|
||||
ce->interfaces[ce->num_interfaces - 1] = zend_ce_stringable;
|
||||
do_interface_implementation(ce, zend_ce_stringable);
|
||||
}
|
||||
|
||||
zend_build_properties_info_table(ce);
|
||||
} zend_catch {
|
||||
/* Do not leak recorded errors to the next linked class. */
|
||||
if (!orig_record_errors) {
|
||||
EG(record_errors) = false;
|
||||
zend_free_recorded_errors();
|
||||
}
|
||||
zend_bailout();
|
||||
} zend_end_try();
|
||||
|
||||
zend_build_properties_info_table(ce);
|
||||
EG(record_errors) = orig_record_errors;
|
||||
|
||||
if (!(ce->ce_flags & ZEND_ACC_UNRESOLVED_VARIANCE)) {
|
||||
@@ -3027,22 +3039,29 @@ ZEND_API zend_class_entry *zend_try_early_bind(zend_class_entry *ce, zend_class_
|
||||
orig_linking_class = CG(current_linking_class);
|
||||
CG(current_linking_class) = is_cacheable ? ce : NULL;
|
||||
|
||||
if (is_cacheable) {
|
||||
zend_begin_record_errors();
|
||||
}
|
||||
zend_try{
|
||||
if (is_cacheable) {
|
||||
zend_begin_record_errors();
|
||||
}
|
||||
|
||||
zend_do_inheritance_ex(ce, parent_ce, status == INHERITANCE_SUCCESS);
|
||||
if (parent_ce && parent_ce->num_interfaces) {
|
||||
zend_do_inherit_interfaces(ce, parent_ce);
|
||||
}
|
||||
zend_build_properties_info_table(ce);
|
||||
if ((ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) == ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) {
|
||||
zend_verify_abstract_class(ce);
|
||||
}
|
||||
ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_UNRESOLVED_VARIANCE));
|
||||
ce->ce_flags |= ZEND_ACC_LINKED;
|
||||
zend_do_inheritance_ex(ce, parent_ce, status == INHERITANCE_SUCCESS);
|
||||
if (parent_ce && parent_ce->num_interfaces) {
|
||||
zend_do_inherit_interfaces(ce, parent_ce);
|
||||
}
|
||||
zend_build_properties_info_table(ce);
|
||||
if ((ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) == ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) {
|
||||
zend_verify_abstract_class(ce);
|
||||
}
|
||||
ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_UNRESOLVED_VARIANCE));
|
||||
ce->ce_flags |= ZEND_ACC_LINKED;
|
||||
|
||||
CG(current_linking_class) = orig_linking_class;
|
||||
} zend_catch {
|
||||
EG(record_errors) = false;
|
||||
zend_free_recorded_errors();
|
||||
zend_bailout();
|
||||
} zend_end_try();
|
||||
|
||||
CG(current_linking_class) = orig_linking_class;
|
||||
EG(record_errors) = false;
|
||||
|
||||
if (is_cacheable) {
|
||||
|
||||
31
ext/opcache/tests/gh8063-001.phpt
Normal file
31
ext/opcache/tests/gh8063-001.phpt
Normal file
@@ -0,0 +1,31 @@
|
||||
--TEST--
|
||||
Bug GH-8063 (Opcache breaks autoloading after E_COMPILE_ERROR) 001
|
||||
--INI--
|
||||
opcache.enable=1
|
||||
opcache.enable_cli=1
|
||||
opcache.record_warnings=0
|
||||
--EXTENSIONS--
|
||||
opcache
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
spl_autoload_register(function ($class) {
|
||||
printf("Autoloading %s\n", $class);
|
||||
include __DIR__.DIRECTORY_SEPARATOR.'gh8063'.DIRECTORY_SEPARATOR.$class.'.inc';
|
||||
});
|
||||
|
||||
register_shutdown_function(function () {
|
||||
new Bar();
|
||||
new Baz();
|
||||
print "Finished\n";
|
||||
});
|
||||
|
||||
new BadClass();
|
||||
--EXPECTF--
|
||||
Autoloading BadClass
|
||||
Autoloading Foo
|
||||
|
||||
Fatal error: Declaration of BadClass::dummy() must be compatible with Foo::dummy(): void in %sBadClass.inc on line 5
|
||||
Autoloading Bar
|
||||
Autoloading Baz
|
||||
Finished
|
||||
31
ext/opcache/tests/gh8063-002.phpt
Normal file
31
ext/opcache/tests/gh8063-002.phpt
Normal file
@@ -0,0 +1,31 @@
|
||||
--TEST--
|
||||
Bug GH-8063 (Opcache breaks autoloading after E_COMPILE_ERROR) 002
|
||||
--INI--
|
||||
opcache.enable=1
|
||||
opcache.enable_cli=1
|
||||
opcache.record_warnings=1
|
||||
--EXTENSIONS--
|
||||
opcache
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
spl_autoload_register(function ($class) {
|
||||
printf("Autoloading %s\n", $class);
|
||||
include __DIR__.DIRECTORY_SEPARATOR.'gh8063'.DIRECTORY_SEPARATOR.$class.'.inc';
|
||||
});
|
||||
|
||||
register_shutdown_function(function () {
|
||||
new Bar();
|
||||
new Baz();
|
||||
print "Finished\n";
|
||||
});
|
||||
|
||||
new BadClass();
|
||||
--EXPECTF--
|
||||
Autoloading BadClass
|
||||
Autoloading Foo
|
||||
|
||||
Fatal error: Declaration of BadClass::dummy() must be compatible with Foo::dummy(): void in %sBadClass.inc on line 5
|
||||
Autoloading Bar
|
||||
Autoloading Baz
|
||||
Finished
|
||||
30
ext/opcache/tests/gh8063-003.phpt
Normal file
30
ext/opcache/tests/gh8063-003.phpt
Normal file
@@ -0,0 +1,30 @@
|
||||
--TEST--
|
||||
Bug GH-8063 (Opcache breaks autoloading after E_COMPILE_ERROR) 003
|
||||
--INI--
|
||||
opcache.enable=1
|
||||
opcache.enable_cli=1
|
||||
opcache.record_warnings=0
|
||||
--EXTENSIONS--
|
||||
opcache
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
spl_autoload_register(function ($class) {
|
||||
printf("Autoloading %s\n", $class);
|
||||
include __DIR__.DIRECTORY_SEPARATOR.'gh8063'.DIRECTORY_SEPARATOR.$class.'.inc';
|
||||
});
|
||||
|
||||
register_shutdown_function(function () {
|
||||
new Bar();
|
||||
new Baz();
|
||||
print "Finished\n";
|
||||
});
|
||||
|
||||
new BadClass2();
|
||||
--EXPECTF--
|
||||
Autoloading BadClass2
|
||||
|
||||
Fatal error: Declaration of BadClass2::dummy() must be compatible with Foo2::dummy(): void in %sBadClass2.inc on line %d
|
||||
Autoloading Bar
|
||||
Autoloading Baz
|
||||
Finished
|
||||
8
ext/opcache/tests/gh8063/BadClass.inc
Normal file
8
ext/opcache/tests/gh8063/BadClass.inc
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
class BadClass extends Foo
|
||||
{
|
||||
function dummy()
|
||||
{
|
||||
}
|
||||
}
|
||||
15
ext/opcache/tests/gh8063/BadClass2.inc
Normal file
15
ext/opcache/tests/gh8063/BadClass2.inc
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
class Foo2
|
||||
{
|
||||
function dummy(): void
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class BadClass2 extends Foo2
|
||||
{
|
||||
function dummy()
|
||||
{
|
||||
}
|
||||
}
|
||||
3
ext/opcache/tests/gh8063/Bar.inc
Normal file
3
ext/opcache/tests/gh8063/Bar.inc
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
class Bar {}
|
||||
3
ext/opcache/tests/gh8063/Baz.inc
Normal file
3
ext/opcache/tests/gh8063/Baz.inc
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
class Baz {}
|
||||
8
ext/opcache/tests/gh8063/Foo.inc
Normal file
8
ext/opcache/tests/gh8063/Foo.inc
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
class Foo
|
||||
{
|
||||
function dummy(): void
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -138,6 +138,9 @@ int fpm_pctl_kill(pid_t pid, int how) /* {{{ */
|
||||
case FPM_PCTL_QUIT :
|
||||
s = SIGQUIT;
|
||||
break;
|
||||
case FPM_PCTL_KILL:
|
||||
s = SIGKILL;
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
@@ -313,6 +316,17 @@ static void fpm_pctl_check_request_timeout(struct timeval *now) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void fpm_pctl_kill_idle_child(struct fpm_child_s *child) /* {{{ */
|
||||
{
|
||||
if (child->idle_kill) {
|
||||
fpm_pctl_kill(child->pid, FPM_PCTL_KILL);
|
||||
} else {
|
||||
child->idle_kill = 1;
|
||||
fpm_pctl_kill(child->pid, FPM_PCTL_QUIT);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now) /* {{{ */
|
||||
{
|
||||
struct fpm_worker_pool_s *wp;
|
||||
@@ -375,8 +389,7 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now) /* {{{
|
||||
fpm_request_last_activity(last_idle_child, &last);
|
||||
fpm_clock_get(&now);
|
||||
if (last.tv_sec < now.tv_sec - wp->config->pm_process_idle_timeout) {
|
||||
last_idle_child->idle_kill = 1;
|
||||
fpm_pctl_kill(last_idle_child->pid, FPM_PCTL_QUIT);
|
||||
fpm_pctl_kill_idle_child(last_idle_child);
|
||||
}
|
||||
|
||||
continue;
|
||||
@@ -388,8 +401,7 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now) /* {{{
|
||||
zlog(ZLOG_DEBUG, "[pool %s] currently %d active children, %d spare children, %d running children. Spawning rate %d", wp->config->name, active, idle, wp->running_children, wp->idle_spawn_rate);
|
||||
|
||||
if (idle > wp->config->pm_max_spare_servers && last_idle_child) {
|
||||
last_idle_child->idle_kill = 1;
|
||||
fpm_pctl_kill(last_idle_child->pid, FPM_PCTL_QUIT);
|
||||
fpm_pctl_kill_idle_child(last_idle_child);
|
||||
wp->idle_spawn_rate = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,8 @@ enum {
|
||||
FPM_PCTL_TERM,
|
||||
FPM_PCTL_STOP,
|
||||
FPM_PCTL_CONT,
|
||||
FPM_PCTL_QUIT
|
||||
FPM_PCTL_QUIT,
|
||||
FPM_PCTL_KILL
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
65
sapi/fpm/tests/bug77023-pm-dynamic-blocking-sigquit.phpt
Normal file
65
sapi/fpm/tests/bug77023-pm-dynamic-blocking-sigquit.phpt
Normal file
@@ -0,0 +1,65 @@
|
||||
--TEST--
|
||||
FPM: Blocked SIGQUIT prevents idle process to be killed
|
||||
--EXTENSIONS--
|
||||
pcntl
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include "skipif.inc";
|
||||
if (!function_exists('pcntl_sigprocmask')) die('skip Requires pcntl_sigprocmask()');
|
||||
if (getenv('SKIP_SLOW_TESTS')) die('skip slow tests excluded by request');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG}}
|
||||
pid = {{FILE:PID}}
|
||||
[unconfined]
|
||||
listen = {{ADDR}}
|
||||
pm.status_path = /status
|
||||
pm = dynamic
|
||||
pm.max_children = 2
|
||||
pm.start_servers = 1
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 1
|
||||
EOT;
|
||||
|
||||
$code = <<<EOT
|
||||
<?php
|
||||
pcntl_sigprocmask(SIG_BLOCK, [SIGQUIT, SIGTERM]);
|
||||
usleep(300000);
|
||||
EOT;
|
||||
|
||||
|
||||
$tester = new FPM\Tester($cfg, $code);
|
||||
$tester->start();
|
||||
$tester->expectLogStartNotices();
|
||||
$tester->multiRequest(2);
|
||||
$tester->status([
|
||||
'total processes' => 2,
|
||||
]);
|
||||
// wait for process to be killed
|
||||
sleep(7);
|
||||
$tester->expectLogWarning('child \\d+ exited on signal 9 \\(SIGKILL\\) after \\d+.\\d+ seconds from start', 'unconfined');
|
||||
$tester->expectLogNotice('child \\d+ started', 'unconfined');
|
||||
$tester->expectLogWarning('child \\d+ exited on signal 9 \\(SIGKILL\\) after \\d+.\\d+ seconds from start', 'unconfined');
|
||||
$tester->expectLogNotice('child \\d+ started', 'unconfined');
|
||||
$tester->status([
|
||||
'total processes' => 1,
|
||||
]);
|
||||
$tester->terminate();
|
||||
$tester->expectLogTerminatingNotices();
|
||||
$tester->close();
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECT--
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
||||
Reference in New Issue
Block a user