0 && !$unclassified, true); // The four classes the client distinguishes. foreach (array('NO_SOCKET' => 'no_socket', 'TIMEOUT' => 'timeout', 'TRANSIENT' => 'transient', 'INVALID' => 'invalid') as $const => $value) { check("STREAM_ERR_$const is defined as '$value'", (bool)preg_match("/define\('STREAM_ERR_$const',\s*'$value'\)/", $src), true); } // A missing socket, and a send to a socket with no listener, are the only // cases that mean zms is gone. These are the ones that may restart the stream. echo "\nfatal classification\n"; check('missing socket file is no_socket', (bool)preg_match('/does not exist.*?STREAM_ERR_NO_SOCKET/s', $src), true); check('socket_sendto failure is no_socket', (bool)preg_match('/socket_sendto\(.*?STREAM_ERR_NO_SOCKET/s', $src), true); // A timeout must NOT be reported as a generic failure: zms is most likely // alive, and restarting it is what orphaned the process. echo "\nnon-fatal classification\n"; check('select timeout is reported as timeout, not transient', (bool)preg_match('/\$select_timed_out\s*\)\s*\{\s*ajaxError\(.*?STREAM_ERR_TIMEOUT/s', $src), true); check('socket_create failure is transient', (bool)preg_match('/socket_create\(\).*?STREAM_ERR_TRANSIENT/s', $src), true); check('socket_bind failure is transient', (bool)preg_match('/socket_bind\(.*?STREAM_ERR_TRANSIENT/s', $src), true); check('bad request is invalid', (bool)preg_match('/No connkey or no command.*?STREAM_ERR_INVALID/s', $src), true); // socket_recvfrom() returns false on failure, and false == 0 under switch's // loose comparison, so a timed-out select lands on `case 0` rather than -1. // If this ever stopped holding, the timeout branch would silently never run. echo "\nphp switch semantics the timeout branch relies on\n"; $matched = null; switch (false) { case -1: $matched = -1; break; case 0: $matched = 0; break; default: $matched = 'default'; break; } check('switch(false) matches case 0, not case -1', $matched, 0); echo "\n$passes passed, $failures failed\n"; exit($failures ? 1 : 0);