Add native C ABI mobench backend#31
Closed
dcbuild3r wants to merge 69 commits into
Closed
Conversation
…fetch, Android logging, iOS UI tests, and docs (#2) * initial commit * Fix Android UniFFI integration and benchmark display This commit resolves multiple issues preventing the Android app from loading the Rust native library and correctly displaying benchmark results. Changes implemented: 1. Added JNA dependency (android/app/build.gradle) - Added net.java.dev.jna:jna:5.14.0@aar dependency - Required for UniFFI's Kotlin bindings to interface with native code - Also added NDK version specification and benchmark spec asset directories 2. Fixed library naming mismatch (crates/sample-fns/Cargo.toml) - Set explicit lib name = "sample_fns" (not uniffi_sample_fns) - Changed crate-type to ["lib", "cdylib", "staticlib"] for UniFFI - Added UniFFI dependencies and build configuration - Migrated from JNI to UniFFI for cleaner FFI bindings 3. Updated sync script for library renaming (scripts/sync-android-libs.sh) - Added TARGET_LIB_NAME variable to rename .so during copy - Rust builds libsample_fns.so but JNA expects libuniffi_sample_fns.so - Script now copies and renames: libsample_fns.so -> libuniffi_sample_fns.so - Ensures FFI symbol prefixes match UniFFI expectations 4. Updated Android MainActivity (android/app/src/main/java/dev/world/bench/MainActivity.kt) - Changed System.loadLibrary("sample_fns") to System.loadLibrary("uniffi_sample_fns") - Migrated from JNI to UniFFI-generated Kotlin bindings - Updated benchmark display to show microseconds (μs) instead of milliseconds - Added raw nanosecond display alongside formatted values - Improved error handling with UniFFI's BenchException variants - Added support for loading benchmark specs from assets (bench_spec.json) Root cause analysis: - UniFFI generates Kotlin bindings that expect library name "uniffi_<namespace>" - The namespace from sample_fns.udl is "sample_fns" - JNA looks for libuniffi_sample_fns.so based on this naming convention - Rust builds libsample_fns.so by default (from crate name) - Solution: Keep Rust lib name simple, rename during Android integration Benchmark display fix: - Functions execute in 0-42 nanoseconds (extremely fast) - Previous millisecond display showed "0.000 ms" for all samples - Now displays in microseconds with raw nanosecond values for clarity - Example: "0.042 μs (42 ns)" instead of "0.000 ms" Testing: - App builds successfully with ./gradlew :app:assembleDebug - Native library loads without UnsatisfiedLinkError - Benchmarks execute and display timing results correctly - Fibonacci(24) averages ~17 nanoseconds per iteration on ARM64 * Android: log benchmark JSON and fix test matcher * iOS: add UI test target and accessibility id * bench-cli: add BrowserStack fetch and artifact download * Commit remaining workspace changes * Ignore generated build artifacts * gitignore: exclude CLI-generated artifacts - Add run-summary.json (benchmark run results) - Add bench-config.toml (user configuration template) - Add device-matrix.yaml (device matrix template) These files are generated by bench-cli and should not be tracked in git. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * iOS: standardize time units to microseconds Change benchmark result display from milliseconds (ms) to microseconds (μs) to match Android's output format. This provides better granularity for typical function benchmarks and makes cross-platform comparison easier. Before: 0.045 ms After: 45.320 μs (45320 ns) Also add raw nanosecond values in parentheses to match Android formatting. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * bench-cli: add comprehensive BrowserStack client tests Add 11 new tests covering: - Client initialization and configuration - URL construction and path handling - Input validation for schedule/upload methods - Error cases for missing artifacts - Both Espresso (Android) and XCUITest (iOS) code paths Also suppress dead_code warning for test-only with_base_url helper. Test coverage increased from 1 to 12 tests for browserstack.rs module. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: dcbuilder.eth <dcbuilder@protonmail.com> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
….1.5) (#4) * Initial commit * Add .github/workflows/relyance-sci.yml * initial commit * Fix Android UniFFI integration and benchmark display This commit resolves multiple issues preventing the Android app from loading the Rust native library and correctly displaying benchmark results. Changes implemented: 1. Added JNA dependency (android/app/build.gradle) - Added net.java.dev.jna:jna:5.14.0@aar dependency - Required for UniFFI's Kotlin bindings to interface with native code - Also added NDK version specification and benchmark spec asset directories 2. Fixed library naming mismatch (crates/sample-fns/Cargo.toml) - Set explicit lib name = "sample_fns" (not uniffi_sample_fns) - Changed crate-type to ["lib", "cdylib", "staticlib"] for UniFFI - Added UniFFI dependencies and build configuration - Migrated from JNI to UniFFI for cleaner FFI bindings 3. Updated sync script for library renaming (scripts/sync-android-libs.sh) - Added TARGET_LIB_NAME variable to rename .so during copy - Rust builds libsample_fns.so but JNA expects libuniffi_sample_fns.so - Script now copies and renames: libsample_fns.so -> libuniffi_sample_fns.so - Ensures FFI symbol prefixes match UniFFI expectations 4. Updated Android MainActivity (android/app/src/main/java/dev/world/bench/MainActivity.kt) - Changed System.loadLibrary("sample_fns") to System.loadLibrary("uniffi_sample_fns") - Migrated from JNI to UniFFI-generated Kotlin bindings - Updated benchmark display to show microseconds (μs) instead of milliseconds - Added raw nanosecond display alongside formatted values - Improved error handling with UniFFI's BenchException variants - Added support for loading benchmark specs from assets (bench_spec.json) Root cause analysis: - UniFFI generates Kotlin bindings that expect library name "uniffi_<namespace>" - The namespace from sample_fns.udl is "sample_fns" - JNA looks for libuniffi_sample_fns.so based on this naming convention - Rust builds libsample_fns.so by default (from crate name) - Solution: Keep Rust lib name simple, rename during Android integration Benchmark display fix: - Functions execute in 0-42 nanoseconds (extremely fast) - Previous millisecond display showed "0.000 ms" for all samples - Now displays in microseconds with raw nanosecond values for clarity - Example: "0.042 μs (42 ns)" instead of "0.000 ms" Testing: - App builds successfully with ./gradlew :app:assembleDebug - Native library loads without UnsatisfiedLinkError - Benchmarks execute and display timing results correctly - Fibonacci(24) averages ~17 nanoseconds per iteration on ARM64 * Android: log benchmark JSON and fix test matcher * iOS: add UI test target and accessibility id * bench-cli: add BrowserStack fetch and artifact download * Commit remaining workspace changes * Ignore generated build artifacts * gitignore: exclude CLI-generated artifacts - Add run-summary.json (benchmark run results) - Add bench-config.toml (user configuration template) - Add device-matrix.yaml (device matrix template) These files are generated by bench-cli and should not be tracked in git. * iOS: standardize time units to microseconds Change benchmark result display from milliseconds (ms) to microseconds (μs) to match Android's output format. This provides better granularity for typical function benchmarks and makes cross-platform comparison easier. Before: 0.045 ms After: 45.320 μs (45320 ns) Also add raw nanosecond values in parentheses to match Android formatting. * bench-cli: add comprehensive BrowserStack client tests Add 11 new tests covering: - Client initialization and configuration - URL construction and path handling - Input validation for schedule/upload methods - Error cases for missing artifacts - Both Espresso (Android) and XCUITest (iOS) code paths Also suppress dead_code warning for test-only with_base_url helper. Test coverage increased from 1 to 12 tests for browserstack.rs module. * Migrate from UniFFI UDL to proc macros Replace manual UDL file with proc macro attributes for better developer experience and single source of truth in Rust code. ## Changes ### sample-fns crate: - Add `#[derive(uniffi::Record)]` to BenchSpec, BenchSample, BenchReport - Add `#[derive(uniffi::Error)]` with `#[uniffi(flat_error)]` to BenchError - Add `#[uniffi::export]` to run_benchmark function - Add `uniffi::setup_scaffolding!()` macro to generate scaffolding - Remove UDL file (sample_fns.udl) - Update Cargo.toml: enable uniffi "cli" feature - Update build.rs: remove UDL scaffolding generation (now proc macro-based) - Update generate-bindings.rs: use library_mode instead of UDL-based generation ### Generated bindings: - Kotlin bindings regenerated from proc macros - Swift bindings regenerated from proc macros - FFI interface remains identical (no breaking changes) ## Benefits 1. **Single source of truth**: Rust code is the only place to define types 2. **Better IDE support**: Type checking and autocomplete in Rust 3. **Automatic sync**: No manual UDL maintenance required 4. **Improved DevEx**: Attributes are inline with type definitions 5. **Type safety**: Compiler enforces FFI boundaries ## Migration notes - UniFFI 0.28 supports both UDL and proc macros - Generated bindings are functionally identical - All tests pass (22 tests) - CLI demo verified working - Android/iOS apps use same generated bindings * docs: update for proc macros and dual workflows Update documentation to reflect: 1. UniFFI proc macros (no UDL file needed) 2. Two distinct workflows: Local Development vs BrowserStack ## README.md Changes - Add "Testing Workflows" section with clear separation - Update UniFFI section for proc macro mode with examples - Add comprehensive BrowserStack workflow section: - Android + Espresso step-by-step - iOS + XCUITest step-by-step - Config file examples - BrowserStack features overview - Reorganize into Local Development vs BrowserStack sections - Remove outdated UDL references - Add requirements for both workflows ## CLAUDE.md Changes - Update Mobile Integration Flow to mention proc macros - Rewrite FFI Boundary section with proc macro examples - Update "Adding New Benchmark Functions" workflow - Remove references to sample_fns.udl - Add note that no UDL file is needed These changes make it much clearer for users: - How to test locally (fast iteration) - How to test on BrowserStack (real devices) - How to add new FFI types with proc macros * initial procmacros * feat: Phase 1 - Transform mobile-bench-rs into bench-sdk library crate This commit implements the complete Phase 1 MVP, transforming mobile-bench-rs from a standalone tool into a library crate (bench-sdk) that can be imported into any Rust project for mobile benchmarking. ## Core Features ### 1. Proc Macro System (bench-macros) - Implement #[benchmark] attribute macro for automatic function registration - Use inventory crate for compile-time collection, runtime discovery - Generate fully-qualified function names (e.g., my_crate::my_function) ### 2. Core SDK Library (bench-sdk) - **types.rs**: Core types (BenchError, Target, BuildConfig, BuildProfile, etc.) - **registry.rs**: Function discovery via inventory::collect!() - discover_benchmarks(), find_benchmark(), list_benchmark_names() - **runner.rs**: Execution engine with BenchmarkBuilder fluent API - **codegen.rs**: Template generation system - Generates bench-mobile FFI wrapper crate with UniFFI - Creates Android/iOS project structures - Generates config files and examples - **builders/android.rs**: Complete Android build pipeline - cargo-ndk integration for multi-ABI builds - JNI library syncing - Gradle APK generation - **builders/ios.rs**: Complete iOS build pipeline - Multi-architecture builds (device + simulator) - xcframework creation with proper structure - Automatic code signing - XcodeGen integration ### 3. CLI Integration (bench-cli) - Refactor to use SDK API as thin wrapper - Add new commands: - init-sdk: Initialize benchmark project with templates - build: Build mobile artifacts using SDK builders - list: Discover and list all registered benchmarks - Maintain backward compatibility with existing commands ### 4. Templates (templates/) - **Android**: Gradle project, MainActivity, Espresso tests, resources - Templatized with package name, library name, etc. - Complete build.gradle, settings.gradle, AndroidManifest.xml - **iOS**: XcodeGen project, SwiftUI app, XCUITest tests - Templatized with project name, bundle ID, etc. - Complete project.yml, Swift files, bridging headers ### 5. Example Project (examples/basic-benchmark) - Migrate sample-fns to example demonstrating SDK usage - Use #[benchmark] attributes with registry-based execution - Full test coverage (6 passing tests) ## Architecture Changes ### Workspace Structure ``` mobile-bench-rs/ ├── crates/ │ ├── bench-sdk/ # Core library (NEW, for crates.io) │ ├── bench-macros/ # Proc macro crate (NEW) │ ├── bench-cli/ # CLI tool (REFACTORED) │ ├── bench-runner/ # Timing harness (UNCHANGED) │ └── sample-fns/ # Legacy (DEPRECATED) ├── examples/ │ └── basic-benchmark/ # SDK example (NEW) └── templates/ # Mobile app templates (NEW) ├── android/ └── ios/ ``` ### Public API Surface ```rust // Proc macro #[benchmark] fn my_function() { /* ... */ } // Discovery bench_sdk::discover_benchmarks() -> Vec<&BenchFunction> bench_sdk::find_benchmark(name) -> Option<&BenchFunction> // Execution bench_sdk::run_benchmark(spec) -> Result<BenchReport> BenchmarkBuilder::new(name).iterations(100).run() // Builders AndroidBuilder::new(root, crate_name).build(&config) IosBuilder::new(root, crate_name).build(&config) // Codegen generate_project(&InitConfig) -> Result<PathBuf> ``` ## Testing All tests passing (25 total): - bench-sdk: 12 tests - basic-benchmark: 6 tests - sample-fns: 6 tests (legacy) - bench-runner: 1 test ## Documentation - Updated README.md with Phase 1 information - Inline rustdoc comments throughout - Working example in examples/basic-benchmark - Updated references in BUILD.md, TESTING.md ## Migration Path Users can now: 1. Add bench-sdk to Cargo.toml 2. Annotate functions with #[benchmark] 3. Run `cargo bench-sdk init-sdk` to generate project 4. Run `cargo bench-sdk build` to build mobile artifacts 5. Run `cargo bench-sdk list` to discover benchmarks ## Future Work Phase 1 provides the foundation for: - Phase 2: Adaptive iterations, warmup detection - Phase 3: Statistical analysis, baselines - Phase 4: Full BrowserStack integration - Phase 5: cargo bench harness, DevEx improvements - Phase 6: Caching, reproducibility, CI optimization * feat: wire sdk scaffolding and bindings - Render Android/iOS templates with project-specific names and link user crate in bench-mobile - Run UniFFI binding generation in SDK builders and ensure headers are packaged - Route CLI builds through SDK builders and detect bench-mobile crate name - Align Android JNI library naming (sample_fns) and update templates/scripts - Improve binding generation tooling for ABI-aware Android builds * docs: align build and binding workflow - Document ABI-aware Android builds with UNIFFI_ANDROID_ABI - Update binding regeneration steps to use scripts/generate-bindings.sh - Simplify Android local/testing steps to use build-android-app.sh * docs: add bench-sdk integration guide - Add step-by-step setup for dependencies and annotations - Document local Android/iOS testing workflow - Document BrowserStack Espresso/XCUITest runs * docs: expand integration guide - Add prerequisites and clarify script availability - Document CLI build path when scripts are absent - Link guide from README * docs: link prerequisite downloads - Add official download links for Rust, Android, JDK, Xcode, and xcodegen * docs: clarify JDK requirement - Use vendor-agnostic JDK 17+ wording and OpenJDK link - Note AGP official support for Java 17 * feat: Rename bench-cli to mobench and add iOS IPA packaging Major improvements to CLI tooling and iOS workflow: 1. Rename bench-cli → mobench - More memorable and concise name (7 chars) - Available on crates.io - Dual binaries: mobench + cargo-mobench - Updated all documentation and references 2. Add iOS IPA packaging with xcodebuild - New command: cargo mobench package-ipa - SigningMethod enum: AdHoc and Development - Ad-hoc signing (no Apple ID needed) for BrowserStack - Development signing for physical devices - Pure xcodebuild implementation (no fastlane dependency) - Automatic ExportOptions.plist generation 3. Eliminate script dependencies for SDK integrators - Added prominent warnings in README and integration docs - Deprecation notices in all shell scripts - CLI-first approach: cargo mobench build replaces ./scripts/ - Templates embedded in binary, no repo checkout needed 4. Add package metadata - Author: Dominik Clemente - dcbuilder.eth <dc@world.org> - Added to mobench, bench-sdk, and bench-macros - Repository links and keywords for crates.io All changes tested and verified: - 25 tests passing - cargo mobench --help shows all commands - package-ipa supports both adhoc and development methods - Documentation updated across all files * refactor: Rename bench-sdk → mobench-sdk and bench-macros → mobench-macros Complete branding consistency across all packages: 1. Crate renames: - bench-sdk → mobench-sdk - bench-macros → mobench-macros 2. Updated all references: - Package names in Cargo.toml files - Workspace member names - Dependency declarations - Import statements (bench_sdk → mobench_sdk) - Documentation and code examples - CLI help messages 3. All tests passing (25 tests) - mobench-sdk: 12 tests - sample-fns: 6 tests - basic-benchmark: 6 tests - mobench CLI verified Now all three publishable packages have consistent branding: - mobench (CLI) - mobench-sdk (core library) - mobench-macros (proc macros) * feat: Add metadata to bench-runner for crates.io publication * fix: Add version requirements to path dependencies in mobench-sdk * fix: Update repository URLs to worldcoin org and include templates in mobench-sdk package * fix: Include templates directory in mobench-sdk crate for crates.io packaging * chore: prepare mobench for crates.io publication - Update repository URL to worldcoin organization - Add version requirements to published dependencies (mobench-sdk, bench-runner) * chore: make sample-fns dependency optional for publishing - Add 'demo' feature flag for sample-fns dependency - Feature-gate Demo command to only work when demo feature is enabled - Users can install with: cargo install mobench --features demo This allows mobench to be published without requiring sample-fns (which is not published to crates.io). * chore: remove Demo command for crates.io publication - Demo command was only useful for development/testing - Requires unpublished sample-fns crate - Move sample-fns to dev-dependencies only - Published CLI focuses on core functionality * docs: add BrowserStack test run results and manual test script Completed test runs on BrowserStack: - ✅ Android Espresso test PASSED on Pixel 7 (50s duration) -⚠️ iOS XCUITest encountered packaging/parsing issues Build artifacts created: - Android APK (9.5 MB) + test APK - iOS IPA (284 KB) + test suite (5.6 MB) The Android integration is fully functional. iOS XCUITest requires additional work on test runner packaging to meet BrowserStack's parsing requirements. Added test_browserstack.sh for manual BrowserStack API testing, bypassing CLI's benchmark registry validation. * refactor: rename bench-runner to mobench-runner for consistency - Renamed crates/bench-runner to crates/mobench-runner - Updated package name from bench-runner to mobench-runner - Updated all imports from bench_runner to mobench_runner - Updated workspace and all dependent crates: - mobench-sdk - mobench CLI - sample-fns - examples/basic-benchmark This aligns the runner crate naming with the mobench ecosystem (mobench, mobench-sdk, mobench-macros, mobench-runner). Preparing for republication to crates.io. * chore: bump version to 0.1.1 for republication Updated workspace version to 0.1.1 after: - Publishing mobench-runner v0.1.0 (new package) - Republishing mobench-sdk v0.1.1 (updated dependency) - Republishing mobench v0.1.1 (updated dependency) All packages now use mobench-runner instead of bench-runner. * docs: add comprehensive READMEs to all packages for crates.io Added detailed README files to all packages: - mobench-runner: Explains timing harness, shows basic usage examples - mobench-macros: Documents #[benchmark] attribute, macro expansion - mobench-sdk: Comprehensive SDK guide with examples and architecture - mobench: Complete CLI documentation with all commands and workflows Each README includes: - Feature overview - Installation instructions - Usage examples - API documentation - Best practices - Integration with other packages - Requirements and troubleshooting Updated Cargo.toml files to include readme = "README.md" field for proper display on crates.io package pages. Bumped version to 0.1.2 for republication with documentation. * chore: add MIT license and update all package licenses - Added LICENSE.md with MIT license under World Foundation (2026) - Updated all READMEs to reference MIT license only - Changed workspace license from 'MIT OR Apache-2.0' to 'MIT' - Updated license sections in all 4 package READMEs: - mobench-runner - mobench-macros - mobench-sdk - mobench - Bumped version to 0.1.3 for republication Copyright (c) 2026 World Foundation * chore: reset version to 0.1.0 for fresh release Yanked all previous versions (0.1.0-0.1.3) from crates.io. Starting fresh with proper: - MIT license under World Foundation (2026) - Comprehensive READMEs for all packages - Consistent naming (mobench-runner instead of bench-runner) This is the canonical first release. * chore: use version 0.1.4 as canonical first release Cannot reuse version 0.1.0 even after yanking. Version 0.1.4 will be the canonical first release with: - MIT license under World Foundation (2026) - Comprehensive READMEs - Proper naming (mobench-runner) Versions 0.1.0-0.1.3 are yanked. * docs: update CLAUDE.md to reflect SDK-first architecture and crates.io publication - Update project overview with published packages (v0.1.4) - Document recommended cargo mobench build workflow - Mark scripts/ as legacy for repository development only - Add SDK integration examples and Quick Start - Reorganize file structure documentation - Add template system documentation * fix: address GitHub Advanced Security and Codex review findings 1. Add explicit workflow permissions (contents: read) - Addresses GitHub Advanced Security CodeQL warnings - Limits GITHUB_TOKEN permissions to read-only for CI workflow - Reduces security risk by following principle of least privilege 2. Fix local smoke test for user benchmarks - Only run local smoke test for sample_fns::* functions - Skip gracefully for user-defined benchmarks - Prevents 'unknown benchmark function' errors - User benchmarks aren't linked into CLI binary (will run on device) - Addresses Codex P1 review finding Note: Skipped iOS certificate pinning (Semgrep finding) as the app does not make network requests. Can be revisited if needed later. * mobench: support repository structure and fix iOS IPA packaging Updates CLI and SDK to work seamlessly with both SDK projects (bench-mobile/) and repository structure (crates/sample-fns/), enabling full end-to-end testing using only mobench commands. Changes: - AndroidBuilder/IosBuilder: Add find_crate_dir() to detect benchmark crate in multiple locations (bench-mobile/ or crates/{crate_name}/) - UniFFI binding generation: Make optional, use pre-existing bindings if available, only require uniffi-bindgen CLI for fresh generation - iOS IPA packaging: Complete rewrite from xcodebuild archive to simpler xcodebuild build approach, with ad-hoc signing support for BrowserStack testing (no Apple Developer account needed) - BrowserStack XCUITest: Add only-testing parameter support to specify test methods (required by BrowserStack API) - iOS project: Add schemes configuration to project.yml for proper xcodebuild support Verified working: - cargo mobench build --target android - cargo mobench build --target ios - cargo mobench package-ipa --method adhoc - cargo mobench run (both Android and iOS on BrowserStack) * mobench: add --fetch flag for CI-ready result retrieval Implements automatic polling and result fetching for BrowserStack runs, making the CLI fully CI-ready with one-command benchmark execution. BrowserStack Client API: - poll_build_completion(): Wait for build to finish with configurable timeout - get_espresso_build_status() / get_xcuitest_build_status(): Check build status - get_device_logs(): Fetch logs from specific device sessions - extract_benchmark_results(): Parse benchmark JSON from logs - wait_and_fetch_results(): Complete workflow (poll + fetch + extract) CLI Integration: - --fetch flag on 'run' command triggers automatic result fetching - Merges benchmark_results into output JSON (device -> results map) - Configurable timeout (--fetch-timeout-secs, default: 1800) - Configurable poll interval (--fetch-poll-interval-secs, default: 10) - Graceful error handling with warnings (command succeeds even if fetch fails) Output Format Enhancement: - RunSummary now includes optional benchmark_results field - Results organized by device name - Each device has array of benchmark results with samples, mean, min, max Testing: - 8 new comprehensive tests for result extraction and parsing - Tests for BuildStatus conversion and deserialization - Tests for JSON extraction from logs (single, multiple, invalid, missing) - All tests passing (21 total in browserstack module) Documentation: - FETCH_RESULTS_GUIDE.md: Complete guide for --fetch usage - BROWSERSTACK_CI_INTEGRATION.md: Programmatic API reference - GitHub Actions examples with step summaries - Error handling patterns and best practices Example Usage: cargo mobench run \ --target android \ --function sample_fns::fibonacci \ --iterations 30 \ --warmup 5 \ --devices "Google Pixel 7-13.0" \ --fetch \ --output results.json This release makes mobench fully CI-ready with automatic result retrieval, eliminating the need for manual log parsing or separate fetch commands. * gitignore: exclude BrowserStack run artifacts and temp files * mobench: print dashboard URL and result summary with --fetch Improves CLI output when using --fetch to show: - Dashboard URL immediately after scheduling (not just on error) - Summary of benchmark results for each device - Mean time in both nanoseconds and milliseconds - Number of samples collected - Dashboard URL again after successful fetch for easy access Example output: Waiting for build 88f8c5a... to complete... Dashboard: https://app-automate.browserstack.com/dashboard/v2/builds/88f8c5a... ✓ Successfully fetched results from 1 device(s) Device: Google Pixel 7-13.0 Benchmark 1: sample_fns::fibonacci Mean: 1237000 ns (1.24 ms) Samples: 30 View full results: https://app-automate.browserstack.com/... Makes CI output more informative and actionable without requiring manual JSON parsing or URL construction. * docs: document BrowserStack metrics and performance monitoring Adds comprehensive documentation on what device metrics BrowserStack provides and what mobench currently captures. Key points: - BrowserStack does NOT provide built-in CPU/memory/battery profiling - Performance metrics must be collected by your app code - We currently capture: logs, videos, network traces, screenshots - We extract: benchmark timing data from logs - Future enhancement: Extract custom performance metrics from logs Provides examples for collecting memory/CPU metrics on Android/iOS and logging them as JSON for extraction. References BrowserStack API documentation and platform-specific APIs for memory profiling. * feat(mobench): add performance metrics extraction (v0.1.5) - Add performance metrics types (PerformanceSnapshot, MemoryMetrics, CpuMetrics, etc.) - Implement extract_performance_metrics() to parse memory/CPU data from device logs - Add wait_and_fetch_all_results() to fetch both benchmark and performance results - Update RunSummary to include performance_metrics field - Add comprehensive tests for performance metrics extraction - Update CLI --fetch to display performance metrics alongside benchmark results - Update BROWSERSTACK_METRICS.md to reflect new functionality Performance metrics are automatically extracted when using --fetch flag if the app logs them in JSON format with memory/cpu fields or type='performance'. Example output format: { "memory": {"used_mb": 128.5, "max_mb": 512.0}, "cpu": {"usage_percent": 45.2} } * refactor: remove dead code and fix compiler warnings - Remove unused `wait_and_fetch_results()` from browserstack.rs (superseded by `wait_and_fetch_all_results()`) - Add `#[cfg(test)]` to `run_local_smoke()` in main.rs - Remove unused iOS signing methods (`identity()`, `export_method()`, `create_export_options_plist()`) - Remove unused imports (`std::io::Write`, `BenchSpec`, `run_closure`) - Add explanatory comment for dual binary targets in Cargo.toml This cleanup addresses all compiler warnings and removes 117 lines of dead code. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: build Android test APK and harden BrowserStack fetch --------- Co-authored-by: tfe-app[bot] <200245884+tfe-app[bot]@users.noreply.github.com> Co-authored-by: wld-terraform <infrastructure@toolsforhumanity.com> Co-authored-by: dcbuilder.eth <dcbuilder@protonmail.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Improve mobench fetch and iOS/Android builders * Chore: align docs with markdownlint * Refine rust-analyzer diagnostics * Bump workspace version to 0.1.5 * Docs: refresh mobench testing and CLI guidance Update docs to reflect current CLI usage, remove host demo references, and clarify local device workflows. Ignore Cursor project files and sync lockfile version entries. * feat: add run summaries and CI artifacts Add JSON/Markdown (optional CSV) summaries for mobench runs and wire CI to publish host + BrowserStack results. * fix test * feat: add compare reports and device tag filters Add a mobench compare command plus device tag filtering from matrix configs, and publish benchmark summaries to CI job summaries. Refresh docs to cover compare usage and updated config examples. * chore: clean up formatting in tests and bindgen * address minor pr codex comments * fix: treat BrowserStack passed builds as complete Update polling to accept passed/completed build statuses and ignore run summary outputs in git. This prevents fetch timeouts after successful runs. * Docs: align configs, devices, and rustdoc naming Refresh markdown docs and rustdocs to use current mobench config names, BrowserStack device strings, and API references. Update codegen templates and examples to match mobench-sdk naming. --------- Co-authored-by: dcbuilder.eth <dcbuilder@protonmail.com>
- split CLI entrypoint into library and cargo-mobench bin - update workspace manifests and lockfile for crate changes - rewrite README with current workflow and crate list
Drop the unused bench-cli and bench-runner crates, update docs to reflect the current mobench-runner workflow, and adjust legacy scripts/comments to reference cargo mobench.
Simplify basic-benchmark to only show #[benchmark] usage and add a new ffi-benchmark example that contains the UniFFI types and entrypoint. Update workspace metadata and docs to reflect the new example layout.
Drop the unused UniFFI UDL file for sample-fns and update build script notes to reflect the proc-macro binding generation flow.
Delete deprecated build scripts, switch CI and docs to cargo mobench commands, and refresh integration guidance for the new flow.
Update CLAUDE, BUILD, and mobench-sdk README to remove script references, clarify the builder flow, and document the new examples.
The repo_root() function now walks up the directory tree looking for marker files instead of relying on the compile-time manifest path. This fixes cases where the CLI is run from subdirectories. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update workspace version and inter-crate dependencies. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add output_dir field to AndroidBuilder and IosBuilder
- Default to {project_root}/target/mobench/ for all mobile artifacts
- Add output_dir() builder method for customization
- Add --output-dir CLI argument to `cargo mobench build`
- Update all path references in builders to use output_dir
This keeps generated mobile artifacts inside target/, following Rust
conventions and preventing accidental commits of Android/iOS project files.
- Update all path references from target/ios/ to target/mobench/ios/ - Update Android paths to target/mobench/android/ - Document --output-dir CLI flag - Update troubleshooting sections with correct paths
- Add extensive crate-level documentation to all four crates: - mobench-sdk: Full SDK docs with examples, architecture, and best practices - mobench-macros: #[benchmark] macro documentation with usage examples - mobench-runner: Timing harness docs with runnable examples - mobench: CLI documentation with command reference - Document all public types with examples: - BenchSpec, BenchSample, BenchReport, BenchError - Target, BuildConfig, BuildProfile, BuildResult - InitConfig and builder types - Configure docs.rs metadata in all Cargo.toml files: - Add documentation URLs - Add maintenance badges - Configure rustdoc-args for docs.rs builds - Add serde_json dev-dependency to mobench-runner for doc tests
This commit implements all 11 developer experience improvements from IMPROVEMENTS.md, making mobench significantly more user-friendly. ## Key Changes ### P0 - Critical (Tasks 1-3) - Fix aws-lc-rs Android NDK incompatibility (ring backend) - Fix workspace target directory detection (cargo metadata) - Auto-generate project scaffolding during build ### P1 - High Priority (Tasks 4-6) - Process template variables during build (TemplateContext) - Improve uniffi-bindgen handling (local binary + fallback) - Generate error handling code dynamically (generic catch) ### P2 - Medium Priority (Tasks 7-9) - Add mobench.toml configuration file support - Improve error messages with actionable suggestions - Add --crate-path flag for custom crate locations ### P3 - Nice to Have (Tasks 10-11) - Add --dry-run and --verbose CLI modes - Auto-generate local.properties for Android ## Code Quality Improvements - Extract shared utilities to builders/common.rs (DRY) - Consistent error message formatting with: - Clear description of what failed - Context (commands, paths, exit status) - Actionable fix suggestions - Links to documentation - Standardized path formatting using display() ## New Files - crates/mobench/src/config.rs - Configuration file support - crates/mobench-sdk/src/builders/common.rs - Shared utilities - IMPROVEMENTS.md - Task tracking document ## Consolidation - Merged mobench-runner crate into mobench-sdk - Timing functionality now in mobench-sdk/src/timing.rs
The test `ios_requires_artifacts_for_browserstack` was failing because
iOS project scaffolding was not being generated correctly during
auto-build for BrowserStack.
Root causes and fixes:
1. render_dir() was incorrectly joining prefix with file.path(), but
file.path() from include_dir already returns the full relative path.
Removed the prefix parameter entirely.
2. project.yml lacked .template extension, so template variables like
{{PROJECT_NAME_PASCAL}} were not being substituted. Renamed to
project.yml.template.
3. xcframework path in project.yml.template was wrong (../../target/ios/).
Fixed to ../{{LIBRARY_NAME}}.xcframework since the iOS project is at
target/mobench/ios/BenchRunner/.
4. ensure_ios_project now uses fixed "BenchRunner" for PROJECT_NAME_PASCAL
to match the template directory structure, while deriving LIBRARY_NAME
from the actual crate name.
All 37 tests now pass.
README updates:
- Document mobench-runner consolidation into mobench-sdk
- Add mobench.toml configuration file documentation
- Document new CLI flags: --dry-run, --verbose, --crate-path
- Update all artifact paths to target/mobench/
- Add examples for new features
Rust doc comments:
- Add comprehensive module docs to builders/{mod,android,ios,common}.rs
- Document build pipelines, requirements, and examples
- Add dry-run mode documentation
- Note mobench-runner consolidation in timing.rs
docs.rs configuration:
- Add targets = ["x86_64-unknown-linux-gnu"] for docs.rs builds
- Add #![cfg_attr(docsrs, feature(doc_cfg))] attributes
- Add crates.io/docs.rs/license badges to crate roots
- Add #[doc(cfg(...))] annotations for feature-gated items
- Update workspace version from 0.1.8 to 0.1.9 - Update mobench-sdk dependency in mobench crate - Update mobench-macros dependency in mobench-sdk crate - All mobench-runner versions have been yanked on crates.io
Critical bugs fixed (12):
- Bugs 1-5: Template variables (PROJECT_NAME, PACKAGE_NAME, LIBRARY_NAME,
PROJECT_NAME_PASCAL, APP_NAME) now properly substituted
- Bug 6: Added gradle.properties template with AndroidX settings
- Bug 7: Auto-generate Gradle wrapper if missing
- Bug 8: Fixed AGP version from 8.13.2 to 8.2.2
- Bug 9: Package name in Kotlin templates now uses {{PACKAGE_NAME}}
- Bug 10: Added x86_64-apple-ios target for Intel Mac simulators
- Bug 11: Fixed path handling by canonicalizing project root
- Bug 12: DEFAULT_FUNCTION now auto-detected from #[benchmark] functions
High severity issues fixed (8):
- Issue 1: Added post-template validation for unreplaced {{...}} patterns
- Issue 2: codesign_xcframework now returns Err on failure
- Issue 3: generate_xcode_project now returns Err on failure
- Issue 4: Missing native libraries always warn (not just verbose)
- Issue 5: Added validate_project_root() for early validation
- Issue 6: cargo metadata fallback now warns when used
- Issue 7: Kotlin catch block logs exceptions instead of swallowing
- Issue 8: Added validate_build_artifacts() post-build validation
Medium/Low issues fixed (4):
- Added .gitignore templates for Android and iOS
- Added README.md templates for Android and iOS
New files:
- templates/android/.gitignore
- templates/android/README.md
- templates/android/gradle.properties
- templates/ios/BenchRunner/.gitignore
- templates/ios/BenchRunner/README.md
- Fix all path references to use target/mobench/ as default output dir - Update CLAUDE.md version reference to v0.1.9 - Fix PROJECT_PLAN.md to reflect mobench-runner consolidation into mobench-sdk - Remove dead links to BROWSERSTACK_RUN_2.md (use BROWSERSTACK_METRICS.md) - Fix all init-sdk references to use correct init command - Fix duplicate command and step numbering in TESTING.md - Update iOS artifact paths in BENCH_SDK_INTEGRATION.md
P0 fixes: - Add testBuildType "release" to build.gradle templates - Gradle now creates assembleReleaseAndroidTest task P1 fixes: - local.properties only uses ANDROID_HOME/ANDROID_SDK_ROOT env vars - No longer probes filesystem for hardcoded SDK paths - Kotlin files moved to correct package directory structure P2 fixes: - iOS bundle ID now uses app name: dev.world.benchmobile.BenchRunner - No longer duplicates crate name in bundle ID
Crate detection (P0):
- Check current directory Cargo.toml before nested paths
- Add read_package_name() helper for parsing Cargo.toml
- Search order: current dir → bench-mobile/ → crates/{name}/ → {name}/
- Add 10 new tests for crate detection logic
Error handling improvements:
- Add Log.e() calls for Android exception handlers
- Add print() statements for iOS config parsing failures
- Log config sources (intent, bench_spec.json, default)
- Show warnings when using fallback defaults
Cross-platform consistency:
- Standardize Android package names (remove underscores like iOS)
- Both platforms now use dev.world.benchmobile format
- Standardize version strings to 1.0.0 on both platforms
- Add 3 new consistency tests
Tests added:
- test_find_crate_dir_current_directory_is_crate
- test_find_crate_dir_nested_bench_mobile
- test_find_crate_dir_crates_subdir
- test_find_crate_dir_not_found
- test_find_crate_dir_explicit_crate_path
- test_read_package_name_standard
- test_read_package_name_with_single_quotes
- test_read_package_name_not_found
- test_read_package_name_no_package_section
- test_cross_platform_naming_consistency
- test_cross_platform_version_consistency
- test_bundle_id_prefix_consistency
- Add --release flag to mobench run command for release builds (reduces APK size from ~544MB debug to ~133MB release) - Add mobench package-xcuitest command for iOS BrowserStack testing - Add output_dir option to package-ipa command - Update timing display format from μs to ms (or seconds if >=1000ms) - Auto-package iOS artifacts in release mode when --release is set
- Update Android/iOS apps to display timing in ms (or seconds if >=1000ms) - Update CLAUDE.md, TESTING.md, README with --release flag examples - Document package-xcuitest command across all relevant docs - Add release build recommendations for BrowserStack workflows
iOS XCUITest was exiting in ~2 seconds without capturing benchmark data, while Android properly waited and extracted full timing reports. Changes: - XCUITest now waits up to 5 minutes for benchmark completion (not 2 sec) - Extract benchmark JSON via accessibility identifiers - Output JSON with BENCH_REPORT_JSON_START/END markers for log parsing - Add iOS-specific JSON extraction in fetch logic (handles NSLog prefixes) - Both Android and iOS now hold the report screen for 5 seconds so BrowserStack video recordings capture the benchmark results Files updated: - iOS XCUITest template and reference implementation - iOS ContentView with completion indicators and JSON exposure - iOS BenchRunnerFFI with JSON report generation - BrowserStack fetch logic for iOS log parsing - Android MainActivity with 5-second display hold
- Add --release flag to BrowserStack examples in README.md - Update mobench-sdk README and rustdocs with --release recommendation - Update mobench CLI rustdocs with --release flag - Expand template READMEs with BrowserStack workflow and video capture info - Document benchmark report capture mechanism (5-second delay, JSON markers)
- Add Info.plist to XCUITest bundle to fix BrowserStack test detection BrowserStack requires Info.plist with XCTContainsUITests=true to identify and run tests; without it, builds are skipped with "no tests detected" - Add info: section to UITests target in project.yml templates with proper bundle identifier (*.uitests suffix) - Increase XCUITest delay from 0.5s to 5s after benchmark completion to ensure BrowserStack video captures the results - Update initial display text from "Running benchmark..." to "Running benchmarks..." for better UX during video recording
Changes in this release: - Fix iOS XCUITest BrowserStack detection (Info.plist added to UITests target) - Improve video capture for BrowserStack (5s delay for video evidence) - Show "Running benchmarks..." text before results appear - Sync top-level templates with SDK templates - Various DX fixes
Changed only-testing filter from testLaunchShowsBenchmarkReport to testLaunchAndCaptureBenchmarkReport to match what BrowserStack parses from the xctest bundle.
Fix iOS XCUITest test name mismatch with BrowserStack - changed only-testing filter to use testLaunchAndCaptureBenchmarkReport.
* Refactor mobench layout and refresh README - split CLI entrypoint into library and cargo-mobench bin - update workspace manifests and lockfile for crate changes - rewrite README with current workflow and crate list * Remove legacy bench-cli crates and update docs Drop the unused bench-cli and bench-runner crates, update docs to reflect the current mobench-runner workflow, and adjust legacy scripts/comments to reference cargo mobench. * Split examples into minimal and FFI variants Simplify basic-benchmark to only show #[benchmark] usage and add a new ffi-benchmark example that contains the UniFFI types and entrypoint. Update workspace metadata and docs to reflect the new example layout. * Remove legacy sample_fns UDL Drop the unused UniFFI UDL file for sample-fns and update build script notes to reflect the proc-macro binding generation flow. * Remove legacy scripts and update docs Delete deprecated build scripts, switch CI and docs to cargo mobench commands, and refresh integration guidance for the new flow. * Refresh docs for mobench build flow Update CLAUDE, BUILD, and mobench-sdk README to remove script references, clarify the builder flow, and document the new examples. --------- Co-authored-by: dcbuilder.eth <dcbuilder@protonmail.com>
…ch-runner into mobench-sdk (PR #7)
…ch 0.1.10-0.1.13 (PR #8)
) * Refactor mobench layout and refresh README - split CLI entrypoint into library and cargo-mobench bin - update workspace manifests and lockfile for crate changes - rewrite README with current workflow and crate list * Remove legacy bench-cli crates and update docs Drop the unused bench-cli and bench-runner crates, update docs to reflect the current mobench-runner workflow, and adjust legacy scripts/comments to reference cargo mobench. * Split examples into minimal and FFI variants Simplify basic-benchmark to only show #[benchmark] usage and add a new ffi-benchmark example that contains the UniFFI types and entrypoint. Update workspace metadata and docs to reflect the new example layout. * Remove legacy sample_fns UDL Drop the unused UniFFI UDL file for sample-fns and update build script notes to reflect the proc-macro binding generation flow. * Remove legacy scripts and update docs Delete deprecated build scripts, switch CI and docs to cargo mobench commands, and refresh integration guidance for the new flow. * Refresh docs for mobench build flow Update CLAUDE, BUILD, and mobench-sdk README to remove script references, clarify the builder flow, and document the new examples. * Improve repo root detection with ancestor search The repo_root() function now walks up the directory tree looking for marker files instead of relying on the compile-time manifest path. This fixes cases where the CLI is run from subdirectories. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Bump version to 0.1.7 for release Update workspace version and inter-crate dependencies. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Add commit guidelines to CLAUDE.md * Output mobile artifacts to target/mobench/ by default - Add output_dir field to AndroidBuilder and IosBuilder - Default to {project_root}/target/mobench/ for all mobile artifacts - Add output_dir() builder method for customization - Add --output-dir CLI argument to `cargo mobench build` - Update all path references in builders to use output_dir This keeps generated mobile artifacts inside target/, following Rust conventions and preventing accidental commits of Android/iOS project files. * Update docs for target/mobench/ output directory - Update all path references from target/ios/ to target/mobench/ios/ - Update Android paths to target/mobench/android/ - Document --output-dir CLI flag - Update troubleshooting sections with correct paths * Add comprehensive docs.rs documentation - Add extensive crate-level documentation to all four crates: - mobench-sdk: Full SDK docs with examples, architecture, and best practices - mobench-macros: #[benchmark] macro documentation with usage examples - mobench-runner: Timing harness docs with runnable examples - mobench: CLI documentation with command reference - Document all public types with examples: - BenchSpec, BenchSample, BenchReport, BenchError - Target, BuildConfig, BuildProfile, BuildResult - InitConfig and builder types - Configure docs.rs metadata in all Cargo.toml files: - Add documentation URLs - Add maintenance badges - Configure rustdoc-args for docs.rs builds - Add serde_json dev-dependency to mobench-runner for doc tests * Bump version to 0.1.8 for release * Implement all IMPROVEMENTS.md tasks with enhanced DX This commit implements all 11 developer experience improvements from IMPROVEMENTS.md, making mobench significantly more user-friendly. ## Key Changes ### P0 - Critical (Tasks 1-3) - Fix aws-lc-rs Android NDK incompatibility (ring backend) - Fix workspace target directory detection (cargo metadata) - Auto-generate project scaffolding during build ### P1 - High Priority (Tasks 4-6) - Process template variables during build (TemplateContext) - Improve uniffi-bindgen handling (local binary + fallback) - Generate error handling code dynamically (generic catch) ### P2 - Medium Priority (Tasks 7-9) - Add mobench.toml configuration file support - Improve error messages with actionable suggestions - Add --crate-path flag for custom crate locations ### P3 - Nice to Have (Tasks 10-11) - Add --dry-run and --verbose CLI modes - Auto-generate local.properties for Android ## Code Quality Improvements - Extract shared utilities to builders/common.rs (DRY) - Consistent error message formatting with: - Clear description of what failed - Context (commands, paths, exit status) - Actionable fix suggestions - Links to documentation - Standardized path formatting using display() ## New Files - crates/mobench/src/config.rs - Configuration file support - crates/mobench-sdk/src/builders/common.rs - Shared utilities - IMPROVEMENTS.md - Task tracking document ## Consolidation - Merged mobench-runner crate into mobench-sdk - Timing functionality now in mobench-sdk/src/timing.rs * Fix iOS test failure in auto-build scaffolding The test `ios_requires_artifacts_for_browserstack` was failing because iOS project scaffolding was not being generated correctly during auto-build for BrowserStack. Root causes and fixes: 1. render_dir() was incorrectly joining prefix with file.path(), but file.path() from include_dir already returns the full relative path. Removed the prefix parameter entirely. 2. project.yml lacked .template extension, so template variables like {{PROJECT_NAME_PASCAL}} were not being substituted. Renamed to project.yml.template. 3. xcframework path in project.yml.template was wrong (../../target/ios/). Fixed to ../{{LIBRARY_NAME}}.xcframework since the iOS project is at target/mobench/ios/BenchRunner/. 4. ensure_ios_project now uses fixed "BenchRunner" for PROJECT_NAME_PASCAL to match the template directory structure, while deriving LIBRARY_NAME from the actual crate name. All 37 tests now pass. * Update documentation for consolidated crates and new features README updates: - Document mobench-runner consolidation into mobench-sdk - Add mobench.toml configuration file documentation - Document new CLI flags: --dry-run, --verbose, --crate-path - Update all artifact paths to target/mobench/ - Add examples for new features Rust doc comments: - Add comprehensive module docs to builders/{mod,android,ios,common}.rs - Document build pipelines, requirements, and examples - Add dry-run mode documentation - Note mobench-runner consolidation in timing.rs docs.rs configuration: - Add targets = ["x86_64-unknown-linux-gnu"] for docs.rs builds - Add #![cfg_attr(docsrs, feature(doc_cfg))] attributes - Add crates.io/docs.rs/license badges to crate roots - Add #[doc(cfg(...))] annotations for feature-gated items * Bump version to 0.1.9 for release - Update workspace version from 0.1.8 to 0.1.9 - Update mobench-sdk dependency in mobench crate - Update mobench-macros dependency in mobench-sdk crate - All mobench-runner versions have been yanked on crates.io * Remove IMPROVEMENTS.md after completing all tasks * Fix all DX issues from mobench 0.1.9 testing Critical bugs fixed (12): - Bugs 1-5: Template variables (PROJECT_NAME, PACKAGE_NAME, LIBRARY_NAME, PROJECT_NAME_PASCAL, APP_NAME) now properly substituted - Bug 6: Added gradle.properties template with AndroidX settings - Bug 7: Auto-generate Gradle wrapper if missing - Bug 8: Fixed AGP version from 8.13.2 to 8.2.2 - Bug 9: Package name in Kotlin templates now uses {{PACKAGE_NAME}} - Bug 10: Added x86_64-apple-ios target for Intel Mac simulators - Bug 11: Fixed path handling by canonicalizing project root - Bug 12: DEFAULT_FUNCTION now auto-detected from #[benchmark] functions High severity issues fixed (8): - Issue 1: Added post-template validation for unreplaced {{...}} patterns - Issue 2: codesign_xcframework now returns Err on failure - Issue 3: generate_xcode_project now returns Err on failure - Issue 4: Missing native libraries always warn (not just verbose) - Issue 5: Added validate_project_root() for early validation - Issue 6: cargo metadata fallback now warns when used - Issue 7: Kotlin catch block logs exceptions instead of swallowing - Issue 8: Added validate_build_artifacts() post-build validation Medium/Low issues fixed (4): - Added .gitignore templates for Android and iOS - Added README.md templates for Android and iOS New files: - templates/android/.gitignore - templates/android/README.md - templates/android/gradle.properties - templates/ios/BenchRunner/.gitignore - templates/ios/BenchRunner/README.md * Update documentation for v0.1.9 and fix inconsistencies - Fix all path references to use target/mobench/ as default output dir - Update CLAUDE.md version reference to v0.1.9 - Fix PROJECT_PLAN.md to reflect mobench-runner consolidation into mobench-sdk - Remove dead links to BROWSERSTACK_RUN_2.md (use BROWSERSTACK_METRICS.md) - Fix all init-sdk references to use correct init command - Fix duplicate command and step numbering in TESTING.md - Update iOS artifact paths in BENCH_SDK_INTEGRATION.md * Bump version to 0.1.10 for release * Fix CI workflow paths to use target/mobench/ output directory * Fix DX issues from 0.1.10 report Android fixes: - Add APK detection for both signed and unsigned builds - Parse output-metadata.json for actual APK filename - Add proguard-rules.pro template for release builds - Update .gitignore to exclude jniLibs and uniffi bindings iOS fixes: - Sanitize bundle identifiers (remove hyphens/underscores) - Framework bundle IDs now use alphanumeric chars only - Add logging for config loading failures - Update .gitignore to exclude xcodeproj, frameworks, bindings Config fixes: - Add logging for missing/invalid JSON keys in templates - Android MainActivity logs warnings for missing config values - iOS BenchRunnerFFI prints errors when JSON parsing fails * Bump version to 0.1.11 for release * Update CLAUDE.md version reference to 0.1.11 * Fix DX issues from 0.1.11 report P0 fixes: - Add testBuildType "release" to build.gradle templates - Gradle now creates assembleReleaseAndroidTest task P1 fixes: - local.properties only uses ANDROID_HOME/ANDROID_SDK_ROOT env vars - No longer probes filesystem for hardcoded SDK paths - Kotlin files moved to correct package directory structure P2 fixes: - iOS bundle ID now uses app name: dev.world.benchmobile.BenchRunner - No longer duplicates crate name in bundle ID * Fix all DX issues from bug reports Crate detection (P0): - Check current directory Cargo.toml before nested paths - Add read_package_name() helper for parsing Cargo.toml - Search order: current dir → bench-mobile/ → crates/{name}/ → {name}/ - Add 10 new tests for crate detection logic Error handling improvements: - Add Log.e() calls for Android exception handlers - Add print() statements for iOS config parsing failures - Log config sources (intent, bench_spec.json, default) - Show warnings when using fallback defaults Cross-platform consistency: - Standardize Android package names (remove underscores like iOS) - Both platforms now use dev.world.benchmobile format - Standardize version strings to 1.0.0 on both platforms - Add 3 new consistency tests Tests added: - test_find_crate_dir_current_directory_is_crate - test_find_crate_dir_nested_bench_mobile - test_find_crate_dir_crates_subdir - test_find_crate_dir_not_found - test_find_crate_dir_explicit_crate_path - test_read_package_name_standard - test_read_package_name_with_single_quotes - test_read_package_name_not_found - test_read_package_name_no_package_section - test_cross_platform_naming_consistency - test_cross_platform_version_consistency - test_bundle_id_prefix_consistency * Add --release flag and package-xcuitest command - Add --release flag to mobench run command for release builds (reduces APK size from ~544MB debug to ~133MB release) - Add mobench package-xcuitest command for iOS BrowserStack testing - Add output_dir option to package-ipa command - Update timing display format from μs to ms (or seconds if >=1000ms) - Auto-package iOS artifacts in release mode when --release is set * Update mobile timing display and documentation - Update Android/iOS apps to display timing in ms (or seconds if >=1000ms) - Update CLAUDE.md, TESTING.md, README with --release flag examples - Document package-xcuitest command across all relevant docs - Add release build recommendations for BrowserStack workflows * Fix iOS XCUITest benchmark report gap and add video capture delay iOS XCUITest was exiting in ~2 seconds without capturing benchmark data, while Android properly waited and extracted full timing reports. Changes: - XCUITest now waits up to 5 minutes for benchmark completion (not 2 sec) - Extract benchmark JSON via accessibility identifiers - Output JSON with BENCH_REPORT_JSON_START/END markers for log parsing - Add iOS-specific JSON extraction in fetch logic (handles NSLog prefixes) - Both Android and iOS now hold the report screen for 5 seconds so BrowserStack video recordings capture the benchmark results Files updated: - iOS XCUITest template and reference implementation - iOS ContentView with completion indicators and JSON exposure - iOS BenchRunnerFFI with JSON report generation - BrowserStack fetch logic for iOS log parsing - Android MainActivity with 5-second display hold * Sync top-level templates with SDK templates * Update documentation for --release flag and iOS XCUITest features - Add --release flag to BrowserStack examples in README.md - Update mobench-sdk README and rustdocs with --release recommendation - Update mobench CLI rustdocs with --release flag - Expand template READMEs with BrowserStack workflow and video capture info - Document benchmark report capture mechanism (5-second delay, JSON markers) * Fix iOS XCUITest BrowserStack detection and video capture - Add Info.plist to XCUITest bundle to fix BrowserStack test detection BrowserStack requires Info.plist with XCTContainsUITests=true to identify and run tests; without it, builds are skipped with "no tests detected" - Add info: section to UITests target in project.yml templates with proper bundle identifier (*.uitests suffix) - Increase XCUITest delay from 0.5s to 5s after benchmark completion to ensure BrowserStack video captures the results - Update initial display text from "Running benchmark..." to "Running benchmarks..." for better UX during video recording * Remove resolved issue tracking docs * Remove stale DX report doc * Bump version to 0.1.12 for release Changes in this release: - Fix iOS XCUITest BrowserStack detection (Info.plist added to UITests target) - Improve video capture for BrowserStack (5s delay for video evidence) - Show "Running benchmarks..." text before results appear - Sync top-level templates with SDK templates - Various DX fixes * Fix error message hints * Fix iOS XCUITest test name mismatch with BrowserStack Changed only-testing filter from testLaunchShowsBenchmarkReport to testLaunchAndCaptureBenchmarkReport to match what BrowserStack parses from the xctest bundle. * Bump version to 0.1.13 for release Fix iOS XCUITest test name mismatch with BrowserStack - changed only-testing filter to use testLaunchAndCaptureBenchmarkReport. * Add DX improvements: verify, summary, devices commands and SDK enhancements CLI improvements: - Add `mobench verify` command to validate registry, spec, and artifacts - Add `mobench summary` command to display benchmark result statistics - Add `mobench devices` command to list available BrowserStack devices - Add benchmark function validation before runs with helpful error messages - Add resolved spec and artifact location output at run start - Add run completion summary with build IDs and artifact paths BrowserStack improvements: - Add device listing APIs for Espresso and XCUITest - Add device validation with fuzzy matching and suggestions - Add helpful credential error messages with setup instructions - Add artifact correlation output (build ID, device, local paths) SDK improvements: - Add bench_meta.json with spec, commit hash, build time, and profile - Add embed_bench_spec() for bundling spec into app assets - Add UniFFI type templates for easier FFI boundary setup - Add git info helpers (commit, branch, dirty state detection) * Add comprehensive DX improvements: check command, macro validation, better errors SDK Improvements: - Add compile-time validation to #[benchmark] macro (no params, returns ()) - Add debug_benchmarks!() macro for verifying registration - Enhance UnknownFunction error to show available benchmarks - Enhance TimingError::NoIterations to show the actual value - Add Quick Setup Checklist to lib.rs documentation CLI Improvements: - Add `cargo mobench check` command for prerequisite validation - Add --progress flag for simplified build/run output - Add build progress feedback with status messages - Print clear results summary at end of runs BrowserStack Improvements: - Improve credential error messages with setup instructions - Add artifact pre-flight validation before uploads - Add upload progress indication with file sizes - Print dashboard link immediately after build starts - Improve device fuzzy matching with OS version suggestions * Update all documentation for DX improvements v0.1.14 README.md: - Add new commands to quick start (check, verify, summary, devices) - Add --progress flag example - Add v0.1.14 release notes with all new features CLAUDE.md: - Update version to v0.1.14 - Add check command as first build step - Document --progress flag and verify command - Add debug_benchmarks!() macro documentation - Document improved BrowserStack error messages BUILD.md: - Add new Prerequisites Check section - Document cargo mobench check command with examples - Add --progress flag to build commands TESTING.md: - Add prerequisite validation section - Document verify command in testing workflow - Add BrowserStack device validation section - Add summary command for viewing results BENCH_SDK_INTEGRATION.md: - Add Quick Setup Checklist section - Document #[benchmark] macro validation requirements - Add debug_benchmarks!() macro usage guide - Add verification and troubleshooting section FETCH_RESULTS_GUIDE.md: - Add summary command documentation - Add result analysis examples with different formats - Update best practices BROWSERSTACK_CI_INTEGRATION.md: - Add pre-flight validation section - Document devices command with fuzzy matching - Update GitHub Actions example with validation steps - Expand troubleshooting with credential error messages PROJECT_PLAN.md: - Add completed DX improvements section - Update roadmap with remaining P2 items * Add setup/teardown support to #[benchmark] macro This enables expensive setup to be excluded from benchmark timing: API: - #[benchmark] - Simple benchmark (unchanged) - #[benchmark(setup = fn)] - Setup runs once before iterations - #[benchmark(setup = fn, per_iteration)] - Setup runs before each iteration - #[benchmark(setup = fn, teardown = fn)] - Setup + cleanup Implementation: - timing.rs: Add run_closure_with_setup(), run_closure_with_setup_per_iter(), run_closure_with_setup_teardown() functions - registry.rs: Change BenchFunction.invoke to BenchFunction.runner for direct timing control - mobench-macros: Parse setup/teardown/per_iteration attributes and generate appropriate runner code - runner.rs: Simplify to delegate to registry runner Example: ```rust fn setup_proof() -> ProofInput { generate_complex_proof() // Not measured } #[benchmark(setup = setup_proof)] fn verify_proof(input: &ProofInput) { verify(&input.proof); // Only this is measured } ``` Tests: 135 passing * Document setup/teardown feature in README, CLAUDE.md, and integration guide README.md: - Add "Setup and Teardown" section with problem/solution examples - Add v0.1.15 release notes for setup/teardown feature CLAUDE.md: - Update version to v0.1.15 - Expand SDK Integration Pattern with setup/teardown examples - Update macro validation notes BENCH_SDK_INTEGRATION.md: - Add comprehensive "Setup and Teardown" section - Cover one-time setup, per-iteration, and teardown patterns - Add pattern selection guide table * Update version references to 0.1.13 and consolidate release notes - Updated CLAUDE.md version from v0.1.15 to v0.1.13 - Updated feature version markers (v0.1.14+, v0.1.15+) to v0.1.13+ - Consolidated README release notes into single v0.1.13 section - Fixed documentation for setup/teardown feature - Published mobench-macros, mobench-sdk, mobench v0.1.13 to crates.io * Fix documentation issues in BENCH_SDK_INTEGRATION.md - Remove redundant gradle steps (cargo mobench build handles test APK) - Add devices command to quick setup checklist for BrowserStack users * Add device selection guide with tier examples for BrowserStack - Added section 9 with Android and iOS device tiers (6 tiers each) - Flagship to Lowest performance tiers with real BrowserStack device specs - Multi-device benchmarking examples - Device validation commands - Renumbered section 10 (Verification and Troubleshooting) --------- Co-authored-by: dcbuilder.eth <dcbuilder@protonmail.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
…lease 0.1.14) (#10) * docs: map existing codebase - STACK.md - Technologies and dependencies - ARCHITECTURE.md - System design and patterns - STRUCTURE.md - Directory layout - CONVENTIONS.md - Code style and patterns - TESTING.md - Test structure - INTEGRATIONS.md - External services - CONCERNS.md - Technical debt and issues * chore: remove obsolete planning documents * docs: document iOS auto-packaging behavior with progress messages Add progress output when mobench auto-packages iOS artifacts for BrowserStack runs, showing the IPA and XCUITest paths that are generated. Update CLAUDE.md with a new "Automatic iOS Packaging" section that explains how users can let mobench automatically package iOS artifacts instead of manually running package-ipa and package-xcuitest commands. * fix: add emoji indicators to iOS auto-packaging progress messages * feat(sdk): add unified ffi module for UniFFI integration Add a new `ffi` module to mobench-sdk that provides a single import point for all FFI-related types and traits needed to create UniFFI bindings for mobile platforms. The module includes: - BenchSpecFfi, BenchSampleFfi, BenchReportFfi, BenchErrorFfi types - IntoFfi and FromFfi conversion traits with blanket implementations - run_benchmark_ffi convenience function for FFI-ready benchmark execution - Re-exports from uniffi_types for backwards compatibility - Comprehensive tests for all type conversions * feat(cli): add extract_benchmark_summary helper for unified result parsing * docs: clarify single-command BrowserStack flow in CLI and CLAUDE.md * test(cli): add init-sdk mobench.toml generation tests Add test module to verify that init-sdk command properly generates mobench.toml configuration file with correct project settings including project name, library name (with hyphens converted to underscores), and all required configuration sections. * docs: update examples and integration guide with ffi module usage - Add comment to ffi-benchmark example about mobench_sdk::ffi module alternative - Add "Using the FFI Module" section to BENCH_SDK_INTEGRATION.md with: - Overview of ffi module types (BenchSpecFfi, BenchReportFfi, etc.) - Option 1: Using FFI types directly for simple cases - Option 2: Defining custom UniFFI types (recommended for full bindings) * chore: gitignore docs/plans directory * feat(sdk): add statistical helpers, black_box and inventory re-exports - Add BenchReport methods: mean_ns(), median_ns(), std_dev_ns(), percentile_ns(), min_ns(), max_ns(), summary() - Add BenchSummary struct for serializable statistics - Re-export `inventory` crate so users don't need separate dependency - Re-export `std::hint::black_box` for preventing compiler optimizations Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(cli): add CI/devex helpers (doctor, ci init, junit, device-matrix) * perf(ci): improve action caching (gradle/target/android sdk root) * Improve CI template and doctor env/flag behavior * feat(ci): add ci run orchestration and local action example * Fix iOS CI target setup and preserve CI outputs on regression exit * feat(mobench): implement CI contract phases, fixture/report commands, and migration docs * fix: address open PR review threads * docs: align guides with latest CI/action behavior * docs+sdk: refresh rustdocs, package metadata, and concerns resolution * chore(release): bump mobench crates to v0.1.14 --------- Co-authored-by: dcbuilder.eth <dcbuilder@protonmail.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Initial commit
* Add .github/workflows/relyance-sci.yml
* Update .github/workflows/relyance-sci.yml
* Update .github/workflows/relyance-sci.yml
* Bootstrap mobile-bench-rs with UniFFI integration, BrowserStack runs/fetch, Android logging, iOS UI tests, and docs (#2)
* initial commit
* Fix Android UniFFI integration and benchmark display
This commit resolves multiple issues preventing the Android app from
loading the Rust native library and correctly displaying benchmark results.
Changes implemented:
1. Added JNA dependency (android/app/build.gradle)
- Added net.java.dev.jna:jna:5.14.0@aar dependency
- Required for UniFFI's Kotlin bindings to interface with native code
- Also added NDK version specification and benchmark spec asset directories
2. Fixed library naming mismatch (crates/sample-fns/Cargo.toml)
- Set explicit lib name = "sample_fns" (not uniffi_sample_fns)
- Changed crate-type to ["lib", "cdylib", "staticlib"] for UniFFI
- Added UniFFI dependencies and build configuration
- Migrated from JNI to UniFFI for cleaner FFI bindings
3. Updated sync script for library renaming (scripts/sync-android-libs.sh)
- Added TARGET_LIB_NAME variable to rename .so during copy
- Rust builds libsample_fns.so but JNA expects libuniffi_sample_fns.so
- Script now copies and renames: libsample_fns.so -> libuniffi_sample_fns.so
- Ensures FFI symbol prefixes match UniFFI expectations
4. Updated Android MainActivity (android/app/src/main/java/dev/world/bench/MainActivity.kt)
- Changed System.loadLibrary("sample_fns") to System.loadLibrary("uniffi_sample_fns")
- Migrated from JNI to UniFFI-generated Kotlin bindings
- Updated benchmark display to show microseconds (μs) instead of milliseconds
- Added raw nanosecond display alongside formatted values
- Improved error handling with UniFFI's BenchException variants
- Added support for loading benchmark specs from assets (bench_spec.json)
Root cause analysis:
- UniFFI generates Kotlin bindings that expect library name "uniffi_<namespace>"
- The namespace from sample_fns.udl is "sample_fns"
- JNA looks for libuniffi_sample_fns.so based on this naming convention
- Rust builds libsample_fns.so by default (from crate name)
- Solution: Keep Rust lib name simple, rename during Android integration
Benchmark display fix:
- Functions execute in 0-42 nanoseconds (extremely fast)
- Previous millisecond display showed "0.000 ms" for all samples
- Now displays in microseconds with raw nanosecond values for clarity
- Example: "0.042 μs (42 ns)" instead of "0.000 ms"
Testing:
- App builds successfully with ./gradlew :app:assembleDebug
- Native library loads without UnsatisfiedLinkError
- Benchmarks execute and display timing results correctly
- Fibonacci(24) averages ~17 nanoseconds per iteration on ARM64
* Android: log benchmark JSON and fix test matcher
* iOS: add UI test target and accessibility id
* bench-cli: add BrowserStack fetch and artifact download
* Commit remaining workspace changes
* Ignore generated build artifacts
* gitignore: exclude CLI-generated artifacts
- Add run-summary.json (benchmark run results)
- Add bench-config.toml (user configuration template)
- Add device-matrix.yaml (device matrix template)
These files are generated by bench-cli and should not be tracked in git.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* iOS: standardize time units to microseconds
Change benchmark result display from milliseconds (ms) to microseconds (μs)
to match Android's output format. This provides better granularity for
typical function benchmarks and makes cross-platform comparison easier.
Before: 0.045 ms
After: 45.320 μs (45320 ns)
Also add raw nanosecond values in parentheses to match Android formatting.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* bench-cli: add comprehensive BrowserStack client tests
Add 11 new tests covering:
- Client initialization and configuration
- URL construction and path handling
- Input validation for schedule/upload methods
- Error cases for missing artifacts
- Both Espresso (Android) and XCUITest (iOS) code paths
Also suppress dead_code warning for test-only with_base_url helper.
Test coverage increased from 1 to 12 tests for browserstack.rs module.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: dcbuilder.eth <dcbuilder@protonmail.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* feat: Mobile benchmarking SDK (Phase 1 MVP) + Performance Metrics (v0.1.5) (#4)
* Initial commit
* Add .github/workflows/relyance-sci.yml
* initial commit
* Fix Android UniFFI integration and benchmark display
This commit resolves multiple issues preventing the Android app from
loading the Rust native library and correctly displaying benchmark results.
Changes implemented:
1. Added JNA dependency (android/app/build.gradle)
- Added net.java.dev.jna:jna:5.14.0@aar dependency
- Required for UniFFI's Kotlin bindings to interface with native code
- Also added NDK version specification and benchmark spec asset directories
2. Fixed library naming mismatch (crates/sample-fns/Cargo.toml)
- Set explicit lib name = "sample_fns" (not uniffi_sample_fns)
- Changed crate-type to ["lib", "cdylib", "staticlib"] for UniFFI
- Added UniFFI dependencies and build configuration
- Migrated from JNI to UniFFI for cleaner FFI bindings
3. Updated sync script for library renaming (scripts/sync-android-libs.sh)
- Added TARGET_LIB_NAME variable to rename .so during copy
- Rust builds libsample_fns.so but JNA expects libuniffi_sample_fns.so
- Script now copies and renames: libsample_fns.so -> libuniffi_sample_fns.so
- Ensures FFI symbol prefixes match UniFFI expectations
4. Updated Android MainActivity (android/app/src/main/java/dev/world/bench/MainActivity.kt)
- Changed System.loadLibrary("sample_fns") to System.loadLibrary("uniffi_sample_fns")
- Migrated from JNI to UniFFI-generated Kotlin bindings
- Updated benchmark display to show microseconds (μs) instead of milliseconds
- Added raw nanosecond display alongside formatted values
- Improved error handling with UniFFI's BenchException variants
- Added support for loading benchmark specs from assets (bench_spec.json)
Root cause analysis:
- UniFFI generates Kotlin bindings that expect library name "uniffi_<namespace>"
- The namespace from sample_fns.udl is "sample_fns"
- JNA looks for libuniffi_sample_fns.so based on this naming convention
- Rust builds libsample_fns.so by default (from crate name)
- Solution: Keep Rust lib name simple, rename during Android integration
Benchmark display fix:
- Functions execute in 0-42 nanoseconds (extremely fast)
- Previous millisecond display showed "0.000 ms" for all samples
- Now displays in microseconds with raw nanosecond values for clarity
- Example: "0.042 μs (42 ns)" instead of "0.000 ms"
Testing:
- App builds successfully with ./gradlew :app:assembleDebug
- Native library loads without UnsatisfiedLinkError
- Benchmarks execute and display timing results correctly
- Fibonacci(24) averages ~17 nanoseconds per iteration on ARM64
* Android: log benchmark JSON and fix test matcher
* iOS: add UI test target and accessibility id
* bench-cli: add BrowserStack fetch and artifact download
* Commit remaining workspace changes
* Ignore generated build artifacts
* gitignore: exclude CLI-generated artifacts
- Add run-summary.json (benchmark run results)
- Add bench-config.toml (user configuration template)
- Add device-matrix.yaml (device matrix template)
These files are generated by bench-cli and should not be tracked in git.
* iOS: standardize time units to microseconds
Change benchmark result display from milliseconds (ms) to microseconds (μs)
to match Android's output format. This provides better granularity for
typical function benchmarks and makes cross-platform comparison easier.
Before: 0.045 ms
After: 45.320 μs (45320 ns)
Also add raw nanosecond values in parentheses to match Android formatting.
* bench-cli: add comprehensive BrowserStack client tests
Add 11 new tests covering:
- Client initialization and configuration
- URL construction and path handling
- Input validation for schedule/upload methods
- Error cases for missing artifacts
- Both Espresso (Android) and XCUITest (iOS) code paths
Also suppress dead_code warning for test-only with_base_url helper.
Test coverage increased from 1 to 12 tests for browserstack.rs module.
* Migrate from UniFFI UDL to proc macros
Replace manual UDL file with proc macro attributes for better developer
experience and single source of truth in Rust code.
## Changes
### sample-fns crate:
- Add `#[derive(uniffi::Record)]` to BenchSpec, BenchSample, BenchReport
- Add `#[derive(uniffi::Error)]` with `#[uniffi(flat_error)]` to BenchError
- Add `#[uniffi::export]` to run_benchmark function
- Add `uniffi::setup_scaffolding!()` macro to generate scaffolding
- Remove UDL file (sample_fns.udl)
- Update Cargo.toml: enable uniffi "cli" feature
- Update build.rs: remove UDL scaffolding generation (now proc macro-based)
- Update generate-bindings.rs: use library_mode instead of UDL-based generation
### Generated bindings:
- Kotlin bindings regenerated from proc macros
- Swift bindings regenerated from proc macros
- FFI interface remains identical (no breaking changes)
## Benefits
1. **Single source of truth**: Rust code is the only place to define types
2. **Better IDE support**: Type checking and autocomplete in Rust
3. **Automatic sync**: No manual UDL maintenance required
4. **Improved DevEx**: Attributes are inline with type definitions
5. **Type safety**: Compiler enforces FFI boundaries
## Migration notes
- UniFFI 0.28 supports both UDL and proc macros
- Generated bindings are functionally identical
- All tests pass (22 tests)
- CLI demo verified working
- Android/iOS apps use same generated bindings
* docs: update for proc macros and dual workflows
Update documentation to reflect:
1. UniFFI proc macros (no UDL file needed)
2. Two distinct workflows: Local Development vs BrowserStack
## README.md Changes
- Add "Testing Workflows" section with clear separation
- Update UniFFI section for proc macro mode with examples
- Add comprehensive BrowserStack workflow section:
- Android + Espresso step-by-step
- iOS + XCUITest step-by-step
- Config file examples
- BrowserStack features overview
- Reorganize into Local Development vs BrowserStack sections
- Remove outdated UDL references
- Add requirements for both workflows
## CLAUDE.md Changes
- Update Mobile Integration Flow to mention proc macros
- Rewrite FFI Boundary section with proc macro examples
- Update "Adding New Benchmark Functions" workflow
- Remove references to sample_fns.udl
- Add note that no UDL file is needed
These changes make it much clearer for users:
- How to test locally (fast iteration)
- How to test on BrowserStack (real devices)
- How to add new FFI types with proc macros
* initial procmacros
* feat: Phase 1 - Transform mobile-bench-rs into bench-sdk library crate
This commit implements the complete Phase 1 MVP, transforming mobile-bench-rs
from a standalone tool into a library crate (bench-sdk) that can be imported
into any Rust project for mobile benchmarking.
## Core Features
### 1. Proc Macro System (bench-macros)
- Implement #[benchmark] attribute macro for automatic function registration
- Use inventory crate for compile-time collection, runtime discovery
- Generate fully-qualified function names (e.g., my_crate::my_function)
### 2. Core SDK Library (bench-sdk)
- **types.rs**: Core types (BenchError, Target, BuildConfig, BuildProfile, etc.)
- **registry.rs**: Function discovery via inventory::collect!()
- discover_benchmarks(), find_benchmark(), list_benchmark_names()
- **runner.rs**: Execution engine with BenchmarkBuilder fluent API
- **codegen.rs**: Template generation system
- Generates bench-mobile FFI wrapper crate with UniFFI
- Creates Android/iOS project structures
- Generates config files and examples
- **builders/android.rs**: Complete Android build pipeline
- cargo-ndk integration for multi-ABI builds
- JNI library syncing
- Gradle APK generation
- **builders/ios.rs**: Complete iOS build pipeline
- Multi-architecture builds (device + simulator)
- xcframework creation with proper structure
- Automatic code signing
- XcodeGen integration
### 3. CLI Integration (bench-cli)
- Refactor to use SDK API as thin wrapper
- Add new commands:
- init-sdk: Initialize benchmark project with templates
- build: Build mobile artifacts using SDK builders
- list: Discover and list all registered benchmarks
- Maintain backward compatibility with existing commands
### 4. Templates (templates/)
- **Android**: Gradle project, MainActivity, Espresso tests, resources
- Templatized with package name, library name, etc.
- Complete build.gradle, settings.gradle, AndroidManifest.xml
- **iOS**: XcodeGen project, SwiftUI app, XCUITest tests
- Templatized with project name, bundle ID, etc.
- Complete project.yml, Swift files, bridging headers
### 5. Example Project (examples/basic-benchmark)
- Migrate sample-fns to example demonstrating SDK usage
- Use #[benchmark] attributes with registry-based execution
- Full test coverage (6 passing tests)
## Architecture Changes
### Workspace Structure
```
mobile-bench-rs/
├── crates/
│ ├── bench-sdk/ # Core library (NEW, for crates.io)
│ ├── bench-macros/ # Proc macro crate (NEW)
│ ├── bench-cli/ # CLI tool (REFACTORED)
│ ├── bench-runner/ # Timing harness (UNCHANGED)
│ └── sample-fns/ # Legacy (DEPRECATED)
├── examples/
│ └── basic-benchmark/ # SDK example (NEW)
└── templates/ # Mobile app templates (NEW)
├── android/
└── ios/
```
### Public API Surface
```rust
// Proc macro
#[benchmark]
fn my_function() { /* ... */ }
// Discovery
bench_sdk::discover_benchmarks() -> Vec<&BenchFunction>
bench_sdk::find_benchmark(name) -> Option<&BenchFunction>
// Execution
bench_sdk::run_benchmark(spec) -> Result<BenchReport>
BenchmarkBuilder::new(name).iterations(100).run()
// Builders
AndroidBuilder::new(root, crate_name).build(&config)
IosBuilder::new(root, crate_name).build(&config)
// Codegen
generate_project(&InitConfig) -> Result<PathBuf>
```
## Testing
All tests passing (25 total):
- bench-sdk: 12 tests
- basic-benchmark: 6 tests
- sample-fns: 6 tests (legacy)
- bench-runner: 1 test
## Documentation
- Updated README.md with Phase 1 information
- Inline rustdoc comments throughout
- Working example in examples/basic-benchmark
- Updated references in BUILD.md, TESTING.md
## Migration Path
Users can now:
1. Add bench-sdk to Cargo.toml
2. Annotate functions with #[benchmark]
3. Run `cargo bench-sdk init-sdk` to generate project
4. Run `cargo bench-sdk build` to build mobile artifacts
5. Run `cargo bench-sdk list` to discover benchmarks
## Future Work
Phase 1 provides the foundation for:
- Phase 2: Adaptive iterations, warmup detection
- Phase 3: Statistical analysis, baselines
- Phase 4: Full BrowserStack integration
- Phase 5: cargo bench harness, DevEx improvements
- Phase 6: Caching, reproducibility, CI optimization
* feat: wire sdk scaffolding and bindings
- Render Android/iOS templates with project-specific names and link user crate in bench-mobile
- Run UniFFI binding generation in SDK builders and ensure headers are packaged
- Route CLI builds through SDK builders and detect bench-mobile crate name
- Align Android JNI library naming (sample_fns) and update templates/scripts
- Improve binding generation tooling for ABI-aware Android builds
* docs: align build and binding workflow
- Document ABI-aware Android builds with UNIFFI_ANDROID_ABI
- Update binding regeneration steps to use scripts/generate-bindings.sh
- Simplify Android local/testing steps to use build-android-app.sh
* docs: add bench-sdk integration guide
- Add step-by-step setup for dependencies and annotations
- Document local Android/iOS testing workflow
- Document BrowserStack Espresso/XCUITest runs
* docs: expand integration guide
- Add prerequisites and clarify script availability
- Document CLI build path when scripts are absent
- Link guide from README
* docs: link prerequisite downloads
- Add official download links for Rust, Android, JDK, Xcode, and xcodegen
* docs: clarify JDK requirement
- Use vendor-agnostic JDK 17+ wording and OpenJDK link
- Note AGP official support for Java 17
* feat: Rename bench-cli to mobench and add iOS IPA packaging
Major improvements to CLI tooling and iOS workflow:
1. Rename bench-cli → mobench
- More memorable and concise name (7 chars)
- Available on crates.io
- Dual binaries: mobench + cargo-mobench
- Updated all documentation and references
2. Add iOS IPA packaging with xcodebuild
- New command: cargo mobench package-ipa
- SigningMethod enum: AdHoc and Development
- Ad-hoc signing (no Apple ID needed) for BrowserStack
- Development signing for physical devices
- Pure xcodebuild implementation (no fastlane dependency)
- Automatic ExportOptions.plist generation
3. Eliminate script dependencies for SDK integrators
- Added prominent warnings in README and integration docs
- Deprecation notices in all shell scripts
- CLI-first approach: cargo mobench build replaces ./scripts/
- Templates embedded in binary, no repo checkout needed
4. Add package metadata
- Author: Dominik Clemente - dcbuilder.eth <dc@world.org>
- Added to mobench, bench-sdk, and bench-macros
- Repository links and keywords for crates.io
All changes tested and verified:
- 25 tests passing
- cargo mobench --help shows all commands
- package-ipa supports both adhoc and development methods
- Documentation updated across all files
* refactor: Rename bench-sdk → mobench-sdk and bench-macros → mobench-macros
Complete branding consistency across all packages:
1. Crate renames:
- bench-sdk → mobench-sdk
- bench-macros → mobench-macros
2. Updated all references:
- Package names in Cargo.toml files
- Workspace member names
- Dependency declarations
- Import statements (bench_sdk → mobench_sdk)
- Documentation and code examples
- CLI help messages
3. All tests passing (25 tests)
- mobench-sdk: 12 tests
- sample-fns: 6 tests
- basic-benchmark: 6 tests
- mobench CLI verified
Now all three publishable packages have consistent branding:
- mobench (CLI)
- mobench-sdk (core library)
- mobench-macros (proc macros)
* feat: Add metadata to bench-runner for crates.io publication
* fix: Add version requirements to path dependencies in mobench-sdk
* fix: Update repository URLs to worldcoin org and include templates in mobench-sdk package
* fix: Include templates directory in mobench-sdk crate for crates.io packaging
* chore: prepare mobench for crates.io publication
- Update repository URL to worldcoin organization
- Add version requirements to published dependencies (mobench-sdk, bench-runner)
* chore: make sample-fns dependency optional for publishing
- Add 'demo' feature flag for sample-fns dependency
- Feature-gate Demo command to only work when demo feature is enabled
- Users can install with: cargo install mobench --features demo
This allows mobench to be published without requiring sample-fns
(which is not published to crates.io).
* chore: remove Demo command for crates.io publication
- Demo command was only useful for development/testing
- Requires unpublished sample-fns crate
- Move sample-fns to dev-dependencies only
- Published CLI focuses on core functionality
* docs: add BrowserStack test run results and manual test script
Completed test runs on BrowserStack:
- ✅ Android Espresso test PASSED on Pixel 7 (50s duration)
- ⚠️ iOS XCUITest encountered packaging/parsing issues
Build artifacts created:
- Android APK (9.5 MB) + test APK
- iOS IPA (284 KB) + test suite (5.6 MB)
The Android integration is fully functional. iOS XCUITest requires
additional work on test runner packaging to meet BrowserStack's
parsing requirements.
Added test_browserstack.sh for manual BrowserStack API testing,
bypassing CLI's benchmark registry validation.
* refactor: rename bench-runner to mobench-runner for consistency
- Renamed crates/bench-runner to crates/mobench-runner
- Updated package name from bench-runner to mobench-runner
- Updated all imports from bench_runner to mobench_runner
- Updated workspace and all dependent crates:
- mobench-sdk
- mobench CLI
- sample-fns
- examples/basic-benchmark
This aligns the runner crate naming with the mobench ecosystem
(mobench, mobench-sdk, mobench-macros, mobench-runner).
Preparing for republication to crates.io.
* chore: bump version to 0.1.1 for republication
Updated workspace version to 0.1.1 after:
- Publishing mobench-runner v0.1.0 (new package)
- Republishing mobench-sdk v0.1.1 (updated dependency)
- Republishing mobench v0.1.1 (updated dependency)
All packages now use mobench-runner instead of bench-runner.
* docs: add comprehensive READMEs to all packages for crates.io
Added detailed README files to all packages:
- mobench-runner: Explains timing harness, shows basic usage examples
- mobench-macros: Documents #[benchmark] attribute, macro expansion
- mobench-sdk: Comprehensive SDK guide with examples and architecture
- mobench: Complete CLI documentation with all commands and workflows
Each README includes:
- Feature overview
- Installation instructions
- Usage examples
- API documentation
- Best practices
- Integration with other packages
- Requirements and troubleshooting
Updated Cargo.toml files to include readme = "README.md" field
for proper display on crates.io package pages.
Bumped version to 0.1.2 for republication with documentation.
* chore: add MIT license and update all package licenses
- Added LICENSE.md with MIT license under World Foundation (2026)
- Updated all READMEs to reference MIT license only
- Changed workspace license from 'MIT OR Apache-2.0' to 'MIT'
- Updated license sections in all 4 package READMEs:
- mobench-runner
- mobench-macros
- mobench-sdk
- mobench
- Bumped version to 0.1.3 for republication
Copyright (c) 2026 World Foundation
* chore: reset version to 0.1.0 for fresh release
Yanked all previous versions (0.1.0-0.1.3) from crates.io.
Starting fresh with proper:
- MIT license under World Foundation (2026)
- Comprehensive READMEs for all packages
- Consistent naming (mobench-runner instead of bench-runner)
This is the canonical first release.
* chore: use version 0.1.4 as canonical first release
Cannot reuse version 0.1.0 even after yanking.
Version 0.1.4 will be the canonical first release with:
- MIT license under World Foundation (2026)
- Comprehensive READMEs
- Proper naming (mobench-runner)
Versions 0.1.0-0.1.3 are yanked.
* docs: update CLAUDE.md to reflect SDK-first architecture and crates.io publication
- Update project overview with published packages (v0.1.4)
- Document recommended cargo mobench build workflow
- Mark scripts/ as legacy for repository development only
- Add SDK integration examples and Quick Start
- Reorganize file structure documentation
- Add template system documentation
* fix: address GitHub Advanced Security and Codex review findings
1. Add explicit workflow permissions (contents: read)
- Addresses GitHub Advanced Security CodeQL warnings
- Limits GITHUB_TOKEN permissions to read-only for CI workflow
- Reduces security risk by following principle of least privilege
2. Fix local smoke test for user benchmarks
- Only run local smoke test for sample_fns::* functions
- Skip gracefully for user-defined benchmarks
- Prevents 'unknown benchmark function' errors
- User benchmarks aren't linked into CLI binary (will run on device)
- Addresses Codex P1 review finding
Note: Skipped iOS certificate pinning (Semgrep finding) as the app
does not make network requests. Can be revisited if needed later.
* mobench: support repository structure and fix iOS IPA packaging
Updates CLI and SDK to work seamlessly with both SDK projects (bench-mobile/)
and repository structure (crates/sample-fns/), enabling full end-to-end testing
using only mobench commands.
Changes:
- AndroidBuilder/IosBuilder: Add find_crate_dir() to detect benchmark crate
in multiple locations (bench-mobile/ or crates/{crate_name}/)
- UniFFI binding generation: Make optional, use pre-existing bindings if
available, only require uniffi-bindgen CLI for fresh generation
- iOS IPA packaging: Complete rewrite from xcodebuild archive to simpler
xcodebuild build approach, with ad-hoc signing support for BrowserStack
testing (no Apple Developer account needed)
- BrowserStack XCUITest: Add only-testing parameter support to specify
test methods (required by BrowserStack API)
- iOS project: Add schemes configuration to project.yml for proper
xcodebuild support
Verified working:
- cargo mobench build --target android
- cargo mobench build --target ios
- cargo mobench package-ipa --method adhoc
- cargo mobench run (both Android and iOS on BrowserStack)
* mobench: add --fetch flag for CI-ready result retrieval
Implements automatic polling and result fetching for BrowserStack runs,
making the CLI fully CI-ready with one-command benchmark execution.
BrowserStack Client API:
- poll_build_completion(): Wait for build to finish with configurable timeout
- get_espresso_build_status() / get_xcuitest_build_status(): Check build status
- get_device_logs(): Fetch logs from specific device sessions
- extract_benchmark_results(): Parse benchmark JSON from logs
- wait_and_fetch_results(): Complete workflow (poll + fetch + extract)
CLI Integration:
- --fetch flag on 'run' command triggers automatic result fetching
- Merges benchmark_results into output JSON (device -> results map)
- Configurable timeout (--fetch-timeout-secs, default: 1800)
- Configurable poll interval (--fetch-poll-interval-secs, default: 10)
- Graceful error handling with warnings (command succeeds even if fetch fails)
Output Format Enhancement:
- RunSummary now includes optional benchmark_results field
- Results organized by device name
- Each device has array of benchmark results with samples, mean, min, max
Testing:
- 8 new comprehensive tests for result extraction and parsing
- Tests for BuildStatus conversion and deserialization
- Tests for JSON extraction from logs (single, multiple, invalid, missing)
- All tests passing (21 total in browserstack module)
Documentation:
- FETCH_RESULTS_GUIDE.md: Complete guide for --fetch usage
- BROWSERSTACK_CI_INTEGRATION.md: Programmatic API reference
- GitHub Actions examples with step summaries
- Error handling patterns and best practices
Example Usage:
cargo mobench run \
--target android \
--function sample_fns::fibonacci \
--iterations 30 \
--warmup 5 \
--devices "Google Pixel 7-13.0" \
--fetch \
--output results.json
This release makes mobench fully CI-ready with automatic result retrieval,
eliminating the need for manual log parsing or separate fetch commands.
* gitignore: exclude BrowserStack run artifacts and temp files
* mobench: print dashboard URL and result summary with --fetch
Improves CLI output when using --fetch to show:
- Dashboard URL immediately after scheduling (not just on error)
- Summary of benchmark results for each device
- Mean time in both nanoseconds and milliseconds
- Number of samples collected
- Dashboard URL again after successful fetch for easy access
Example output:
Waiting for build 88f8c5a... to complete...
Dashboard: https://app-automate.browserstack.com/dashboard/v2/builds/88f8c5a...
✓ Successfully fetched results from 1 device(s)
Device: Google Pixel 7-13.0
Benchmark 1: sample_fns::fibonacci
Mean: 1237000 ns (1.24 ms)
Samples: 30
View full results: https://app-automate.browserstack.com/...
Makes CI output more informative and actionable without requiring manual
JSON parsing or URL construction.
* docs: document BrowserStack metrics and performance monitoring
Adds comprehensive documentation on what device metrics BrowserStack
provides and what mobench currently captures.
Key points:
- BrowserStack does NOT provide built-in CPU/memory/battery profiling
- Performance metrics must be collected by your app code
- We currently capture: logs, videos, network traces, screenshots
- We extract: benchmark timing data from logs
- Future enhancement: Extract custom performance metrics from logs
Provides examples for collecting memory/CPU metrics on Android/iOS
and logging them as JSON for extraction.
References BrowserStack API documentation and platform-specific APIs
for memory profiling.
* feat(mobench): add performance metrics extraction (v0.1.5)
- Add performance metrics types (PerformanceSnapshot, MemoryMetrics, CpuMetrics, etc.)
- Implement extract_performance_metrics() to parse memory/CPU data from device logs
- Add wait_and_fetch_all_results() to fetch both benchmark and performance results
- Update RunSummary to include performance_metrics field
- Add comprehensive tests for performance metrics extraction
- Update CLI --fetch to display performance metrics alongside benchmark results
- Update BROWSERSTACK_METRICS.md to reflect new functionality
Performance metrics are automatically extracted when using --fetch flag if the app
logs them in JSON format with memory/cpu fields or type='performance'.
Example output format:
{
"memory": {"used_mb": 128.5, "max_mb": 512.0},
"cpu": {"usage_percent": 45.2}
}
* refactor: remove dead code and fix compiler warnings
- Remove unused `wait_and_fetch_results()` from browserstack.rs (superseded by `wait_and_fetch_all_results()`)
- Add `#[cfg(test)]` to `run_local_smoke()` in main.rs
- Remove unused iOS signing methods (`identity()`, `export_method()`, `create_export_options_plist()`)
- Remove unused imports (`std::io::Write`, `BenchSpec`, `run_closure`)
- Add explanatory comment for dual binary targets in Cargo.toml
This cleanup addresses all compiler warnings and removes 117 lines of dead code.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: build Android test APK and harden BrowserStack fetch
---------
Co-authored-by: tfe-app[bot] <200245884+tfe-app[bot]@users.noreply.github.com>
Co-authored-by: wld-terraform <infrastructure@toolsforhumanity.com>
Co-authored-by: dcbuilder.eth <dcbuilder@protonmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Update .github/workflows/relyance-sci.yml
* Add benchmark summaries, compare command, and CI polish (#5)
* Improve mobench fetch and iOS/Android builders
* Chore: align docs with markdownlint
* Refine rust-analyzer diagnostics
* Bump workspace version to 0.1.5
* Docs: refresh mobench testing and CLI guidance
Update docs to reflect current CLI usage, remove host demo references, and clarify local device workflows. Ignore Cursor project files and sync lockfile version entries.
* feat: add run summaries and CI artifacts
Add JSON/Markdown (optional CSV) summaries for mobench runs and wire CI to publish host + BrowserStack results.
* fix test
* feat: add compare reports and device tag filters
Add a mobench compare command plus device tag filtering from matrix configs, and publish benchmark summaries to CI job summaries. Refresh docs to cover compare usage and updated config examples.
* chore: clean up formatting in tests and bindgen
* address minor pr codex comments
* fix: treat BrowserStack passed builds as complete
Update polling to accept passed/completed build statuses and ignore run summary outputs in git. This prevents fetch timeouts after successful runs.
* Docs: align configs, devices, and rustdoc naming
Refresh markdown docs and rustdocs to use current mobench config names, BrowserStack device strings, and API references. Update codegen templates and examples to match mobench-sdk naming.
---------
Co-authored-by: dcbuilder.eth <dcbuilder@protonmail.com>
* Refactor mobench layout and refresh README
- split CLI entrypoint into library and cargo-mobench bin
- update workspace manifests and lockfile for crate changes
- rewrite README with current workflow and crate list
* Remove legacy bench-cli crates and update docs
Drop the unused bench-cli and bench-runner crates, update docs to reflect the current mobench-runner workflow, and adjust legacy scripts/comments to reference cargo mobench.
* Split examples into minimal and FFI variants
Simplify basic-benchmark to only show #[benchmark] usage and add a new ffi-benchmark example that contains the UniFFI types and entrypoint. Update workspace metadata and docs to reflect the new example layout.
* Remove legacy sample_fns UDL
Drop the unused UniFFI UDL file for sample-fns and update build script notes to reflect the proc-macro binding generation flow.
* Remove legacy scripts and update docs
Delete deprecated build scripts, switch CI and docs to cargo mobench commands, and refresh integration guidance for the new flow.
* Refresh docs for mobench build flow
Update CLAUDE, BUILD, and mobench-sdk README to remove script references, clarify the builder flow, and document the new examples.
* Improve repo root detection with ancestor search
The repo_root() function now walks up the directory tree looking for
marker files instead of relying on the compile-time manifest path.
This fixes cases where the CLI is run from subdirectories.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Bump version to 0.1.7 for release
Update workspace version and inter-crate dependencies.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add commit guidelines to CLAUDE.md
* Output mobile artifacts to target/mobench/ by default
- Add output_dir field to AndroidBuilder and IosBuilder
- Default to {project_root}/target/mobench/ for all mobile artifacts
- Add output_dir() builder method for customization
- Add --output-dir CLI argument to `cargo mobench build`
- Update all path references in builders to use output_dir
This keeps generated mobile artifacts inside target/, following Rust
conventions and preventing accidental commits of Android/iOS project files.
* Update docs for target/mobench/ output directory
- Update all path references from target/ios/ to target/mobench/ios/
- Update Android paths to target/mobench/android/
- Document --output-dir CLI flag
- Update troubleshooting sections with correct paths
* Add comprehensive docs.rs documentation
- Add extensive crate-level documentation to all four crates:
- mobench-sdk: Full SDK docs with examples, architecture, and best practices
- mobench-macros: #[benchmark] macro documentation with usage examples
- mobench-runner: Timing harness docs with runnable examples
- mobench: CLI documentation with command reference
- Document all public types with examples:
- BenchSpec, BenchSample, BenchReport, BenchError
- Target, BuildConfig, BuildProfile, BuildResult
- InitConfig and builder types
- Configure docs.rs metadata in all Cargo.toml files:
- Add documentation URLs
- Add maintenance badges
- Configure rustdoc-args for docs.rs builds
- Add serde_json dev-dependency to mobench-runner for doc tests
* Bump version to 0.1.8 for release
* Implement all IMPROVEMENTS.md tasks with enhanced DX
This commit implements all 11 developer experience improvements from
IMPROVEMENTS.md, making mobench significantly more user-friendly.
## Key Changes
### P0 - Critical (Tasks 1-3)
- Fix aws-lc-rs Android NDK incompatibility (ring backend)
- Fix workspace target directory detection (cargo metadata)
- Auto-generate project scaffolding during build
### P1 - High Priority (Tasks 4-6)
- Process template variables during build (TemplateContext)
- Improve uniffi-bindgen handling (local binary + fallback)
- Generate error handling code dynamically (generic catch)
### P2 - Medium Priority (Tasks 7-9)
- Add mobench.toml configuration file support
- Improve error messages with actionable suggestions
- Add --crate-path flag for custom crate locations
### P3 - Nice to Have (Tasks 10-11)
- Add --dry-run and --verbose CLI modes
- Auto-generate local.properties for Android
## Code Quality Improvements
- Extract shared utilities to builders/common.rs (DRY)
- Consistent error message formatting with:
- Clear description of what failed
- Context (commands, paths, exit status)
- Actionable fix suggestions
- Links to documentation
- Standardized path formatting using display()
## New Files
- crates/mobench/src/config.rs - Configuration file support
- crates/mobench-sdk/src/builders/common.rs - Shared utilities
- IMPROVEMENTS.md - Task tracking document
## Consolidation
- Merged mobench-runner crate into mobench-sdk
- Timing functionality now in mobench-sdk/src/timing.rs
* Fix iOS test failure in auto-build scaffolding
The test `ios_requires_artifacts_for_browserstack` was failing because
iOS project scaffolding was not being generated correctly during
auto-build for BrowserStack.
Root causes and fixes:
1. render_dir() was incorrectly joining prefix with file.path(), but
file.path() from include_dir already returns the full relative path.
Removed the prefix parameter entirely.
2. project.yml lacked .template extension, so template variables like
{{PROJECT_NAME_PASCAL}} were not being substituted. Renamed to
project.yml.template.
3. xcframework path in project.yml.template was wrong (../../target/ios/).
Fixed to ../{{LIBRARY_NAME}}.xcframework since the iOS project is at
target/mobench/ios/BenchRunner/.
4. ensure_ios_project now uses fixed "BenchRunner" for PROJECT_NAME_PASCAL
to match the template directory structure, while deriving LIBRARY_NAME
from the actual crate name.
All 37 tests now pass.
* Update documentation for consolidated crates and new features
README updates:
- Document mobench-runner consolidation into mobench-sdk
- Add mobench.toml configuration file documentation
- Document new CLI flags: --dry-run, --verbose, --crate-path
- Update all artifact paths to target/mobench/
- Add examples for new features
Rust doc comments:
- Add comprehensive module docs to builders/{mod,android,ios,common}.rs
- Document build pipelines, requirements, and examples
- Add dry-run mode documentation
- Note mobench-runner consolidation in timing.rs
docs.rs configuration:
- Add targets = ["x86_64-unknown-linux-gnu"] for docs.rs builds
- Add #![cfg_attr(docsrs, feature(doc_cfg))] attributes
- Add crates.io/docs.rs/license badges to crate roots
- Add #[doc(cfg(...))] annotations for feature-gated items
* Bump version to 0.1.9 for release
- Update workspace version from 0.1.8 to 0.1.9
- Update mobench-sdk dependency in mobench crate
- Update mobench-macros dependency in mobench-sdk crate
- All mobench-runner versions have been yanked on crates.io
* Remove IMPROVEMENTS.md after completing all tasks
* Fix all DX issues from mobench 0.1.9 testing
Critical bugs fixed (12):
- Bugs 1-5: Template variables (PROJECT_NAME, PACKAGE_NAME, LIBRARY_NAME,
PROJECT_NAME_PASCAL, APP_NAME) now properly substituted
- Bug 6: Added gradle.properties template with AndroidX settings
- Bug 7: Auto-generate Gradle wrapper if missing
- Bug 8: Fixed AGP version from 8.13.2 to 8.2.2
- Bug 9: Package name in Kotlin templates now uses {{PACKAGE_NAME}}
- Bug 10: Added x86_64-apple-ios target for Intel Mac simulators
- Bug 11: Fixed path handling by canonicalizing project root
- Bug 12: DEFAULT_FUNCTION now auto-detected from #[benchmark] functions
High severity issues fixed (8):
- Issue 1: Added post-template validation for unreplaced {{...}} patterns
- Issue 2: codesign_xcframework now returns Err on failure
- Issue 3: generate_xcode_project now returns Err on failure
- Issue 4: Missing native libraries always warn (not just verbose)
- Issue 5: Added validate_project_root() for early validation
- Issue 6: cargo metadata fallback now warns when used
- Issue 7: Kotlin catch block logs exceptions instead of swallowing
- Issue 8: Added validate_build_artifacts() post-build validation
Medium/Low issues fixed (4):
- Added .gitignore templates for Android and iOS
- Added README.md templates for Android and iOS
New files:
- templates/android/.gitignore
- templates/android/README.md
- templates/android/gradle.properties
- templates/ios/BenchRunner/.gitignore
- templates/ios/BenchRunner/README.md
* Update documentation for v0.1.9 and fix inconsistencies
- Fix all path references to use target/mobench/ as default output dir
- Update CLAUDE.md version reference to v0.1.9
- Fix PROJECT_PLAN.md to reflect mobench-runner consolidation into mobench-sdk
- Remove dead links to BROWSERSTACK_RUN_2.md (use BROWSERSTACK_METRICS.md)
- Fix all init-sdk references to use correct init command
- Fix duplicate command and step numbering in TESTING.md
- Update iOS artifact paths in BENCH_SDK_INTEGRATION.md
* Bump version to 0.1.10 for release
* Fix CI workflow paths to use target/mobench/ output directory
* Fix DX issues from 0.1.10 report
Android fixes:
- Add APK detection for both signed and unsigned builds
- Parse output-metadata.json for actual APK filename
- Add proguard-rules.pro template for release builds
- Update .gitignore to exclude jniLibs and uniffi bindings
iOS fixes:
- Sanitize bundle identifiers (remove hyphens/underscores)
- Framework bundle IDs now use alphanumeric chars only
- Add logging for config loading failures
- Update .gitignore to exclude xcodeproj, frameworks, bindings
Config fixes:
- Add logging for missing/invalid JSON keys in templates
- Android MainActivity logs warnings for missing config values
- iOS BenchRunnerFFI prints errors when JSON parsing fails
* Bump version to 0.1.11 for release
* Update CLAUDE.md version reference to 0.1.11
* Fix DX issues from 0.1.11 report
P0 fixes:
- Add testBuildType "release" to build.gradle templates
- Gradle now creates assembleReleaseAndroidTest task
P1 fixes:
- local.properties only uses ANDROID_HOME/ANDROID_SDK_ROOT env vars
- No longer probes filesystem for hardcoded SDK paths
- Kotlin files moved to correct package directory structure
P2 fixes:
- iOS bundle ID now uses app name: dev.world.benchmobile.BenchRunner
- No longer duplicates crate name in bundle ID
* Fix all DX issues from bug reports
Crate detection (P0):
- Check current directory Cargo.toml before nested paths
- Add read_package_name() helper for parsing Cargo.toml
- Search order: current dir → bench-mobile/ → crates/{name}/ → {name}/
- Add 10 new tests for crate detection logic
Error handling improvements:
- Add Log.e() calls for Android exception handlers
- Add print() statements for iOS config parsing failures
- Log config sources (intent, bench_spec.json, default)
- Show warnings when using fallback defaults
Cross-platform consistency:
- Standardize Android package names (remove underscores like iOS)
- Both platforms now use dev.world.benchmobile format
- Standardize version strings to 1.0.0 on both platforms
- Add 3 new consistency tests
Tests added:
- test_find_crate_dir_current_directory_is_crate
- test_find_crate_dir_nested_bench_mobile
- test_find_crate_dir_crates_subdir
- test_find_crate_dir_not_found
- test_find_crate_dir_explicit_crate_path
- test_read_package_name_standard
- test_read_package_name_with_single_quotes
- test_read_package_name_not_found
- test_read_package_name_no_package_section
- test_cross_platform_naming_consistency
- test_cross_platform_version_consistency
- test_bundle_id_prefix_consistency
* Remove IMPROVEMENTS.md after completing all tasks
* Fix all DX issues from mobench 0.1.9 testing
Critical bugs fixed (12):
- Bugs 1-5: Template variables (PROJECT_NAME, PACKAGE_NAME, LIBRARY_NAME,
PROJECT_NAME_PASCAL, APP_NAME) now properly substituted
- Bug 6: Added gradle.properties template with AndroidX settings
- Bug 7: Auto-generate Gradle wrapper if missing
- Bug 8: Fixed AGP version from 8.13.2 to 8.2.2
- Bug 9: Package name in Kotlin templates now uses {{PACKAGE_NAME}}
- Bug 10: Added x86_64-apple-ios target for Intel Mac simulators
- Bug 11: Fixed path handling by canonicalizing project root
- Bug 12: DEFAULT_FUNCTION now auto-detected from #[benchmark] functions
High severity issues fixed (8):
- Issue 1: Added post-template validation for unreplaced {{...}} patterns
- Issue 2: codesign_xcframework now returns Err on failure
- Issue 3: generate_xcode_project now returns Err on failure
- Issue 4: Missing native libraries always warn (not just verbose)
- Issue 5: Added validate_project_root() for early validation
- Issue 6: cargo metadata fallback now warns when used
- Issue 7: Kotlin catch block logs exceptions instead of swallowing
- Issue 8: Added validate_build_artifacts() post-build validation
Medium/Low issues fixed (4):
- Added .gitignore templates for Android and iOS
- Added README.md templates for Android and iOS
New files:
- templates/android/.gitignore
- templates/android/README.md
- templates/android/gradle.properties
- templates/ios/BenchRunner/.gitignore
- templates/ios/BenchRunner/README.md
* Update documentation for v0.1.9 and fix inconsistencies
- Fix all path references to use target/mobench/ as default output dir
- Update CLAUDE.md version reference to v0.1.9
- Fix PROJECT_PLAN.md to reflect mobench-runner consolidation into mobench-sdk
- Remove dead links to BROWSERSTACK_RUN_2.md (use BROWSERSTACK_METRICS.md)
- Fix all init-sdk references to use correct init command
- Fix duplicate command and step numbering in TESTING.md
- Update iOS artifact paths in BENCH_SDK_INTEGRATION.md
* Bump version to 0.1.10 for release
* Fix CI workflow paths to use target/mobench/ output directory
* Fix DX issues from 0.1.10 report
Android fixes:
- Add APK detection for both signed and unsigned builds
- Parse output-metadata.json for actual APK filename
- Add proguard-rules.pro template for release builds
- Update .gitignore to exclude jniLibs and uniffi bindings
iOS fixes:
- Sanitize bundle identifiers (remove hyphens/underscores)
- Framework bundle IDs now use alphanumeric chars only
- Add logging for config loading failures
- Update .gitignore to exclude xcodeproj, frameworks, bindings
Config fixes:
- Add logging for missing/invalid JSON keys in templates
- Android MainActivity logs warnings for missing config values
- iOS BenchRunnerFFI prints errors when JSON parsing fails
* Bump version to 0.1.11 for release
* Update CLAUDE.md version reference to 0.1.11
* Fix DX issues from 0.1.11 report
P0 fixes:
- Add testBuildType "release" to build.gradle templates
- Gradle now creates assembleReleaseAndroidTest task
P1 fixes:
- local.properties only uses ANDROID_HOME/ANDROID_SDK_ROOT env vars
- No longer probes filesystem for hardcoded SDK paths
- Kotlin files moved to correct package directory structure
P2 fixes:
- iOS bundle ID now uses app name: dev.world.benchmobile.BenchRunner
- No longer duplicates crate name in bundle ID
* Fix all DX issues from bug reports
Crate detection (P0):
- Check current directory Cargo.toml before nested paths
- Add read_package_name() helper for parsing Cargo.toml
- Search order: current dir → bench-mobile/ → crates/{name}/ → {name}/
- Add 10 new tests for crate detection logic
Error handling improvements:
- Add Log.e() calls for Android exception handlers
- Add print() statements for iOS config parsing failures
- Log config sources (intent, bench_spec.json, default)
- Show warnings when using fallback defaults
Cross-platform consistency:
- Standardize Android package names (remove underscores like iOS)
- Both platforms now use dev.world.benchmobile format
- Standardize version strings to 1.0.0 on both platforms
- Add 3 new consistency tests
Tests added:
- test_find_crate_dir_current_directory_is_crate
- test_find_crate_dir_nested_bench_mobile
- test_find_crate_dir_crates_subdir
- test_find_crate_dir_not_found
- test_find_crate_dir_explicit_crate_path
- test_read_package_name_standard
- test_read_package_name_with_single_quotes
- test_read_package_name_not_found
- test_read_package_name_no_package_section
- test_cross_platform_naming_consistency
- test_cross_platform_version_consistency
- test_bundle_id_prefix_consistency
* Add --release flag and package-xcuitest command
- Add --release flag to mobench run command for release builds
(reduces APK size from ~544MB debug to ~133MB release)
- Add mobench package-xcuitest command for iOS BrowserStack testing
- Add output_dir option to package-ipa command
- Update timing display format from μs to ms (or seconds if >=1000ms)
- Auto-package iOS artifacts in release mode when --release is set
* Update mobile timing display and documentation
- Update Android/iOS apps to display timing in ms (or seconds if >=1000ms)
- Update CLAUDE.md, TESTING.md, README with --release flag examples
- Document package-xcuitest command across all relevant docs
- Add release build recommendations for BrowserStack workflows
* Fix iOS XCUITest benchmark report gap and add video capture delay
iOS XCUITest was exiting in ~2 seconds without capturing benchmark data,
while Android properly waited and extracted full timing reports.
Changes:
- XCUITest now waits up to 5 minutes for benchmark completion (not 2 sec)
- Extract benchmark JSON via accessibility identifiers
- Output JSON with BENCH_REPORT_JSON_START/END markers for log parsing
- Add iOS-specific JSON extraction in fetch logic (handles NSLog prefixes)
- Both Android and iOS now hold the report screen for 5 seconds so
BrowserStack video recordings capture the benchmark results
Files updated:
- iOS XCUITest template and reference implementation
- iOS ContentView with completion indicators and JSON exposure
- iOS BenchRunnerFFI with JSON report generation
- BrowserStack fetch logic for iOS log parsing
- Android MainActivity with 5-second display hold
* Sync top-level templates with SDK templates
* Update documentation for --release flag and iOS XCUITest features
- Add --release flag to BrowserStack examples in README.md
- Update mobench-sdk README and rustdocs with --release recommendation
- Update mobench CLI rustdocs with --release flag
- Expand template READMEs with BrowserStack workflow and video capture info
- Document benchmark report capture mechanism (5-second delay, JSON markers)
* Fix iOS XCUITest BrowserStack detection and video capture
- Add Info.plist to XCUITest bundle to fix BrowserStack test detection
BrowserStack requires Info.plist with XCTContainsUITests=true to
identify and run tests; without it, builds are skipped with
"no tests detected"
- Add info: section to UITests target in project.yml templates
with proper bundle identifier (*.uitests suffix)
- Increase XCUITest delay from 0.5s to 5s after benchmark completion
to ensure BrowserStack video captures the results
- Update initial display text from "Running benchmark..." to
"Running benchmarks..." for better UX during video recording
* Remove resolved issue tracking docs
* Remove stale DX report doc
* Bump version to 0.1.12 for release
Changes in this release:
- Fix iOS XCUITest BrowserStack detection (Info.plist added to UITests target)
- Improve video capture for BrowserStack (5s delay for video evidence)
- Show "Running benchmarks..." text before results appear
- Sync top-level templates with SDK templates
- Various DX fixes
* Fix error message hints
* Fix iOS XCUITest test name mismatch with BrowserStack
Changed only-testing filter from testLaunchShowsBenchmarkReport to
testLaunchAndCaptureBenchmarkReport to match what BrowserStack parses
from the xctest bundle.
* Bump version to 0.1.13 for release
Fix iOS XCUITest test name mismatch with BrowserStack - changed
only-testing filter to use testLaunchAndCaptureBenchmarkReport.
* Modernize build flow and examples (#6)
* Refactor mobench layout and refresh README
- split CLI entrypoint into library and cargo-mobench bin
- update workspace manifests and lockfile for crate changes
- rewrite README with current workflow and crate list
* Remove legacy bench-cli crates and update docs
Drop the unused bench-cli and bench-runner crates, update docs to reflect the current mobench-runner workflow, and adjust legacy scripts/comments to reference cargo mobench.
* Split examples into minimal and FFI variants
Simplify basic-benchmark to only show #[benchmark] usage and add a new ffi-benchmark example that contains the UniFFI types and entrypoint. Update workspace metadata and docs to reflect the new example layout.
* Remove legacy sample_fns UDL
Drop the unused UniFFI UDL file for sample-fns and update build script notes to reflect the proc-macro binding generation flow.
* Remove legacy scripts and update docs
Delete deprecated build scripts, switch CI and docs to cargo mobench commands, and refresh integration guidance for the new flow.
* Refresh docs for mobench build flow
Update CLAUDE, BUILD, and mobench-sdk README to remove script references, clarify the builder flow, and document the new examples.
---------
Co-authored-by: dcbuilder.eth <dcbuilder@protonmail.com>
* DX Improvements v0.1.13: Setup/teardown, new commands, better errors (#9)
* Refactor mobench layout and refresh README
- split CLI entrypoint into library and cargo-mobench bin
- update workspace manifests and lockfile for crate changes
- rewrite README with current workflow and crate list
* Remove legacy bench-cli crates and update docs
Drop the unused bench-cli and bench-runner crates, update docs to reflect the current mobench-runner workflow, and adjust legacy scripts/comments to reference cargo mobench.
* Split examples into minimal and FFI variants
Simplify basic-benchmark to only show #[benchmark] usage and add a new ffi-benchmark example that contains the UniFFI types and entrypoint. Update workspace metadata and docs to reflect the new example layout.
* Remove legacy sample_fns UDL
Drop the unused UniFFI UDL file for sample-fns and update build script notes to reflect the proc-macro binding generation flow.
* Remove legacy scripts and update docs
Delete deprecated build scripts, switch CI and docs to cargo mobench commands, and refresh integration guidance for the new flow.
* Refresh docs for mobench build flow
Update CLAUDE, BUILD, and mobench-sdk README to remove script references, clarify the builder flow, and document the new examples.
* Improve repo root detection with ancestor search
The repo_root() function now walks up the directory tree looking for
marker files instead of relying on the compile-time manifest path.
This fixes cases where the CLI is run from subdirectories.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Bump version to 0.1.7 for release
Update workspace version and inter-crate dependencies.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add commit guidelines to CLAUDE.md
* Output mobile artifacts to target/mobench/ by default
- Add output_dir field to AndroidBuilder and IosBuilder
- Default to {project_root}/target/mobench/ for all mobile artifacts
- Add output_dir() builder method for customization
- Add --output-dir CLI argument to `cargo mobench build`
- Update all path references in builders to use output_dir
This keeps generated mobile artifacts inside target/, following Rust
conventions and preventing accidental commits of Android/iOS project files.
* Update docs for target/mobench/ output directory
- Update all path references from target/ios/ to target/mobench/ios/
- Update Android paths to target/mobench/android/
- Document --output-dir CLI flag
- Update troubleshooting sections with correct paths
* Add comprehensive docs.rs documentation
- Add extensive crate-level documentation to all four crates:
- mobench-sdk: Full SDK docs with examples, architecture, and best practices
- mobench-macros: #[benchmark] macro documentation with usage examples
- mobench-runner: Timing harness docs with runnable examples
- mobench: CLI documentation with command reference
- Document all public types with examples:
- BenchSpec, BenchSample, BenchReport, BenchError
- Target, BuildConfig, BuildProfile, BuildResult
- InitConfig and builder types
- Configure docs.rs metadata in all Cargo.toml files:
- Add documentation URLs
- Add maintenance badges
- Configure rustdoc-args for docs.rs builds
- Add serde_json dev-dependency to mobench-runner for doc tests
* Bump version to 0.1.8 for release
* Implement all IMPROVEMENTS.md tasks with enhanced DX
This commit implements all 11 developer experience improvements from
IMPROVEMENTS.md, making mobench significantly more user-friendly.
## Key Changes
### P0 - Critical (Tasks 1-3)
- Fix aws-lc-rs Android NDK incompatibility (ring backend)
- Fix workspace target directory detection (cargo metadata)
- Auto-generate project scaffolding during build
### P1 - High Priority (Tasks 4-6)
- Process template variables during build (TemplateContext)
- Improve uniffi-bindgen handling (local binary + fallback)
- Generate error handling code dynamically (generic catch)
### P2 - Medium Priority (Tasks 7-9)
- Add mobench.toml configuration file support
- Improve error messages with actionable suggestions
- Add --crate-path flag for custom crate locations
### P3 - Nice to Have (Tasks 10-11)
- Add --dry-run and --verbose CLI modes
- Auto-generate local.properties for Android
## Code Quality Improvements
- Extract shared utilities to builders/common.rs (DRY)
- Consistent error message formatting with:
- Clear description of what failed
- Context (commands, paths, exit status)
- Actionable fix suggestions
- Links to documentation
- Standardized path formatting using display()
## New Files
- crates/mobench/src/config.rs - Configuration file support
- crates/mobench-sdk/src/builders/common.rs - Shared utilities
- IMPROVEMENTS.md - Task tracking document
## Consolidation
- Merged mobench-runner crate into mobench-sdk
- Timing functionality now in mobench-sdk/src/timing.rs
* Fix iOS test failure in auto-build scaffolding
The test `ios_requires_artifacts_for_browserstack` was failing because
iOS project scaffolding was not being generated correctly during
auto-build for BrowserStack.
Root causes and fixes:
1. render_dir() was incorrectly joining prefix with file.path(), but
file.path() from include_dir already returns the full relative path.
Removed the prefix parameter entirely.
2. project.yml lacked .template extension, so template variables like
{{PROJECT_NAME_PASCAL}} were not being substituted. Renamed to
project.yml.template.
3. xcframework path in project.yml.template was wrong (../../target/ios/).
Fixed to ../{{LIBRARY_NAME}}.xcframework since the iOS project is at
target/mobench/ios/BenchRunner/.
4. ensure_ios_project now uses fixed "BenchRunner" for PROJECT_NAME_PASCAL
to match the template directory structure, while deriving LIBRARY_NAME
from the actual crate name.
All 37 tests now pass.
* Update documentation for consolidated crates and new features
README updates:
- Document mobench-runner consolidation into mobench-sdk
- Add mobench.toml configuration file documentation
- Document new CLI flags: --dry-run, --verbose, --crate-path
- Update all artifact paths to target/mobench/
- Add examples for new features
Rust doc comments:
- Add comprehensive module docs to builders/{mod,android,ios,common}.rs
- Document build pipelines, requirements, and examples
- Add dry-run mode documentation
- Note mobench-runner consolidation in timing.rs
docs.rs configuration:
- Add targets = ["x86_64-unknown-linux-gnu"] for docs.rs builds
- Add #![cfg_attr(docsrs, feature(doc_cfg))] attributes
- Add crates.io/docs.rs/license badges to crate roots
- Add #[doc(cfg(...))] annotations for feature-gated items
* Bump version to 0.1.9 for release
- Update workspace version from 0.1.8 to 0.1.9
- Update mobench-sdk dependency in mobench crate
- Update mobench-macros dependency in mobench-sdk crate
- All mobench-runner versions have been yanked on crates.io
* Remove IMPROVEMENTS.md after completing all tasks
* Fix all DX issues from mobench 0.1.9 testing
Critical bugs fixed (12):
- Bugs 1-5: Template variables (PROJECT_NAME, PACKAGE_NAME, LIBRARY_NAME,
PROJECT_NAME_PASCAL, APP_NAME) now properly substituted
- Bug 6: Added gradle.properties template with AndroidX settings
- Bug 7: Auto-generate Gradle wrapper if missing
- Bug 8: Fixed AGP version from 8.13.2 to 8.2.2
- Bug 9: Package name in Kotlin templates now uses {{PACKAGE_NAME}}
- Bug 10: Added x86_64-apple-ios target for Intel Mac simulators
- Bug 11: Fixed path handling by canonicalizing project root
- Bug 12: DEFAULT_FUNCTION now auto-detected from #[benchmark] functions
High severity issues fixed (8):
- Issue 1: Added post-template validation for unreplaced {{...}} patterns
- Issue 2: codesign_xcframework now returns Err on failure
- Issue 3: generate_xcode_project now returns Err on failure
- Issue 4: Missing native libraries always warn (not just verbose)
- Issue 5: Added validate_project_root() for early validation
- Issue 6: cargo metadata fallback now warns when used
- Issue 7: Kotlin catch block logs exceptions instead of swallowing
- Issue 8: Added validate_build_artifacts() post-build validation
Medium/Low issues fixed (4):
- Added .gitignore templates for Android and iOS
- Added README.md templates for Android and iOS
New files:
- templates/android/.gitignore
- templates/android/README.md
- templates/android/gradle.properties
- templates/ios/BenchRunner/.gitignore
- templates/ios/BenchRunner/README.md
* Update documentation for v0.1.9 and fix inconsistencies
- Fix all path references to use target/mobench/ as default output dir
- Update CLAUDE.md version reference to v0.1.9
- Fix PROJECT_PLAN.md to reflect mobench-runner consolidation into mobench-sdk
- Remove dead links to BROWSERSTACK_RUN_2.md (use BROWSERSTACK_METRICS.md)
- Fix all init-sdk references to use correct init command
- Fix duplicate command and step numbering in TESTING.md
- Update iOS artifact paths in BENCH_SDK_INTEGRATION.md
* Bump version to 0.1.10 for release
* Fix CI workflow paths to use target/mobench/ output directory
* Fix DX issues from 0.1.10 report
Android fixes:
- Add APK detection for both signed and unsigned builds
- Parse output-metadata.json for actual APK filename
- Add proguard-rules.pro template for release builds
- Update .gitignore to exclude jniLibs and uniffi bindings
iOS fixes:
- Sanitize bundle identifiers (remove hyphens/underscores)
- Framework bundle IDs now use alphanumeric chars only
- Add logging for config loading failures
- Update .gitignore to exclude xcodeproj, frameworks, bindings
Config fixes:
- Add logging for missing/invalid JSON keys in templates
- Android MainActivity logs warnings for missing config values
- iOS BenchRunnerFFI prints errors when JSON parsing fails
* Bump version to 0.1.11 for release
* Update CLAUDE.md version reference to 0.1.11
* Fix DX issues from 0.1.11 report
P0 fixes:
- Add testBuildType "release" to build.gradle templates
- Gradle now creates assembleReleaseAndroidTest task
P1 fixes:
- local.properties only uses ANDROID_HOME/ANDROID_SDK_ROOT env vars
- No longer probes filesystem for hardcoded SDK paths
- Kotlin files moved to correct package directory structure
P2 fixes:
- iOS bundle ID now uses app name: dev.world.benchmobile.BenchRunner
- No longer duplicates crate name in bundle ID
* Fix all DX issues from bug reports
Crate detection (P0):
- Check current directory Cargo.toml before nested paths
- Add read_package_name() helper for parsing Cargo.toml
- Search order: current dir → bench-mobile/ → crates/{name}/ → {name}/
- Add 10 new tests for crate detection logic
Error handling improvements:
- Add Log.e() calls for Android exception handlers
- Add print() statements for iOS config parsing failures
- Log config sources (intent, bench_spec.json, default)
- Show warnings when using fallback defaults
Cross-platform consistency:
- Standardize Android package names (remove underscores like iOS)
- Both platforms now use dev.world.benchmobile format
- Standardize version strings to 1.0.0 on both platforms
- Add 3 new consistency tests
Tests added:
- test_find_crate_dir_current_directory_is_crate
- test_find_crate_dir_nested_bench_mobile
- test_find_crate_dir_crates_subdir
- test_find_crate_dir_not_found
- test_find_crate_dir_explicit_crate_path
- test_read_package_name_standard
- test_read_package_name_with_single_quotes
- test_read_package_name_not_found
- test_read_package_name_no_package_section
- test_cross_platform_naming_consistency
- test_cross_platform_version_consistency
- test_bundle_id_prefix_consistency
* Add --release flag and package-xcuitest command
- Add --release flag to mobench run command for release builds
(reduces APK size from ~544MB debug to ~133MB release)
- Add mobench package-xcuitest command for iOS BrowserStack testing
- Add output_dir option to package-ipa command
- Update timing display format from μs to ms (or seconds if >=1000ms)
- Auto-package iOS artifacts in release mode when --release is set
* Update mobile timing display and documentation
- Update Android/iOS apps to display timing in ms (or seconds if >=1000ms)
- Update CLAUDE.md, TESTIN…
16de746 to
06be260
Compare
06be260 to
17f4793
Compare
33787e1 to
cb1f7b5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ffi_backend = "native-c-abi"mobench-sdknative JSON C ABI export macro and generated Android/iOS native runnersVerification
cargo clippy --all-targets -- -D warningscargo test --all --no-fail-fastcargo test -p mobench-sdk native_backend_runner_template -- --nocaptureCrates.io publish is still blocked locally by missing
CARGO_REGISTRY_TOKEN.