From 5549a69b1c9b46e9928546eb91b3ccf6a7fa0432 Mon Sep 17 00:00:00 2001 From: evgeny Date: Thu, 22 Oct 2026 13:31:13 +0200 Subject: [PATCH] Cover failed file stream creation and document media cancellation effects --- doc/service_lifecycle.md | 8 ++++++++ tests/test_media_primitives.c | 24 ++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/doc/service_lifecycle.md b/doc/service_lifecycle.md index 709537b5..44e0947d 100644 --- a/doc/service_lifecycle.md +++ b/doc/service_lifecycle.md @@ -117,6 +117,14 @@ Worker резервирует completion до запуска и передаёт транскодирование или распознавание речи может задержать stop; принудительного прерывания этих библиотек нет. +Владелец принимает не более 16 задач, включая уже завершённые workers до доставки +completion. Отказ запуска/неверные аргументы дают синхронный done с -1, остановка +владельца — с `MEDIA_ASYNC_CANCELLED`; при NULL done только логируется ошибка. +Примитивы `media_async.h` синхронные: отмена задачи не откатывает выполненные ими +действия. `ma_copy_file()` публикует копию внутри worker после проверенных записи и +закрытия temp; вызывающий отвечает за очистку своего результата при отмене. +Подробные файловые контракты, 64-битные размеры и ошибки RNG описаны в `media_async.h`. + Подготовка файлов в `src/video/video.h` выполняет remux подходящих H.264/AAC либо перекодирование в MP4 H.264/YUV420P и AAC. Worker пишет уникальный соседний временный файл, завершает декодеры/ресемплер/FIFO/кодеры, проверяет trailer, закрытие и метаданные. diff --git a/tests/test_media_primitives.c b/tests/test_media_primitives.c index b8181d12..2f2524e9 100644 --- a/tests/test_media_primitives.c +++ b/tests/test_media_primitives.c @@ -19,7 +19,7 @@ static char root[256], source[512], destination[512]; static unsigned visits; #ifdef __linux__ -enum fault { NONE, READ, WRITE, FLUSH, SOURCE_CLOSE, OUTPUT_CLOSE, PUBLISH, OPEN_DIR, READ_DIR, CLOSE_DIR, SEEK, THREAD }; +enum fault { NONE, READ, WRITE, FLUSH, SOURCE_CLOSE, OUTPUT_CLOSE, FDOPEN, PUBLISH, OPEN_DIR, READ_DIR, CLOSE_DIR, SEEK, THREAD }; static enum fault fault; static int injected, read_failed, rng_after = -1, allocation_after = -1; static FILE *input_file, *output_file; @@ -48,6 +48,7 @@ FILE *__wrap_fopen(const char *path, const char *mode) { return file; } FILE *__wrap_fdopen(int fd, const char *mode) { + if (inject(FDOPEN)) return NULL; FILE *file = __real_fdopen(fd, mode); if (!strcmp(mode, "wb+")) output_file = file; return file; @@ -126,6 +127,7 @@ static void copy_tests(void) { assert(!ma_copy_file(source, alias)); check_text(source, "source-payload"); snprintf(alias, sizeof(alias), "%s/missing", root); assert(ma_copy_file(alias, alias) == -1); + snprintf(alias, sizeof(alias), "%s/missing/output", root); assert(ma_copy_file(source, alias) == -1); #ifndef _WIN32 snprintf(alias, sizeof(alias), "%s/alias", root); assert(!link(source, alias)); assert(!ma_copy_file(source, alias)); assert(!remove(alias)); @@ -149,6 +151,24 @@ static void copy_tests(void) { DEBUG_INFO(DEBUG_CATEGORY_MEDIA, "PASS copy aliases, links, missing source, successful and empty file"); } +/* Ошибки чтения/close и неверные аргументы не оставляют правдоподобный hash/signature. */ +static void crypto_tests(void) { + uint8_t output[64], zero[64] = {0}; + memset(output, 0xa5, sizeof(output)); + assert(ma_sha256_file(NULL, output) == -1 && !memcmp(output, zero, 32)); + memset(output, 0xa5, sizeof(output)); + assert(ma_sign_block(NULL, NULL, 0, output) == -1 && !memcmp(output, zero, sizeof(output))); +#ifdef __linux__ + const enum fault cases[] = {READ, SOURCE_CLOSE}; + for (unsigned n = 0; n < sizeof(cases) / sizeof(cases[0]); n++) { + fault = cases[n]; injected = 0; memset(output, 0xa5, sizeof(output)); + int error = ma_sha256_file(source, output); fault = NONE; + assert(error == -1 && injected && !memcmp(output, zero, 32)); + } +#endif + DEBUG_INFO(DEBUG_CATEGORY_MEDIA, "PASS digest/signature failures clear output"); +} + static void size_and_walk_tests(void) { char path[512]; snprintf(path, sizeof(path), "%s/large", root); const int64_t sizes[] = {INT_MAX, (int64_t)INT_MAX + 1, INT64_C(4294967296) + 17}; @@ -286,7 +306,7 @@ int main(void) { #endif assert(!utun_mkdir(root, 0700)); snprintf(source, sizeof(source), "%s/source", root); snprintf(destination, sizeof(destination), "%s/destination", root); - copy_tests(); size_and_walk_tests(); + copy_tests(); crypto_tests(); size_and_walk_tests(); struct UASYNC *ua = uasync_create(); assert(ua); registration_tests(ua); #ifdef __linux__