Skip to content

Commit

Permalink
Toggle connectivity as Airplane Mode via UIAutomator (#291)
Browse files Browse the repository at this point in the history
Simply turning off the WiFi doensn't "cut it."

Likewise, disabling cellular connectivity is not possible without
reflection.

A durable approach is to toggle airplane mode via the system settings
panel. UIAutomator can be used to achieve this.

Refer: https://stackoverflow.com/q/27620976/695787
  • Loading branch information
jamesonwilliams authored Jun 11, 2020
1 parent 0764253 commit 8cf6844
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 58 deletions.
3 changes: 2 additions & 1 deletion aws-android-sdk-appsync-tests/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ android {
compileSdkVersion 28

defaultConfig {
minSdkVersion 15
minSdkVersion 18
targetSdkVersion 28
versionCode 1
versionName "1.0"
Expand Down Expand Up @@ -49,6 +49,7 @@ repositories {

dependencies {
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.uiautomator:uiautomator-v18:2.1.3'
androidTestImplementation 'junit:junit:4.13'
androidTestImplementation "com.amazonaws:aws-android-sdk-s3:$aws_version"
androidTestImplementation "com.amazonaws:aws-android-sdk-appsync:$VERSION_NAME"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import java.util.Map;
import java.util.concurrent.CountDownLatch;

import static com.amazonaws.mobileconnectors.appsync.util.InternetConnectivity.goOnline;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
Expand All @@ -54,7 +55,8 @@ public class ComplexObjectsInstrumentationTests {
private static AWSAppSyncClient iamAWSAppSyncClient;

@BeforeClass
public static void setUpBeforeClass() {
public static void beforeAnyTests() {
goOnline();
CustomCognitoUserPool.setup();
awsAppSyncClient = AWSAppSyncClients.withAPIKEYFromAWSConfiguration();
iamAWSAppSyncClient = AWSAppSyncClients.withIAMFromAWSConfiguration();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;

import static com.amazonaws.mobileconnectors.appsync.util.InternetConnectivity.goOnline;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
Expand All @@ -44,7 +45,9 @@ public class ConflictManagementInstrumentationTest {
* when one of the tests in this suite starts.
*/
@BeforeClass
public static void setupBeforeClass() {
public static void beforeAnyTests() {
goOnline();

String title = "Minstrel in the Gallery";
String author = "Tull";

Expand Down Expand Up @@ -114,7 +117,7 @@ public void testAddUpdateArticleNoConflict() {
public void testAddUpdateArticleConflictDiscard() {
AWSAppSyncClient awsAppSyncClient = AWSAppSyncClients.withAPIKEYFromAWSConfiguration();

//The TestConflictResolver setup in AppSyncTestSetupHelper will fail mutation
// The TestConflictResolver setup in AppSyncTestSetupHelper will fail mutation
// if the title is set to ALWAYS DISCARD
String title = "ALWAYS DISCARD";
String author = "Tull @" + System.currentTimeMillis();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import com.amazonaws.mobileconnectors.appsync.sigv4.BasicAPIKeyAuthProvider;
import com.amazonaws.mobileconnectors.appsync.util.Await;
import com.amazonaws.mobileconnectors.appsync.util.JsonExtract;
import com.amazonaws.mobileconnectors.appsync.util.Wifi;
import com.amazonaws.regions.Regions;
import com.apollographql.apollo.GraphQLCall;
import com.apollographql.apollo.api.Operation.Variables;
Expand Down Expand Up @@ -64,6 +63,8 @@
import javax.annotation.Nonnull;

import static android.support.test.InstrumentationRegistry.getTargetContext;
import static com.amazonaws.mobileconnectors.appsync.util.InternetConnectivity.goOffline;
import static com.amazonaws.mobileconnectors.appsync.util.InternetConnectivity.goOnline;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
Expand All @@ -83,14 +84,15 @@ public class MultiClientInstrumentationTest {
private static String idToken = null;

@BeforeClass
public static void setupOnce() {
public static void beforeAnyTests() {
goOnline();
idToken = CustomCognitoUserPool.setup();
}

@Before
@After
public void ensureNetworkIsUp() {
Wifi.turnOn();
goOnline();
}

@Test
Expand Down Expand Up @@ -503,7 +505,7 @@ public void testMultipleOfflineMutations() {
assertNotNull(postId);

int numberOfLatches = 3;
Wifi.turnOff();
goOffline();

List<LatchedGraphQLCallback<UpdatePostMutation.Data>> callbacks = new ArrayList<>();
for (int i = 0; i < numberOfLatches; i++) {
Expand Down Expand Up @@ -575,7 +577,7 @@ public void testSingleOfflineMutation() {
String postId = post.id();
assertNotNull(postId);

Wifi.turnOff();
goOffline();

Log.v(TAG, "Thread:[" + Thread.currentThread().getId() + "]: Kicking off update");
LatchedGraphQLCallback<UpdatePostMutation.Data> callback = LatchedGraphQLCallback.instance();
Expand Down Expand Up @@ -610,7 +612,7 @@ public void testSingleOfflineMutation() {
@Test
public void testClearCache() throws ClearCacheException {
AWSAppSyncClient client = AWSAppSyncClients.withAPIKEYFromAWSConfiguration();
Wifi.turnOff();
goOffline();

// Add a post
AddPostMutation.Data expected = new AddPostMutation.Data(new AddPostMutation.CreatePost(
Expand Down Expand Up @@ -673,7 +675,7 @@ public void testClearMutationsCacheOnly() throws ClearCacheException {
assertNotNull(networkResponse);
assertNotNull(networkResponse.data());

Wifi.turnOff();
goOffline();

//Add a post
AddPostMutation.Data addPostMutationData = new AddPostMutation.Data(new AddPostMutation.CreatePost(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import com.amazonaws.mobileconnectors.appsync.models.Posts;
import com.amazonaws.mobileconnectors.appsync.util.Await;
import com.amazonaws.mobileconnectors.appsync.util.Sleep;
import com.amazonaws.mobileconnectors.appsync.util.Wifi;
import com.apollographql.apollo.GraphQLCall;
import com.apollographql.apollo.api.Error;
import com.apollographql.apollo.api.Operation;
Expand All @@ -47,6 +46,8 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import static com.amazonaws.mobileconnectors.appsync.util.InternetConnectivity.goOffline;
import static com.amazonaws.mobileconnectors.appsync.util.InternetConnectivity.goOnline;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
Expand All @@ -63,14 +64,15 @@ public final class QueryInstrumentationTest {
private static final long EXTENDED_WAIT_TIME_MS = TimeUnit.SECONDS.toMillis(30);

@BeforeClass
public static void beforeAny() {
public static void beforeAnyTest() {
goOnline();
CustomCognitoUserPool.setup();
}

@Before
@After
public void enableWifiIfNotEnabled() {
Wifi.turnOn();
public void ensureInternetConnection() {
goOnline();
}

@Test
Expand Down Expand Up @@ -189,8 +191,7 @@ public void testMultipleOfflineMutations() {
assertNotNull(createPost.id());
final String postID = createPost.id();

// Go "offline"
Wifi.turnOff();
goOffline();

for (int i = 0; i < onUpdatePostCallbacks.size(); i++) {
awsAppSyncClient
Expand Down Expand Up @@ -256,8 +257,7 @@ public void testSingleOfflineMutation() {
assertNotNull(createPost.id());
final String postID = createPost.id();

// Set Wifi Network offline
Wifi.turnOff();
goOffline();

Log.v(TAG, "Thread:[" + Thread.currentThread().getId() + "]: Kicking off update");
LatchedGraphQLCallback<UpdatePostMutation.Data> onUpdatePostCallback = LatchedGraphQLCallback.instance();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

import java.util.concurrent.TimeUnit;

import static com.amazonaws.mobileconnectors.appsync.util.InternetConnectivity.goOnline;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

Expand All @@ -42,7 +43,8 @@ public final class SubscriptionInstrumentationTest {
private static final long REASONABLE_WAIT_TIME_MS = TimeUnit.SECONDS.toMillis(10);

@BeforeClass
public static void beforeClass() {
public static void beforeAnyTests() {
goOnline();
CustomCognitoUserPool.setup();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright 2020 Amazon.com,
* Inc. or its affiliates. All Rights Reserved.
* <p>
* SPDX-License-Identifier: Apache-2.0
*/
package com.amazonaws.mobileconnectors.appsync.util;

import android.content.ContentResolver;
import android.content.Intent;
import android.provider.Settings;

import android.support.test.uiautomator.By;
import android.support.test.uiautomator.BySelector;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.Until;

import static android.support.test.InstrumentationRegistry.getInstrumentation;

public final class AirplaneMode {
private static final int TIMEOUT_MS = 500;

private AirplaneMode() {}

public static void enable() {
setAirplaneMode(true);
}

public static void disable() {
setAirplaneMode(false);
}

public static boolean isEnabled() {
ContentResolver contentResolver = getInstrumentation().getContext().getContentResolver();
int status = Settings.System.getInt(contentResolver, Settings.Global.AIRPLANE_MODE_ON, 0);
return status == 1;
}

private static void setAirplaneMode(boolean shouldEnable) {
if (shouldEnable == isEnabled()) return;

UiDevice device = UiDevice.getInstance(getInstrumentation());
device.openQuickSettings();

BySelector description = By.desc("Airplane mode");
device.wait(Until.hasObject(description), TIMEOUT_MS);
device.findObject(description).click();

getInstrumentation().getContext()
.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2020 Amazon.com,
* Inc. or its affiliates. All Rights Reserved.
* <p>
* SPDX-License-Identifier: Apache-2.0
*/
package com.amazonaws.mobileconnectors.appsync.util;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.concurrent.TimeUnit;

public final class InternetConnectivity {
private InternetConnectivity() {}

public static void goOnline() {
RetryStrategies.linear(AirplaneMode::disable, InternetConnectivity::isOnline, 3, 2);
}

public static void goOffline() {
RetryStrategies.linear(AirplaneMode::enable, InternetConnectivity::isOffline, 3, 2);
}

private static boolean isOnline() {
int connectionTimeoutMs = (int) TimeUnit.SECONDS.toMillis(2);
String host = "amazon.com";
int port = 443;

Socket socket = new Socket();
try {
socket.connect(new InetSocketAddress(host, port), connectionTimeoutMs);
socket.close();
return true;
} catch (IOException socketFailure) {
return false;
}
}

private static boolean isOffline() {
return !isOnline();
}
}

This file was deleted.

0 comments on commit 8cf6844

Please sign in to comment.