test: add minified emulator smoke test - #1972
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1972 +/- ##
=======================================
Coverage 65.67% 65.67%
=======================================
Files 172 172
Lines 3918 3918
Branches 442 442
=======================================
Hits 2573 2573
Misses 1213 1213
Partials 132 132 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Adds a new Android instrumented “minified release” smoke-test harness that boots a shrinked target app on an emulator, triggers a span export via OTLP/HTTP, and validates the exported protobuf payload. This provides higher-confidence coverage for R8 shrinking + real startup/export behavior in CI (connectedCheck), aligning with #1955.
Changes:
- Introduces a
:smoke-testAndroid test-only module with a bounded loopback HTTP server and an emulator test that decodes/validates OTLP trace export. - Adds a
:smoke-test-appminified/shrunk target app that initializes the Android agent and emits a single span on startup. - Updates build/coverage config to include the new modules and exclude the harness from Kover/Codecov where coverage can’t be collected.
PR Merge Tier: 3 (new test harness modules + CI-relevant build changes)
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| smoke-test/src/main/kotlin/io/opentelemetry/android/smoketest/OtlpHttpServer.kt | Adds a minimal loopback HTTP server to capture and return OTLP/HTTP requests for assertions. |
| smoke-test/src/main/kotlin/io/opentelemetry/android/smoketest/MinifiedAppSmokeTest.kt | Adds emulator instrumentation test that launches the minified app and validates exported trace protobuf content. |
| smoke-test/proguard-rules.pro | Test APK Proguard rules to keep needed runtime pieces and suppress irrelevant warnings. |
| smoke-test/build.gradle.kts | Defines com.android.test module configured to run only against the target’s minified release variant. |
| smoke-test-app/src/main/kotlin/io/opentelemetry/android/smoketestapp/SmokeTestActivity.kt | Target activity that initializes the agent, emits a span, and shuts down to trigger export. |
| smoke-test-app/src/main/AndroidManifest.xml | Declares the minified smoke-test target app and enables cleartext HTTP for loopback OTLP. |
| smoke-test-app/proguard-rules.pro | Target app Proguard rules to keep required runtime classes for instrumentation execution. |
| smoke-test-app/build.gradle.kts | Sets up the minified/shrunk release target app depending on :android-agent. |
| settings.gradle.kts | Includes the new :smoke-test and :smoke-test-app modules in the build. |
| core/consumer-rules.pro | Adds -dontwarn com.google.errorprone.annotations.** to prevent minifier warnings/failures in consumers. |
| codecov.yml | Excludes the smoke-test-app harness from Codecov since Kover can’t collect instrumented coverage. |
| CHANGELOG.md | Records the R8/Error Prone annotation minification fix for the next release notes. |
| build.gradle.kts | Excludes smoke-test app classes from Kover report aggregation. |
fractalwrench
left a comment
There was a problem hiding this comment.
Thanks for taking this on! I left a few comments inline around the test harness and assertions that follow on from discussion at the last SIG. The test case and app itself look fine to me
| val body: ByteArray, | ||
| ) | ||
|
|
||
| internal class OtlpHttpServer : Closeable { |
There was a problem hiding this comment.
I think OkHttp's mock webserver would help reduce boilerplate here. Alternatively I think @breedx-splk mentioned there were some existing test utilities for receiving OTLP export that are in opentelemetry-java?
There was a problem hiding this comment.
I tried MockWebServer with the minified release setup. Because OkHttp and Okio are shared between the target and test APKs, the independently minified APKs fail at runtime unless the target keeps all of okhttp3.** and okio.**. That would weaken the R8 and exporter coverage this test is intended to provide, so I kept the small loopback server here.
There was a problem hiding this comment.
Marking this as unresolved as I'd like Jason's input on this question. The test server itself might be fine although my instinct is that Mockwebserver will be simpler.
There are existing assertions for asserting against telemetry (although I can't remember the exact module where they live) and we should decide whether they're a good fit here.
There was a problem hiding this comment.
Sounds good, I’ll wait for Jason’s input before changing the test harness. @breedx-splk
There was a problem hiding this comment.
Hey @aranhave thanks for this, I think it's awesome. I mentioned earlier that the opentelemetry-java-instrumentation (and our Splunk distro of the same) have a pretty advanced/sophisticated set of smoke tests. These run a "fake backend" via docker (image is here https://github.com/open-telemetry/opentelemetry-java-instrumentation/pkgs/container/opentelemetry-java-instrumentation%2Fsmoke-test-fake-backend)...and then they run instrumented code and can then fetch back the exported data in json format to do assertions.
I think the challenge with this right now is that it looks to me like all of the components are running on the emulate device: the (junit) test code, the fake backend app (from this PR), and the minified and instrumented app. With that approach, it's not really possible to leverage the existing docker image.
Do we think it's important/wise to have everything running in the emulator? Can we set things up so that the test and the server run off-device, and only the app runs on device?
There was a problem hiding this comment.
Only the minified app needs to run on the emulator. Moving the server and orchestration to the host seems like the cleaner long-term direction and avoids the test/target APK dependency issue. The Java fake backend currently expects OTLP/gRPC while the Android agent uses OTLP/HTTP, so I’d keep this PR focused and follow up with a host-side harness once we choose between HTTP support or a collector bridge. Does that sound reasonable?
There was a problem hiding this comment.
For additional discussion: breedx-splk#7 (draft in my fork)
There was a problem hiding this comment.
Thanks for putting this together. The smoke test passed in the emulator job, so the host-side setup looks viable. The overall failure looks like check also runs smokeTest without an emulator. I’m happy to adapt #1972 to this structure and fix the task wiring if this is the direction we want.
aae9985 to
23e71ac
Compare
Adds a small minified release app that initializes the Android agent, records a span, and exports it over OTLP/HTTP. A separate emulator test captures the request with a bounded loopback server and verifies the exported protobuf payload.
The test runs through the existing
connectedCheckPR job and covers R8 shrinking, app startup, SDK initialization, and a real export.Test flow for clarity
flowchart TD A[connectedCheck] --> B[Start emulator smoke test] B --> C[Start bounded loopback server] B --> D[Launch minified release app] D --> E[Initialize Android agent] E --> F[Create one span] F -->|OTLP/HTTP protobuf| C C --> G[Decode payload and verify span]Resolves #1955