96fd32796e
Lands the fake HTTP server, the patch fixture pipeline, and the first two scenarios that exercise the real FFI path end-to-end. Plus a test that would have caught the patch-to-release rollback bug (shorebirdtech/shorebird#3728). Architecture follows the principles surfaced in review: - Dart tests call the public `ShorebirdUpdater` API only — never the raw `Updater` FFI wrapper, never the engine API. - Engine API stays inside the `library_test_hooks` Rust crate. `shorebird_test_init` constructs `AppParameters` + stub `FileCallbacks` internally so Dart never sees those types. `shorebird_test_simulate_successful_launch` wraps the start/success protocol so the Dart layer never knows there's a protocol — it just knows "the engine reported a successful boot." - ffigen scans only the test_hooks header. The engine header (updater_engine.h) does not appear in the Dart bindings. - A `TestEngine` Dart helper concentrates engine-side simulation in one place; the test bodies stay focused on `ShorebirdUpdater`. Implementation choices worth flagging: - FFI calls run via `Isolate.run`. Synchronous run blocks the main isolate, deadlocking against the in-isolate shelf server. The test's IsolateRun callback re-opens the cdylib (cheap: dlopen is ref-counted) and resets `Updater.bindings` in the sub-isolate because Dart isolates do not share static fields. - `libapp_path` must be a real file on the desktop integration build: the non-Android non-iOS non-test `patch_base` reads it directly from disk. Tests that install a patch write the fixture's `base` bytes to `libapp.so` before init. - Fake server kept minimal: shelf, no Range support, no auth, no concurrency knobs. Stage 3+ scenarios (download cutoff, hash mismatch loop, etc.) extend it as needed. Three scenarios cover three reasons we wanted this suite: 1. `checkForUpdate returns upToDate when server has no patch` — baseline: confirms the harness boots cleanly and returns the expected enum. 2. `install a patch and boot from it` — golden path: check → update → simulateSuccessfulLaunch, then assert `readCurrentPatch` / `readNextPatch` / `checkForUpdate` transitions match the public API contract. 3. `checkForUpdate returns restartRequired after patch-to-release rollback` — regression for shorebirdtech/shorebird#3728. Pre-fix this returned `upToDate` and left no signal to prompt a restart. Verified locally: 232 Rust unit tests + 44 Dart tests (41 existing unit + 3 new integration) green; clippy/fmt/cspell clean.
56 lines
1.7 KiB
C
56 lines
1.7 KiB
C
#ifndef library_test_hooks_h
|
|
#define library_test_hooks_h
|
|
|
|
/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */
|
|
|
|
#include <stdarg.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#ifdef _WIN32
|
|
#define SHOREBIRD_EXPORT __declspec(dllexport)
|
|
#else
|
|
#define SHOREBIRD_EXPORT __attribute__((visibility("default")))
|
|
#endif
|
|
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif // __cplusplus
|
|
|
|
/**
|
|
* Resets the updater's global config so the next `shorebird_init`
|
|
* starts from scratch. Equivalent to a process restart for state
|
|
* purposes — Dart tests call this between scenarios so each test
|
|
* runs against a fresh updater.
|
|
*/
|
|
SHOREBIRD_EXPORT void shorebird_test_reset(void);
|
|
|
|
/**
|
|
* Test-only convenience wrapper around `shorebird_init` that builds
|
|
* `AppParameters` and stub `FileCallbacks` internally. Dart tests
|
|
* pass plain C strings instead of needing bindings for those
|
|
* engine-API structs.
|
|
*/
|
|
SHOREBIRD_EXPORT
|
|
bool shorebird_test_init(const char *app_storage_dir,
|
|
const char *code_cache_dir,
|
|
const char *release_version,
|
|
const char *libapp_path,
|
|
const char *yaml);
|
|
|
|
/**
|
|
* Simulates the engine's successful boot of `next_boot_patch`.
|
|
* In production this is two engine actions (launch-start, then
|
|
* launch-success after Dart VM startup completes); the Dart layer
|
|
* has no concept of either, so we expose the combined outcome as a
|
|
* single semantic action: "the next patch booted cleanly."
|
|
*/
|
|
SHOREBIRD_EXPORT void shorebird_test_simulate_successful_launch(void);
|
|
|
|
#ifdef __cplusplus
|
|
} // extern "C"
|
|
#endif // __cplusplus
|
|
|
|
#endif /* library_test_hooks_h */
|