From 23c7971cafc85657ad1f274da446902612a39714 Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 16:01:43 -0600 Subject: [PATCH 01/31] use external mock RAC server --- .github/workflows/test.yaml | 48 +++++++++++++++++++ eppo/build.gradle | 5 +- .../cloud/eppo/android/EppoClientTest.java | 28 +++-------- 3 files changed, 57 insertions(+), 24 deletions(-) create mode 100644 .github/workflows/test.yaml diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 00000000..b81f0c25 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,48 @@ +name: Test + +on: + push: + branches: + - main + pull_request: + paths: + - '**/*' + +jobs: + test-android-sdk: + runs-on: macos-latest + env: + ANDROID_API_LEVEL: 33 + steps: + - name: Check out Java SDK + uses: actions/checkout@v3 + with: + repository: 'Eppo-exp/android-sdk' + - name: Set up JDK 11 + uses: actions/setup-java@v3 + with: + java-version: '11' + distribution: 'adopt' + - name: 'Set up GCP SDK' + uses: 'google-github-actions/setup-gcloud@v0' + - name: Restore gradle.properties + env: + MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }} + shell: bash + run: | + mkdir -p ~/.gradle/ + echo "GRADLE_USER_HOME=${HOME}/.gradle" >> $GITHUB_ENV + echo "MAVEN_USERNAME=${MAVEN_USERNAME}" > ~/.gradle/gradle.properties + echo "MAVEN_PASSWORD=${MAVEN_PASSWORD}" >> ~/.gradle/gradle.properties + - name: Set up test data + run: make test-data + - name: Spin up emulator + uses: ReactiveCircus/android-emulator-runner@v2 + with: + api-level: 33 + target: google_apis + arch: x86_64 + script: | + echo "Emulator started" + ./gradlew connectedCheck \ No newline at end of file diff --git a/eppo/build.gradle b/eppo/build.gradle index 52a25664..c0ee3e0e 100644 --- a/eppo/build.gradle +++ b/eppo/build.gradle @@ -63,17 +63,16 @@ ext.versions = [ "androidx_runner": "1.5.2", "gson": "2.9.1", "okhttp": "4.10.0", - "wiremock": "2.34.0" + "commonsio": "2.14.0" ] dependencies { testImplementation "junit:junit:${versions.junit}" - androidTestImplementation "com.github.tomakehurst:wiremock-jre8:${versions.wiremock}" androidTestImplementation "androidx.test.ext:junit:${versions.androidx_junit}" androidTestImplementation "androidx.test:core:${versions.androidx_core}" androidTestImplementation "androidx.test:runner:${versions.androidx_runner}" - + androidTestImplementation "commons-io:commons-io:${versions.commonsio}" implementation("com.google.code.gson:gson:${versions.gson}") implementation("com.squareup.okhttp3:okhttp:${versions.okhttp}") } diff --git a/eppo/src/androidTest/java/cloud/eppo/android/EppoClientTest.java b/eppo/src/androidTest/java/cloud/eppo/android/EppoClientTest.java index 0c0471e5..1fdfabea 100644 --- a/eppo/src/androidTest/java/cloud/eppo/android/EppoClientTest.java +++ b/eppo/src/androidTest/java/cloud/eppo/android/EppoClientTest.java @@ -9,8 +9,9 @@ import android.content.res.AssetManager; import androidx.test.core.app.ApplicationProvider; -import com.github.tomakehurst.wiremock.WireMockServer; -import com.github.tomakehurst.wiremock.client.WireMock; +import org.apache.commons.io.Charsets; +import org.apache.commons.io.IOUtils; + import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonDeserializationContext; @@ -18,8 +19,6 @@ import com.google.gson.JsonElement; import com.google.gson.JsonParseException; -import org.apache.commons.io.Charsets; -import org.apache.commons.io.IOUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -39,10 +38,8 @@ public class EppoClientTest { private static final String TAG = EppoClientTest.class.getSimpleName(); - private static final int TEST_PORT = 4001; - private static final String HOST = "http://localhost:" + TEST_PORT; - private static final String INVALID_HOST = "http://localhost:" + (TEST_PORT + 1); - private WireMockServer mockServer; + private static final String TEST_HOST = "http://us-central1-eppo-prod-312905.cloudfunctions.net/serveGithubRacTestFile"; + private static final String INVALID_HOST = "http://thisisabaddomainforthistest.com"; private Gson gson = new GsonBuilder() .registerTypeAdapter(EppoValue.class, new EppoValueAdapter()) .registerTypeAdapter(AssignmentValueType.class, new AssignmentValueTypeAdapter(AssignmentValueType.STRING)) @@ -156,10 +153,8 @@ public void onError(String errorMessage) { @Before public void init() { - setupMockRacServer(); - try { - initClient(HOST, true, true); + initClient(TEST_HOST, true, true); } catch (InterruptedException e) { e.printStackTrace(); fail(); @@ -168,18 +163,9 @@ public void init() { @After public void teardown() { - this.mockServer.stop(); deleteCacheFiles(); } - private void setupMockRacServer() { - this.mockServer = new WireMockServer(TEST_PORT); - this.mockServer.start(); - String racResponseJson = getMockRandomizedAssignmentResponse(); - this.mockServer.stubFor(WireMock.get(WireMock.urlMatching(".*randomized_assignment.*")) - .willReturn(WireMock.okJson(racResponseJson))); - } - @Test public void testAssignments() { runTestCases(); @@ -202,7 +188,7 @@ private void runTestCases() { @Test public void testCachedAssignments() { try { - initClient(HOST, false, true); // ensure cache is populated + initClient(TEST_HOST, false, true); // ensure cache is populated initClient(INVALID_HOST, false, false); // invalid port to force to use cache // wait for a bit since file is loaded asynchronously From 79fd4c1a6f88f2a1f0c90dde0e9dcb1ecd3eb095 Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 16:04:28 -0600 Subject: [PATCH 02/31] pass dns as emulator option --- .github/workflows/test.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index b81f0c25..341b681d 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -43,6 +43,7 @@ jobs: api-level: 33 target: google_apis arch: x86_64 + emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -dns-server 8.8.8.8 script: | echo "Emulator started" ./gradlew connectedCheck \ No newline at end of file From c74ac226d8bc782929c72c1ac9dcdb4271562c9f Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 16:23:19 -0600 Subject: [PATCH 03/31] upload report --- .github/workflows/test.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 341b681d..aa8d9382 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -46,4 +46,10 @@ jobs: emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -dns-server 8.8.8.8 script: | echo "Emulator started" - ./gradlew connectedCheck \ No newline at end of file + ./gradlew connectedCheck + - name: Upload logs + if: always() # This ensures the logs are uploaded even if previous step fails + uses: actions/upload-artifact@v2 + with: + name: report + path: /Users/runner/work/android-sdk/android-sdk/eppo/build/reports/androidTests/connected/index.html \ No newline at end of file From 606008ec2a6d7d7142ab23c079fdff5bf5020047 Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 16:47:05 -0600 Subject: [PATCH 04/31] allow writing to storage in manifest --- eppo/src/androidTest/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/eppo/src/androidTest/AndroidManifest.xml b/eppo/src/androidTest/AndroidManifest.xml index 629962c7..9496fc86 100644 --- a/eppo/src/androidTest/AndroidManifest.xml +++ b/eppo/src/androidTest/AndroidManifest.xml @@ -4,5 +4,6 @@ + \ No newline at end of file From f811529e04dc95b8ceffa7e48f7820c1e762ef5c Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 17:02:11 -0600 Subject: [PATCH 05/31] upload emulator logs too --- .github/workflows/test.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index aa8d9382..e15e5b19 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -47,8 +47,14 @@ jobs: script: | echo "Emulator started" ./gradlew connectedCheck + - name: Upload Failing Test Report Log + if: always() + uses: actions/upload-artifact@v2 + with: + name: emulator logs + path: app/emulator.log # path to where the log is - name: Upload logs - if: always() # This ensures the logs are uploaded even if previous step fails + if: always() uses: actions/upload-artifact@v2 with: name: report From 53e002552a6a733ab44dce89207e2f154fb17f08 Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 17:15:43 -0600 Subject: [PATCH 06/31] save logs --- .github/workflows/test.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index e15e5b19..14454f4a 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -46,7 +46,13 @@ jobs: emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -dns-server 8.8.8.8 script: | echo "Emulator started" - ./gradlew connectedCheck + script: | + adb logcat -c # clear logs + mkdir -p app/ # create directory + touch app/emulator.log # create log file + chmod 777 app/emulator.log # allow writing to log file + adb logcat EppoSDK:D "*:S" >> app/emulator.log & # pipe all logcat messages into log file as a background process + ./gradlew connectedCheck # run tests - name: Upload Failing Test Report Log if: always() uses: actions/upload-artifact@v2 From 6c1f6f34a219afd6cf9386c96617e42d6b5183d6 Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 17:27:04 -0600 Subject: [PATCH 07/31] fix dumb copy paste mistake --- .github/workflows/test.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 14454f4a..46910038 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -46,7 +46,6 @@ jobs: emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -dns-server 8.8.8.8 script: | echo "Emulator started" - script: | adb logcat -c # clear logs mkdir -p app/ # create directory touch app/emulator.log # create log file From cd8ec0d962763e7d2c6855b3c7afb2fd5cc7c168 Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 17:55:49 -0600 Subject: [PATCH 08/31] try a different way to pipe logs: --- .github/workflows/test.yaml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 46910038..10e5d893 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -48,16 +48,14 @@ jobs: echo "Emulator started" adb logcat -c # clear logs mkdir -p app/ # create directory - touch app/emulator.log # create log file - chmod 777 app/emulator.log # allow writing to log file - adb logcat EppoSDK:D "*:S" >> app/emulator.log & # pipe all logcat messages into log file as a background process + adb logcat > emulator_logs.txt & # pipe all logcat messages into log file as a background process ./gradlew connectedCheck # run tests - name: Upload Failing Test Report Log if: always() uses: actions/upload-artifact@v2 with: name: emulator logs - path: app/emulator.log # path to where the log is + path: emulator_logs.txt # path to where the log is - name: Upload logs if: always() uses: actions/upload-artifact@v2 From 1163a2da0a25779c49443d033e25ac93dbd5b9e1 Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 17:58:21 -0600 Subject: [PATCH 09/31] another log attempt --- .github/workflows/test.yaml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 10e5d893..44c18d09 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -46,10 +46,11 @@ jobs: emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -dns-server 8.8.8.8 script: | echo "Emulator started" - adb logcat -c # clear logs - mkdir -p app/ # create directory - adb logcat > emulator_logs.txt & # pipe all logcat messages into log file as a background process - ./gradlew connectedCheck # run tests + adb logcat -c # clear logs + touch app/emulator.log # create log file + chmod 777 app/emulator.log # allow writing to log file + adb logcat >> app/emulator.log & # pipe all logcat messages into log file as a background process + ./gradlew connectedCheck # run tests - name: Upload Failing Test Report Log if: always() uses: actions/upload-artifact@v2 From 3ecce645c0117e76a63d3031511a804534d8f1b9 Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 17:59:44 -0600 Subject: [PATCH 10/31] give test step an id --- .github/workflows/test.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 44c18d09..abe19317 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -38,6 +38,7 @@ jobs: - name: Set up test data run: make test-data - name: Spin up emulator + id: testing uses: ReactiveCircus/android-emulator-runner@v2 with: api-level: 33 @@ -52,13 +53,13 @@ jobs: adb logcat >> app/emulator.log & # pipe all logcat messages into log file as a background process ./gradlew connectedCheck # run tests - name: Upload Failing Test Report Log - if: always() + if: steps.testing.outcome != 'success' uses: actions/upload-artifact@v2 with: name: emulator logs path: emulator_logs.txt # path to where the log is - name: Upload logs - if: always() + if: steps.testing.outcome != 'success' uses: actions/upload-artifact@v2 with: name: report From 5d72c0cca2ed477bbad6baff981754e90ef86e6d Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 18:15:26 -0600 Subject: [PATCH 11/31] make the directory --- .github/workflows/test.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index abe19317..bbc3e87a 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -48,6 +48,7 @@ jobs: script: | echo "Emulator started" adb logcat -c # clear logs + mkdir -p app/ # create directory touch app/emulator.log # create log file chmod 777 app/emulator.log # allow writing to log file adb logcat >> app/emulator.log & # pipe all logcat messages into log file as a background process From aeec9252c53c1f8ed351c14f94ca92ad0f81d7f5 Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 18:28:16 -0600 Subject: [PATCH 12/31] always upload artifacts --- .github/workflows/test.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index bbc3e87a..ed79fad5 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -54,13 +54,13 @@ jobs: adb logcat >> app/emulator.log & # pipe all logcat messages into log file as a background process ./gradlew connectedCheck # run tests - name: Upload Failing Test Report Log - if: steps.testing.outcome != 'success' + if: always() uses: actions/upload-artifact@v2 with: name: emulator logs - path: emulator_logs.txt # path to where the log is + path: emulator_logs.txt - name: Upload logs - if: steps.testing.outcome != 'success' + if: always() uses: actions/upload-artifact@v2 with: name: report From d9ecd8171203ea723ea0e58501e01ed364c06ee0 Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 18:30:16 -0600 Subject: [PATCH 13/31] gradle cache --- .github/workflows/test.yaml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index ed79fad5..e8d176d4 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -35,9 +35,16 @@ jobs: echo "GRADLE_USER_HOME=${HOME}/.gradle" >> $GITHUB_ENV echo "MAVEN_USERNAME=${MAVEN_USERNAME}" > ~/.gradle/gradle.properties echo "MAVEN_PASSWORD=${MAVEN_PASSWORD}" >> ~/.gradle/gradle.properties + - name: Gradle cache + uses: actions/cache@v2 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: gradle-v2-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }}-${{ hashFiles('**/buildSrc/**/*.kt') }} - name: Set up test data run: make test-data - - name: Spin up emulator + - name: Spin up emulator and run tests id: testing uses: ReactiveCircus/android-emulator-runner@v2 with: From f2d0007edf8fdc342ddd67300656cf4d295c11aa Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 18:49:25 -0600 Subject: [PATCH 14/31] correct path --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index e8d176d4..5837a117 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -65,7 +65,7 @@ jobs: uses: actions/upload-artifact@v2 with: name: emulator logs - path: emulator_logs.txt + path: app/emulator_logs.txt - name: Upload logs if: always() uses: actions/upload-artifact@v2 From 3b9df9484ad057e4ca7a7a2cb3a6fe91c9374bf5 Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 19:14:48 -0600 Subject: [PATCH 15/31] try to copy logging from other PR --- .github/workflows/test.yaml | 44 ++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 5837a117..e8fb4bb3 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -18,13 +18,16 @@ jobs: uses: actions/checkout@v3 with: repository: 'Eppo-exp/android-sdk' + - name: Set up JDK 11 uses: actions/setup-java@v3 with: java-version: '11' distribution: 'adopt' + - name: 'Set up GCP SDK' uses: 'google-github-actions/setup-gcloud@v0' + - name: Restore gradle.properties env: MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }} @@ -36,14 +39,33 @@ jobs: echo "MAVEN_USERNAME=${MAVEN_USERNAME}" > ~/.gradle/gradle.properties echo "MAVEN_PASSWORD=${MAVEN_PASSWORD}" >> ~/.gradle/gradle.properties - name: Gradle cache - uses: actions/cache@v2 + uses: gradle/gradle-build-action@v2 + + - name: AVD cache + uses: actions/cache@v3 + id: avd-cache with: path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: gradle-v2-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }}-${{ hashFiles('**/buildSrc/**/*.kt') }} + ~/.android/avd/* + ~/.android/adb* + key: avd-${{ matrix.api-level }} + + - name: create AVD and generate snapshot for caching + if: steps.avd-cache.outputs.cache-hit != 'true' + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: ${{ matrix.api-level }} + profile: 29 # pixel 7 + target: google_apis + arch: x86_64 + force-avd-creation: false + emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: true + script: echo "Generated AVD snapshot for caching." + - name: Set up test data run: make test-data + - name: Spin up emulator and run tests id: testing uses: ReactiveCircus/android-emulator-runner@v2 @@ -54,18 +76,20 @@ jobs: emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -dns-server 8.8.8.8 script: | echo "Emulator started" - adb logcat -c # clear logs - mkdir -p app/ # create directory - touch app/emulator.log # create log file - chmod 777 app/emulator.log # allow writing to log file - adb logcat >> app/emulator.log & # pipe all logcat messages into log file as a background process - ./gradlew connectedCheck # run tests + adb logcat -c # clear logs + mkdir -p app/ # create directory + touch app/emulator.log # create log file + chmod 777 app/emulator.log # allow writing to log file + adb logcat EppoSDK:D "*:S" >> app/emulator.log & # pipe all logcat messages into log file as a background process + ./gradlew connectedCheck # run tests + - name: Upload Failing Test Report Log if: always() uses: actions/upload-artifact@v2 with: name: emulator logs path: app/emulator_logs.txt + - name: Upload logs if: always() uses: actions/upload-artifact@v2 From 7c864c4ad7537ee2166ac81dc7308fc0415b719a Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 19:24:53 -0600 Subject: [PATCH 16/31] specify API level --- .github/workflows/test.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index e8fb4bb3..88536250 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -48,14 +48,14 @@ jobs: path: | ~/.android/avd/* ~/.android/adb* - key: avd-${{ matrix.api-level }} + key: avd-33 - name: create AVD and generate snapshot for caching if: steps.avd-cache.outputs.cache-hit != 'true' uses: reactivecircus/android-emulator-runner@v2 with: - api-level: ${{ matrix.api-level }} - profile: 29 # pixel 7 + api-level: 33 + profile: 33 target: google_apis arch: x86_64 force-avd-creation: false From 5baef28307b2fd0ab04187089c8dccc7ef403cbc Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 19:45:33 -0600 Subject: [PATCH 17/31] correct log file name --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 88536250..e457bdc1 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -88,7 +88,7 @@ jobs: uses: actions/upload-artifact@v2 with: name: emulator logs - path: app/emulator_logs.txt + path: app/emulator.log - name: Upload logs if: always() From f4f53d570b6784016845c8ff1e226d8cb8b6a987 Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 20:06:11 -0600 Subject: [PATCH 18/31] log all the logs --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index e457bdc1..d4f2b326 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -80,7 +80,7 @@ jobs: mkdir -p app/ # create directory touch app/emulator.log # create log file chmod 777 app/emulator.log # allow writing to log file - adb logcat EppoSDK:D "*:S" >> app/emulator.log & # pipe all logcat messages into log file as a background process + adb logcat >> app/emulator.log & # pipe all logcat messages into log file as a background process ./gradlew connectedCheck # run tests - name: Upload Failing Test Report Log From 48df560450a4d06b4937e107e7f2808ea70029ee Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 20:13:38 -0600 Subject: [PATCH 19/31] use same log tag everywhere --- .github/workflows/test.yaml | 2 +- .../java/cloud/eppo/android/EppoClientTest.java | 1 - .../main/java/cloud/eppo/android/ConfigCacheFile.java | 1 - .../cloud/eppo/android/ConfigurationRequestor.java | 8 ++++---- .../java/cloud/eppo/android/ConfigurationStore.java | 11 +++++------ eppo/src/main/java/cloud/eppo/android/Constants.java | 5 +++++ eppo/src/main/java/cloud/eppo/android/EppoClient.java | 10 +++++----- 7 files changed, 20 insertions(+), 18 deletions(-) create mode 100644 eppo/src/main/java/cloud/eppo/android/Constants.java diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index d4f2b326..e457bdc1 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -80,7 +80,7 @@ jobs: mkdir -p app/ # create directory touch app/emulator.log # create log file chmod 777 app/emulator.log # allow writing to log file - adb logcat >> app/emulator.log & # pipe all logcat messages into log file as a background process + adb logcat EppoSDK:D "*:S" >> app/emulator.log & # pipe all logcat messages into log file as a background process ./gradlew connectedCheck # run tests - name: Upload Failing Test Report Log diff --git a/eppo/src/androidTest/java/cloud/eppo/android/EppoClientTest.java b/eppo/src/androidTest/java/cloud/eppo/android/EppoClientTest.java index 1fdfabea..e50338ef 100644 --- a/eppo/src/androidTest/java/cloud/eppo/android/EppoClientTest.java +++ b/eppo/src/androidTest/java/cloud/eppo/android/EppoClientTest.java @@ -37,7 +37,6 @@ import cloud.eppo.android.dto.adapters.EppoValueAdapter; public class EppoClientTest { - private static final String TAG = EppoClientTest.class.getSimpleName(); private static final String TEST_HOST = "http://us-central1-eppo-prod-312905.cloudfunctions.net/serveGithubRacTestFile"; private static final String INVALID_HOST = "http://thisisabaddomainforthistest.com"; private Gson gson = new GsonBuilder() diff --git a/eppo/src/main/java/cloud/eppo/android/ConfigCacheFile.java b/eppo/src/main/java/cloud/eppo/android/ConfigCacheFile.java index 813f7732..7cfc1b0d 100644 --- a/eppo/src/main/java/cloud/eppo/android/ConfigCacheFile.java +++ b/eppo/src/main/java/cloud/eppo/android/ConfigCacheFile.java @@ -10,7 +10,6 @@ import java.io.OutputStreamWriter; public class ConfigCacheFile { - private static final String TAG = ConfigCacheFile.class.getSimpleName(); static final String CACHE_FILE_NAME = "eppo-sdk-config-v2.json"; private final File filesDir; private final File cacheFile; diff --git a/eppo/src/main/java/cloud/eppo/android/ConfigurationRequestor.java b/eppo/src/main/java/cloud/eppo/android/ConfigurationRequestor.java index b628223e..6eeb2bb6 100644 --- a/eppo/src/main/java/cloud/eppo/android/ConfigurationRequestor.java +++ b/eppo/src/main/java/cloud/eppo/android/ConfigurationRequestor.java @@ -1,5 +1,7 @@ package cloud.eppo.android; +import static cloud.eppo.android.Constants.LoggingTag; + import android.util.Log; import com.google.gson.JsonIOException; @@ -10,8 +12,6 @@ import cloud.eppo.android.dto.FlagConfig; public class ConfigurationRequestor { - private static final String TAG = ConfigurationRequestor.class.getCanonicalName(); - private EppoHttpClient client; private ConfigurationStore configurationStore; @@ -29,7 +29,7 @@ public void onSuccess(Reader response) { try { configurationStore.setFlags(response); } catch (JsonSyntaxException | JsonIOException e) { - Log.e(TAG, "Error loading configuration response", e); + Log.e(LoggingTag, "Error loading configuration response", e); if (callback != null && !usedCache) { callback.onError("Unable to load configuration from network"); } @@ -43,7 +43,7 @@ public void onSuccess(Reader response) { @Override public void onFailure(String errorMessage) { - Log.e(TAG, errorMessage); + Log.e(LoggingTag, errorMessage); if (callback != null && !usedCache) { callback.onError(errorMessage); } diff --git a/eppo/src/main/java/cloud/eppo/android/ConfigurationStore.java b/eppo/src/main/java/cloud/eppo/android/ConfigurationStore.java index 04bbaf8f..8216292d 100644 --- a/eppo/src/main/java/cloud/eppo/android/ConfigurationStore.java +++ b/eppo/src/main/java/cloud/eppo/android/ConfigurationStore.java @@ -1,5 +1,7 @@ package cloud.eppo.android; +import static cloud.eppo.android.Constants.LoggingTag; + import android.app.Application; import android.content.SharedPreferences; import android.os.AsyncTask; @@ -22,9 +24,6 @@ import cloud.eppo.android.util.Utils; public class ConfigurationStore { - - private static final String TAG = ConfigurationStore.class.getSimpleName(); - private final Gson gson = new GsonBuilder() .registerTypeAdapter(EppoValue.class, new EppoValueAdapter()) .serializeNulls() @@ -54,7 +53,7 @@ public boolean loadFromCache(InitializationCallback callback) { flags = configResponse.getFlags(); } } catch (Exception e) { - Log.e(TAG, "Error loading from local cache", e); + Log.e(LoggingTag, "Error loading from local cache", e); cacheFile.delete(); if (callback != null) { @@ -117,7 +116,7 @@ private void writeConfigToFile(RandomizationConfigResponse config) { writer.close(); } } catch (Exception e) { - Log.e(TAG, "Unable to cache config to file", e); + Log.e(LoggingTag, "Unable to cache config to file", e); } }); } @@ -126,7 +125,7 @@ private FlagConfig getFlagFromSharedPrefs(String hashedFlagKey) { try { return gson.fromJson(sharedPrefs.getString(hashedFlagKey, null), FlagConfig.class); } catch (Exception e) { - Log.e(TAG, "Unable to load flag from prefs", e); + Log.e(LoggingTag, "Unable to load flag from prefs", e); } return null; } diff --git a/eppo/src/main/java/cloud/eppo/android/Constants.java b/eppo/src/main/java/cloud/eppo/android/Constants.java new file mode 100644 index 00000000..de18611a --- /dev/null +++ b/eppo/src/main/java/cloud/eppo/android/Constants.java @@ -0,0 +1,5 @@ +package cloud.eppo.android; + +public class Constants { + public static final String LoggingTag = "EppoSDK"; +} \ No newline at end of file diff --git a/eppo/src/main/java/cloud/eppo/android/EppoClient.java b/eppo/src/main/java/cloud/eppo/android/EppoClient.java index 244375ec..fc2d88cc 100644 --- a/eppo/src/main/java/cloud/eppo/android/EppoClient.java +++ b/eppo/src/main/java/cloud/eppo/android/EppoClient.java @@ -1,5 +1,6 @@ package cloud.eppo.android; +import static cloud.eppo.android.Constants.LoggingTag; import static cloud.eppo.android.util.Utils.validateNotEmptyOrNull; import android.app.ActivityManager; @@ -26,7 +27,6 @@ import cloud.eppo.android.util.Utils; public class EppoClient { - private static final String TAG = EppoClient.class.getCanonicalName(); private static final String DEFAULT_HOST = "https://fscdn.eppo.cloud"; private final ConfigurationRequestor requestor; @@ -103,7 +103,7 @@ private EppoValue getTypedAssignment(String subjectKey, String flagKey, SubjectA FlagConfig flag = requestor.getConfiguration(flagKey); if (flag == null) { - Log.w(TAG, "no configuration found for key: " + flagKey); + Log.w(LoggingTag, "no configuration found for key: " + flagKey); return null; } @@ -113,20 +113,20 @@ private EppoValue getTypedAssignment(String subjectKey, String flagKey, SubjectA } if (!flag.isEnabled()) { - Log.i(TAG, "no assigned variation because the experiment or feature flag is disabled: " + flagKey); + Log.i(LoggingTag, "no assigned variation because the experiment or feature flag is disabled: " + flagKey); return null; } TargetingRule rule = RuleEvaluator.findMatchingRule(subjectAttributes, flag.getRules()); if (rule == null) { - Log.i(TAG, "no assigned variation. The subject attributes did not match any targeting rules"); + Log.i(LoggingTag, "no assigned variation. The subject attributes did not match any targeting rules"); return null; } String allocationKey = rule.getAllocationKey(); Allocation allocation = flag.getAllocations().get(allocationKey); if (!isInExperimentSample(subjectKey, flagKey, flag.getSubjectShards(), allocation.getPercentExposure())) { - Log.i(TAG, "no assigned variation. The subject is not part of the sample population"); + Log.i(LoggingTag, "no assigned variation. The subject is not part of the sample population"); return null; } From b6173dbed906f0176cc5f46757c74b07659e639f Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 20:29:17 -0600 Subject: [PATCH 20/31] change sleep and add additional logs --- .../cloud/eppo/android/EppoClientTest.java | 18 +++++++----------- .../cloud/eppo/android/ConfigurationStore.java | 3 +++ 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/eppo/src/androidTest/java/cloud/eppo/android/EppoClientTest.java b/eppo/src/androidTest/java/cloud/eppo/android/EppoClientTest.java index e50338ef..6d2f54ee 100644 --- a/eppo/src/androidTest/java/cloud/eppo/android/EppoClientTest.java +++ b/eppo/src/androidTest/java/cloud/eppo/android/EppoClientTest.java @@ -150,16 +150,6 @@ public void onError(String errorMessage) { lock.await(2000, TimeUnit.MILLISECONDS); } - @Before - public void init() { - try { - initClient(TEST_HOST, true, true); - } catch (InterruptedException e) { - e.printStackTrace(); - fail(); - } - } - @After public void teardown() { deleteCacheFiles(); @@ -167,6 +157,11 @@ public void teardown() { @Test public void testAssignments() { + try { + initClient(TEST_HOST, true, true); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } runTestCases(); } @@ -188,11 +183,12 @@ private void runTestCases() { public void testCachedAssignments() { try { initClient(TEST_HOST, false, true); // ensure cache is populated - initClient(INVALID_HOST, false, false); // invalid port to force to use cache // wait for a bit since file is loaded asynchronously System.out.println("Sleeping for a bit to wait for cache population to complete"); Thread.sleep(1000); + + initClient(INVALID_HOST, false, false); // invalid port to force to use cache } catch (Exception e) { fail(); } diff --git a/eppo/src/main/java/cloud/eppo/android/ConfigurationStore.java b/eppo/src/main/java/cloud/eppo/android/ConfigurationStore.java index 8216292d..63d54d55 100644 --- a/eppo/src/main/java/cloud/eppo/android/ConfigurationStore.java +++ b/eppo/src/main/java/cloud/eppo/android/ConfigurationStore.java @@ -41,10 +41,12 @@ public ConfigurationStore(Application application) { public boolean loadFromCache(InitializationCallback callback) { if (flags != null || !cacheFile.exists()) { + Log.d(LoggingTag, "Not loading from cache ("+(flags == null ? "null flags" : "non-null flags")+")"); return false; } AsyncTask.execute(() -> { + Log.d(LoggingTag, "Loading from cache"); try { synchronized (cacheFile) { InputStreamReader reader = cacheFile.getInputReader(); @@ -52,6 +54,7 @@ public boolean loadFromCache(InitializationCallback callback) { reader.close(); flags = configResponse.getFlags(); } + Log.d(LoggingTag, "Cache loaded successfully"); } catch (Exception e) { Log.e(LoggingTag, "Error loading from local cache", e); cacheFile.delete(); From e95b85738df512cbc269d83dbaf5d484ad68f0bc Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 20:34:58 -0600 Subject: [PATCH 21/31] some more logs --- .../src/main/java/cloud/eppo/android/EppoHttpClient.java | 9 ++++++--- .../eppo/android/dto/adapters/EppoValueAdapter.java | 4 +++- .../java/cloud/eppo/androidexample/EppoApplication.java | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/eppo/src/main/java/cloud/eppo/android/EppoHttpClient.java b/eppo/src/main/java/cloud/eppo/android/EppoHttpClient.java index 4e744bea..3207d07e 100644 --- a/eppo/src/main/java/cloud/eppo/android/EppoHttpClient.java +++ b/eppo/src/main/java/cloud/eppo/android/EppoHttpClient.java @@ -1,5 +1,7 @@ package cloud.eppo.android; +import static cloud.eppo.android.Constants.LoggingTag; + import android.util.Log; import java.io.IOException; @@ -41,6 +43,7 @@ public void get(String path, RequestCallback callback) { @Override public void onResponse(Call call, Response response) { if (response.isSuccessful()) { + Log.d(LoggingTag, "Fetch successfull"); callback.onSuccess(response.body().charStream()); } else { switch (response.code()) { @@ -49,9 +52,9 @@ public void onResponse(Call call, Response response) { break; default: if (BuildConfig.DEBUG) { - Log.e(EppoHttpClient.class.getCanonicalName(), "Fetch failed with status code: " + response.code()); + Log.e(LoggingTag, "Fetch failed with status code: " + response.code()); } - callback.onFailure("Unable to fetch from URL"); + callback.onFailure("Bad response from URL "+httpUrl); } } response.close(); @@ -62,7 +65,7 @@ public void onFailure(Call call, IOException e) { if (BuildConfig.DEBUG) { e.printStackTrace(); } - callback.onFailure("Unable to fetch from URL"); + callback.onFailure("Unable to fetch from URL "+httpUrl); } }); } diff --git a/eppo/src/main/java/cloud/eppo/android/dto/adapters/EppoValueAdapter.java b/eppo/src/main/java/cloud/eppo/android/dto/adapters/EppoValueAdapter.java index 7488ae53..2417dc59 100644 --- a/eppo/src/main/java/cloud/eppo/android/dto/adapters/EppoValueAdapter.java +++ b/eppo/src/main/java/cloud/eppo/android/dto/adapters/EppoValueAdapter.java @@ -1,5 +1,7 @@ package cloud.eppo.android.dto.adapters; +import static cloud.eppo.android.Constants.LoggingTag; + import android.util.Log; import com.google.gson.JsonArray; @@ -28,7 +30,7 @@ public EppoValue deserialize(JsonElement json, Type typeOfT, JsonDeserialization try { array.add(element.getAsString()); } catch (Exception e) { - Log.e(EppoValueAdapter.class.getCanonicalName(), "only Strings are supported"); + Log.e(LoggingTag, "only Strings are supported"); } } return EppoValue.valueOf(array); diff --git a/example/src/main/java/cloud/eppo/androidexample/EppoApplication.java b/example/src/main/java/cloud/eppo/androidexample/EppoApplication.java index 79c145f6..ba3bb952 100644 --- a/example/src/main/java/cloud/eppo/androidexample/EppoApplication.java +++ b/example/src/main/java/cloud/eppo/androidexample/EppoApplication.java @@ -17,7 +17,7 @@ public void onCreate() { .application(this) .apiKey(API_KEY) .assignmentLogger(assignment -> { - Log.d(EppoApplication.class.getSimpleName(), assignment.getExperiment() + "-> subject: " + assignment.getSubject() + " assigned to " + assignment.getExperiment()); + Log.d(TAG, assignment.getExperiment() + "-> subject: " + assignment.getSubject() + " assigned to " + assignment.getExperiment()); }) .callback(new InitializationCallback() { @Override From 89ba2612032a69f045abca0ea311b70f84dc306d Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 20:50:38 -0600 Subject: [PATCH 22/31] include DNS in cache --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index e457bdc1..6474534b 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -59,7 +59,7 @@ jobs: target: google_apis arch: x86_64 force-avd-creation: false - emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -dns-server 8.8.8.8 disable-animations: true script: echo "Generated AVD snapshot for caching." From b27b2e225701158d3eb6ef3638d6f19de1040926 Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 20:51:11 -0600 Subject: [PATCH 23/31] skip caching for now --- .github/workflows/test.yaml | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 6474534b..8e20bbd9 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -41,28 +41,6 @@ jobs: - name: Gradle cache uses: gradle/gradle-build-action@v2 - - name: AVD cache - uses: actions/cache@v3 - id: avd-cache - with: - path: | - ~/.android/avd/* - ~/.android/adb* - key: avd-33 - - - name: create AVD and generate snapshot for caching - if: steps.avd-cache.outputs.cache-hit != 'true' - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: 33 - profile: 33 - target: google_apis - arch: x86_64 - force-avd-creation: false - emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -dns-server 8.8.8.8 - disable-animations: true - script: echo "Generated AVD snapshot for caching." - - name: Set up test data run: make test-data From 9e92243a87db9029995c19555b9ad940f5201c70 Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Wed, 25 Oct 2023 21:30:35 -0600 Subject: [PATCH 24/31] remove another gradle caching thing --- .github/workflows/test.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 8e20bbd9..af2fa439 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -38,8 +38,6 @@ jobs: echo "GRADLE_USER_HOME=${HOME}/.gradle" >> $GITHUB_ENV echo "MAVEN_USERNAME=${MAVEN_USERNAME}" > ~/.gradle/gradle.properties echo "MAVEN_PASSWORD=${MAVEN_PASSWORD}" >> ~/.gradle/gradle.properties - - name: Gradle cache - uses: gradle/gradle-build-action@v2 - name: Set up test data run: make test-data From 1660271a15e281d264df30507827dc95c877712f Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Thu, 26 Oct 2023 13:36:14 -0600 Subject: [PATCH 25/31] adjust log tag --- .../java/cloud/eppo/android/EppoClientTest.java | 1 - .../eppo/android/ConfigurationRequestor.java | 8 +++++--- .../cloud/eppo/android/ConfigurationStore.java | 17 ++++++++++------- .../main/java/cloud/eppo/android/Constants.java | 5 ----- .../java/cloud/eppo/android/EppoClient.java | 11 ++++++----- .../java/cloud/eppo/android/EppoHttpClient.java | 8 +++++--- .../android/dto/adapters/EppoValueAdapter.java | 7 ++++--- .../java/cloud/eppo/android/util/Utils.java | 6 ++++-- 8 files changed, 34 insertions(+), 29 deletions(-) delete mode 100644 eppo/src/main/java/cloud/eppo/android/Constants.java diff --git a/eppo/src/androidTest/java/cloud/eppo/android/EppoClientTest.java b/eppo/src/androidTest/java/cloud/eppo/android/EppoClientTest.java index 6d2f54ee..11a102d2 100644 --- a/eppo/src/androidTest/java/cloud/eppo/android/EppoClientTest.java +++ b/eppo/src/androidTest/java/cloud/eppo/android/EppoClientTest.java @@ -20,7 +20,6 @@ import com.google.gson.JsonParseException; import org.junit.After; -import org.junit.Before; import org.junit.Test; import java.io.File; diff --git a/eppo/src/main/java/cloud/eppo/android/ConfigurationRequestor.java b/eppo/src/main/java/cloud/eppo/android/ConfigurationRequestor.java index 6eeb2bb6..06d335b5 100644 --- a/eppo/src/main/java/cloud/eppo/android/ConfigurationRequestor.java +++ b/eppo/src/main/java/cloud/eppo/android/ConfigurationRequestor.java @@ -1,6 +1,6 @@ package cloud.eppo.android; -import static cloud.eppo.android.Constants.LoggingTag; +import static cloud.eppo.android.util.Utils.logTag; import android.util.Log; @@ -12,6 +12,8 @@ import cloud.eppo.android.dto.FlagConfig; public class ConfigurationRequestor { + private static final String TAG = logTag(ConfigurationRequestor.class); + private EppoHttpClient client; private ConfigurationStore configurationStore; @@ -29,7 +31,7 @@ public void onSuccess(Reader response) { try { configurationStore.setFlags(response); } catch (JsonSyntaxException | JsonIOException e) { - Log.e(LoggingTag, "Error loading configuration response", e); + Log.e(TAG, "Error loading configuration response", e); if (callback != null && !usedCache) { callback.onError("Unable to load configuration from network"); } @@ -43,7 +45,7 @@ public void onSuccess(Reader response) { @Override public void onFailure(String errorMessage) { - Log.e(LoggingTag, errorMessage); + Log.e(TAG, errorMessage); if (callback != null && !usedCache) { callback.onError(errorMessage); } diff --git a/eppo/src/main/java/cloud/eppo/android/ConfigurationStore.java b/eppo/src/main/java/cloud/eppo/android/ConfigurationStore.java index 63d54d55..df5ad5db 100644 --- a/eppo/src/main/java/cloud/eppo/android/ConfigurationStore.java +++ b/eppo/src/main/java/cloud/eppo/android/ConfigurationStore.java @@ -1,6 +1,6 @@ package cloud.eppo.android; -import static cloud.eppo.android.Constants.LoggingTag; +import static cloud.eppo.android.util.Utils.logTag; import android.app.Application; import android.content.SharedPreferences; @@ -24,6 +24,9 @@ import cloud.eppo.android.util.Utils; public class ConfigurationStore { + + private static final String TAG = logTag(ConfigurationStore.class); + private final Gson gson = new GsonBuilder() .registerTypeAdapter(EppoValue.class, new EppoValueAdapter()) .serializeNulls() @@ -41,12 +44,12 @@ public ConfigurationStore(Application application) { public boolean loadFromCache(InitializationCallback callback) { if (flags != null || !cacheFile.exists()) { - Log.d(LoggingTag, "Not loading from cache ("+(flags == null ? "null flags" : "non-null flags")+")"); + Log.d(TAG, "Not loading from cache ("+(flags == null ? "null flags" : "non-null flags")+")"); return false; } AsyncTask.execute(() -> { - Log.d(LoggingTag, "Loading from cache"); + Log.d(TAG, "Loading from cache"); try { synchronized (cacheFile) { InputStreamReader reader = cacheFile.getInputReader(); @@ -54,9 +57,9 @@ public boolean loadFromCache(InitializationCallback callback) { reader.close(); flags = configResponse.getFlags(); } - Log.d(LoggingTag, "Cache loaded successfully"); + Log.d(TAG, "Cache loaded successfully"); } catch (Exception e) { - Log.e(LoggingTag, "Error loading from local cache", e); + Log.e(TAG, "Error loading from local cache", e); cacheFile.delete(); if (callback != null) { @@ -119,7 +122,7 @@ private void writeConfigToFile(RandomizationConfigResponse config) { writer.close(); } } catch (Exception e) { - Log.e(LoggingTag, "Unable to cache config to file", e); + Log.e(TAG, "Unable to cache config to file", e); } }); } @@ -128,7 +131,7 @@ private FlagConfig getFlagFromSharedPrefs(String hashedFlagKey) { try { return gson.fromJson(sharedPrefs.getString(hashedFlagKey, null), FlagConfig.class); } catch (Exception e) { - Log.e(LoggingTag, "Unable to load flag from prefs", e); + Log.e(TAG, "Unable to load flag from prefs", e); } return null; } diff --git a/eppo/src/main/java/cloud/eppo/android/Constants.java b/eppo/src/main/java/cloud/eppo/android/Constants.java deleted file mode 100644 index de18611a..00000000 --- a/eppo/src/main/java/cloud/eppo/android/Constants.java +++ /dev/null @@ -1,5 +0,0 @@ -package cloud.eppo.android; - -public class Constants { - public static final String LoggingTag = "EppoSDK"; -} \ No newline at end of file diff --git a/eppo/src/main/java/cloud/eppo/android/EppoClient.java b/eppo/src/main/java/cloud/eppo/android/EppoClient.java index fc2d88cc..1339b21f 100644 --- a/eppo/src/main/java/cloud/eppo/android/EppoClient.java +++ b/eppo/src/main/java/cloud/eppo/android/EppoClient.java @@ -1,6 +1,6 @@ package cloud.eppo.android; -import static cloud.eppo.android.Constants.LoggingTag; +import static cloud.eppo.android.util.Utils.logTag; import static cloud.eppo.android.util.Utils.validateNotEmptyOrNull; import android.app.ActivityManager; @@ -27,6 +27,7 @@ import cloud.eppo.android.util.Utils; public class EppoClient { + private static final String TAG = logTag(EppoClient.class); private static final String DEFAULT_HOST = "https://fscdn.eppo.cloud"; private final ConfigurationRequestor requestor; @@ -103,7 +104,7 @@ private EppoValue getTypedAssignment(String subjectKey, String flagKey, SubjectA FlagConfig flag = requestor.getConfiguration(flagKey); if (flag == null) { - Log.w(LoggingTag, "no configuration found for key: " + flagKey); + Log.w(TAG, "no configuration found for key: " + flagKey); return null; } @@ -113,20 +114,20 @@ private EppoValue getTypedAssignment(String subjectKey, String flagKey, SubjectA } if (!flag.isEnabled()) { - Log.i(LoggingTag, "no assigned variation because the experiment or feature flag is disabled: " + flagKey); + Log.i(TAG, "no assigned variation because the experiment or feature flag is disabled: " + flagKey); return null; } TargetingRule rule = RuleEvaluator.findMatchingRule(subjectAttributes, flag.getRules()); if (rule == null) { - Log.i(LoggingTag, "no assigned variation. The subject attributes did not match any targeting rules"); + Log.i(TAG, "no assigned variation. The subject attributes did not match any targeting rules"); return null; } String allocationKey = rule.getAllocationKey(); Allocation allocation = flag.getAllocations().get(allocationKey); if (!isInExperimentSample(subjectKey, flagKey, flag.getSubjectShards(), allocation.getPercentExposure())) { - Log.i(LoggingTag, "no assigned variation. The subject is not part of the sample population"); + Log.i(TAG, "no assigned variation. The subject is not part of the sample population"); return null; } diff --git a/eppo/src/main/java/cloud/eppo/android/EppoHttpClient.java b/eppo/src/main/java/cloud/eppo/android/EppoHttpClient.java index 3207d07e..17d0f06a 100644 --- a/eppo/src/main/java/cloud/eppo/android/EppoHttpClient.java +++ b/eppo/src/main/java/cloud/eppo/android/EppoHttpClient.java @@ -1,6 +1,6 @@ package cloud.eppo.android; -import static cloud.eppo.android.Constants.LoggingTag; +import static cloud.eppo.android.util.Utils.logTag; import android.util.Log; @@ -17,6 +17,8 @@ import okhttp3.Response; public class EppoHttpClient { + private static final String TAG = logTag(EppoHttpClient.class); + private final OkHttpClient client = new OkHttpClient().newBuilder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) @@ -43,7 +45,7 @@ public void get(String path, RequestCallback callback) { @Override public void onResponse(Call call, Response response) { if (response.isSuccessful()) { - Log.d(LoggingTag, "Fetch successfull"); + Log.d(TAG, "Fetch successfull"); callback.onSuccess(response.body().charStream()); } else { switch (response.code()) { @@ -52,7 +54,7 @@ public void onResponse(Call call, Response response) { break; default: if (BuildConfig.DEBUG) { - Log.e(LoggingTag, "Fetch failed with status code: " + response.code()); + Log.e(TAG, "Fetch failed with status code: " + response.code()); } callback.onFailure("Bad response from URL "+httpUrl); } diff --git a/eppo/src/main/java/cloud/eppo/android/dto/adapters/EppoValueAdapter.java b/eppo/src/main/java/cloud/eppo/android/dto/adapters/EppoValueAdapter.java index 2417dc59..07b434db 100644 --- a/eppo/src/main/java/cloud/eppo/android/dto/adapters/EppoValueAdapter.java +++ b/eppo/src/main/java/cloud/eppo/android/dto/adapters/EppoValueAdapter.java @@ -1,6 +1,6 @@ package cloud.eppo.android.dto.adapters; -import static cloud.eppo.android.Constants.LoggingTag; +import static cloud.eppo.android.util.Utils.logTag; import android.util.Log; @@ -15,12 +15,13 @@ import java.lang.reflect.Type; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import cloud.eppo.android.dto.EppoValue; public class EppoValueAdapter implements JsonDeserializer, JsonSerializer { + public static final String TAG = logTag(EppoValueAdapter.class); + @Override public EppoValue deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { @@ -30,7 +31,7 @@ public EppoValue deserialize(JsonElement json, Type typeOfT, JsonDeserialization try { array.add(element.getAsString()); } catch (Exception e) { - Log.e(LoggingTag, "only Strings are supported"); + Log.e(TAG, "only Strings are supported"); } } return EppoValue.valueOf(array); diff --git a/eppo/src/main/java/cloud/eppo/android/util/Utils.java b/eppo/src/main/java/cloud/eppo/android/util/Utils.java index eb44edd3..c8b3a795 100644 --- a/eppo/src/main/java/cloud/eppo/android/util/Utils.java +++ b/eppo/src/main/java/cloud/eppo/android/util/Utils.java @@ -2,14 +2,12 @@ import android.content.Context; import android.content.SharedPreferences; -import android.os.Build; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.DateFormat; import java.text.SimpleDateFormat; -import java.util.Base64; import java.util.Date; import java.util.TimeZone; @@ -65,4 +63,8 @@ public static SharedPreferences getSharedPrefs(Context context) { public static String generateExperimentKey(String featureFlagKey, String allocationKey) { return featureFlagKey + '-' + allocationKey; } + + public static String logTag(Class loggingClass) { + return "EppoSDK:"+loggingClass.getSimpleName(); + } } From 570d3bfcfea749506dcff86e0c288254b7223b95 Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Thu, 26 Oct 2023 13:54:45 -0600 Subject: [PATCH 26/31] try grep to still filter logs --- .github/workflows/test.yaml | 2 +- eppo/src/main/java/cloud/eppo/android/util/Utils.java | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index af2fa439..350698e6 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -56,7 +56,7 @@ jobs: mkdir -p app/ # create directory touch app/emulator.log # create log file chmod 777 app/emulator.log # allow writing to log file - adb logcat EppoSDK:D "*:S" >> app/emulator.log & # pipe all logcat messages into log file as a background process + adb logcat | grep EppoSDK >> app/emulator.log & # pipe all logcat messages into log file as a background process ./gradlew connectedCheck # run tests - name: Upload Failing Test Report Log diff --git a/eppo/src/main/java/cloud/eppo/android/util/Utils.java b/eppo/src/main/java/cloud/eppo/android/util/Utils.java index c8b3a795..6a3e1984 100644 --- a/eppo/src/main/java/cloud/eppo/android/util/Utils.java +++ b/eppo/src/main/java/cloud/eppo/android/util/Utils.java @@ -65,6 +65,8 @@ public static String generateExperimentKey(String featureFlagKey, String allocat } public static String logTag(Class loggingClass) { - return "EppoSDK:"+loggingClass.getSimpleName(); + // Common prefix can make filtering logs easier + // Android prefers keeping log tags 23 characters or less + return ("EppoSDK:"+loggingClass.getSimpleName()).substring(0, 23); } } From 0b372143ff2febc31a025caa409253c30a21514e Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Thu, 26 Oct 2023 15:26:54 -0600 Subject: [PATCH 27/31] safe truncating of log tag --- eppo/src/main/java/cloud/eppo/android/util/Utils.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/eppo/src/main/java/cloud/eppo/android/util/Utils.java b/eppo/src/main/java/cloud/eppo/android/util/Utils.java index 6a3e1984..e84d11ee 100644 --- a/eppo/src/main/java/cloud/eppo/android/util/Utils.java +++ b/eppo/src/main/java/cloud/eppo/android/util/Utils.java @@ -66,7 +66,13 @@ public static String generateExperimentKey(String featureFlagKey, String allocat public static String logTag(Class loggingClass) { // Common prefix can make filtering logs easier + String logTag = ("EppoSDK:"+loggingClass.getSimpleName()); + // Android prefers keeping log tags 23 characters or less - return ("EppoSDK:"+loggingClass.getSimpleName()).substring(0, 23); + if (logTag.length() > 23) { + logTag = logTag.substring(0, 23); + } + + return logTag; } } From 432611b458df2dde5232c4cd7eac600381794608 Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Thu, 26 Oct 2023 15:41:59 -0600 Subject: [PATCH 28/31] rename task names --- .github/workflows/test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 350698e6..1cf71cc7 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -59,14 +59,14 @@ jobs: adb logcat | grep EppoSDK >> app/emulator.log & # pipe all logcat messages into log file as a background process ./gradlew connectedCheck # run tests - - name: Upload Failing Test Report Log + - name: Upload Emulator Logs if: always() uses: actions/upload-artifact@v2 with: name: emulator logs path: app/emulator.log - - name: Upload logs + - name: Upload Test Report if: always() uses: actions/upload-artifact@v2 with: From 0c2c12e6fceab08616efe293232c7702970e3285 Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Thu, 26 Oct 2023 16:04:23 -0600 Subject: [PATCH 29/31] minSdk version back to 21 --- eppo/build.gradle | 9 +-------- example/build.gradle | 2 +- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/eppo/build.gradle b/eppo/build.gradle index c0ee3e0e..9fa71cb1 100644 --- a/eppo/build.gradle +++ b/eppo/build.gradle @@ -11,14 +11,7 @@ android { defaultConfig { namespace "cloud.eppo.android" - - gradle.startParameter.taskNames.each { - if (it.contains("AndroidTest") || it.contains('connectedCheck')) { - minSdk 33 // required to use wiremock in tests - } else { - minSdk 21 - } - } + minSdk 21 targetSdk 33 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/example/build.gradle b/example/build.gradle index 20727489..21317ebe 100644 --- a/example/build.gradle +++ b/example/build.gradle @@ -8,7 +8,7 @@ android { defaultConfig { applicationId "cloud.eppo.androidexample" namespace "com.geteppo.androidexample" - minSdk 33 + minSdk 21 targetSdk 33 versionCode 1 versionName "1.0" From 9fc5dd267e9466c9871a86ad6a16cbadef4bd114 Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Thu, 26 Oct 2023 16:06:48 -0600 Subject: [PATCH 30/31] git rid of extraneous env variable --- .github/workflows/test.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 1cf71cc7..a6aac723 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -11,8 +11,6 @@ on: jobs: test-android-sdk: runs-on: macos-latest - env: - ANDROID_API_LEVEL: 33 steps: - name: Check out Java SDK uses: actions/checkout@v3 From 44f33b0f8c16d3aaaca5271d1494d44a954c4131 Mon Sep 17 00:00:00 2001 From: Aaron Silverman Date: Thu, 26 Oct 2023 16:33:14 -0600 Subject: [PATCH 31/31] remove deprecated android manfest write permission --- eppo/src/androidTest/AndroidManifest.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/eppo/src/androidTest/AndroidManifest.xml b/eppo/src/androidTest/AndroidManifest.xml index 9496fc86..629962c7 100644 --- a/eppo/src/androidTest/AndroidManifest.xml +++ b/eppo/src/androidTest/AndroidManifest.xml @@ -4,6 +4,5 @@ - \ No newline at end of file