From d5c59292c86366bf709840cb4d22942c325e83b0 Mon Sep 17 00:00:00 2001 From: Otto Winter Date: Wed, 15 Jul 2020 14:00:02 +0200 Subject: [PATCH] Add pytest to CI (#1138) --- .github/workflows/ci.yml | 42 +++++++++++++++++++++-------- .github/workflows/release-dev.yml | 42 ++++++++++++++++++++++------- .github/workflows/release.yml | 44 +++++++++++++++++++++++-------- esphome/core.py | 16 +++++++++-- esphome/pins.py | 10 ++++--- tests/unit_tests/test_core.py | 4 ++- tests/unit_tests/test_pins.py | 1 - 7 files changed, 120 insertions(+), 39 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6ade0655a2..6d6798314f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,8 +9,6 @@ on: branches: [beta, master] pull_request: - # Only trigger on certain events (not when comments are added) - types: [opened, reopened, synchronize] # Only run when PR is against dev branch (all PRs should be against dev branch) # Helps prevent accidentally merging PRs against master branch branches: [dev] @@ -176,15 +174,6 @@ jobs: key: test-home-platformio-${{ matrix.test }}-${{ hashFiles('esphome/core_config.py') }} restore-keys: | test-home-platformio-${{ matrix.test }}- - # Cache the intermediary build files - - name: Cache Test Build - uses: actions/cache@v1 - with: - path: tests/build/${{ matrix.test }} - key: test-pio-${{ matrix.test }}-${{ hashFiles('esphome/core_config.py') }}-${{ hashFiles('esphome/**') }} - restore-keys: | - test-pio-${{ matrix.test }}-${{ hashFiles('esphome/core_config.py') }}- - test-pio-${{ matrix.test }}- - name: Set up environment run: script/setup @@ -194,3 +183,34 @@ jobs: echo "::add-matcher::.github/workflows/matchers/gcc.json" echo "::add-matcher::.github/workflows/matchers/python.json" - run: esphome tests/${{ matrix.test }}.yaml compile + + pytest: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.7' + - name: Cache pip modules + uses: actions/cache@v1 + with: + path: ~/.cache/pip + key: esphome-pip-3.7-${{ hashFiles('setup.py') }} + restore-keys: | + esphome-pip-3.7- + - name: Set up environment + run: script/setup + - name: Install Github Actions annotator + run: pip install pytest-github-actions-annotate-failures + + - name: Register problem matchers + run: | + echo "::add-matcher::.github/workflows/matchers/python.json" + - name: Run pytest + run: | + pytest \ + -qq \ + --durations=10 \ + -o console_output_style=count \ + tests diff --git a/.github/workflows/release-dev.yml b/.github/workflows/release-dev.yml index e807666de4..3eb6884ee0 100644 --- a/.github/workflows/release-dev.yml +++ b/.github/workflows/release-dev.yml @@ -129,15 +129,6 @@ jobs: key: test-home-platformio-${{ matrix.test }}-${{ hashFiles('esphome/core_config.py') }} restore-keys: | test-home-platformio-${{ matrix.test }}- - # Cache the intermediary build files - - name: Cache Test Build - uses: actions/cache@v1 - with: - path: tests/build/${{ matrix.test }} - key: test-pio-${{ matrix.test }}-${{ hashFiles('esphome/core_config.py') }}-${{ hashFiles('esphome/**') }} - restore-keys: | - test-pio-${{ matrix.test }}-${{ hashFiles('esphome/core_config.py') }}- - test-pio-${{ matrix.test }}- - name: Set up environment run: script/setup @@ -148,10 +139,41 @@ jobs: echo "::add-matcher::.github/workflows/matchers/python.json" - run: esphome tests/${{ matrix.test }}.yaml compile + pytest: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.7' + - name: Cache pip modules + uses: actions/cache@v1 + with: + path: ~/.cache/pip + key: esphome-pip-3.7-${{ hashFiles('setup.py') }} + restore-keys: | + esphome-pip-3.7- + - name: Set up environment + run: script/setup + - name: Install Github Actions annotator + run: pip install pytest-github-actions-annotate-failures + + - name: Register problem matchers + run: | + echo "::add-matcher::.github/workflows/matchers/python.json" + - name: Run pytest + run: | + pytest \ + -qq \ + --durations=10 \ + -o console_output_style=count \ + tests + deploy-docker: name: Build and publish docker containers runs-on: ubuntu-latest - needs: [lint-clang-format, lint-clang-tidy, lint-python, test] + needs: [lint-clang-format, lint-clang-tidy, lint-python, test, pytest] strategy: matrix: arch: [amd64, i386, armv7, aarch64] diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 47811cc53c..43e0d86365 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -128,15 +128,6 @@ jobs: key: test-home-platformio-${{ matrix.test }}-${{ hashFiles('esphome/core_config.py') }} restore-keys: | test-home-platformio-${{ matrix.test }}- - # Cache the intermediary build files - - name: Cache Test Build - uses: actions/cache@v1 - with: - path: tests/build/${{ matrix.test }} - key: test-pio-${{ matrix.test }}-${{ hashFiles('esphome/core_config.py') }}-${{ hashFiles('esphome/**') }} - restore-keys: | - test-pio-${{ matrix.test }}-${{ hashFiles('esphome/core_config.py') }}- - test-pio-${{ matrix.test }}- - name: Set up environment run: script/setup @@ -145,10 +136,41 @@ jobs: echo "::add-matcher::.github/workflows/matchers/gcc.json" echo "::add-matcher::.github/workflows/matchers/python.json" - run: esphome tests/${{ matrix.test }}.yaml compile + + pytest: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.7' + - name: Cache pip modules + uses: actions/cache@v1 + with: + path: ~/.cache/pip + key: esphome-pip-3.7-${{ hashFiles('setup.py') }} + restore-keys: | + esphome-pip-3.7- + - name: Set up environment + run: script/setup + - name: Install Github Actions annotator + run: pip install pytest-github-actions-annotate-failures + + - name: Register problem matchers + run: | + echo "::add-matcher::.github/workflows/matchers/python.json" + - name: Run pytest + run: | + pytest \ + -qq \ + --durations=10 \ + -o console_output_style=count \ + tests deploy-pypi: name: Build and publish to PyPi - needs: [lint-clang-format, lint-clang-tidy, lint-python, test] + needs: [lint-clang-format, lint-clang-tidy, lint-python, test, pytest] runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -171,7 +193,7 @@ jobs: deploy-docker: name: Build and publish docker containers runs-on: ubuntu-latest - needs: [lint-clang-format, lint-clang-tidy, lint-python, test] + needs: [lint-clang-format, lint-clang-tidy, lint-python, test, pytest] strategy: matrix: arch: [amd64, i386, armv7, aarch64] diff --git a/esphome/core.py b/esphome/core.py index dfb37555e1..52904f0d0b 100644 --- a/esphome/core.py +++ b/esphome/core.py @@ -493,9 +493,9 @@ class EsphomeCore: # The board that's used (for example nodemcuv2) self.board: Optional[str] = None # The full raw configuration - self.raw_config: ConfigType = {} + self.raw_config: Optional[ConfigType] = None # The validated configuration, this is None until the config has been validated - self.config: ConfigType = {} + self.config: Optional[ConfigType] = None # The pending tasks in the task queue (mostly for C++ generation) # This is a priority queue (with heapq) # Each item is a tuple of form: (-priority, unique number, task) @@ -547,6 +547,10 @@ class EsphomeCore: @property def address(self) -> Optional[str]: + if self.config is None: + raise ValueError("Config has not been loaded yet") + + # pylint: disable=unsupported-membership-test,unsubscriptable-object if 'wifi' in self.config: return self.config[CONF_WIFI][CONF_USE_ADDRESS] @@ -557,6 +561,10 @@ class EsphomeCore: @property def comment(self) -> Optional[str]: + if self.config is None: + raise ValueError("Config has not been loaded yet") + + # pylint: disable=unsubscriptable-object if CONF_COMMENT in self.config[CONF_ESPHOME]: return self.config[CONF_ESPHOME][CONF_COMMENT] @@ -570,6 +578,10 @@ class EsphomeCore: @property def arduino_version(self) -> str: + if self.config is None: + raise ValueError("Config has not been loaded yet") + + # pylint: disable=unsubscriptable-object return self.config[CONF_ESPHOME][CONF_ARDUINO_VERSION] @property diff --git a/esphome/pins.py b/esphome/pins.py index 7f4c869895..b6fde85250 100644 --- a/esphome/pins.py +++ b/esphome/pins.py @@ -256,16 +256,20 @@ ESP32_BOARD_PINS = { def _lookup_pin(value): if CORE.is_esp8266: - board_pins = ESP8266_BOARD_PINS.get(CORE.board, {}) + board_pins_dict = ESP8266_BOARD_PINS base_pins = ESP8266_BASE_PINS elif CORE.is_esp32: - board_pins = ESP32_BOARD_PINS.get(CORE.board, {}) + board_pins_dict = ESP32_BOARD_PINS base_pins = ESP32_BASE_PINS else: raise NotImplementedError + board_pins = board_pins_dict.get(CORE.board, {}) + + # Resolved aliased board pins (shorthand when two boards have the same pin configuration) while isinstance(board_pins, str): - board_pins = ESP8266_BOARD_PINS.get(board_pins, {}) + board_pins = board_pins_dict[board_pins] + if value in board_pins: return board_pins[value] if value in base_pins: diff --git a/tests/unit_tests/test_core.py b/tests/unit_tests/test_core.py index cd0b0947f3..166a12c40e 100644 --- a/tests/unit_tests/test_core.py +++ b/tests/unit_tests/test_core.py @@ -459,7 +459,6 @@ class TestEsphomeCore: target.config_path = "foo/config" return target - @pytest.mark.xfail(reason="raw_config and config differ, should they?") def test_reset(self, target): """Call reset on target and compare to new instance""" other = core.EsphomeCore() @@ -469,15 +468,18 @@ class TestEsphomeCore: assert target.__dict__ == other.__dict__ def test_address__none(self, target): + target.config = {} assert target.address is None def test_address__wifi(self, target): + target.config = {} target.config[const.CONF_WIFI] = {const.CONF_USE_ADDRESS: "1.2.3.4"} target.config["ethernet"] = {const.CONF_USE_ADDRESS: "4.3.2.1"} assert target.address == "1.2.3.4" def test_address__ethernet(self, target): + target.config = {} target.config["ethernet"] = {const.CONF_USE_ADDRESS: "4.3.2.1"} assert target.address == "4.3.2.1" diff --git a/tests/unit_tests/test_pins.py b/tests/unit_tests/test_pins.py index 606c20eea2..7d68181add 100644 --- a/tests/unit_tests/test_pins.py +++ b/tests/unit_tests/test_pins.py @@ -94,7 +94,6 @@ class Test_lookup_pin: assert actual == expected - @pytest.mark.xfail(reason="This may be expected") def test_valid_32_pin_alias(self, core_esp32): core_esp32.board = MOCK_ESP32_BOARD_ALIAS_ID