Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test FETCH_HEAD #4

Closed
wants to merge 11 commits into from
Closed
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
56 changes: 50 additions & 6 deletions .github/workflows/android.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,54 @@ jobs:
with:
fetch-depth: 0

- name: Check for Bazel build file changes
id: bazel_check
run: ./ci/check_bazel.sh //examples/android:android_app
continue-on-error: true

- name: Check for workflow file changes
id: workflow_check
run: ./ci/files_changed.sh .github/workflows/android.yaml
continue-on-error: true

- name: Check for relevant Gradle changes
id: gradle_check
run: ./ci/files_changed.sh "^platform/jvm/gradle-test-app/.*\.(gradle|kts|kt|xml)$"
continue-on-error: true

- name: Determine if tests should run
id: check_changes_separate
run: |
if [[ "${{ steps.bazel_check.outcome }}" == "success" ]]; then
echo "Bazel check passed!"
else
echo "Bazel check failed!"
fi

if [[ "${{ steps.workflow_check.outcome }}" == "success" ]]; then
echo "Workflow check passed!"
else
echo "Workflow check failed!"
fi

if [[ "${{ steps.gradle_check.outcome }}" == "success" ]]; then
echo "Gradle check passed!"
else
echo "Gradle check failed!"
fi
shell: bash

- name: check for relevant changes
id: check_changes
run: |
./ci/check_bazel.sh //examples/android:android_app || ./ci/files_changed.sh .github/workflows/android.yaml || ./ci/files_changed.sh "^platform/jvm/gradle-test-app/.*\.(gradle|kts|kt|xml)$" && ./ci/run_tests.sh
true
./ci/run_tests.sh


build_apk:
runs-on: ubuntu-latest
if: needs.pre_check.outputs.should_run == 'true'
# TODO Remove hardcoding after testing
if: false
# if: needs.pre_check.outputs.should_run == 'true'
needs: pre_check
steps:
# Checkout repo to Github Actions runner
Expand All @@ -49,7 +89,9 @@ jobs:
runs-on: ubuntu-latest-8-cores
env:
SKIP_PROTO_GEN: 1
if: needs.pre_check.outputs.should_run == 'true'
# TODO Remove hardcoding after testing
if: false
# if: needs.pre_check.outputs.should_run == 'true'
needs: pre_check
steps:
- name: Checkout project sources
Expand Down Expand Up @@ -115,6 +157,8 @@ jobs:
script: cd platform/jvm && adb uninstall io.bitdrift.gradletestapp.test; adb uninstall io.bitdrift.gradletestapp; cd ../.. && ./tools/android_sdk_wrapper.sh platform/jvm/gradlew -p platform/jvm gradle-test-app:check gradle-test-app:connectedCheck --stacktrace

verify_android_hello_world_per_version:
# TODO Remove hardcoding after testing
if: false
needs: build_apk
runs-on: ubuntu-latest-8-cores
strategy:
Expand Down Expand Up @@ -178,7 +222,7 @@ jobs:
# job completing, we are able to gate it on all the previous jobs without explicitly enumerating them.
verify_android:
runs-on: ubuntu-latest
needs: ["build_apk", "verify_android_hello_world_per_version", "gradle_tests"]
needs: ["pre_check", "build_apk", "verify_android_hello_world_per_version", "gradle_tests"]
if: always()
steps:
# Checkout repo to Github Actions runner
Expand All @@ -187,4 +231,4 @@ jobs:
with:
fetch-depth: 1
- name: check result
run: ./ci/check_result.sh ${{ needs.build_apk.result }} && ./ci/check_result.sh ${{ needs.verify_android_hello_world_per_version.result }} && ./ci/check_result.sh ${{ needs.gradle_tests.result }}
run: ./ci/check_result.sh ${{ needs.pre_check.result }} && ./ci/check_result.sh ${{ needs.build_apk.result }} && ./ci/check_result.sh ${{ needs.verify_android_hello_world_per_version.result }} && ./ci/check_result.sh ${{ needs.gradle_tests.result }}
6 changes: 3 additions & 3 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,9 @@ http_archive(

http_archive(
name = "robolectric",
sha256 = "ba1269064f5509531b024cdea70349e97756f0f639e53b7cbb0938127218d6f8",
strip_prefix = "robolectric-bazel-4.11",
urls = ["https://github.com/robolectric/robolectric-bazel/archive/4.11.tar.gz"],
sha256 = "a270fd6fd83f9f024623e787696e6b73c44664b7c95f3d937ed35bf0a94a67ae",
strip_prefix = "robolectric-bazel-4.13",
urls = ["https://github.com/robolectric/robolectric-bazel/releases/download/4.13/robolectric-bazel-4.13.tar.gz"],
)

load("@robolectric//bazel:robolectric.bzl", "robolectric_repositories")
Expand Down
2 changes: 1 addition & 1 deletion bazel/capture_dependencies.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def jvm_dependencies():
"org.mockito:mockito-inline:4.11.0",
"com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0",
"androidx.test:core:1.6.0",
"org.robolectric:robolectric:4.11",
"org.robolectric:robolectric:4.13",
"org.assertj:assertj-core:3.22.0",
"com.squareup.okhttp3:mockwebserver:{}".format(okhttp_version),
"junit:junit:4.13.2",
Expand Down
26 changes: 21 additions & 5 deletions ci/check_bazel.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,37 @@

set -euo pipefail

echo "DEBUG: Starting check_bazel.sh"
echo "DEBUG: Current directory: $(pwd)"
echo "DEBUG: GITHUB_BASE_REF: $GITHUB_BASE_REF"
echo "DEBUG: GITHUB_HEAD_REF: $GITHUB_HEAD_REF"
echo "DEBUG: Remote repositories: $(git remote -v)"

# Compares $GITHUB_HEAD_REF and $GITHUB_BASE_REF (PR branch + target branch, usually main) to
# determine which Bazel targets have changed. This is done by analysizing the cache keys and
# should be authoritive assuming the builds are hermietic.
# determine which Bazel targets have changed. This is done by analyzing the cache keys and
# should be authoritative assuming the builds are hermetic.
#
# Usage ./ci/check_bazel.sh <list of targets to check for in the changeset>

# Path to your Bazel WORKSPACE directory
workspace_path=$(pwd)
# Path to your Bazel executable
bazel_path=$(pwd)/bazelw
# Find the remote associated with the base branch (GITHUB_BASE_REF)
remote_name=$(git remote -v | grep fetch | awk '{print $1}' | head -n 1)
# Fetch the base branch if not present
echo "DEBUG: Fetching base branch: $remote_name/$GITHUB_BASE_REF"
git fetch "$remote_name" "$GITHUB_BASE_REF"
# Starting Revision SHA. We use the merge-base to better handle the case where HEAD is not ahead of main.
base_sha=$(git rev-parse "origin/$GITHUB_BASE_REF")
previous_revision=$(git merge-base "$base_sha" "origin/$GITHUB_HEAD_REF")
base_sha=$(git rev-parse "$remote_name/$GITHUB_BASE_REF")
echo "DEBUG: base_sha: $base_sha"
# For the head branch, use FETCH_HEAD which is automatically set for the PR branch
echo "DEBUG: Using FETCH_HEAD for head branch"
previous_revision=$(git merge-base "$base_sha" FETCH_HEAD)
echo "DEBUG: previous_revision: $previous_revision"
# Final Revision SHA
final_revision=$GITHUB_HEAD_REF
final_revision=FETCH_HEAD
echo "DEBUG: final_revision: $final_revision"

starting_hashes_json="/tmp/starting_hashes.json"
final_hashes_json="/tmp/final_hashes.json"
Expand Down
34 changes: 28 additions & 6 deletions ci/files_changed.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,32 @@
#!/bin/bash

# Checks whether the files in provided regex via the command line has changed when comparing the HEAD ref and
# $GITHUB_BASE_REF, i.e. the target branch (usually main). Returns true if the current branch is main.
#
# Usage: ./ci/files_changed.sh <regex>

set -e

git rev-parse --abbrev-ref HEAD | grep -q ^main$ || git diff --name-only "origin/$GITHUB_BASE_REF" | grep -E "$1"
echo "DEBUG: Starting files_changed.sh"
echo "DEBUG: Current directory: $(pwd)"
echo "DEBUG: Current branch: $(git rev-parse --abbrev-ref HEAD)"
echo "DEBUG: GITHUB_BASE_REF: $GITHUB_BASE_REF"
echo "DEBUG: Remote repositories: $(git remote -v)"

# Get the current branch name
current_branch=$(git rev-parse --abbrev-ref HEAD)

# Find the remote associated with the base branch (GITHUB_BASE_REF)
remote_name=$(git remote -v | grep fetch | awk '{print $1}' | head -n 1)

echo "DEBUG: Remote name: $remote_name"

# If the current branch is "main", exit successfully (no need to check file changes)
if [[ "$current_branch" == "main" ]]; then
exit 0
fi

# Fetch the base branch if it doesn't exist locally
if ! git show-ref --quiet refs/remotes/$remote_name/$GITHUB_BASE_REF; then
echo "DEBUG: Fetching base branch: $remote_name/$GITHUB_BASE_REF"
git fetch $remote_name $GITHUB_BASE_REF
fi

# Check if any files matching the regex have changed between the current HEAD and the base branch
echo "DEBUG: Comparing changes between HEAD and $remote_name/$GITHUB_BASE_REF"
git diff --name-only "$remote_name/$GITHUB_BASE_REF" | grep -E "$1"
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
// capture-sdk - bitdrift's client SDK
// Copyright Bitdrift, Inc. All rights reserved.
//
// Use of this source code is governed by a source available license that can be found in the
// LICENSE file or at:
// https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt

package io.bitdrift.capture

import android.content.Context
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.test.core.app.ApplicationProvider
import io.bitdrift.capture.attributes.ClientAttributes
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.any
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mockito.anyString
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.mock
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config

@Suppress("DEPRECATION")
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [21])
class ClientAttributesTest {

@Test
fun foreground() {
val context = ApplicationProvider.getApplicationContext<Context>()
val mockedLifecycleOwnerLifecycleStateStarted = obtainMockedLifecycleOwnerWith(Lifecycle.State.STARTED)

val clientAttributes = ClientAttributes(context, mockedLifecycleOwnerLifecycleStateStarted).invoke()

assertThat(clientAttributes).containsEntry("foreground", "1")
}

@Test
fun not_foreground() {
val context = ApplicationProvider.getApplicationContext<Context>()
val mockedLifecycleOwnerLifecycleStateCreated = obtainMockedLifecycleOwnerWith(Lifecycle.State.CREATED)

val clientAttributes = ClientAttributes(context, mockedLifecycleOwnerLifecycleStateCreated).invoke()

assertThat(clientAttributes).containsEntry("foreground", "0")
}

@Test
fun app_id() {
val packageName = "my.bitdrift.test"
val context = spy(ApplicationProvider.getApplicationContext<Context>())
doReturn(packageName).`when`(context).packageName
val mockedLifecycleOwnerLifecycleStateStarted =
obtainMockedLifecycleOwnerWith(Lifecycle.State.STARTED)

val clientAttributes = ClientAttributes(context, mockedLifecycleOwnerLifecycleStateStarted).invoke()

assertThat(clientAttributes).containsEntry("app_id", packageName)
}

@Test
fun app_id_unknown() {
val context = spy(ApplicationProvider.getApplicationContext<Context>())
doReturn(null).`when`(context).packageName
val mockedLifecycleOwnerLifecycleStateStarted =
obtainMockedLifecycleOwnerWith(Lifecycle.State.STARTED)

val clientAttributes = ClientAttributes(context, mockedLifecycleOwnerLifecycleStateStarted).invoke()

assertThat(clientAttributes).containsEntry("app_id", "unknown")
}

@Test
fun app_version() {
val versionName = "1.2.3.4"
val context = spy(ApplicationProvider.getApplicationContext<Context>())
val mockedPackageInfo = obtainMockedPackageInfo(context)
mockedPackageInfo.versionName = versionName
val mockedLifecycleOwnerLifecycleStateStarted = obtainMockedLifecycleOwnerWith(Lifecycle.State.STARTED)

val clientAttributes = ClientAttributes(context, mockedLifecycleOwnerLifecycleStateStarted).invoke()

assertThat(clientAttributes).containsEntry("app_version", versionName)
}

@Test
fun app_version_unknown() {
val context = ApplicationProvider.getApplicationContext<Context>()
val mockedLifecycleOwnerLifecycleStateStarted = obtainMockedLifecycleOwnerWith(Lifecycle.State.STARTED)

val clientAttributes = ClientAttributes(context, mockedLifecycleOwnerLifecycleStateStarted).invoke()

assertThat(clientAttributes).containsEntry("app_version", "?.?.?")
}

@Test
fun app_version_code() {
val versionCode = 66
val context = spy(ApplicationProvider.getApplicationContext<Context>())
val mockedPackageInfo = obtainMockedPackageInfo(context)
mockedPackageInfo.versionCode = versionCode
val mockedLifecycleOwnerLifecycleStateStarted = obtainMockedLifecycleOwnerWith(Lifecycle.State.STARTED)

val clientAttributes = ClientAttributes(context, mockedLifecycleOwnerLifecycleStateStarted).invoke()

assertThat(clientAttributes).containsEntry("_app_version_code", versionCode.toString())
}

@Test
fun app_version_code_unknown() {
val context = spy(ApplicationProvider.getApplicationContext<Context>())
val packageManager = obtainMockedPackageManager(context)
doReturn(null).`when`(packageManager).getPackageInfo(anyString(), eq(0))
val mockedLifecycleOwnerLifecycleStateStarted = obtainMockedLifecycleOwnerWith(Lifecycle.State.STARTED)

val clientAttributes = ClientAttributes(context, mockedLifecycleOwnerLifecycleStateStarted).invoke()

assertThat(clientAttributes).containsEntry("_app_version_code", "-1")
}

@Test
@Config(sdk = [28])
fun app_version_code_android_pie() {
val versionCode = 66L
val context = spy(ApplicationProvider.getApplicationContext<Context>())
val mockedPackageInfo = obtainMockedPackageInfo(context)
doReturn(versionCode).`when`(mockedPackageInfo).longVersionCode
val mockedLifecycleOwnerLifecycleStateStarted = obtainMockedLifecycleOwnerWith(Lifecycle.State.STARTED)

val clientAttributes = ClientAttributes(context, mockedLifecycleOwnerLifecycleStateStarted).invoke()

assertThat(clientAttributes).containsEntry("_app_version_code", versionCode.toString())
}

@Test
@Config(sdk = [28])
fun app_version_code_unknown_android_pie() {
val context = spy(ApplicationProvider.getApplicationContext<Context>())
val packageManager = obtainMockedPackageManager(context)
doReturn(null).`when`(packageManager).getPackageInfo(anyString(), eq(0))
val mockedLifecycleOwnerLifecycleStateStarted = obtainMockedLifecycleOwnerWith(Lifecycle.State.STARTED)

val clientAttributes = ClientAttributes(context, mockedLifecycleOwnerLifecycleStateStarted).invoke()

assertThat(clientAttributes).containsEntry("_app_version_code", "-1")
}

@Test
@Config(sdk = [33])
fun package_info_android_tiramisu() {
val context = spy(ApplicationProvider.getApplicationContext<Context>())
val packageManager = obtainMockedPackageManager(context)
val mockedLifecycleOwnerLifecycleStateStarted = obtainMockedLifecycleOwnerWith(Lifecycle.State.STARTED)

ClientAttributes(context, mockedLifecycleOwnerLifecycleStateStarted).invoke()

verify(packageManager).getPackageInfo(anyString(), any(PackageManager.PackageInfoFlags::class.java))
}

private fun obtainMockedLifecycleOwnerWith(state: Lifecycle.State): LifecycleOwner {
val mockedLifecycle = mock(Lifecycle::class.java)
doReturn(state).`when`(mockedLifecycle).currentState
val mockedLifecycleOwner = mock(LifecycleOwner::class.java)
doReturn(mockedLifecycle).`when`(mockedLifecycleOwner).lifecycle
return mockedLifecycleOwner
}

private fun obtainMockedPackageInfo(context: Context): PackageInfo {
val mockedPackageManager = obtainMockedPackageManager(context)
val mockedPackageInfo: PackageInfo = mock(PackageInfo::class.java)
doReturn(mockedPackageInfo).`when`(mockedPackageManager).getPackageInfo(anyString(), eq(0))
return mockedPackageInfo
}

private fun obtainMockedPackageManager(context: Context): PackageManager {
val mockedPackageManager: PackageManager = mock(PackageManager::class.java)
doReturn(mockedPackageManager).`when`(context).packageManager
return mockedPackageManager
}
}
Loading
Loading