100 lines
4.6 KiB
C
100 lines
4.6 KiB
C
/* SPDX-License-Identifier: AGPL-3.0-or-later */
|
|
/* Copyright (C) 2026 David (Corey) Herrera */
|
|
/**
|
|
* @file test_program_blob_empty.c
|
|
* @brief Gate the state the tree is ACTUALLY in: an empty `ft_tt_programs.h`.
|
|
*
|
|
* The committed blob is an explicitly-empty placeholder, because the real program
|
|
* directories and SFPI live on the card host and this work was done on the Mac. That is a
|
|
* state, not an accident, and it needs its own gate — otherwise the first thing anyone
|
|
* learns about it is a serve that cannot find its programs.
|
|
*
|
|
* What this asserts is that the empty state is LOUD and USABLE:
|
|
* * every lookup refuses, with a code that says "not in this binary" rather than
|
|
* succeeding over zero images;
|
|
* * `ft_tt_program_blob_count() == 0` distinguishes "never generated" from "you asked
|
|
* for a program nobody built";
|
|
* * the filesystem override still serves, so an empty blob is a missing optimisation
|
|
* and not a broken machine.
|
|
*
|
|
* It is compiled against a DELIBERATELY EMPTY header (generated by Makefile.programblob),
|
|
* and checks that it was, so it cannot silently become a second run of the fixture suite.
|
|
*
|
|
* It used to compile against the SHIPPING ft_tt_programs.h and relied on that file still
|
|
* being the empty placeholder. On 2026-08-17 a real blob was generated and all six checks
|
|
* failed -- they were asserting a property of the artifact, not of the code. An empty-state
|
|
* gate that can only pass before the work is done is backwards, so the emptiness is now
|
|
* supplied by the harness instead of borrowed from the tree.
|
|
*
|
|
* Run: ./build-programblob/test_program_blob_empty <fixture-root>
|
|
*
|
|
* @status Green on the Mac. Will need updating — to "the blob is not empty" — the day a
|
|
* real regeneration lands on the card host; that is the point.
|
|
* @issues None
|
|
* @todo None
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "ft_tt_device.h"
|
|
#include "ft_tt_memmap.h"
|
|
#include "ft_tt_program_blob.h"
|
|
#include "ft_tt_program_resolve.h"
|
|
#include "ft_tt_test_report.h"
|
|
|
|
#define ALL_PROCESSORS 0x1fu
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
ft_tt_runtime_images images;
|
|
const ft_tt_program_blob_entry *entry = NULL;
|
|
char programs_root[512];
|
|
const char *header = ft_tt_program_blob_generated_header();
|
|
int rc;
|
|
|
|
if (argc != 2) {
|
|
fprintf(stderr, "usage: %s <fixture-root>\n", argv[0]);
|
|
return 2;
|
|
}
|
|
if (snprintf(programs_root, sizeof(programs_root), "%s/programs", argv[1]) < 0)
|
|
return 2;
|
|
|
|
ft_tt_test_step("this binary carries a DELIBERATELY EMPTY blob");
|
|
ft_tt_test_check_fmt("compiled against the empty fixture, not the shipping header",
|
|
strcmp(header, "ft_tt_programs_empty.h") == 0, "header is %s", header);
|
|
ft_tt_test_check_fmt("it is empty, and says so", ft_tt_program_blob_count() == 0u,
|
|
"count is %u", ft_tt_program_blob_count());
|
|
ft_tt_test_check("entry_at(0) is NULL", ft_tt_program_blob_entry_at(0) == NULL, "NULL");
|
|
|
|
ft_tt_test_step("an empty blob refuses every name, loudly");
|
|
rc = ft_tt_program_blob_find("rtriad_bfp8", &entry);
|
|
ft_tt_test_check_fmt("find(\"rtriad_bfp8\") refuses", rc == FT_TT_ENOTFOUND, "rc %d (%s)",
|
|
rc, ft_tt_error_string(rc));
|
|
ft_tt_test_check("and hands back no entry", entry == NULL, "NULL");
|
|
|
|
memset(&images, 0, sizeof(images));
|
|
rc = ft_tt_program_open_kernels("rtriad_bfp8", NULL, ALL_PROCESSORS, &images);
|
|
ft_tt_test_check_fmt("open_kernels with no override refuses", rc == FT_TT_ENOTFOUND,
|
|
"rc %d (%s)", rc, ft_tt_error_string(rc));
|
|
ft_tt_test_check("nothing was loaded",
|
|
images.program.image_count == 0u && images.elf_data[0] == NULL, "empty");
|
|
|
|
ft_tt_test_step("the override still serves, so an empty blob is not a dead binary");
|
|
memset(&images, 0, sizeof(images));
|
|
rc = ft_tt_program_open_kernels("prog_alpha", programs_root, ALL_PROCESSORS, &images);
|
|
ft_tt_test_check_fmt("open_kernels with an override root succeeds", rc == FT_TT_OK,
|
|
"rc %d, %u image(s)", rc, images.program.image_count);
|
|
ft_tt_test_check("and it reports the directory arm",
|
|
images.source == FT_TT_PROGRAM_SOURCE_DIRECTORY, "directory");
|
|
ft_tt_runtime_images_release(&images);
|
|
|
|
memset(&images, 0, sizeof(images));
|
|
rc = ft_tt_program_open_firmware("prog_alpha", programs_root, &images);
|
|
ft_tt_test_check_fmt("open_firmware with an override root succeeds", rc == FT_TT_OK,
|
|
"rc %d", rc);
|
|
ft_tt_runtime_images_release(&images);
|
|
|
|
return ft_tt_test_finish();
|
|
}
|