Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci(lcd_qemu_rgb_panel): test example in CI #440

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/test_requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Generic requirements for all tests
pytest-embedded==1.11.7
pytest-embedded-serial-esp==1.11.7
pytest-embedded-idf==1.11.7
pytest-embedded-qemu==1.11.7
pytest-custom_exit_code==0.3.0

# Test-specific requirements
cryptography==43.0.3
pillow==10.3.0
43 changes: 29 additions & 14 deletions .github/workflows/build_and_run_apps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ jobs:
fail-fast: false
matrix:
idf_ver:
- "release-v5.0"
- "release-v5.1"
- "release-v5.2"
- "release-v5.3"
# - "release-v5.0"
# - "release-v5.1"
# - "release-v5.2"
# - "release-v5.3"
- "latest"
parallel_index: [1,2,3,4,5] # Update --parallel-count below when changing this
runs-on: ubuntu-22.04
Expand Down Expand Up @@ -122,27 +122,30 @@ jobs:
fail-fast: false
matrix:
idf_ver:
- "release-v5.0"
- "release-v5.1"
- "release-v5.2"
- "release-v5.3"
# - "release-v5.0"
# - "release-v5.1"
# - "release-v5.2"
# - "release-v5.3"
- "latest"
runner:
- runs-on: "esp32"
- runs-on: '["self-hosted", "linux", "docker", "esp32"]'
marker: "generic"
target: "esp32"
- runs-on: "ESP32-ETHERNET-KIT"
- runs-on: '["self-hosted", "linux", "docker", "ESP32-ETHERNET-KIT"]'
marker: "ethernet"
target: "esp32"
- runs-on: "spi_nand_flash"
- runs-on: '["self-hosted", "linux", "docker", "spi_nand_flash"]'
marker: "spi_nand_flash"
target: "esp32"
- runs-on: '["ubuntu-22.04"]'
marker: "qemu"
target: "esp32"
env:
TEST_RESULT_NAME: test_results_${{ matrix.runner.target }}_${{ matrix.runner.marker }}_${{ matrix.idf_ver }}
TEST_RESULT_FILE: test_results_${{ matrix.runner.target }}_${{ matrix.runner.marker }}_${{ matrix.idf_ver }}.xml
runs-on: [self-hosted, linux, docker, "${{ matrix.runner.runs-on }}"]
runs-on: ${{ fromjson(matrix.runner.runs-on) }}
container:
image: python:3.11-bookworm
image: 'python:3.11-bookworm'
options: --privileged # Privileged mode has access to serial ports
steps:
- uses: actions/checkout@v4
Expand All @@ -153,7 +156,19 @@ jobs:
- name: Install Python packages
env:
PIP_EXTRA_INDEX_URL: "https://dl.espressif.com/pypi/"
run: pip install --prefer-binary cryptography pytest-embedded pytest-embedded-serial-esp pytest-embedded-idf pytest-custom_exit_code
run: python3 -m pip install --prefer-binary -r .github/test_requirements.txt
- name: Install QEMU
if: matrix.runner.marker == 'qemu'
env:
QEMU_VERSION: "esp-develop-9.0.0-20240606"
QEMU_ARCHIVE: "qemu-xtensa-softmmu-esp_develop_9.0.0_20240606-x86_64-linux-gnu.tar.xz"
run: |
curl -sSL -o ${QEMU_ARCHIVE} https://github.com/espressif/qemu/releases/download/${QEMU_VERSION}/${QEMU_ARCHIVE}
tar -xf ${QEMU_ARCHIVE}
rm ${QEMU_ARCHIVE}
apt-get update
apt-get install -y libgcrypt20 libglib2.0-0 libpixman-1-0 libsdl2-2.0-0 libslirp0
echo "$PWD/qemu/bin" >> $GITHUB_PATH
- name: Run apps
run: |
python3 .github/get_pytest_args.py --target=${{ matrix.runner.target }} -v 'build_info*.json' pytest-args.txt
Expand Down
10 changes: 8 additions & 2 deletions esp_lcd_qemu_rgb/examples/lcd_qemu_rgb_panel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@ By default, the example will use the target internal RAM as the frame buffer. To

### Build and run

To build the example, run `idf.py build` command.
To build and run the example, run:
```shell
idf.py qemu -g monitor
```

Please refer to the [QEMU Guide](https://github.com/espressif/esp-toolchain-docs/blob/main/qemu/README.md) for the detailed steps to setup and run the image.
Please refer to the [QEMU Guide](https://github.com/espressif/esp-toolchain-docs/blob/main/qemu/README.md) for more information on installing and running QEMU.

## Example Output

Expand All @@ -34,3 +37,6 @@ I (55) example: Starting LVGL task
I (65) example: Display LVGL Scatter Chart
I (75) main_task: Returned from app_main()
```

The following image should be displayed:
![](doc/scatter_chart.png)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,11 @@ menu "Example Configuration"
help
Use QEMU RGB panel dedicated framebuffer as the framebuffer for LVGL.

config EXAMPLE_QEMU_RGB_PANEL_STATIC
bool "Static UI (for testing)"
default "n"
help
If this option is enabled, example will not update the chart after
it was drawn. This option is used in CI when testing the example.

endmenu
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,6 @@ void app_main(void)
// Release the mutex
example_lvgl_unlock();
}

ESP_LOGI(TAG, "LVGL Scatter Chart displayed");
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ static void draw_event_cb(lv_event_t *e)
}
}

#ifndef CONFIG_EXAMPLE_QEMU_RGB_PANEL_STATIC
static void add_data(lv_timer_t *timer)
{
lv_obj_t *chart = timer->user_data;
lv_chart_set_next_value2(chart, lv_chart_get_series_next(chart, NULL), lv_rand(0, 200), lv_rand(0, 1000));
}
#endif //CONFIG_EXAMPLE_QEMU_RGB_PANEL_STATIC

void example_lvgl_demo_ui(lv_disp_t *disp)
{
Expand All @@ -64,5 +66,7 @@ void example_lvgl_demo_ui(lv_disp_t *disp)
lv_chart_set_next_value2(chart, ser, lv_rand(0, 200), lv_rand(0, 1000));
}

#ifndef CONFIG_EXAMPLE_QEMU_RGB_PANEL_STATIC
lv_timer_create(add_data, 100, chart);
#endif
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0

import pytest
import os
from pytest_embedded import Dut
import time
try:
from PIL import Image
from PIL import ImageChops
except ImportError:
Image = None

Check warning on line 13 in esp_lcd_qemu_rgb/examples/lcd_qemu_rgb_panel/pytest_lcd_qemu_rgb_panel.py

View workflow job for this annotation

GitHub Actions / Test Results

test_qemu_rgb_panel[idf,qemu--display sdl] (esp_lcd_qemu_rgb.examples.lcd_qemu_rgb_panel.pytest_lcd_qemu_rgb_panel) failed

test_results/test_results_esp32_qemu_latest/test_results_esp32_qemu_latest.xml [took 5s]
Raw output
qemu.qmp.qmp_client.ExecuteError: The command screendump has not been found
esp_lcd_qemu_rgb/examples/lcd_qemu_rgb_panel/pytest_lcd_qemu_rgb_panel.py:25: in test_qemu_rgb_panel
    dut.qemu.take_screenshot(filename)
/usr/local/lib/python3.11/site-packages/pytest_embedded_qemu/qemu.py:128: in take_screenshot
    self.qmp_execute_cmd('screendump', arguments={'filename': image_path})
/usr/local/lib/python3.11/site-packages/pytest_embedded_qemu/qemu.py:121: in qmp_execute_cmd
    asyncio.run(h_r())
/usr/local/lib/python3.11/asyncio/runners.py:190: in run
    return runner.run(main)
/usr/local/lib/python3.11/asyncio/runners.py:118: in run
    return self._loop.run_until_complete(task)
/usr/local/lib/python3.11/asyncio/base_events.py:654: in run_until_complete
    return future.result()
/usr/local/lib/python3.11/site-packages/pytest_embedded_qemu/qemu.py:117: in h_r
    response = await qmp.execute(execute, arguments=arguments)
/usr/local/lib/python3.11/site-packages/qemu/qmp/qmp_client.py:687: in execute
    return await self.execute_msg(msg)
/usr/local/lib/python3.11/site-packages/qemu/qmp/protocol.py:173: in _async_wrapper
    return await func(proto, *args, **kwargs)
/usr/local/lib/python3.11/site-packages/qemu/qmp/qmp_client.py:634: in execute_msg
    raise ExecuteError(error_response, msg, reply)
E   qemu.qmp.qmp_client.ExecuteError: The command screendump has not been found
@pytest.mark.qemu
@pytest.mark.parametrize('qemu_extra_args', ['-display sdl'])
@pytest.mark.parametrize('embedded_services', ['idf,qemu'])
def test_qemu_rgb_panel(dut: Dut) -> None:
if not Image:
pytest.fail('Pillow is not installed')

dut.expect_exact('Install RGB LCD panel driver')
dut.expect_exact('LVGL Scatter Chart displayed')
time.sleep(2)
filename = 'scatter_chart.ppm'
dut.qemu.take_screenshot(filename)

img = Image.open(filename)
ref_img = Image.open(os.path.join(os.path.dirname(__file__), 'doc', 'scatter_chart.png'))

diff = ImageChops.difference(img, ref_img)
assert not diff.getbbox(), 'Images are different'
1 change: 1 addition & 0 deletions esp_lcd_qemu_rgb/examples/lcd_qemu_rgb_panel/sdkconfig.ci
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CONFIG_EXAMPLE_QEMU_RGB_PANEL_STATIC=y
1 change: 1 addition & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ markers =
generic: generic runner
ethernet: ethernet runners
spi_nand_flash: runner with SPI NAND flash connected
qemu: test runs in QEMU emulator

# log related
log_cli = True
Expand Down
Loading