Each unwrap() is a potential crash. Shorebird's updater code
should never crash.
There still are a couple, but I think we should set up coverage
first so we can track that we're testing all these changes.
Adds support for iOS to the updater library.
Refactored the android-specific code into an android module.
The tests still mostly use the android code, rather than testing iOS paths too, but that can be fixed in a follow-up.
I had to change how "latest patch number" works to understand when patch files disappear from disk (which I thought was happening on iOS initially).
I also had to make status.json not store absolute paths to patch files (since the absolute path changes per-xcode run on iOS).
* Make our rust tests use per-thread config rather than global static
This lets our unit tests run in parallel. I also moved our "integration"
tests back to be unit tests for now.
This also exposes a network mocking abstraction.
I've added an incomplete test of applying a full patch. Still
needs some work to complete.
* Finish making the patch success test work
* Changed our test config to use println instead of info/error, etc. so that tests show output on failure (there might be a better way?)
Unfortunately macro_use (which is the way we were causing error!, info! etc to appear everywhere with only one global import before, only works on crates not on std, so I had to be explicit with my imports per-file.
* Add a function to build a fake zip file, because that's what the updater currently expects. Better would be for us to move to a AssetManager system I suspect, then the updater would ask the asset manager for the libapp.so and we'd return it instead of having to go through writing out a zip file.
* Added a string_patch.rs tool and shared code between that and the patch tool. This made it possible/easy for me to generate the necessary binary patches as well as needed hashes to pretend to be the patch server.
* Added one simple test of the patch tool core logic.
In total we're now above 80% coverage of our rust code after this.
* remove stray comment
This removes another source of possible crashes from the rust code.
I also took this opportunity to try and test the C-api. I also
discovered rust "integration tests" as part of this and chose
to move some of the (new) c_api tests to an integration test
as well as the existing rust api (updater.rs) tests.
* feat: Add start_updater_thread to update off the main thread
This makes it so that clients can easily not block when wanting to
queue an update.
I have a separate patch which updates the Engine to use this new
API.
I also needed to split the concept of the "next_boot" patch
from the "current_boot" patch, previously refered to as
"current" or "active" patch. This required adding a
report_launch_start api to let the updater library know
when to set current_boot patch from next_boot.
I also removed the rust updater/cli in this as well as the
vmpath argument to init.
I also exposed the report_launch_success api, but its not yet
used by the Engine.
I renamed report_failed_launch to report_launch_failure to match
report_launch_start which I introduced.
* Update naming per comments from Felix.
Also added a helper for char* allocation (not sure if it's better).
* Update library/src/updater.rs
---------
Co-authored-by: Felix Angelov <felix@shorebird.dev>
* Teach update about split apks
Fixes https://github.com/shorebirdtech/shorebird/issues/292.
The previous code only worked with universal apks, not split apks (which is what the play store produces).
We now look for APKs in the same directory as base.apk (through the same path hacks as before) and look for one matching the arch/abi name first. If we don't find one we also check base.apk.
This works in my testing with bundletool locally.
I also removed support for hashes being optional and removed a few unwraps (which will crash on failure).
I also fixed our use of imports/use statements to be a bit more consistent, including using "std::fs" rather than "std::fs::File" in one place but not another.
* Fix failing unit tests
Fixesshorebirdtech/shorebird#235🤞
This moves us away from depending on libapp.so having been extracted from the APK and instead we always extract it ourselves.
Flutter uses a very old NDK (v16 iirc) but thankfully it pulls
down it's Android NDK into third_party/android_tools/ndk. Update
our instructions to explain how to use that ndk when building.
If we don't link against that ndk the arm64 version seems to work
fine, but the arm32 version seems to depend on an extra symbol
which the older ndk does not expose. Linking against the correct
ndk gets rust to do the right thing.
There was a separate change to fix a *second* missing symbol
caused by the ring crate (from rustls, from reqwests) depending
on getauxval, but that we changed by exposing a stub copy
from the flutter engine code for now.
Combined with the fix in the engine:
https://github.com/shorebirdtech/engine/commit/4288ae1125e38a772c6cc8a918ed020c276534a4
This makes it so the updater no longer crashes repeatedly with bad patches. Previously
1. the engine was not successfully reporting a patch bad before crashing (now it does just before crashing).
2. With that fixed, the patch was getting marked bad, but because we were sending the "current" patch to the server, the server would tell us to download a new one every time (which we would not check against our bad patches) and we'd repeatedly boot of a "new" known-bad patch. This is now fixed to both send the latest_installed_patch to the server (as patch_version) as well as refusing to install known bad patches.
3. Fixed the cache to destroy itself on version change (which I expect could hit us when an app upgrades its cache might not get cleared).
4. Also fixed tests being flakey because TempDir cleans up after itself when it goes out of scope (thus needs to be held at the test-lifetime scope rather than inside init_for_testing).