| 1 |  |  | <?php namespace Chekote\BehatRetryExtension\ServiceContainer; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | use Behat\Behat\Definition\ServiceContainer\DefinitionExtension; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  | use Behat\Testwork\Call\ServiceContainer\CallExtension; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | use Behat\Testwork\ServiceContainer\Extension; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | use Behat\Testwork\ServiceContainer\ExtensionManager; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | use Chekote\BehatRetryExtension\Tester\RuntimeStepTester; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | use Symfony\Component\DependencyInjection\ContainerBuilder; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | use Symfony\Component\DependencyInjection\Definition; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | use Symfony\Component\DependencyInjection\Reference; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  |  * Extension for automatically retrying "Then" steps. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |  */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | class BehatRetryExtension implements Extension | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  | { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |     /** The service that our step tester needs to replace */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  |     const SERVICE_ID = 'tester.step.wrapper.hookable.inner'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |     const CONFIG_KEY = 'spinner'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |     const CONFIG_ENV_TIMEOUT = 'BEHAT_RETRY_TIMEOUT'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |     const CONFIG_PARAM_ALL = 'parameters'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |     const CONFIG_PARAM_INTERVAL = 'interval'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |     const CONFIG_PARAM_TIMEOUT = 'timeout'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |     const CONFIG_PARAM_STRICT_KEYWORDS = 'strictKeywords'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |     const CONFIG_ALL = self::CONFIG_KEY . '.' . self::CONFIG_PARAM_ALL; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |     const CONFIG_RETRY_INTERVAL = self::CONFIG_KEY . '.' . self::CONFIG_PARAM_INTERVAL; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |     const CONFIG_TIMEOUT = self::CONFIG_KEY . '.' . self::CONFIG_PARAM_TIMEOUT; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |     const CONFIG_STRICT_KEYWORDS = self::CONFIG_KEY . '.' . self::CONFIG_PARAM_STRICT_KEYWORDS; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |      * {@inheritdoc} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |     public function process(ContainerBuilder $container) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |         $definition = new Definition(RuntimeStepTester::class, [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |             new Reference(DefinitionExtension::FINDER_ID), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |             new Reference(CallExtension::CALL_CENTER_ID), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |         ]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |         $container->setDefinition(self::SERVICE_ID, $definition); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |      * {@inheritdoc} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |     public function getConfigKey() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |         return self::CONFIG_KEY; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |      * {@inheritdoc} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |     public function initialize(ExtensionManager $extensionManager) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |      * {@inheritdoc} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |     public function configure(ArrayNodeDefinition $builder) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |         /* @scrutinizer ignore-call Scrutinizer does not understand the context that determines the return types  */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |         $builder | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |             ->children() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |                 ->floatNode(self::CONFIG_PARAM_TIMEOUT)->defaultValue(5)->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |                 ->integerNode(self::CONFIG_PARAM_INTERVAL)->defaultValue(100000000)->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |                 ->booleanNode(self::CONFIG_PARAM_STRICT_KEYWORDS)->defaultTrue()->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |             ->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |         ->end(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |      * {@inheritdoc} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |     public function load(ContainerBuilder $container, array $config) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |         $container->setParameter(self::CONFIG_ALL, $config); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |         $envTimeout = $this->getEnvTimeout(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |         $container->setParameter( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |             self::CONFIG_TIMEOUT, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |             $envTimeout !== null ? $envTimeout : $config[self::CONFIG_PARAM_TIMEOUT] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |         $container->setParameter(self::CONFIG_RETRY_INTERVAL, $config[self::CONFIG_PARAM_INTERVAL]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |         $container->setParameter(self::CONFIG_STRICT_KEYWORDS, $config[self::CONFIG_PARAM_STRICT_KEYWORDS]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |         $this->loadRuntimeStepTester($container); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |      * Sets up up the RuntimeStepTester. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |      * The specified container should have a self::CONFIG_TIMEOUT and a self::CONFIG_RETRY_INTERVAL parameter. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |      * @param ContainerBuilder $container the container with the parameters to use. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |     private function loadRuntimeStepTester(ContainerBuilder $container) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |         RuntimeStepTester::$timeout = $container->getParameter(self::CONFIG_TIMEOUT); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |         RuntimeStepTester::$interval = $container->getParameter(self::CONFIG_RETRY_INTERVAL); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |         RuntimeStepTester::$strictKeywords = $container->getParameter(self::CONFIG_STRICT_KEYWORDS); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |      * Gets the timeout from the environment variable, if set. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |      * @return float|null the timeout in seconds, or null if not set or invalid. | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 112 |  |  |      */ | 
            
                                                                        
                            
            
                                    
            
            
                | 113 |  |  |     private function getEnvTimeout(): ?float | 
            
                                                                        
                            
            
                                    
            
            
                | 114 |  |  |     { | 
            
                                                                        
                            
            
                                    
            
            
                | 115 |  |  |         $raw = getenv(self::CONFIG_ENV_TIMEOUT); | 
            
                                                                        
                            
            
                                    
            
            
                | 116 |  |  |         if ($raw === false) { | 
            
                                                                        
                            
            
                                    
            
            
                | 117 |  |  |             return null; | 
            
                                                                        
                            
            
                                    
            
            
                | 118 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 119 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 120 |  |  |         $value = trim($raw); | 
            
                                                                        
                            
            
                                    
            
            
                | 121 |  |  |         if ($value === '') { | 
            
                                                                        
                            
            
                                    
            
            
                | 122 |  |  |             return null; | 
            
                                                                        
                            
            
                                    
            
            
                | 123 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 124 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 125 |  |  |         if (!is_numeric($value)) { | 
            
                                                                        
                            
            
                                    
            
            
                | 126 |  |  |             fwrite(STDERR, 'Warning: Environment variable ' . self::CONFIG_ENV_TIMEOUT . | 
            
                                                                        
                            
            
                                    
            
            
                | 127 |  |  |                 ' should be numeric (seconds), got "' . $raw . '"' . PHP_EOL); | 
            
                                                                        
                            
            
                                    
            
            
                | 128 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 129 |  |  |             return null; | 
            
                                                                        
                            
            
                                    
            
            
                | 130 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 131 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 132 |  |  |         $numeric = (float) $value; | 
            
                                                                        
                            
            
                                    
            
            
                | 133 |  |  |         if ($numeric < 0) { | 
            
                                                                        
                            
            
                                    
            
            
                | 134 |  |  |             fwrite(STDERR, 'Warning: Environment variable ' . self::CONFIG_ENV_TIMEOUT . | 
            
                                                                        
                            
            
                                    
            
            
                | 135 |  |  |                 ' must be >= 0, got "' . $raw . '"' . PHP_EOL); | 
            
                                                                        
                            
            
                                    
            
            
                | 136 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 137 |  |  |             return null; | 
            
                                                                        
                            
            
                                    
            
            
                | 138 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 139 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 140 |  |  |         return $numeric; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 142 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 143 |  |  |  |