You are using staging server - a separate instance of the ESP Component Registry that allows you to try distribution tools and processes without affecting the real registry.

kostaond/eth_test_app

0.1.1

Latest
uploaded 7 hours ago
Common Ethernet test utilities and test cases for ESP-IDF Ethernet drivers

readme

# Ethernet Test App

This component provides common test utilities and pre-written test cases for ESP-IDF Ethernet drivers. It can be used to test Ethernet MAC behavior with different chips.

## ESP-IDF Usage

Add this component from [IDF Component Manager](https://components.espressif.com/) to your project using `idf.py add-dependency` and include `esp_eth_test_utils.h`:

```c
#include "esp_eth_test_utils.h"
```

## Pytest host tests (driver-specific test apps)

!!! TODO !!!

The component provides a common pytest runner so each driver (e.g. DM9051, W5500) can run the same Unity test suite from its own test app.

- **Script:** `eth_test_runner.py` — defines `EthTestRunner` and `EthTestIntf`. The legacy `pytest_esp_eth.py` still exists and delegates to the runner for backward compatibility.
- **Usage:** In your driver test app (e.g. `dm9051/test_apps/`):
  1. Add the component directory to `sys.path` in `conftest.py` (from registry it lives in `managed_components/espressif__eth_test_app`; with `override_path` it is at your repo path, e.g. `../../eth_test_app`). See `conftest_example.py` in this component.
  2. In your test file, use the `eth_test_runner` fixture (or import `EthTestRunner` and instantiate it), then call `run_ethernet_test(dut)`, `run_ethernet_l2_test(dut)`, `run_ethernet_heap_alloc_test(dut)`.

Example test (see `dm9051/test_apps/pytest_dm9051.py` and `conftest_example.py`):

```python
# conftest.py adds component to path and defines eth_test_runner fixture

def test_eth_dm9051(dut, eth_test_runner):
    eth_test_runner.run_ethernet_test(dut)
    dut.serial.hard_reset()
    eth_test_runner.run_ethernet_l2_test(dut)
    dut.serial.hard_reset()
    eth_test_runner.run_ethernet_heap_alloc_test(dut)
```

**Where the component is loaded from:** When the project uses the component from the registry, it is under `managed_components/espressif__eth_test_app/`. When using `override_path` (e.g. in a monorepo), the component is used from that path. The conftest path logic checks both so the same test app works in either setup.

## Prerequisites

Install third-party Python packages required by the pytest test script:

```bash
pip install scapy
```

## Chip-Specific Configuration

Different Ethernet chips may have deviations from the standard behavior or may not support certain features. To accommodate these chip-specific differences, the test framework provides Kconfig options that allow disabling or modifying specific tests that are incompatible with certain chips.

For example, some chips may not support 10 Mbps loopback mode, or may have known errata that require workarounds. These Kconfig options are defined in `Kconfig.projbuild` and can be configured through the ESP-IDF menuconfig system to adjust test behavior for the specific chip under test.

Refer to `Kconfig.projbuild` for the complete list of available configuration options and their descriptions.

## Test Framework Overview

The test framework provides common initialization and helper functions through `esp_eth_test_utils.h` and `esp_eth_test_utils.c`. These modules handle Ethernet initialization, event registration, and resource management automatically using Unity's `setUp()` and `tearDown()` functions.

### Unity setUp() and tearDown()

The `setUp()` function automatically performs the following initialization before each test case:

1. **Sets up event handling** (creates event group and default event loop)
2. **Initializes the Ethernet driver** by calling `esp_eth_test_eth_init()` (uses Ethernet init component by default, can be customized - see [Customizing Ethernet Initialization](#customizing-ethernet-initialization) section below)
3. **Optionally sets up esp-netif** if the `[esp-netif]` marker is used (see [Markers](#test-markers) section below)
4. **Registers event handlers**:
   - `eth_test_default_event_handler()` for ETH_EVENT events (ETHERNET_EVENT_START, ETHERNET_EVENT_STOP, ETHERNET_EVENT_CONNECTED, ETHERNET_EVENT_DISCONNECTED)
   - `eth_test_got_ip_event_handler()` for IP_EVENT_ETH_GOT_IP events (only when `[esp-netif]` marker is used)

The `tearDown()` function automatically performs cleanup after each test case:

1. **Frees all allocated memory** tracked by the test framework
2. **Unregisters event handlers**
3. **Stops and deinitializes the Ethernet driver** by calling `esp_eth_test_eth_deinit()` (uses Ethernet init component by default, can be customized - see [Customizing Ethernet Initialization](#customizing-ethernet-initialization) section below)
4. **Destroys the event loop and event group**

### Customizing Ethernet Initialization

By default, the test framework initializes Ethernet using the **Ethernet init component**. This provides initialization of Ethernet hardware based on Kconfig settings.

For test cases that require custom Ethernet initialization (e.g., chip not supported by Ethernet init component, specific MAC/PHY configurations, multiple Ethernet ports, or custom hardware setup), you can override the weak functions:

- **`esp_eth_test_eth_init(esp_eth_handle_t *eth_handle)`**: Override this function to provide custom Ethernet initialization. The function should initialize the Ethernet driver and return the handle via the `eth_handle` parameter.

    > [!IMPORTANT]
    > Initialization function must print DUT PHY identification string as it is expected by `pytest` script. The PHY identification message must be in the following format:
    > ```c
    > printf("DUT PHY: %s", my_phy_str);
    >```

- **`esp_eth_test_eth_deinit(esp_eth_handle_t eth_handle)`**: Override this function to provide custom Ethernet deinitialization. The function should clean up the Ethernet driver resources.

### Test Markers

Test cases can use markers in their Unity test identifiers to control initialization behavior:

#### `[esp-netif]` Marker

When this marker is included in the test case identifier, `setUp()` will additionally initialize TCP/IP stack by:

- Creating an ESP-NETIF interface using `ESP_NETIF_DEFAULT_ETH()` configuration
- Attaching the Ethernet driver to the netif using `esp_eth_new_netif_glue()`
- Registering the `eth_test_got_ip_event_handler()` for IP_EVENT_ETH_GOT_IP events

**Example:**
```c
TEST_CASE("ethernet dhcp test", "[ethernet][esp-netif]")
{
    esp_eth_handle_t eth_handle = eth_test_get_eth_handle();
    EventGroupHandle_t eth_event_group = eth_test_get_default_event_group();
    esp_netif_t *netif = eth_test_get_netif();  // Valid when [esp-netif] is used
    
    // Test code using TCP/IP stack...
}
```

#### `[skip_setup_teardown]` Marker

When this marker is included, `setUp()` and `tearDown()` will skip all automatic initialization and cleanup. This allows the test to perform its own custom initialization and cleanup procedures.

> [!IMPORTANT]
> When using this marker, you must manually:
> - Register event handlers using `eth_test_default_event_handler()` and/or `eth_test_got_ip_event_handler()`
> - Initialize and deinitialize all resources except for memory allocated by `eth_test_alloc()`

> [!NOTE]
> Memory allocated through `eth_test_alloc()` is automatically freed by `tearDown()` even when using this marker.

**Example:**
```c
TEST_CASE("internal emac interrupt priority", "[esp_emac][skip_setup_teardown]")
{
    // Manual initialization
    EventGroupHandle_t eth_event_group = xEventGroupCreate();
    TEST_ESP_OK(esp_event_loop_create_default());
    // Register handlers manually if needed
    // ... custom test code ...
}
```

### Helper Functions

#### Getting Initialized Handles

- **`eth_test_get_eth_handle()`**: Returns the Ethernet handle initialized by `setUp()`. Returns `NULL` if initialization failed or if `[skip_setup_teardown]` marker is used.
- **`eth_test_get_default_event_group()`**: Returns the event group handle created by `setUp()`. Use this to wait for Ethernet events using `xEventGroupWaitBits()` with the predefined bits (ETH_START_BIT, ETH_STOP_BIT, ETH_CONNECT_BIT, ETH_GOT_IP_BIT).
- **`eth_test_get_netif()`**: Returns the ESP-NETIF handle initialized by `setUp()`. **Only valid when `[esp-netif]` marker is used**, otherwise returns `NULL`.

#### PHY Register Manipulation

- **`eth_test_set_phy_reg_bits()`**: Sets specific bits in a PHY register with retry logic. Useful for configuring PHY behavior during tests.
- **`eth_test_clear_phy_reg_bits()`**: Clears specific bits in a PHY register with retry logic.

Both functions include automatic retry logic with configurable maximum attempts and delays between attempts.

#### Memory Management

- **`eth_test_alloc(size)`**: Allocates memory from the heap. The framework automatically tracks all allocations and frees them in `tearDown()`. Maximum of `MAX_HEAP_ALLOCATION_POINTERS` (20) allocations are supported.
- **`eth_test_free(ptr)`**: Frees a specific allocation. Generally not needed as `tearDown()` automatically frees all tracked allocations.
- **`eth_test_free_all()`**: Frees all tracked allocations. Called automatically by `tearDown()`.

#### Event Handlers

- **`eth_test_default_event_handler()`**: Default handler for ETH_EVENT events. Automatically registered by `setUp()` unless `[skip_setup_teardown]` is used. Sets event bits in the event group for:
  - ETHERNET_EVENT_START → ETH_START_BIT
  - ETHERNET_EVENT_STOP → ETH_STOP_BIT
  - ETHERNET_EVENT_CONNECTED → ETH_CONNECT_BIT

- **`eth_test_got_ip_event_handler()`**: Handler for IP_EVENT_ETH_GOT_IP events. Automatically registered by `setUp()` when `[esp-netif]` marker is used. Sets ETH_GOT_IP_BIT in the event group and logs IP configuration.

### Usage Example

```c
TEST_CASE("ethernet basic test", "[ethernet][esp-netif]")
{
    // Get handles initialized by setUp()
    esp_eth_handle_t eth_handle = eth_test_get_eth_handle();
    EventGroupHandle_t eth_event_group = eth_test_get_default_event_group();
    esp_netif_t *netif = eth_test_get_netif();
    
    EventBits_t bits = 0;
    
    // Start Ethernet driver
    TEST_ESP_OK(esp_eth_start(eth_handle));
    
    // Wait for Ethernet to start
    bits = xEventGroupWaitBits(eth_event_group, ETH_START_BIT, true, true, 
                               pdMS_TO_TICKS(ETH_START_TIMEOUT_MS));
    TEST_ASSERT((bits & ETH_START_BIT) == ETH_START_BIT);
    
    // Wait for link connection
    bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, 
                               pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS));
    TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
    
    // Wait for IP address (only when [esp-netif] is used)
    bits = xEventGroupWaitBits(eth_event_group, ETH_GOT_IP_BIT, true, true, 
                               pdMS_TO_TICKS(ETH_GET_IP_TIMEOUT_MS));
    TEST_ASSERT((bits & ETH_GOT_IP_BIT) == ETH_GOT_IP_BIT);
    
    // Test code here...
    
    // Stop Ethernet driver
    TEST_ESP_OK(esp_eth_stop(eth_handle));
    
    // Wait for stop event
    bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, 
                               pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS));
    TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
    
    // tearDown() will automatically clean up everything
}
```

## Basic Test Suite

The Ethernet Test App is shipped with basic set of tests to test common Ethernet modes configuration and basic Ethernet functionality with IP stack (like DHCP IP address assignment,...)

## TODO

* describe that the easiest way is to start with example (is there any command to create project based on example => if so use that)
* maybe move this information at the start of the README as this will be the most common use case. The rest is too specific and boring

Links

Supports all targets

License: Apache-2.0

To add this component to your project, run:

idf.py add-dependency "kostaond/eth_test_app^0.1.1"

download archive

Stats

  • Archive size
    Archive size ~ 27.38 KB
  • Downloaded in total
    Downloaded in total 0 times
  • Downloaded this version
    This version: 0 times

Badge

kostaond/eth_test_app version: 0.1.1
|