Best Atoum code snippet using runner.loop
JobRunnerPipeline.php
Source:JobRunnerPipeline.php
1<?php2class JobRunnerPipeline {3 /** @var RedisJobService */4 protected $srvc;5 /** @var array (loop ID => slot ID => slot status array) */6 protected $procMap = [];7 /**8 * @param RedisJobService $service9 */10 public function __construct( RedisJobService $service ) {11 $this->srvc = $service;12 }13 /**14 * @param string $loop15 * @param int $slot16 */17 public function initSlot( string $loop, int $slot ) {18 $this->procMap[$loop][$slot] = [19 'handle' => false,20 'pipes' => [],21 'db' => null,22 'type' => null,23 'cmd' => null,24 'stime' => 0,25 'sigtime' => 0,26 'stdout' => '',27 'stderr' => ''28 ];29 }30 /**31 * @param integer $loop32 * @param array $prioMap33 * @param array $pending34 * @return array35 */36 public function refillSlots( int $loop, array $prioMap, array &$pending ) : array {37 $free = 0;38 $new = 0;39 $host = gethostname();40 $cTime = time();41 foreach ( $this->procMap[$loop] as $slot => &$procSlot ) {42 $status = $procSlot['handle'] ? proc_get_status( $procSlot['handle'] ) : null;43 if ( $status ) {44 // Keep reading in any output (nonblocking) to avoid process lockups45 $procSlot['stdout'] .= fread( $procSlot['pipes'][1], 65535 );46 $procSlot['stderr'] .= fread( $procSlot['pipes'][2], 65535 );47 }48 if ( $status && $status['running'] ) {49 $maxReal = isset( $this->srvc->maxRealMap[$procSlot['type']] )50 ? $this->srvc->maxRealMap[$procSlot['type']]51 : $this->srvc->maxRealMap['*'];52 $age = $cTime - $procSlot['stime'];53 if ( $age >= $maxReal && !$procSlot['sigtime'] ) {54 $cmd = $procSlot['cmd'];55 $this->srvc->error( "Runner loop $loop process in slot $slot timed out " .56 "[{$age}s; max: {$maxReal}s]:\n$cmd" );57 posix_kill( $status['pid'], SIGTERM ); // non-blocking58 $procSlot['sigtime'] = time();59 $this->srvc->incrStats( 'runner-status.timeout' );60 } elseif ( $age >= $maxReal && ( $cTime - $procSlot['sigtime'] ) > 5 ) {61 $this->srvc->error( "Runner loop $loop process in slot $slot sent SIGKILL." );62 $this->closeRunner( $loop, $slot, $procSlot, SIGKILL );63 $this->srvc->incrStats( 'runner-status.kill' );64 } else {65 continue; // slot is busy66 }67 } elseif ( $status && !$status['running'] ) {68 // $result will be an array if no exceptions happened69 $result = json_decode( trim( $procSlot['stdout'] ), true );70 if ( $status['exitcode'] == 0 && is_array( $result ) ) {71 // If this finished early, lay off of the queue for a while72 if ( ( $cTime - $procSlot['stime'] ) < $this->srvc->hpMaxTime/2 ) {73 unset( $pending[$procSlot['type']][$procSlot['db']] );74 $this->srvc->debug( "Queue '{$procSlot['db']}/{$procSlot['type']}' emptied." );75 }76 $ok = 0; // jobs that ran OK77 foreach ( $result['jobs'] as $status ) {78 $ok += ( $status['status'] === 'ok' ) ? 1 : 0;79 }80 $failed = count( $result['jobs'] ) - $ok;81 $this->srvc->incrStats( "pop.{$procSlot['type']}.ok.{$host}", $ok );82 $this->srvc->incrStats( "pop.{$procSlot['type']}.failed.{$host}", $failed );83 } else {84 // Mention any serious errors that may have occured85 $cmd = $procSlot['cmd'];86 if ( $procSlot['stderr'] ) {87 $error = $procSlot['stderr'];88 $cmd .= ' STDERR:';89 } else {90 $error = $procSlot['stdout'];91 $cmd .= ' STDOUT:';92 }93 // if ( strlen( $error ) > 4096 ) { // truncate long errors94 // $error = mb_substr( $error, 0, 4096 ) . '...';95 // }96 $this->srvc->error( "Runner loop $loop process in slot $slot " .97 "gave status '{$status['exitcode']}':\n$cmd\n\t$error" );98 $this->srvc->incrStats( 'runner-status.error' );99 }100 $this->closeRunner( $loop, $slot, $procSlot );101 } elseif ( !$status && $procSlot['handle'] ) {102 $this->srvc->error( "Runner loop $loop process in slot $slot gave no status." );103 $this->closeRunner( $loop, $slot, $procSlot );104 $this->srvc->incrStats( 'runner-status.none' );105 }106 ++$free;107 $queue = $this->selectQueue( $loop, $prioMap, $pending );108 if ( !$queue ) {109 break;110 }111 // Spawn a job runner for this loop ID112 $highPrio = $prioMap[$loop]['high'];113 $this->spawnRunner( $loop, $slot, $highPrio, $queue, $procSlot );114 ++$new;115 }116 unset( $procSlot );117 return [ $free, $new ];118 }119 /**120 * @param integer $loop121 * @param array $prioMap122 * @param array $pending123 * @return array|boolean124 */125 protected function selectQueue( int $loop, array $prioMap, array $pending ) {126 $include = $this->srvc->loopMap[$loop]['include'];127 $exclude = $this->srvc->loopMap[$loop]['exclude'];128 if ( $prioMap[$loop]['high'] ) {129 $exclude = array_merge( $exclude, $this->srvc->loopMap[$loop]['low-priority'] );130 } else {131 $include = array_merge( $include, $this->srvc->loopMap[$loop]['low-priority'] );132 }133 if ( in_array( '*', $include ) ) {134 $include = array_merge( $include, array_keys( $pending ) );135 }136 $candidateTypes = array_diff( array_unique( $include ), $exclude, [ '*' ] );137 $candidates = []; // list of (type, db)138 // Flatten the tree of candidates into a flat list so that a random139 // item can be selected, weighing each queue (type/db tuple) equally.140 foreach ( $candidateTypes as $type ) {141 if ( isset( $pending[$type] ) ) {142 foreach ( $pending[$type] as $db => $since ) {143 $candidates[] = [ $type, $db ];144 }145 }146 }147 if ( !count( $candidates ) ) {148 return false; // no jobs for this type149 }150 return $candidates[mt_rand( 0, count( $candidates ) - 1 )];151 }152 /**153 * @param integer $loop154 * @param integer $slot155 * @param bool $highPrio156 * @param array $queue157 * @param array $procSlot158 * @return bool159 */160 protected function spawnRunner( int $loop, int $slot, bool $highPrio, array $queue, array &$procSlot ) : bool {161 // Pick a random queue162 list( $type, $db ) = $queue;163 $maxtime = $highPrio ? $this->srvc->lpMaxTime : $this->srvc->hpMaxTime;164 $maxmem = isset( $this->srvc->maxMemMap[$type] )165 ? $this->srvc->maxMemMap[$type]166 : $this->srvc->maxMemMap['*'];167 // Make sure the runner is launched with various time/memory limits.168 // Nice the process so things like ssh and deployment scripts are fine.169 $what = $with = [];170 foreach ( compact( 'db', 'type', 'maxtime', 'maxmem' ) as $k => $v ) {171 $what[] = "%($k)u";172 $with[] = rawurlencode( $v );173 $what[] = "%($k)x";174 $with[] = escapeshellarg( $v );175 }176 // The dispatcher might be runJobs.php, curl, or wget177 $cmd = str_replace( $what, $with, $this->srvc->dispatcher );178 $descriptors = [179 0 => [ "pipe", "r" ], // stdin (child)180 1 => [ "pipe", "w" ], // stdout (child)181 2 => [ "pipe", "w" ] // stderr (child)182 ];183 $this->srvc->debug( "Spawning runner in loop $loop at slot $slot ($type, $db):\n\t$cmd." );184 // Start the runner in the background185 $procSlot['handle'] = proc_open( $cmd, $descriptors, $procSlot['pipes'] );186 if ( $procSlot['handle'] ) {187 // Make sure socket reads don't wait for data188 stream_set_blocking( $procSlot['pipes'][1], 0 );189 stream_set_blocking( $procSlot['pipes'][2], 0 );190 // Set a timeout so stream_get_contents() won't block for sanity191 stream_set_timeout( $procSlot['pipes'][1], 1 );192 stream_set_timeout( $procSlot['pipes'][2], 1 );193 // Close the unused STDIN pipe194 fclose( $procSlot['pipes'][0] );195 unset( $procSlot['pipes'][0] ); // unused196 }197 $procSlot['db'] = $db;198 $procSlot['type'] = $type;199 $procSlot['cmd'] = $cmd;200 $procSlot['stime'] = time();201 $procSlot['sigtime'] = 0;202 $procSlot['stdout'] = '';203 $procSlot['stderr'] = '';204 if ( $procSlot['handle'] ) {205 return true;206 } else {207 $this->srvc->error( "Could not spawn process in loop $loop: $cmd" );208 $this->srvc->incrStats( 'runner-status.error' );209 return false;210 }211 }212 /**213 * @param integer $loop214 * @param integer $slot215 * @param array $procSlot216 * @param int|null $signal217 */218 protected function closeRunner( int $loop, int $slot, array &$procSlot, int $signal = null ) {219 if ( $procSlot['pipes'] ) {220 if ( $procSlot['pipes'][1] !== false ) {221 fclose( $procSlot['pipes'][1] );222 $procSlot['pipes'][1] = false;223 }224 if ( $procSlot['pipes'][2] !== false ) {225 fclose( $procSlot['pipes'][2] );226 $procSlot['pipes'][2] = false;227 }228 }229 if ( $procSlot['handle'] ) {230 $this->srvc->debug( "Closing process in loop $loop at slot $slot." );231 if ( $signal !== null ) {232 // Tell the process to close with a signal233 proc_terminate( $procSlot['handle'], $signal );234 } else {235 // Wait for the process to finish on its own236 proc_close( $procSlot['handle'] );237 }238 }239 $procSlot['handle'] = false;240 $procSlot['db'] = null;241 $procSlot['type'] = null;242 $procSlot['stime'] = 0;243 $procSlot['sigtime'] = 0;244 $procSlot['cmd'] = null;...
redisJobRunnerService
Source:redisJobRunnerService
...11 /**12 * @throws Exception13 */14 public function main() {15 $this->notice( "Starting job spawner loop(s)..." );16 $host = gethostname();17 $prioMap = []; // map of (id => (current priority, since))18 $pipeline = new JobRunnerPipeline( $this );19 foreach ( $this->loopMap as $loop => $info ) {20 for ( $i=0; $i < $info['runners']; ++$i ) {21 $pipeline->initSlot( $loop, $i );22 $prioMap[$loop] = [ 'high' => (bool)mt_rand( 0, 1 ), 'since' => time() ];23 }24 $this->notice( "Initialized loop $loop with {$info['runners']} runner(s)." );25 }26 // Setup signal handlers...27 $handlerFunc = function( $signo ) use ( $pipeline ) {28 print "Caught signal ($signo)\n";29 $pipeline->terminateSlots();30 exit( 0 );31 };32 $ok = pcntl_signal( SIGHUP, $handlerFunc )33 && pcntl_signal( SIGINT, $handlerFunc )34 && pcntl_signal( SIGTERM, $handlerFunc );35 if ( !$ok ) {36 throw new Exception( 'Could not install signal handlers.' );37 }38 $memLast = memory_get_usage();39 $this->incrStats( "start-runner.$host" );40 while ( true ) {41 pcntl_signal_dispatch();42 $prioSwitches = 0;43 $anyNew = 0;44 $anyFree = 0;45 // Get the list of ready queues46 $pending =& $this->getReadyQueueMap();47 if ( !count( $pending ) ) {48 $this->debug( "No jobs available..." );49 $this->incrStats( "idle.$host" );50 usleep( 100000 ); // no jobs51 continue;52 }53 // Spawn new runners as slots become available54 foreach ( $prioMap as $loop => &$loopPriority ) {55 $this->debug( "Checking runner loop $loop..." );56 // Implement high/low priority via time-sharing57 if ( $loopPriority['high']58 && ( time() - $loopPriority['since'] ) > $this->lpMaxDelay59 ) {60 $loopPriority['high'] = false;61 $loopPriority['since'] = time();62 $this->debug( "Runner loop $loop now in low priority." );63 ++$prioSwitches;64 } elseif ( !$loopPriority['high']65 && ( time() - $loopPriority['since'] ) > $this->hpMaxDelay66 ) {67 $loopPriority['high'] = true;68 $loopPriority['since'] = time();69 $this->debug( "Runner loop $loop now in high priority." );70 ++$prioSwitches;71 }72 // Find any free slots and replace them with new processes73 list( $free, $new ) = $pipeline->refillSlots( $loop, $prioMap, $pending );74 $anyFree += $free;75 $anyNew += $new;76 // Rotate the priority from high/low and back if no jobs were found77 if ( !$free ) {78 $this->debug( "Runner loop $loop is full." );79 } elseif ( !$new ) {80 if ( $loopPriority['high'] ) {81 $loopPriority['high'] = false;82 $this->debug( "Runner loop $loop now in low priority." );83 } else {84 $loopPriority['high'] = true;85 $this->debug( "Runner loop $loop now in high priority." );86 }87 $loopPriority['since'] = time();88 $this->debug( "Runner loop $loop has no jobs." );89 ++$prioSwitches;90 } else {91 $this->debug( "Done checking loop $loop." );92 }93 }94 unset( $loopPriority );95 $this->incrStats( "spawn.$host", $anyNew );96 $this->incrStats( "prioritychange.$host", $prioSwitches );97 // Backoff if there is nothing to do98 if ( !$anyFree ) {99 $this->debug( "All runner loops full." );100 $this->incrStats( "all-full.$host" );101 usleep( 100000 );102 } elseif ( !$anyNew ) {103 $this->debug( "Loops have free slots, but there are no appropriate jobs." );104 $this->incrStats( "some-full.$host" );105 usleep( 100000 );106 }107 // Track memory usage108 $memCurrent = memory_get_usage();109 $this->debug( "Memory usage: $memCurrent bytes." );110 $this->incrStats( "memory.$host", $memCurrent - $memLast );111 $this->sendStats();112 $memLast = $memCurrent;113 }...
WorkerCommand.php
Source:WorkerCommand.php
1<?php2declare (strict_types=1);3namespace Rector\Core\Console\Command;4use RectorPrefix20211231\Clue\React\NDJson\Decoder;5use RectorPrefix20211231\Clue\React\NDJson\Encoder;6use RectorPrefix20211231\React\EventLoop\StreamSelectLoop;7use RectorPrefix20211231\React\Socket\ConnectionInterface;8use RectorPrefix20211231\React\Socket\TcpConnector;9use Rector\Parallel\WorkerRunner;10use RectorPrefix20211231\Symfony\Component\Console\Input\InputInterface;11use RectorPrefix20211231\Symfony\Component\Console\Output\OutputInterface;12use RectorPrefix20211231\Symplify\EasyParallel\Enum\Action;13use RectorPrefix20211231\Symplify\EasyParallel\Enum\ReactCommand;14/**15 * Inspired at: https://github.com/phpstan/phpstan-src/commit/9124c66dcc55a222e21b1717ba5f60771f7dda9216 * https://github.com/phpstan/phpstan-src/blob/c471c7b050e0929daf432288770de673b394a983/src/Command/WorkerCommand.php17 *18 * âââ19 * https://github.com/phpstan/phpstan-src/commit/b84acd2e3eadf66189a64fdbc6dd18ff76323f67#diff-7f625777f1ce5384046df08abffd6c911cfbb1cfc8fcb2bdeaf78f337689e3e220 */21final class WorkerCommand extends \Rector\Core\Console\Command\AbstractProcessCommand22{23 /**24 * @readonly25 * @var \Rector\Parallel\WorkerRunner26 */27 private $workerRunner;28 public function __construct(\Rector\Parallel\WorkerRunner $workerRunner)29 {30 $this->workerRunner = $workerRunner;31 parent::__construct();32 }33 protected function configure() : void34 {35 $this->setDescription('(Internal) Support for parallel process');36 parent::configure();37 }38 protected function execute(\RectorPrefix20211231\Symfony\Component\Console\Input\InputInterface $input, \RectorPrefix20211231\Symfony\Component\Console\Output\OutputInterface $output) : int39 {40 $configuration = $this->configurationFactory->createFromInput($input);41 $streamSelectLoop = new \RectorPrefix20211231\React\EventLoop\StreamSelectLoop();42 $parallelIdentifier = $configuration->getParallelIdentifier();43 $tcpConnector = new \RectorPrefix20211231\React\Socket\TcpConnector($streamSelectLoop);44 $promise = $tcpConnector->connect('127.0.0.1:' . $configuration->getParallelPort());45 $promise->then(function (\RectorPrefix20211231\React\Socket\ConnectionInterface $connection) use($parallelIdentifier, $configuration) : void {46 $inDecoder = new \RectorPrefix20211231\Clue\React\NDJson\Decoder($connection, \true, 512, \JSON_INVALID_UTF8_IGNORE);47 $outEncoder = new \RectorPrefix20211231\Clue\React\NDJson\Encoder($connection, \JSON_INVALID_UTF8_IGNORE);48 // handshake?49 $outEncoder->write([\RectorPrefix20211231\Symplify\EasyParallel\Enum\ReactCommand::ACTION => \RectorPrefix20211231\Symplify\EasyParallel\Enum\Action::HELLO, \RectorPrefix20211231\Symplify\EasyParallel\Enum\ReactCommand::IDENTIFIER => $parallelIdentifier]);50 $this->workerRunner->run($outEncoder, $inDecoder, $configuration);51 });52 $streamSelectLoop->run();53 return self::SUCCESS;54 }55}...
loop
Using AI Code Generation
1$runner = new Runner();2$runner->runLoop();3$runner = new Runner();4$runner->runRecursive();5$runner = new Runner();6$runner->runRecursive();7$runner = new Runner();8$runner->runRecursive();9$runner = new Runner();10$runner->runRecursive();11$runner = new Runner();12$runner->runRecursive();13$runner = new Runner();14$runner->runRecursive();15$runner = new Runner();16$runner->runRecursive();17$runner = new Runner();18$runner->runRecursive();19$runner = new Runner();20$runner->runRecursive();21$runner = new Runner();22$runner->runRecursive();23$runner = new Runner();24$runner->runRecursive();25$runner = new Runner();26$runner->runRecursive();27$runner = new Runner();28$runner->runRecursive();29$runner = new Runner();30$runner->runRecursive();31$runner = new Runner();32$runner->runRecursive();33$runner = new Runner();34$runner->runRecursive();
loop
Using AI Code Generation
1$runner = new Runner();2$runner->run();3$runner = new Runner();4$runner->runRecursive();5$runner = new Runner();6$runner->runIterator();7$runner = new Runner();8$runner->runIteratorRecursive();9$runner = new Runner();10$runner->runIteratorRecursive2();11$runner = new Runner();12$runner->runIteratorRecursive3();13$runner = new Runner();14$runner->runIteratorRecursive4();15$runner = new Runner();16$runner->runIteratorRecursive5();17$runner = new Runner();18$runner->runIteratorRecursive6();19$runner = new Runner();20$runner->runIteratorRecursive7();21$runner = new Runner();22$runner->runIteratorRecursive8();23$runner = new Runner();24$runner->runIteratorRecursive9();25$runner = new Runner();26$runner->runIteratorRecursive10();27$runner = new Runner();28$runner->runIteratorRecursive11();29$runner = new Runner();30$runner->runIteratorRecursive12();31$runner = new Runner();32$runner->runIteratorRecursive13();33$runner = new Runner();
loop
Using AI Code Generation
1$runner = new Runner();2$runner->loop(10);3$runner->loop(20);4$runner->loop(30);5$runner->loop(40);6$runner->loop(50);7$runner->loop(60);8$runner->loop(70);9$runner->loop(80);10$runner->loop(90);11$runner->loop(100);12$runner = new Runner();13$runner->loop(10);14$runner->loop(20);15$runner->loop(30);16$runner->loop(40);17$runner->loop(50);18$runner->loop(60);19$runner->loop(70);20$runner->loop(80);21$runner->loop(90);22$runner->loop(100);23$runner = new Runner();24$runner->loop(10);25$runner->loop(20);26$runner->loop(30);27$runner->loop(40);28$runner->loop(50);29$runner->loop(60);30$runner->loop(70);31$runner->loop(80);32$runner->loop(90);33$runner->loop(100);34$runner = new Runner();35$runner->loop(10);36$runner->loop(20);37$runner->loop(30);38$runner->loop(40);39$runner->loop(50);40$runner->loop(60);41$runner->loop(70);42$runner->loop(80);43$runner->loop(90);44$runner->loop(100);45$runner = new Runner();46$runner->loop(10);47$runner->loop(20);48$runner->loop(30);49$runner->loop(40);50$runner->loop(50);51$runner->loop(60);52$runner->loop(70);53$runner->loop(80);54$runner->loop(90);55$runner->loop(100);56$runner = new Runner();57$runner->loop(10);58$runner->loop(20);59$runner->loop(30);60$runner->loop(40
loop
Using AI Code Generation
1$runner = new Runner();2$runner->loop(100, function($i){3 echo $i;4});5$runner = new Runner();6$runner->recursive(100, function($i){7 echo $i;8});9$runner = new Runner();10$runner->recursive2(100, function($i){11 echo $i;12});13$runner = new Runner();14$runner->recursive3(100, function($i){15 echo $i;16});17$runner = new Runner();18$runner->recursive4(100, function($i){19 echo $i;20});21$runner = new Runner();22$runner->recursive5(100, function($i){23 echo $i;24});25$runner = new Runner();26$runner->recursive6(100, function($i){27 echo $i;28});29$runner = new Runner();30$runner->recursive7(100, function($i){31 echo $i;32});33$runner = new Runner();34$runner->recursive8(100, function($i){35 echo $i;36});37$runner = new Runner();38$runner->recursive9(100, function($i){39 echo $i;40});41$runner = new Runner();42$runner->recursive10(100, function($i){43 echo $i;44});45$runner = new Runner();46$runner->recursive11(100, function($i){47 echo $i;48});49$runner = new Runner();
loop
Using AI Code Generation
1$runner = new Runner();2$runner->loop($runner->getRunner());3$runner = new Runner();4$runner->recursive($runner->getRunner());5$runner = new Runner();6$runner->callback($runner->getRunner());7$runner = new Runner();8$runner->array_walk_recursive($runner->getRunner());9$runner = new Runner();10$runner->array_map($runner->getRunner());11$runner = new Runner();12$runner->array_reduce($runner->getRunner());13$runner = new Runner();14$runner->array_filter($runner->getRunner());15$runner = new Runner();16$runner->array_reduce($runner->getRunner());17$runner = new Runner();18$runner->array_reduce($runner->getRunner());19$runner = new Runner();20$runner->array_reduce($runner->getRunner());21$runner = new Runner();22$runner->array_reduce($runner->getRunner());23$runner = new Runner();24$runner->array_reduce($runner->getRunner());25$runner = new Runner();26$runner->array_reduce($runner->getRunner());27$runner = new Runner();28$runner->array_reduce($runner->getRunner());29$runner = new Runner();
loop
Using AI Code Generation
1$runner = new Runner();2$runner->loop('2.php');3$runner = new Runner();4$runner->loop('3.php');5$runner = new Runner();6$runner->loop('4.php');7$runner = new Runner();8$runner->loop('5.php');9$runner = new Runner();10$runner->loop('6.php');11$runner = new Runner();12$runner->loop('7.php');13$runner = new Runner();14$runner->loop('8.php');15$runner = new Runner();16$runner->loop('9.php');17$runner = new Runner();18$runner->loop('10.php');19$runner = new Runner();20$runner->loop('11.php');21$runner = new Runner();22$runner->loop('12.php');23$runner = new Runner();24$runner->loop('13.php');25$runner = new Runner();26$runner->loop('14.php');
loop
Using AI Code Generation
1include_once("runner.php");2$runner = new runner();3$runner->loop();4class runner {5 public function loop() {6 $counter = 1;7 $sum = 0;8 $average = 0;9 $max = 0;10 $min = 0;11 $first = 0;12 $last = 0;13 $count = 0;
loop
Using AI Code Generation
1for (i=1;i<=10;i++){2echo "The number is " . $i . "<br>";3}4while (i<=10){5echo "The number is " . $i . "<br>";6$i++;7}8do {9echo "The number is " . $i . "<br>";10$i++;11} while (i<=10);12$colors = array("red", "green", "blue", "yellow"); 13foreach ($colors as $value) {14echo "$value <br>";15}16$colors = array("red", "green", "blue", "yellow"); 17foreach ($colors as $value) {18echo "$value <br>";19}20$colors = array("red", "green", "blue", "yellow"); 21foreach ($colors as $value) {22echo "$value <br>";23}24$colors = array("red", "green", "blue", "yellow"); 25foreach ($colors as $value) {26echo "$value <br>";27}
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Execute automation tests with loop on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.
Test now for FreeGet 100 minutes of automation test minutes FREE!!