Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions .github/workflows/soak_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: Soak Test

on:
workflow_dispatch:
push:
branches: [ main ]

jobs:
run-soak-test:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read

steps:
- uses: actions/checkout@v4
with:
ref: main

- name: Checkout folder demo-apps/PetClinic-Android from test/e2e
run: |
git fetch origin test/e2e
git checkout origin/test/e2e -- demo-apps/PetClinic-Android

- name: Build Android SDK
run: |
./gradlew build -x :demo-apps:agent-demo:build -x :demo-apps:anr-demo:build -x :demo-apps:crash-demo:build

- name: Publish SDK to Maven Local (not a release)
run: |
unset CI && ./gradlew publishToMavenLocal

- name: Build Android App
run: |
cd demo-apps/PetClinic-Android
./gradlew assembleDebug assembleDebugAndroidTest

- name: Build Artifacts - App APK
uses: actions/upload-artifact@v4
with:
name: petclinic-android-app
path: demo-apps/PetClinic-Android/build/outputs/apk/debug/PetClinic-debug.apk
retention-days: 7

- name: Build Artifacts - Test APK
uses: actions/upload-artifact@v4
with:
name: petclinic-android-test
path: demo-apps/PetClinic-Android/build/outputs/apk/androidTest/debug/PetClinic-debug-androidTest.apk
retention-days: 7

- name: Build Artifacts - TestSpec
uses: actions/upload-artifact@v4
with:
name: petclinic-android-test-spec
path: demo-apps/PetClinic-Android/deviceFarmTestSpec.yml
retention-days: 7

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.SOAKTEST_OIDC_ROLE }}
aws-region: ${{ secrets.SOAKTEST_AWS_REGION }}
role-session-name: GitHubActions-SoakTest
audience: sts.amazonaws.com

- name: Upload TestSpec to S3
run: |
# Upload test specification
set -o pipefail && aws s3 cp ${{ github.workspace }}/demo-apps/PetClinic-Android/deviceFarmTestSpec.yml s3://${{ secrets.SOAKTEST_BUCKET_NAME }}/testSpec/testSpec_$(date +%Y%m%d_%H%M%S).yaml --region ${{ secrets.SOAKTEST_AWS_REGION }} --metadata "commitHash=${{ github.sha }}"
- name: Upload TestPackage to S3
run: |
# Upload test package
set -o pipefail && aws s3 cp ${{ github.workspace }}/demo-apps/PetClinic-Android/build/outputs/apk/androidTest/debug/PetClinic-debug-androidTest.apk s3://${{ secrets.SOAKTEST_BUCKET_NAME }}/tests/tests_$(date +%Y%m%d_%H%M%S).apk --region ${{ secrets.SOAKTEST_AWS_REGION }} --metadata "commitHash=${{ github.sha }}"
- name: Upload App to S3
run: |
# Upload app
set -o pipefail && aws s3 cp ${{ github.workspace }}/demo-apps/PetClinic-Android/build/outputs/apk/debug/PetClinic-debug.apk s3://${{ secrets.SOAKTEST_BUCKET_NAME }}/app/PetClinic_$(date +%Y%m%d_%H%M%S).apk --region ${{ secrets.SOAKTEST_AWS_REGION }} --metadata "commitHash=${{ github.sha }}"
3 changes: 3 additions & 0 deletions demo-apps/PetClinic-Android/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.kotlin
.gradle
build
26 changes: 26 additions & 0 deletions demo-apps/PetClinic-Android/Config
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package.PetClinic-Android = {
interfaces = (1.0);

# Use NoOpBuild. See https://w.amazon.com/index.php/BrazilBuildSystem/NoOpBuild
build-system = no-op;
build-tools = {
1.0 = {
NoOpBuild = 1.0;
};
};

# Use runtime-dependencies for when you want to bring in additional
# packages when deploying.
# Use dependencies instead if you intend for these dependencies to
# be exported to other packages that build against you.
dependencies = {
1.0 = {
};
};

runtime-dependencies = {
1.0 = {
};
};

};
56 changes: 56 additions & 0 deletions demo-apps/PetClinic-Android/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Pet Clinic Android App

A simple Android frontend for the [application-signals-demo](https://github.com/aws-observability/application-signals-demo) PetClinic application.

## Requirements

- Android Studio Hedgehog | 2023.1.1 or newer
- Android SDK 34
- Minimum SDK 24 (Android 7.0)

## Building

1. Open the project in Android Studio
2. Sync the project with Gradle files
3. Run the app on an emulator or physical device

## Instrumentation with AWS OTEL Android

### 1. Add Dependencies

Add to your app's `build.gradle.kts`:

```kotlin
dependencies {
implementation("software.amazon.opentelemetry.android:agent:1.0.0")

// For HTTP instrumentation
byteBuddy("io.opentelemetry.android.instrumentation:okhttp3-agent:0.15.0-alpha")
}
```

### 2. Create Configuration File

Create `app/src/main/res/raw/aws_config.json`:

```json
{
"aws": {
"region": "us-east-1",
"rumAppMonitorId": "<your-app-monitor-id>"
},
"otelResourceAttributes": {
"service.name": "PetClinic-Android",
"service.version": "1.0.0",
"deployment.environment": "production"
}
}
```

### 3. That's it!

The agent automatically initializes and collects telemetry including:
- Activity lifecycle events
- Network requests
- Crashes and ANRs
- UI performance metrics
104 changes: 104 additions & 0 deletions demo-apps/PetClinic-Android/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
plugins {
id("com.android.application") version "8.9.1"
id("org.jetbrains.kotlin.android") version "2.0.0"
id("org.jetbrains.kotlin.plugin.compose") version "2.0.0"
kotlin("plugin.serialization") version "2.1.21"
id("net.bytebuddy.byte-buddy-gradle-plugin") version "1.17.6"
}

android {
namespace = "com.example.petclinic"
compileSdk = 36

defaultConfig {
applicationId = "com.example.petclinic"
minSdk = 26
targetSdk = 35
versionCode = 1
versionName = "1.0"

testInstrumentationRunner = "com.example.petclinic.PetClinicTestRunner"
vectorDrawables {
useSupportLibrary = true
}
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
compose = true
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
}

dependencies {
// Instrument the app w/ ADOT Android
implementation("software.amazon.opentelemetry.android:core:1.0.0-beta")
implementation("io.opentelemetry:opentelemetry-exporter-otlp:1.47.0")
implementation("io.opentelemetry:opentelemetry-sdk:1.47.0")
// Automated HTTP client instrumentation with ByteBuddy (optional but recommended)
byteBuddy("io.opentelemetry.android.instrumentation:okhttp3-agent:0.15.0-alpha")
byteBuddy("io.opentelemetry.android.instrumentation:httpurlconnection-agent:0.15.0-alpha")

implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.4")
implementation("androidx.activity:activity-compose:1.9.1")
implementation("androidx.appcompat:appcompat:1.7.0")

// Compose BOM and dependencies
implementation(platform("androidx.compose:compose-bom:2024.06.00"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.material3:material3-window-size-class")

// Navigation
implementation("androidx.navigation:navigation-compose:2.7.7")
implementation("androidx.compose.material:material-icons-extended:1.6.8")

// ViewModel
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4")

// Networking
implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")

// JSON parsing
implementation("com.squareup.moshi:moshi:1.15.0")
implementation("com.squareup.moshi:moshi-kotlin:1.15.0")

// Coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")

// Image loading
implementation("io.coil-kt:coil-compose:2.6.0")

testImplementation("junit:junit:4.13.2")
testImplementation("com.squareup.okhttp3:mockwebserver:4.12.0")
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3")
androidTestImplementation("androidx.test.ext:junit:1.2.1")
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
androidTestImplementation(platform("androidx.compose:compose-bom:2024.06.00"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
}
29 changes: 29 additions & 0 deletions demo-apps/PetClinic-Android/collector.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
extensions:
exporters:
file/logs:
path: /etc/out/logs.txt
flush_interval: 5
file/traces:
path: /etc/out/traces.txt
flush_interval: 5
otlphttp:
traces_endpoint: "http://jaeger:4318/v1/traces"
debug:
verbosity: normal
debug/detailed:
verbosity: detailed
service:
pipelines:
traces:
receivers: [otlp]
exporters: [debug/detailed, file/traces, otlphttp]
logs:
receivers: [otlp]
exporters: [debug/detailed, file/logs]
19 changes: 19 additions & 0 deletions demo-apps/PetClinic-Android/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
services:
collector:
image: "otel/opentelemetry-collector-contrib@sha256:0076e6c250bef16968e29e8f94177b87b5a851c79ce14b270e657f5f655b9e04"
volumes:
- ./collector.yaml:/etc/demo-collector.yaml
- ./out:/etc/out
entrypoint: ["/otelcol-contrib"]
command: ["--config", "/etc/demo-collector.yaml"]
ports:
- "4317:4317" # OTLP gRPC
- "4318:4318" # OTLP HTTP

jaeger:
image: "jaegertracing/all-in-one:1.60@sha256:4fd2d70fa347d6a47e79fcb06b1c177e6079f92cba88b083153d56263082135e"
environment:
- COLLECTOR_OTLP_ENABLED=true
- COLLECTOR_OTLP_HTTP_HOST_PORT=0.0.0.0:4318
ports:
- "16686:16686" # UI
Loading
Loading