Skip to content

Commit 3305d6a

Browse files
committed
Merge branch 'unable-to-get-initilizationprovider-droid-1238'
2 parents 58a811f + 69bce81 commit 3305d6a

File tree

15 files changed

+86
-41
lines changed

15 files changed

+86
-41
lines changed

.github/workflows/android-app.yml

+6-4
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ jobs:
313313
- uses: actions/download-artifact@v4
314314
with:
315315
name: relay-list
316-
path: android/app/build/extraAssets/relays.json
316+
path: android/app/build/extraAssets
317317

318318
- name: Build app
319319
uses: burrunan/gradle-cache-action@v1
@@ -416,10 +416,9 @@ jobs:
416416
- test-type: app
417417
path: android/app/build/outputs/apk
418418
test-repeat: 1
419-
# Disabled (test-repeat='0') due to flakiness unless overridden by input.
420419
- test-type: mockapi
421420
path: android/test/mockapi/build/outputs/apk
422-
test-repeat: ${{ github.event.inputs.mockapi_test_repeat || 0 }}
421+
test-repeat: ${{ github.event.inputs.mockapi_test_repeat || 1 }}
423422
steps:
424423
- name: Prepare report dir
425424
if: ${{ matrix.test-repeat != 0 }}
@@ -470,7 +469,8 @@ jobs:
470469

471470
instrumented-e2e-tests:
472471
name: Run instrumented e2e tests
473-
runs-on: [self-hosted, android-device]
472+
# Temporary workaround for targeting the runner android-runner-v1
473+
runs-on: [self-hosted, android-device, android-emulator]
474474
if: github.event_name == 'schedule' || github.event.inputs.run_e2e_tests == 'true'
475475
timeout-minutes: 30
476476
needs: [build-app, build-instrumented-tests]
@@ -507,6 +507,7 @@ jobs:
507507
INFRA_FLAVOR: prod
508508
VALID_TEST_ACCOUNT_NUMBER: ${{ secrets.ANDROID_PROD_TEST_ACCOUNT }}
509509
INVALID_TEST_ACCOUNT_NUMBER: '0000000000000000'
510+
ENABLE_HIGHLY_RATE_LIMITED_TESTS: ${{ github.event_name == 'schedule' && 'true' || 'false' }}
510511
REPORT_DIR: ${{ steps.prepare-report-dir.outputs.report_dir }}
511512
run: ./android/scripts/run-instrumented-tests.sh
512513

@@ -521,6 +522,7 @@ jobs:
521522
clearPackageData=true,\
522523
runnerBuilder=de.mannodermaus.junit5.AndroidJUnit5Builder,\
523524
invalid_test_account_number=0000000000000000,\
525+
enable_highly_rate_limited_tests=${{ github.event_name == 'schedule' && 'true' || 'false' }},\
524526
partner_auth=${{ secrets.STAGEMOLE_PARTNER_AUTH }}"
525527
strategy:
526528
fail-fast: false

android/BuildInstructions.md

+3
Original file line numberDiff line numberDiff line change
@@ -238,3 +238,6 @@ the `ENABLE_IN_APP_VERSION_NOTIFICATIONS` property can be set in `local.properti
238238
```
239239
ENABLE_IN_APP_VERSION_NOTIFICATIONS=false
240240
```
241+
242+
### Run tests highly affected by rate limiting
243+
To avoid being rate limited we avoid running tests sending requests that are highly rate limited too often. If you want to run these tests you can set `enable_highly_rate_limited_tests=true` in `local.properties`. The default value is `false`.

android/gradle/libs.versions.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ android-gradle-aapt = { module = "com.android.tools.build:aapt2" }
7171
android-volley = { module = "com.android.volley:volley", version.ref = "android-volley" }
7272

7373
# AndroidX
74-
androidx-activity-Compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activitycompose" }
74+
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activitycompose" }
7575
androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" }
7676
androidx-coresplashscreen = { module = "androidx.core:core-splashscreen", version.ref = "androidx-coresplashscreen" }
7777
androidx-espresso = { module = "androidx.test.espresso:espresso-core", version.ref = "androidx-espresso" }

android/gradle/verification-metadata.xml

+8-3
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,6 @@
208208
</artifact>
209209
</component>
210210
<component group="androidx.annotation" name="annotation-experimental" version="1.1.0">
211-
<artifact name="annotation-experimental-1.1.0.aar">
212-
<sha256 value="0157de61a2064047896a058080f3fd67ba57ad9a94857b3f7a363660243e3f90" origin="Generated by Gradle"/>
213-
</artifact>
214211
<artifact name="annotation-experimental-1.1.0.module">
215212
<sha256 value="0361d1526a4d7501255e19779e09e93cdbd07fee0e2f5c50b7a137432d510119" origin="Generated by Gradle"/>
216213
</artifact>
@@ -5453,6 +5450,14 @@
54535450
<sha256 value="68516559e6f84a621b9783cd892a64630ccd7875843588ddb3f0501425e33f15" origin="Generated by Gradle"/>
54545451
</artifact>
54555452
</component>
5453+
<component group="org.jetbrains.kotlinx" name="kotlinx-coroutines-android" version="1.7.1">
5454+
<artifact name="kotlinx-coroutines-android-1.7.1.jar">
5455+
<sha256 value="107313760c18f8da174e8d8103504a468e806e88f7b55a84bd1c0eaeea118e9a" origin="Generated by Gradle"/>
5456+
</artifact>
5457+
<artifact name="kotlinx-coroutines-android-1.7.1.module">
5458+
<sha256 value="beb7ff0f5ebc63a0b30af2ae1214e0b622a7b7e408240e64a8ea5b213c4d5334" origin="Generated by Gradle"/>
5459+
</artifact>
5460+
</component>
54565461
<component group="org.jetbrains.kotlinx" name="kotlinx-coroutines-android" version="1.7.3">
54575462
<artifact name="kotlinx-coroutines-android-1.7.3.jar">
54585463
<sha256 value="59fffb26bee12c32dadcfa5d420c2a7db85d3253518128b170efda726613256d" origin="Generated by Gradle"/>

android/scripts/run-instrumented-tests.sh

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ TEST_SERVICES_URL=https://dl.google.com/android/maven2/androidx/test/services/te
1616
PARTNER_AUTH="${PARTNER_AUTH:-}"
1717
VALID_TEST_ACCOUNT_NUMBER="${VALID_TEST_ACCOUNT_NUMBER:-}"
1818
INVALID_TEST_ACCOUNT_NUMBER="${INVALID_TEST_ACCOUNT_NUMBER:-}"
19+
ENABLE_HIGHLY_RATE_LIMITED_TESTS="${ENABLE_HIGHLY_RATE_LIMITED_TESTS:-false}"
1920
REPORT_DIR="${REPORT_DIR:-}"
2021

2122
while [[ "$#" -gt 0 ]]; do
@@ -130,6 +131,7 @@ case "$TEST_TYPE" in
130131
echo "Error: The variable PARTNER_AUTH or VALID_TEST_ACCOUNT_NUMBER must be set."
131132
exit 1
132133
fi
134+
OPTIONAL_TEST_ARGUMENTS+=" -e enable_highly_rate_limited_tests $ENABLE_HIGHLY_RATE_LIMITED_TESTS"
133135
USE_ORCHESTRATOR="true"
134136
PACKAGE_NAME="net.mullvad.mullvadvpn"
135137
if [[ "$INFRA_FLAVOR" =~ ^(devmole|stagemole)$ ]]; then

android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt

+1-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import kotlinx.coroutines.flow.filter
1616
import kotlinx.coroutines.flow.first
1717
import kotlinx.coroutines.launch
1818
import kotlinx.coroutines.runBlocking
19-
import net.mullvad.mullvadvpn.lib.common.constant.BuildTypes
2019
import net.mullvad.mullvadvpn.lib.common.constant.GRPC_SOCKET_FILE_NAMED_ARGUMENT
2120
import net.mullvad.mullvadvpn.lib.common.constant.KEY_CONNECT_ACTION
2221
import net.mullvad.mullvadvpn.lib.common.constant.KEY_DISCONNECT_ACTION
@@ -150,7 +149,7 @@ class MullvadVpnService : TalpidVpnService() {
150149

151150
private fun startDaemon() {
152151
val apiEndpointConfiguration =
153-
if (Build.TYPE == BuildTypes.DEBUG) {
152+
if (BuildConfig.DEBUG) {
154153
intentProvider.getLatestIntent()?.getApiEndpointConfigurationExtras()
155154
?: apiEndpointConfiguration
156155
} else {

android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/extension/UiAutomatorExtensions.kt

+5-7
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,11 @@ fun UiDevice.findObjectWithTimeout(
2424

2525
wait(Until.hasObject(selector), timeout)
2626

27-
return try {
28-
findObject(selector)
29-
} catch (e: NullPointerException) {
30-
throw IllegalArgumentException(
31-
"No matches for selector within timeout ($timeout): $selector"
32-
)
33-
}
27+
val foundObject = findObject(selector)
28+
29+
require(foundObject != null) { "No matches for selector within timeout ($timeout): $selector" }
30+
31+
return foundObject
3432
}
3533

3634
fun UiDevice.clickAgreeOnPrivacyDisclaimer() {

android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/interactor/AppInteractor.kt

-9
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,6 @@ class AppInteractor(
5252
ensureLoggedIn()
5353
}
5454

55-
fun launchAndCreateAccount() {
56-
launch()
57-
device.clickAgreeOnPrivacyDisclaimer()
58-
device.clickAllowOnNotificationPermissionPromptIfApiLevel33AndAbove()
59-
waitForLoginPrompt()
60-
attemptCreateAccount()
61-
ensureAccountCreated()
62-
}
63-
6455
fun attemptLogin(accountNumber: String) {
6556
val loginObject =
6657
device.findObjectWithTimeout(By.clazz("android.widget.EditText")).apply {

android/test/e2e/build.gradle.kts

+9
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ android {
4646
put("clearPackageData", "true")
4747
addOptionalPropertyAsArgument("valid_test_account_number")
4848
addOptionalPropertyAsArgument("invalid_test_account_number")
49+
addOptionalPropertyAsArgument("enable_highly_rate_limited_tests")
4950
}
5051
}
5152

@@ -142,4 +143,12 @@ dependencies {
142143
implementation(libs.kotlin.stdlib)
143144

144145
androidTestUtil(libs.androidx.test.orchestrator)
146+
147+
// Needed or else the app crashes when launched
148+
implementation(Dependencies.junit5AndroidTestCompose)
149+
implementation(libs.compose.material3)
150+
151+
// Need these for forcing later versions of dependencies
152+
implementation(libs.compose.ui)
153+
implementation(libs.androidx.activity.compose)
145154
}

android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LoginTest.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import net.mullvad.mullvadvpn.test.common.constant.LOGIN_FAILURE_TIMEOUT
55
import net.mullvad.mullvadvpn.test.common.extension.clickAgreeOnPrivacyDisclaimer
66
import net.mullvad.mullvadvpn.test.common.extension.clickAllowOnNotificationPermissionPromptIfApiLevel33AndAbove
77
import net.mullvad.mullvadvpn.test.common.extension.findObjectWithTimeout
8+
import net.mullvad.mullvadvpn.test.e2e.annotations.HighlyRateLimited
89
import net.mullvad.mullvadvpn.test.e2e.misc.AccountTestRule
9-
import org.junit.jupiter.api.Disabled
1010
import org.junit.jupiter.api.Test
1111
import org.junit.jupiter.api.extension.RegisterExtension
1212

@@ -27,7 +27,7 @@ class LoginTest : EndToEndTest(BuildConfig.FLAVOR_infrastructure) {
2727
}
2828

2929
@Test
30-
@Disabled("Disabled to avoid getting rate-limited.")
30+
@HighlyRateLimited
3131
fun testLoginWithInvalidCredentials() {
3232
// Given
3333
val invalidDummyAccountNumber = accountTestRule.invalidAccountNumber

android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LogoutTest.kt

-13
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,4 @@ class LogoutTest : EndToEndTest(BuildConfig.FLAVOR_infrastructure) {
2323
// Then
2424
assertNotNull(device.findObjectWithTimeout(By.text("Login")))
2525
}
26-
27-
@Test
28-
fun testCreateAccountAndLogout() {
29-
// Given
30-
app.launchAndCreateAccount()
31-
32-
// When
33-
app.clickAccountCog()
34-
app.clickActionButtonByText("Log out")
35-
36-
// Then
37-
assertNotNull(device.findObjectWithTimeout(By.text("Login")))
38-
}
3926
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package net.mullvad.mullvadvpn.test.e2e.annotations
2+
3+
import androidx.test.platform.app.InstrumentationRegistry
4+
import net.mullvad.mullvadvpn.test.e2e.constant.ENABLE_HIGHLY_RATE_LIMITED
5+
import org.junit.jupiter.api.extension.ConditionEvaluationResult
6+
import org.junit.jupiter.api.extension.ExecutionCondition
7+
import org.junit.jupiter.api.extension.ExtendWith
8+
import org.junit.jupiter.api.extension.ExtensionContext
9+
10+
/**
11+
* Annotation for tests making use of API endpoints/requests that are highly rate limited such as
12+
* failed login requests.
13+
*/
14+
@Retention(AnnotationRetention.RUNTIME)
15+
@ExtendWith(HighlyRateLimited.ShouldRunWhenSeverelyAffectedByRateLimiting::class)
16+
annotation class HighlyRateLimited {
17+
class ShouldRunWhenSeverelyAffectedByRateLimiting : ExecutionCondition {
18+
override fun evaluateExecutionCondition(
19+
context: ExtensionContext?
20+
): ConditionEvaluationResult {
21+
val enableHighlyRateLimited =
22+
InstrumentationRegistry.getArguments()
23+
.getString(ENABLE_HIGHLY_RATE_LIMITED)
24+
?.toBoolean() ?: false
25+
26+
if (enableHighlyRateLimited) {
27+
return ConditionEvaluationResult.enabled(
28+
"Running test highly affected by rate limiting."
29+
)
30+
} else {
31+
return ConditionEvaluationResult.disabled(
32+
"Skipping test highly affected by rate limiting."
33+
)
34+
}
35+
}
36+
}
37+
}

android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/constant/Constants.kt

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ const val LOG_TAG = "mullvad-e2e"
44
const val PARTNER_AUTH = "partner_auth"
55
const val VALID_TEST_ACCOUNT_NUMBER_ARGUMENT_KEY = "valid_test_account_number"
66
const val INVALID_TEST_ACCOUNT_NUMBER_ARGUMENT_KEY = "invalid_test_account_number"
7+
const val ENABLE_HIGHLY_RATE_LIMITED = "enable_highly_rate_limited_tests"

android/test/firebase/e2e-play-stagemole.yml

+3
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@ default:
1616
- {model: blueline, version: 28, locale: en, orientation: portrait} # pixel 3
1717
- {model: cactus, version: 27, locale: en, orientation: portrait} # redmi 6a
1818
- {model: starqlteue, version: 26, locale: en, orientation: portrait} # galaxy s9
19+
environment-variables:
20+
clearPackageData: "true"
21+
runnerBuilder: "de.mannodermaus.junit5.AndroidJUnit5Builder"

android/test/mockapi/build.gradle.kts

+8
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,12 @@ dependencies {
8888
implementation(libs.mockkWebserver)
8989

9090
androidTestUtil(libs.androidx.test.orchestrator)
91+
92+
// Needed or else the app crashes when launched
93+
implementation(Dependencies.junit5AndroidTestCompose)
94+
implementation(libs.compose.material3)
95+
96+
// Need these for forcing later versions of dependencies
97+
implementation(libs.compose.ui)
98+
implementation(libs.androidx.activity.compose)
9199
}

0 commit comments

Comments
 (0)