fix(ci): repair all 3 QEMU workflow job failures
1. Fuzz Tests: add esp_timer_create_args_t, esp_timer_create(), esp_timer_start_periodic(), esp_timer_delete() stubs to esp_stubs.h — csi_collector.c uses these for channel hop timer. 2. QEMU Build: add libgcrypt20-dev to apt dependencies — Espressif QEMU's esp32_flash_enc.c includes <gcrypt.h>. Bump cache key v4→v5 to force rebuild with new dep. 3. NVS Matrix: switch to subprocess-first invocation of nvs_partition_gen to avoid 'str' has no attribute 'size' error from esp_idf_nvs_partition_gen API change. Falls back to direct import with both int and hex size args. Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
parent
8afd76da20
commit
a333951349
|
|
@ -38,7 +38,7 @@ jobs:
|
|||
with:
|
||||
path: /opt/qemu-esp32
|
||||
# Include date component so cache refreshes monthly when branch updates
|
||||
key: qemu-esp32s3-${{ env.QEMU_BRANCH }}-v4
|
||||
key: qemu-esp32s3-${{ env.QEMU_BRANCH }}-v5
|
||||
restore-keys: |
|
||||
qemu-esp32s3-${{ env.QEMU_BRANCH }}-
|
||||
|
||||
|
|
@ -49,6 +49,7 @@ jobs:
|
|||
sudo apt-get install -y \
|
||||
git build-essential ninja-build pkg-config \
|
||||
libglib2.0-dev libpixman-1-dev libslirp-dev \
|
||||
libgcrypt20-dev \
|
||||
python3 python3-venv
|
||||
|
||||
- name: Clone and build Espressif QEMU
|
||||
|
|
|
|||
|
|
@ -33,12 +33,32 @@ typedef int esp_err_t;
|
|||
/* ---- esp_timer.h ---- */
|
||||
typedef void *esp_timer_handle_t;
|
||||
|
||||
/** Timer callback type (matches ESP-IDF signature). */
|
||||
typedef void (*esp_timer_cb_t)(void *arg);
|
||||
|
||||
/** Timer creation arguments (matches ESP-IDF esp_timer_create_args_t). */
|
||||
typedef struct {
|
||||
esp_timer_cb_t callback;
|
||||
void *arg;
|
||||
const char *name;
|
||||
} esp_timer_create_args_t;
|
||||
|
||||
/**
|
||||
* Stub: returns a monotonically increasing microsecond counter.
|
||||
* Declared here, defined in esp_stubs.c.
|
||||
*/
|
||||
int64_t esp_timer_get_time(void);
|
||||
|
||||
/** Stub: timer lifecycle (no-ops for fuzz testing). */
|
||||
static inline esp_err_t esp_timer_create(const esp_timer_create_args_t *args, esp_timer_handle_t *h) {
|
||||
(void)args; if (h) *h = (void *)1; return ESP_OK;
|
||||
}
|
||||
static inline esp_err_t esp_timer_start_periodic(esp_timer_handle_t h, uint64_t period) {
|
||||
(void)h; (void)period; return ESP_OK;
|
||||
}
|
||||
static inline esp_err_t esp_timer_stop(esp_timer_handle_t h) { (void)h; return ESP_OK; }
|
||||
static inline esp_err_t esp_timer_delete(esp_timer_handle_t h) { (void)h; return ESP_OK; }
|
||||
|
||||
/* ---- esp_wifi_types.h ---- */
|
||||
|
||||
/** Minimal rx_ctrl fields needed by csi_serialize_frame. */
|
||||
|
|
|
|||
|
|
@ -266,10 +266,10 @@ def generate_nvs_binary(csv_content: str, size: int) -> bytes:
|
|||
"""Generate an NVS partition binary from CSV content.
|
||||
|
||||
Tries multiple methods to find nvs_partition_gen:
|
||||
1. esp_idf_nvs_partition_gen pip package
|
||||
2. Legacy nvs_partition_gen pip package
|
||||
3. ESP-IDF bundled script (via IDF_PATH)
|
||||
4. Module invocation
|
||||
1. Subprocess invocation (most reliable across package versions)
|
||||
2. esp_idf_nvs_partition_gen pip package (direct import)
|
||||
3. Legacy nvs_partition_gen pip package
|
||||
4. ESP-IDF bundled script (via IDF_PATH)
|
||||
"""
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
|
@ -281,25 +281,36 @@ def generate_nvs_binary(csv_content: str, size: int) -> bytes:
|
|||
bin_path = csv_path.replace(".csv", ".bin")
|
||||
|
||||
try:
|
||||
# Try pip-installed version first
|
||||
try:
|
||||
from esp_idf_nvs_partition_gen import nvs_partition_gen
|
||||
nvs_partition_gen.generate(csv_path, bin_path, size)
|
||||
with open(bin_path, "rb") as f:
|
||||
return f.read()
|
||||
except ImportError:
|
||||
pass
|
||||
# Method 1: subprocess invocation (most reliable — avoids API changes)
|
||||
for module_name in ["esp_idf_nvs_partition_gen", "nvs_partition_gen"]:
|
||||
try:
|
||||
subprocess.check_call(
|
||||
[sys.executable, "-m", module_name, "generate",
|
||||
csv_path, bin_path, hex(size)],
|
||||
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
|
||||
)
|
||||
with open(bin_path, "rb") as f:
|
||||
return f.read()
|
||||
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||
continue
|
||||
|
||||
# Try legacy import
|
||||
try:
|
||||
import nvs_partition_gen
|
||||
nvs_partition_gen.generate(csv_path, bin_path, size)
|
||||
with open(bin_path, "rb") as f:
|
||||
return f.read()
|
||||
except ImportError:
|
||||
pass
|
||||
# Method 2: direct import (handles older API where generate() takes int)
|
||||
for module_name in ["esp_idf_nvs_partition_gen.nvs_partition_gen",
|
||||
"nvs_partition_gen"]:
|
||||
try:
|
||||
mod = __import__(module_name, fromlist=["generate"])
|
||||
# Try int size first, then hex string (API varies by version)
|
||||
for size_arg in [size, hex(size)]:
|
||||
try:
|
||||
mod.generate(csv_path, bin_path, size_arg)
|
||||
with open(bin_path, "rb") as f:
|
||||
return f.read()
|
||||
except (TypeError, AttributeError):
|
||||
continue
|
||||
except ImportError:
|
||||
continue
|
||||
|
||||
# Try ESP-IDF bundled script
|
||||
# Method 3: ESP-IDF bundled script
|
||||
idf_path = os.environ.get("IDF_PATH", "")
|
||||
gen_script = os.path.join(
|
||||
idf_path, "components", "nvs_flash",
|
||||
|
|
@ -313,25 +324,16 @@ def generate_nvs_binary(csv_content: str, size: int) -> bytes:
|
|||
with open(bin_path, "rb") as f:
|
||||
return f.read()
|
||||
|
||||
# Last resort: try as a module
|
||||
try:
|
||||
subprocess.check_call([
|
||||
sys.executable, "-m", "nvs_partition_gen", "generate",
|
||||
csv_path, bin_path, hex(size)
|
||||
])
|
||||
with open(bin_path, "rb") as f:
|
||||
return f.read()
|
||||
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||
print("ERROR: NVS partition generator tool not found.", file=sys.stderr)
|
||||
print("Install: pip install esp-idf-nvs-partition-gen", file=sys.stderr)
|
||||
print("Or set IDF_PATH to your ESP-IDF installation", file=sys.stderr)
|
||||
raise RuntimeError(
|
||||
"NVS partition generator not available. "
|
||||
"Install: pip install esp-idf-nvs-partition-gen"
|
||||
)
|
||||
print("ERROR: NVS partition generator tool not found.", file=sys.stderr)
|
||||
print("Install: pip install esp-idf-nvs-partition-gen", file=sys.stderr)
|
||||
print("Or set IDF_PATH to your ESP-IDF installation", file=sys.stderr)
|
||||
raise RuntimeError(
|
||||
"NVS partition generator not available. "
|
||||
"Install: pip install esp-idf-nvs-partition-gen"
|
||||
)
|
||||
|
||||
finally:
|
||||
for p in set((csv_path, bin_path)): # deduplicate in case paths are identical
|
||||
for p in set((csv_path, bin_path)):
|
||||
if os.path.isfile(p):
|
||||
os.unlink(p)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue