async def test_thread_not_started(hass): """Test throwing when the thread is not started.""" test_thread = ThreadWithException(target=lambda *_: None) with pytest.raises(AssertionError): test_thread.raise_exc(TimeoutError)
async def async_render_will_timeout( self, timeout: float, variables: TemplateVarsType = None, strict: bool = False, **kwargs: Any, ) -> bool: """Check to see if rendering a template will timeout during render. This is intended to check for expensive templates that will make the system unstable. The template is rendered in the executor to ensure it does not tie up the event loop. This function is not a security control and is only intended to be used as a safety check when testing templates. This method must be run in the event loop. """ if self.is_static: return False compiled = self._compiled or self._ensure_compiled(strict=strict) if variables is not None: kwargs.update(variables) self._exc_info = None finish_event = asyncio.Event() def _render_template() -> None: try: _render_with_context(self.template, compiled, **kwargs) except TimeoutError: pass except Exception: # pylint: disable=broad-except self._exc_info = sys.exc_info() finally: run_callback_threadsafe(self.hass.loop, finish_event.set) try: template_render_thread = ThreadWithException( target=_render_template) template_render_thread.start() await asyncio.wait_for(finish_event.wait(), timeout=timeout) if self._exc_info: raise TemplateError(self._exc_info[1].with_traceback( self._exc_info[2])) except asyncio.TimeoutError: template_render_thread.raise_exc(TimeoutError) return True finally: template_render_thread.join() return False
async def test_thread_fails_raise(hass): """Test throwing after already ended.""" finish_event = asyncio.Event() def _do_nothing(*_): run_callback_threadsafe(hass.loop, finish_event.set) test_thread = ThreadWithException(target=_do_nothing) test_thread.start() await asyncio.wait_for(finish_event.wait(), timeout=0.1) test_thread.join() with pytest.raises(SystemError): test_thread.raise_exc(ValueError)
async def test_thread_with_exception_invalid(hass): """Test throwing an invalid thread exception.""" finish_event = asyncio.Event() def _do_nothing(*_): run_callback_threadsafe(hass.loop, finish_event.set) test_thread = ThreadWithException(target=_do_nothing) test_thread.start() await asyncio.wait_for(finish_event.wait(), timeout=0.1) with pytest.raises(TypeError): test_thread.raise_exc(_EmptyClass()) test_thread.join()