{"id":48805707,"url":"https://github.com/bbqsrc/vampire-rs","last_synced_at":"2026-04-14T05:03:29.069Z","repository":{"id":317584806,"uuid":"1068032491","full_name":"bbqsrc/vampire-rs","owner":"bbqsrc","description":"Run instrumented Rust integration tests on Android (with JNI compat)","archived":false,"fork":false,"pushed_at":"2025-10-07T21:23:34.000Z","size":108,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-02T07:50:58.050Z","etag":null,"topics":["android","jni","rust","testing"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bbqsrc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["bbqsrc"],"custom":"https://necessary.nu"}},"created_at":"2025-10-01T18:48:19.000Z","updated_at":"2025-10-07T21:23:37.000Z","dependencies_parsed_at":"2025-10-01T21:19:04.595Z","dependency_job_id":"a5f790dc-6edf-40e9-b88e-582d9e140cd7","html_url":"https://github.com/bbqsrc/vampire-rs","commit_stats":null,"previous_names":["bbqsrc/vampire-rs"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bbqsrc/vampire-rs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbqsrc%2Fvampire-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbqsrc%2Fvampire-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbqsrc%2Fvampire-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbqsrc%2Fvampire-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bbqsrc","download_url":"https://codeload.github.com/bbqsrc/vampire-rs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbqsrc%2Fvampire-rs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31782743,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T02:24:21.117Z","status":"ssl_error","status_checked_at":"2026-04-14T02:24:20.627Z","response_time":153,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","jni","rust","testing"],"created_at":"2026-04-14T05:02:48.012Z","updated_at":"2026-04-14T05:03:29.061Z","avatar_url":"https://github.com/bbqsrc.png","language":"Rust","funding_links":["https://github.com/sponsors/bbqsrc","https://necessary.nu"],"categories":[],"sub_categories":[],"readme":"# 🧛 Vampire\n\nA minimalist Android test framework for Rust that enables running Rust tests on Android devices through dynamic loading.\n\n[![License](https://img.shields.io/badge/license-MIT%2FApache--2.0-blue)](https://github.com/vampire-rs/vampire)\n\n## Why Vampire?\n\nNamed after the [vampire crab](https://en.wikipedia.org/wiki/Geosesarma_dennerle) (*Geosesarma dennerle*), a small purple crustacean native to Java. The name is a double pun: the crab lives in **Java** (the island), and this framework runs tests in **Java** (the Android platform). Like its namesake, Vampire dynamically loads into a host environment to do its work.\n\n## Quick Start\n\n1. **Install dependencies:**\n   ```bash\n   # Ensure you have Android SDK and NDK\n   export ANDROID_SDK_ROOT=/path/to/android/sdk\n   # Or on macOS, SDK is auto-detected from ~/Library/Android/sdk\n\n   # Install cargo-ndk\n   cargo install cargo-ndk\n   ```\n\n2. **Run tests:**\n   ```bash\n   # Run tests (builds + deploys + runs automatically)\n   cargo run --bin vampire -- test\n\n   # Show detailed test output including stdout/stderr\n   cargo run --bin vampire -- test --nocapture\n\n   # Force rebuild of APK even if already installed\n   cargo run --bin vampire -- test --force\n   ```\n\n   The `vampire` CLI automatically:\n   - ✅ Builds test library for Android (arm64-v8a)\n   - ✅ Compiles and builds host APK (only when needed)\n   - ✅ Installs APK to device (only if not already installed)\n   - ✅ Deploys native library to app's private storage\n   - ✅ Runs tests and displays results\n\n## Configuration\n\n### Android Permissions\n\nSpecify Android permissions your tests need in `Cargo.toml`:\n\n```toml\n[package.metadata.vampire]\npermissions = [\n    \"android.permission.INTERNET\",\n    \"android.permission.ACCESS_NETWORK_STATE\",\n    \"android.permission.WRITE_EXTERNAL_STORAGE\"\n]\n```\n\nThese permissions are automatically added to the generated AndroidManifest.xml when building the host APK.\n\n### Maven Dependencies\n\nIf your tests require Android libraries (JARs/AARs), specify them using Maven coordinates in a Cargo-style format:\n\n```toml\n[package.metadata.vampire.dependencies]\n\"org.chromium.net:cronet-api\" = \"141.7340.3\"\n\"androidx.annotation:annotation\" = \"1.7.0\"\n```\n\nYou can also use the object form for future extensibility:\n\n```toml\n[package.metadata.vampire.dependencies]\n\"org.chromium.net:cronet-api\" = { version = \"141.7340.3\" }\n```\n\nVampire will automatically:\n- Download the artifacts and their transitive dependencies from Maven Central and Google Maven\n- Resolve version conflicts using Maven's nearest-wins strategy\n- Extract classes from AAR files\n- Include them in the DEX compilation for the host APK\n- Cache downloads in `target/vampire/maven-cache/` for faster builds\n\nThis allows your Rust tests to interact with Java classes via JNI.\n\n## Build Script Setup\n\nIf you have Java sources that need to be compiled for Android (e.g., JNI callback classes), create a `build.rs` file in your package root:\n\n```rust\nfn main() {\n    vampire_build::configure();\n}\n```\n\nAdd `vampire-build` to your build dependencies in `Cargo.toml`:\n\n```toml\n[build-dependencies]\nvampire-build = { path = \"../vampire/vampire-build\" }  # or version from crates.io\n```\n\n### Java Source Directory\n\nBy default, `vampire-build` looks for Java sources in the `java/` directory of your package. Place your `.java` files there:\n\n```\nmy-package/\n├── Cargo.toml\n├── build.rs\n├── java/\n│   └── com/\n│       └── example/\n│           └── MyCallback.java\n└── src/\n    └── lib.rs\n```\n\n### Custom Configuration\n\nFor advanced use cases, you can customize the builder:\n\n```rust\nfn main() {\n    vampire_build::Builder::new()\n        .java_dir(\"src/main/java\")  // Custom Java source directory\n        .target_sdk(33)              // Target SDK version (default: 30)\n        .java_source(\"path/to/specific/File.java\")  // Add specific file\n        .configure();\n}\n```\n\n### What It Does\n\n`vampire-build` automatically:\n- Enables `cfg(vampire)` for conditional compilation\n- Detects Android target builds\n- Finds and compiles all `.java` files in your Java directory\n- Uses Java 8 compatibility for Android\n- Converts `.class` files to DEX format (required for Android)\n- Outputs `classes.dex` to `OUT_DIR`\n- Sets up proper `cargo:rerun-if-changed` triggers\n\n**Note:** DEX generation requires the Android SDK with build-tools installed. Set `ANDROID_SDK_ROOT` or `ANDROID_HOME` environment variable pointing to your SDK location.\n\n## Writing Tests\n\n### Basic Tests\n\n```rust\nuse vampire;\n\n// IMPORTANT: Re-export JNI_OnLoad so Java can initialize the runtime\npub use vampire::JNI_OnLoad;\n\n#[vampire::test]\nfn sync_test() {\n    assert_eq!(2 + 2, 4);\n}\n\n#[vampire::test]\nasync fn async_test() {\n    tokio::time::sleep(Duration::from_millis(100)).await;\n    // Your async test code\n}\n```\n\n### Expected Failures\n\nUse `should_panic` for tests that are expected to fail:\n\n```rust\n#[vampire::test(should_panic)]\nfn test_expected_failure() {\n    panic!(\"This failure is expected and will count as a pass\");\n}\n```\n\n### Android System Interaction\n\nAccess Android system properties and device information:\n\n```rust\nuse vampire::android;\n\n#[vampire::test]\nfn test_android_system() {\n    // Get Android version\n    let version = android::get_android_version()\n        .expect(\"Should get Android version\");\n\n    // Access app's private directory\n    let files_dir = android::get_files_dir()\n        .expect(\"Should get files directory\");\n\n    // Query device information\n    let model = android::get_device_model();\n    let is_emulator = android::is_emulator();\n\n    // Check system properties\n    let prop = android::get_system_property(\"ro.build.version.sdk\");\n}\n```\n\n## Cross-Platform Tests\n\nThe `#[vampire::test]` macro works on both Android and native platforms:\n\n```rust\n#[vampire::test]\nfn test_works_everywhere() {\n    assert_eq!(2 + 2, 4);\n}\n```\n\n- **On Android**: Runs through the instrumentation framework\n- **On native**: Expands to `#[test]` (or `#[tokio::test]` for async)\n\nRun native tests with `cargo test`, Android tests with `cargo run --bin vampire -- test`.\n\n### Tests in `tests/` Directory\n\nSince Android requires all tests in a single cdylib, you need to explicitly include `tests/` files in your `lib.rs`:\n\n```rust\n// In src/lib.rs\n#[cfg(vampire)]\n#[path = \"../tests\"]\nmod integration_tests {\n    #[path = \"my_test.rs\"]\n    mod my_test;\n\n    #[path = \"another_test.rs\"]\n    mod another_test;\n}\n```\n\nThe `vampire` CLI automatically sets `--cfg vampire` when building, so these modules are only included when building for Android tests.\n\n## Architecture\n\n- **Host APK**: Minimal instrumentation container that loads test libraries\n- **Test Library**: Your Rust tests compiled to `.so` with automatic JNI registration\n- **vampire CLI**: Coordinates building, deploying, and running tests\n\n## Components\n\n- `vampire-cli`: Main CLI tool (`cargo run --bin vampire`)\n- `vampire-macro`: Proc macro providing `#[vampire::test]`\n- `vampire`: Runtime library with JNI utilities and Android system access\n- `vampire-example`: Example test suite demonstrating features","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbbqsrc%2Fvampire-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbbqsrc%2Fvampire-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbbqsrc%2Fvampire-rs/lists"}