Skip to content

Commit

Permalink
Adding bats test suite for integration testing
Browse files Browse the repository at this point in the history
  • Loading branch information
freol35241 committed Apr 10, 2023
1 parent 4f00bae commit c76f2d1
Show file tree
Hide file tree
Showing 10 changed files with 300 additions and 83 deletions.
17 changes: 10 additions & 7 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
{
"name": "ltss_devcontainer",
"image": "mcr.microsoft.com/vscode/devcontainers/python:0-3.10-bullseye",
"postCreateCommand": "pip install --requirement requirements.dev.txt",
"remoteUser": "vscode",
"features": {
"rust": "latest",
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
"ghcr.io/edouard-lopez/devcontainer-features/bats:0": {}
},
"postCreateCommand": "pip install --requirement requirements.dev.txt && bash .devcontainer/install-bats-helpers.sh",
"forwardPorts": [
8123
],
"customizations": {
"vscode": {
"extensions": [
"ms-python.python"
"ms-python.python",
"jetmartin.bats@0.1.9",
"timonwong.shellcheck@0.29.4"
],
"settings": {
"files.eol": "\n",
Expand All @@ -25,10 +33,5 @@
"files.trimTrailingWhitespace": true
}
}
},
"remoteUser": "vscode",
"features": {
"rust": "latest",
"ghcr.io/devcontainers/features/docker-in-docker:2": {}
}
}
9 changes: 9 additions & 0 deletions .devcontainer/install-bats-helpers.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash

[ -d tests/bats/bats-helpers ] && rm -rf tests/bats/bats-helpers

mkdir -p tests/bats-helpers

git clone --depth 1 https://github.com/bats-core/bats-support.git tests/bats/bats-helpers/bats-support || true
git clone --depth 1 https://github.com/bats-core/bats-assert.git tests/bats/bats-helpers/bats-assert || true
git clone --depth 1 https://github.com/bats-core/bats-file.git tests/bats/bats-helpers/bats-file || true
30 changes: 0 additions & 30 deletions .github/workflows/ci-tests.yml

This file was deleted.

25 changes: 25 additions & 0 deletions .github/workflows/linting.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

name: Linting

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

permissions:
contents: read

jobs:
black:
runs-on: ubuntu-latest
steps:

- name: Checkout (GitHub)
uses: actions/checkout@v3

- name: Build and run Dev Container task
uses: devcontainers/ci@v0.3
with:
runCmd: |
black --check custom_components/
38 changes: 38 additions & 0 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@

name: Testing

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

permissions:
contents: read

jobs:
pytest:
runs-on: ubuntu-latest
steps:

- name: Checkout (GitHub)
uses: actions/checkout@v3

- name: Build and run Dev Container task
uses: devcontainers/ci@v0.3
with:
runCmd: |
python -m pytest -p no:homeassistant tests/pytest/test_databases.py
bats:
runs-on: ubuntu-latest
steps:

- name: Checkout (GitHub)
uses: actions/checkout@v3

- name: Build and run Dev Container task
uses: devcontainers/ci@v0.3
with:
runCmd: |
bats tests/bats
84 changes: 46 additions & 38 deletions custom_components/ltss/migrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,64 +6,72 @@

_LOGGER = logging.getLogger(__name__)


def check_and_migrate(engine):

#Inspect the DB
# Inspect the DB
iengine = inspect(engine)
columns = iengine.get_columns(LTSS.__tablename__)
indexes = iengine.get_indexes(LTSS.__tablename__)

def index_exists(index_name):
matches = [idx for idx in indexes if idx["name"] == index_name]
return True if matches else False

# Attributes column Text -> JSONB
attributes_column = next(col for col in columns if col["name"] == 'attributes')
if isinstance(attributes_column['type'], Text):
_LOGGER.warning('Migrating you LTSS table to the latest schema, this might take a couple of minutes!')
attributes_column = next(col for col in columns if col["name"] == "attributes")
if isinstance(attributes_column["type"], Text):
_LOGGER.warning(
"Migrating you LTSS table to the latest schema, this might take a couple of minutes!"
)
migrate_attributes_text_to_jsonb(engine)
_LOGGER.info('Migration completed successfully!')
_LOGGER.info("Migration completed successfully!")

# Attributes Index?
if not index_exists('ltss_attributes_idx'):
_LOGGER.warning('Creating an index for the attributes column, this might take a couple of minutes!')
if not index_exists("ltss_attributes_idx"):
_LOGGER.warning(
"Creating an index for the attributes column, this might take a couple of minutes!"
)
create_attributes_index(engine)
_LOGGER.info('Index created successfully!')
_LOGGER.info("Index created successfully!")

# entity_id and time composite Index?
if not index_exists('ltss_entityid_time_composite_idx'):
_LOGGER.warning('Creating a composite index over entity_id and time columns, this might take a couple of minutes!')
if not index_exists("ltss_entityid_time_composite_idx"):
_LOGGER.warning(
"Creating a composite index over entity_id and time columns, this might take a couple of minutes!"
)
create_entityid_time_index(engine)
_LOGGER.info('Index created successfully!')
if index_exists('ix_ltss_entity_id'):
_LOGGER.warning('Index on entity_id no longer needed, dropping...')
_LOGGER.info("Index created successfully!")

if index_exists("ix_ltss_entity_id"):
_LOGGER.warning("Index on entity_id no longer needed, dropping...")
drop_entityid_index(engine)


def migrate_attributes_text_to_jsonb(engine):

with engine.connect() as con:

_LOGGER.info("Migrating attributes column from type text to type JSONB")
con.execute(text(
f"""ALTER TABLE {LTSS.__tablename__}
con.execute(
text(
f"""ALTER TABLE {LTSS.__tablename__}
ALTER COLUMN attributes TYPE JSONB USING attributes::JSONB;"""
).execution_options(autocommit=True))

).execution_options(autocommit=True)
)


def create_attributes_index(engine):
_LOGGER.info("Creating GIN index on the attributes column")
LTSS_attributes_index.create(bind=engine)
_LOGGER.info("Creating GIN index on the attributes column")
LTSS_attributes_index.create(bind=engine)


def create_entityid_time_index(engine):
_LOGGER.info("Creating composite index over entity_id and time columns")
LTSS_entityid_time_composite_index.create(bind=engine)
_LOGGER.info("Creating composite index over entity_id and time columns")
LTSS_entityid_time_composite_index.create(bind=engine)


def drop_entityid_index(engine):

with engine.connect() as con:
con.execute(text(
f"""DROP INDEX ix_ltss_entity_id;"""
).execution_options(autocommit=True))

con.execute(
text(f"""DROP INDEX ix_ltss_entity_id;""").execution_options(
autocommit=True
)
)
21 changes: 13 additions & 8 deletions custom_components/ltss/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def activate_location_extraction(cls):
After activation, this cannot be deactivated (due to how the underlying SQLAlchemy ORM works).
"""
cls.location = column_property(Column(Geometry('POINT', srid=4326)))
cls.location = column_property(Column(Geometry("POINT", srid=4326)))

@classmethod
def from_event(cls, event):
Expand All @@ -53,23 +53,28 @@ def from_event(cls, event):

location = None

if cls.location: # if the additional column exists, use Postgis' Geometry/Point data structure
lat = attrs.pop('latitude', None)
lon = attrs.pop('longitude', None)
if (
cls.location
): # if the additional column exists, use Postgis' Geometry/Point data structure
lat = attrs.pop("latitude", None)
lon = attrs.pop("longitude", None)

location = f'SRID=4326;POINT({lon} {lat})' if lon and lat else None
location = f"SRID=4326;POINT({lon} {lat})" if lon and lat else None

row = LTSS(
entity_id=entity_id,
time=event.time_fired,
state=state.state,
attributes=attrs,
location=location
location=location,
)

return row

LTSS_attributes_index = Index('ltss_attributes_idx', LTSS.attributes, postgresql_using='gin')

LTSS_attributes_index = Index(
"ltss_attributes_idx", LTSS.attributes, postgresql_using="gin"
)
LTSS_entityid_time_composite_index = Index(
'ltss_entityid_time_composite_idx', LTSS.entity_id, LTSS.time.desc()
"ltss_entityid_time_composite_idx", LTSS.entity_id, LTSS.time.desc()
)
11 changes: 11 additions & 0 deletions tests/bats/config/configuration.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# https://www.home-assistant.io/integrations/default_config/
default_config:

ltss:
db_url: postgresql://postgres@localhost:5432

# https://www.home-assistant.io/integrations/logger/
logger:
default: info
logs:
custom_components.ltss: debug
Loading

0 comments on commit c76f2d1

Please sign in to comment.