@@ -14,6 +14,11 @@ function phpt_wait($worker = WORKER_DEFAULT_NAME, $timeout = null)
1414 ServerClientTestCase::getInstance ()->wait ($ worker , $ timeout );
1515}
1616
17+ function phpt_notify_server_start ($ server )
18+ {
19+ ServerClientTestCase::getInstance ()->notify_server_start ($ server );
20+ }
21+
1722function phpt_has_sslv3 () {
1823 static $ result = null ;
1924 if (!is_null ($ result )) {
@@ -119,44 +124,74 @@ class ServerClientTestCase
119124 eval ($ code );
120125 }
121126
122- public function run ($ masterCode , $ workerCode )
127+ /**
128+ * Run client and all workers
129+ *
130+ * @param string $clientCode The client PHP code
131+ * @param string|array $workerCode
132+ * @param bool $ephemeral Select whether automatic port selection and automatic awaiting is used
133+ * @return void
134+ * @throws Exception
135+ */
136+ public function run (string $ clientCode , string |array $ workerCode , bool $ ephemeral = true ): void
123137 {
124138 if (!is_array ($ workerCode )) {
125139 $ workerCode = [WORKER_DEFAULT_NAME => $ workerCode ];
126140 }
127- foreach ($ workerCode as $ worker => $ code ) {
141+ reset ($ workerCode );
142+ $ code = current ($ workerCode );
143+ $ worker = key ($ workerCode );
144+ while ($ worker != null ) {
128145 $ this ->spawnWorkerProcess ($ worker , $ this ->stripPhpTagsFromCode ($ code ));
146+ $ code = next ($ workerCode );
147+ if ($ ephemeral ) {
148+ $ addr = trim ($ this ->wait ($ worker ));
149+ if (empty ($ addr )) {
150+ throw new \Exception ("Failed server start " );
151+ }
152+ if ($ code === false ) {
153+ $ clientCode = preg_replace ('/{{\s*ADDR\s*}}/ ' , $ addr , $ clientCode );
154+ } else {
155+ $ code = preg_replace ('/{{\s*ADDR\s*}}/ ' , $ addr , $ code );
156+ }
157+ }
158+ $ worker = key ($ workerCode );
129159 }
130- eval ($ this ->stripPhpTagsFromCode ($ masterCode ));
160+
161+ eval ($ this ->stripPhpTagsFromCode ($ clientCode ));
131162 foreach ($ workerCode as $ worker => $ code ) {
132163 $ this ->cleanupWorkerProcess ($ worker );
133164 }
134165 }
135166
136- public function wait ($ worker , $ timeout = null )
167+ public function wait ($ worker , $ timeout = null ): ? string
137168 {
138169 $ handle = $ this ->isWorker ? STDIN : $ this ->workerStdOut [$ worker ];
139170 if ($ timeout === null ) {
140- fgets ($ handle );
141- return true ;
171+ return fgets ($ handle );
142172 }
143173
144174 stream_set_blocking ($ handle , false );
145175 $ read = [$ handle ];
146176 $ result = stream_select ($ read , $ write , $ except , $ timeout );
147177 if (!$ result ) {
148- return false ;
178+ return null ;
149179 }
150180
151- fgets ($ handle );
181+ $ result = fgets ($ handle );
152182 stream_set_blocking ($ handle , true );
153- return true ;
183+ return $ result ;
154184 }
155185
156- public function notify ($ worker )
186+ public function notify ($ worker ): void
157187 {
158188 fwrite ($ this ->isWorker ? STDOUT : $ this ->workerStdIn [$ worker ], "\n" );
159189 }
190+
191+ public function notify_server_start ($ server ): void
192+ {
193+ echo stream_socket_get_name ($ server , false ) . "\n" ;
194+ }
160195}
161196
162197if (isset ($ argv [1 ]) && $ argv [1 ] === WORKER_ARGV_VALUE ) {
0 commit comments