Ptvsd debugger component. (#23336)
* ptvsd debugger component. * Add test case * ptvsd as test dependency * Fix for 3.5 * Fixed bootstrap test * Use dict direct lookup. * Don't need to load dependencies. * Get the test working. * 3.5 fix * Set mock return value * Put tests back, but skip them * Change log level
This commit is contained in:
parent
24060e0fb5
commit
b0843f4a38
10 changed files with 150 additions and 1 deletions
|
@ -451,6 +451,7 @@ omit =
|
|||
homeassistant/components/proxy/camera.py
|
||||
homeassistant/components/ps4/__init__.py
|
||||
homeassistant/components/ps4/media_player.py
|
||||
homeassistant/components/ptvsd/*
|
||||
homeassistant/components/pulseaudio_loopback/switch.py
|
||||
homeassistant/components/pushbullet/notify.py
|
||||
homeassistant/components/pushbullet/sensor.py
|
||||
|
|
|
@ -175,6 +175,7 @@ homeassistant/components/pi_hole/* @fabaff
|
|||
homeassistant/components/plant/* @ChristianKuehnel
|
||||
homeassistant/components/point/* @fredrike
|
||||
homeassistant/components/ps4/* @ktnrg45
|
||||
homeassistant/components/ptvsd/* @swamp-ig
|
||||
homeassistant/components/push/* @dgomes
|
||||
homeassistant/components/pvoutput/* @fabaff
|
||||
homeassistant/components/qnap/* @colinodell
|
||||
|
|
|
@ -26,6 +26,7 @@ ERROR_LOG_FILENAME = 'home-assistant.log'
|
|||
# hass.data key for logging information.
|
||||
DATA_LOGGING = 'logging'
|
||||
|
||||
DEBUGGER_INTEGRATIONS = {'ptvsd', }
|
||||
CORE_INTEGRATIONS = ('homeassistant', 'persistent_notification')
|
||||
LOGGING_INTEGRATIONS = {'logger', 'system_log'}
|
||||
STAGE_1_INTEGRATIONS = {
|
||||
|
@ -306,6 +307,15 @@ async def _async_set_up_integrations(
|
|||
"""Set up all the integrations."""
|
||||
domains = _get_domains(hass, config)
|
||||
|
||||
# Start up debuggers. Start these first in case they want to wait.
|
||||
debuggers = domains & DEBUGGER_INTEGRATIONS
|
||||
if debuggers:
|
||||
_LOGGER.debug("Starting up debuggers %s", debuggers)
|
||||
await asyncio.gather(*[
|
||||
async_setup_component(hass, domain, config)
|
||||
for domain in debuggers])
|
||||
domains -= DEBUGGER_INTEGRATIONS
|
||||
|
||||
# Resolve all dependencies of all components so we can find the logging
|
||||
# and integrations that need faster initialization.
|
||||
resolved_domains_task = asyncio.gather(*[
|
||||
|
@ -339,7 +349,7 @@ async def _async_set_up_integrations(
|
|||
stage_2_domains = domains - logging_domains - stage_1_domains
|
||||
|
||||
if logging_domains:
|
||||
_LOGGER.debug("Setting up %s", logging_domains)
|
||||
_LOGGER.info("Setting up %s", logging_domains)
|
||||
|
||||
await asyncio.gather(*[
|
||||
async_setup_component(hass, domain, config)
|
||||
|
|
63
homeassistant/components/ptvsd/__init__.py
Normal file
63
homeassistant/components/ptvsd/__init__.py
Normal file
|
@ -0,0 +1,63 @@
|
|||
"""
|
||||
Enable ptvsd debugger to attach to HA.
|
||||
|
||||
Attach ptvsd debugger by default to port 5678.
|
||||
"""
|
||||
|
||||
import logging
|
||||
from threading import Thread
|
||||
from asyncio import Event
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.const import (
|
||||
CONF_HOST, CONF_PORT)
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.typing import ConfigType, HomeAssistantType
|
||||
|
||||
DOMAIN = 'ptvsd'
|
||||
|
||||
CONF_WAIT = 'wait'
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
DOMAIN: vol.Schema({
|
||||
vol.Optional(
|
||||
CONF_HOST, default='0.0.0.0'
|
||||
): cv.string,
|
||||
vol.Optional(
|
||||
CONF_PORT, default=5678
|
||||
): cv.port,
|
||||
vol.Optional(
|
||||
CONF_WAIT, default=False
|
||||
): cv.boolean,
|
||||
})
|
||||
}, extra=vol.ALLOW_EXTRA)
|
||||
|
||||
|
||||
async def async_setup(hass: HomeAssistantType, config: ConfigType):
|
||||
"""Set up ptvsd debugger."""
|
||||
import ptvsd
|
||||
|
||||
conf = config[DOMAIN]
|
||||
host = conf[CONF_HOST]
|
||||
port = conf[CONF_PORT]
|
||||
|
||||
ptvsd.enable_attach((host, port))
|
||||
|
||||
wait = conf[CONF_WAIT]
|
||||
if wait:
|
||||
_LOGGER.warning("Waiting for ptvsd connection on %s:%s", host, port)
|
||||
ready = Event()
|
||||
|
||||
def waitfor():
|
||||
ptvsd.wait_for_attach()
|
||||
hass.loop.call_soon_threadsafe(ready.set)
|
||||
Thread(target=waitfor).start()
|
||||
|
||||
await ready.wait()
|
||||
else:
|
||||
_LOGGER.warning("Listening for ptvsd connection on %s:%s", host, port)
|
||||
|
||||
return True
|
10
homeassistant/components/ptvsd/manifest.json
Normal file
10
homeassistant/components/ptvsd/manifest.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"domain": "ptvsd",
|
||||
"name": "ptvsd",
|
||||
"documentation": "https://www.home-assistant.io/components/ptvsd",
|
||||
"requirements": [
|
||||
"ptvsd==4.2.8"
|
||||
],
|
||||
"dependencies": [],
|
||||
"codeowners": ["@swamp-ig"]
|
||||
}
|
|
@ -884,6 +884,9 @@ protobuf==3.6.1
|
|||
# homeassistant.components.systemmonitor
|
||||
psutil==5.6.1
|
||||
|
||||
# homeassistant.components.ptvsd
|
||||
ptvsd==4.2.8
|
||||
|
||||
# homeassistant.components.wink
|
||||
pubnubsub-handler==1.0.3
|
||||
|
||||
|
|
|
@ -204,6 +204,9 @@ pmsensor==0.4
|
|||
# homeassistant.components.prometheus
|
||||
prometheus_client==0.2.0
|
||||
|
||||
# homeassistant.components.ptvsd
|
||||
ptvsd==4.2.8
|
||||
|
||||
# homeassistant.components.pushbullet
|
||||
pushbullet.py==0.11.0
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@ TEST_REQUIREMENTS = (
|
|||
'pilight',
|
||||
'pmsensor',
|
||||
'prometheus_client',
|
||||
'ptvsd',
|
||||
'pushbullet.py',
|
||||
'py-canary',
|
||||
'pyblackbird',
|
||||
|
|
1
tests/components/ptvsd/__init__py
Normal file
1
tests/components/ptvsd/__init__py
Normal file
|
@ -0,0 +1 @@
|
|||
"""Tests for PTVSD Debugger"""
|
56
tests/components/ptvsd/test_ptvsd.py
Normal file
56
tests/components/ptvsd/test_ptvsd.py
Normal file
|
@ -0,0 +1,56 @@
|
|||
"""Tests for PTVSD Debugger."""
|
||||
|
||||
from unittest.mock import patch
|
||||
from asynctest import CoroutineMock
|
||||
from pytest import mark
|
||||
|
||||
import homeassistant.components.ptvsd as ptvsd_component
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.bootstrap import _async_set_up_integrations
|
||||
|
||||
|
||||
@mark.skip('causes code cover to fail')
|
||||
async def test_ptvsd(hass):
|
||||
"""Test loading ptvsd component."""
|
||||
with patch('ptvsd.enable_attach') as attach:
|
||||
with patch('ptvsd.wait_for_attach') as wait:
|
||||
assert await async_setup_component(
|
||||
hass, ptvsd_component.DOMAIN, {
|
||||
ptvsd_component.DOMAIN: {}
|
||||
})
|
||||
|
||||
attach.assert_called_once_with(('0.0.0.0', 5678))
|
||||
assert wait.call_count == 0
|
||||
|
||||
|
||||
@mark.skip('causes code cover to fail')
|
||||
async def test_ptvsd_wait(hass):
|
||||
"""Test loading ptvsd component with wait."""
|
||||
with patch('ptvsd.enable_attach') as attach:
|
||||
with patch('ptvsd.wait_for_attach') as wait:
|
||||
assert await async_setup_component(
|
||||
hass, ptvsd_component.DOMAIN, {
|
||||
ptvsd_component.DOMAIN: {
|
||||
ptvsd_component.CONF_WAIT: True
|
||||
}
|
||||
})
|
||||
|
||||
attach.assert_called_once_with(('0.0.0.0', 5678))
|
||||
assert wait.call_count == 1
|
||||
|
||||
|
||||
async def test_ptvsd_bootstrap(hass):
|
||||
"""Test loading ptvsd component with wait."""
|
||||
config = {
|
||||
ptvsd_component.DOMAIN: {
|
||||
ptvsd_component.CONF_WAIT: True
|
||||
}
|
||||
}
|
||||
|
||||
with patch(
|
||||
'homeassistant.components.ptvsd.async_setup',
|
||||
CoroutineMock()) as setup_mock:
|
||||
setup_mock.return_value = True
|
||||
await _async_set_up_integrations(hass, config)
|
||||
|
||||
assert setup_mock.call_count == 1
|
Loading…
Add table
Reference in a new issue