Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Node render test suite on Android #12041

Merged
merged 1 commit into from
Jun 1, 2018
Merged
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
16 changes: 16 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,22 @@ run-android-ui-test-$1-%: platform/android/gradle/configuration.gradle
android-ndk-stack-$1: platform/android/gradle/configuration.gradle
adb logcat | ndk-stack -sym platform/android/MapboxGLAndroidSDK/build/intermediates/cmake/debug/obj/$2/

# Run render tests with pixelmatch
.PHONY: run-android-render-test-$1
run-android-render-test-$1: $(BUILD_DEPS) platform/android/gradle/configuration.gradle
-adb uninstall com.mapbox.mapboxsdk.testapp 2> /dev/null
# delete old test results
rm -rf platform/android/build/render-test/mapbox/
# copy test definitions to test app assets folder, clear old ones first
rm -rf platform/android/MapboxGLAndroidSDKTestApp/src/main/assets/integration
cp -r mapbox-gl-js/test/integration platform/android/MapboxGLAndroidSDKTestApp/src/main/assets
# run RenderTest.java to generate static map images
cd platform/android && $(MBGL_ANDROID_GRADLE) -Pmapbox.abis=$2 :MapboxGLAndroidSDKTestApp:connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.class="com.mapbox.mapboxsdk.testapp.render.RenderTest"
# pull generated images from the device
adb pull "`adb shell 'printenv EXTERNAL_STORAGE' | tr -d '\r'`/mapbox/render" platform/android/build/render-test
# copy expected result and run pixelmatch
python platform/android/scripts/run-render-test.py

endef

# Explodes the arguments into individual variables
Expand Down
4 changes: 4 additions & 0 deletions platform/android/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,7 @@ MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/acti

# Generated list files from code generation
/scripts/generate-style-code.list

# Input files for running render tests
MapboxGLAndroidSDKTestApp/src/main/assets/integration/

4 changes: 2 additions & 2 deletions platform/android/MapboxGLAndroidSDK/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ android {
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

lintOptions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,10 @@
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;

import com.mapbox.android.telemetry.TelemetryUtils;
import com.mapbox.mapboxsdk.BuildConfig;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.constants.MapboxConstants;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.NoRouteToHostException;
import java.net.ProtocolException;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.concurrent.locks.ReentrantLock;

import javax.net.ssl.SSLException;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Dispatcher;
Expand All @@ -32,6 +20,15 @@
import okhttp3.ResponseBody;
import timber.log.Timber;

import javax.net.ssl.SSLException;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.NoRouteToHostException;
import java.net.ProtocolException;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.concurrent.locks.ReentrantLock;

import static android.util.Log.DEBUG;
import static android.util.Log.ERROR;
import static android.util.Log.INFO;
Expand All @@ -57,43 +54,12 @@ class HTTPRequest implements Callback {
private HTTPRequest(long nativePtr, String resourceUrl, String etag, String modified) {
this.nativePtr = nativePtr;

try {
HttpUrl httpUrl = HttpUrl.parse(resourceUrl);
if (httpUrl == null) {
log(Log.ERROR, String.format("[HTTP] Unable to parse resourceUrl %s", resourceUrl));
}

final String host = httpUrl.host().toLowerCase(MapboxConstants.MAPBOX_LOCALE);
// Don't try a request to remote server if we aren't connected
if (!Mapbox.isConnected() && !host.equals("127.0.0.1") && !host.equals("localhost")) {
throw new NoRouteToHostException("No Internet connection available.");
}

if (host.equals("mapbox.com") || host.endsWith(".mapbox.com") || host.equals("mapbox.cn")
|| host.endsWith(".mapbox.cn")) {
if (httpUrl.querySize() == 0) {
resourceUrl = resourceUrl + "?";
} else {
resourceUrl = resourceUrl + "&";
}
resourceUrl = resourceUrl + "events=true";
}

Request.Builder builder = new Request.Builder()
.url(resourceUrl)
.tag(resourceUrl.toLowerCase(MapboxConstants.MAPBOX_LOCALE))
.addHeader("User-Agent", getUserAgent());
if (etag.length() > 0) {
builder = builder.addHeader("If-None-Match", etag);
} else if (modified.length() > 0) {
builder = builder.addHeader("If-Modified-Since", modified);
}
Request request = builder.build();
call = client.newCall(request);
call.enqueue(this);
} catch (Exception exception) {
handleFailure(call, exception);
if (resourceUrl.startsWith("local://")) {
// used by render test to serve files from assets
executeLocalRequest(resourceUrl);
return;
}
executeRequest(resourceUrl, etag, modified);
}

public void cancel() {
Expand Down Expand Up @@ -178,6 +144,57 @@ private static Dispatcher getDispatcher() {
return dispatcher;
}

private void executeRequest(String resourceUrl, String etag, String modified) {
try {
HttpUrl httpUrl = HttpUrl.parse(resourceUrl);
if (httpUrl == null) {
log(Log.ERROR, String.format("[HTTP] Unable to parse resourceUrl %s", resourceUrl));
}

final String host = httpUrl.host().toLowerCase(MapboxConstants.MAPBOX_LOCALE);
// Don't try a request to remote server if we aren't connected
if (!Mapbox.isConnected() && !host.equals("127.0.0.1") && !host.equals("localhost")) {
throw new NoRouteToHostException("No Internet connection available.");
}

if (host.equals("mapbox.com") || host.endsWith(".mapbox.com") || host.equals("mapbox.cn")
|| host.endsWith(".mapbox.cn")) {
if (httpUrl.querySize() == 0) {
resourceUrl = resourceUrl + "?";
} else {
resourceUrl = resourceUrl + "&";
}
resourceUrl = resourceUrl + "events=true";
}

Request.Builder builder = new Request.Builder()
.url(resourceUrl)
.tag(resourceUrl.toLowerCase(MapboxConstants.MAPBOX_LOCALE))
.addHeader("User-Agent", getUserAgent());
if (etag.length() > 0) {
builder = builder.addHeader("If-None-Match", etag);
} else if (modified.length() > 0) {
builder = builder.addHeader("If-Modified-Since", modified);
}
Request request = builder.build();
call = client.newCall(request);
call.enqueue(this);
} catch (Exception exception) {
handleFailure(call, exception);
}
}

private void executeLocalRequest(String resourceUrl) {
new LocalRequestTask(new LocalRequestTask.OnLocalRequestResponse() {
@Override
public void onResponse(byte[] bytes) {
if (bytes != null) {
nativeOnResponse(200, null, null, null, null, null, null, bytes);
}
}
}).execute(resourceUrl);
}

private void handleFailure(Call call, Exception e) {
String errorMessage = e.getMessage() != null ? e.getMessage() : "Error processing the request";
int type = getFailureType(e);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.mapbox.mapboxsdk.http;

import android.content.res.AssetManager;
import android.os.AsyncTask;
import com.mapbox.mapboxsdk.Mapbox;
import timber.log.Timber;

import java.io.IOException;
import java.io.InputStream;

class LocalRequestTask extends AsyncTask<String, Void, byte[]> {

private OnLocalRequestResponse requestResponse;

LocalRequestTask(OnLocalRequestResponse requestResponse) {
this.requestResponse = requestResponse;
}

@Override
protected byte[] doInBackground(String... strings) {
return loadFile(Mapbox.getApplicationContext().getAssets(),
"integration/" + strings[0]
.substring(8)
.replaceAll("%20", " ")
.replaceAll("%2c", ","));
}

@Override
protected void onPostExecute(byte[] bytes) {
super.onPostExecute(bytes);
if (bytes != null && requestResponse != null) {
requestResponse.onResponse(bytes);
}
}

private static byte[] loadFile(AssetManager assets, String path) {
byte[] buffer = null;
try (InputStream input = assets.open(path)) {
int size = input.available();
buffer = new byte[size];
input.read(buffer);
} catch (IOException exception) {
Timber.e(exception);
}
return buffer;
}

public interface OnLocalRequestResponse {
void onResponse(byte[] bytes);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.mapbox.mapboxsdk.testapp.render;

import android.Manifest;
import android.support.test.espresso.IdlingPolicies;
import android.support.test.espresso.IdlingRegistry;
import android.support.test.espresso.IdlingResourceTimeoutException;
import android.support.test.rule.ActivityTestRule;
import android.support.test.rule.GrantPermissionRule;
import android.support.test.runner.AndroidJUnit4;
import com.mapbox.mapboxsdk.testapp.activity.render.RenderTestActivity;
import com.mapbox.mapboxsdk.testapp.utils.SnapshotterIdlingResource;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import timber.log.Timber;

import java.util.concurrent.TimeUnit;

import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;

/**
* Instrumentation render tests
*/
@RunWith(AndroidJUnit4.class)
public class RenderTest {

private static final int RENDER_TEST_TIMEOUT = 30;
private SnapshotterIdlingResource idlingResource;

@Rule
public ActivityTestRule<RenderTestActivity> activityRule = new ActivityTestRule<>(RenderTestActivity.class);

@Rule
public GrantPermissionRule writeRule = GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE);

@Rule
public GrantPermissionRule readRule = GrantPermissionRule.grant(Manifest.permission.READ_EXTERNAL_STORAGE);

@Before
public void beforeTest() {
IdlingPolicies.setMasterPolicyTimeout(RENDER_TEST_TIMEOUT, TimeUnit.MINUTES);
setupIdlingResource();
}

private void setupIdlingResource() {
try {
Timber.e("@Before test: register idle resource");
IdlingPolicies.setIdlingResourceTimeout(RENDER_TEST_TIMEOUT, TimeUnit.MINUTES);
IdlingRegistry.getInstance().register(idlingResource = new SnapshotterIdlingResource(activityRule.getActivity()));
} catch (IdlingResourceTimeoutException idlingResourceTimeoutException) {
throw new RuntimeException("Idling out!");
}
}

@Test
public void testRender() {
onView(withId(android.R.id.content)).check(matches(isDisplayed()));
}

@After
public void afterTest() {
Timber.e("@After test: unregister idle resource");
IdlingRegistry.getInstance().unregister(idlingResource);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import org.hamcrest.Matcher;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand Down Expand Up @@ -68,6 +69,7 @@ public void testOpenCloseMapView() throws Exception {
}

@Test
@Ignore
public void testRotateMapView() throws Exception {
assertFalse("1) FileSource should not be active", fileSource.isActivated());
onView(withText("Simple Map")).perform(click());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.mapbox.mapboxsdk.testapp.utils;

import android.support.test.espresso.IdlingResource;

import com.mapbox.mapboxsdk.testapp.activity.render.RenderTestActivity;

public class SnapshotterIdlingResource implements IdlingResource, RenderTestActivity.OnRenderTestCompletionListener {

private IdlingResource.ResourceCallback resourceCallback;
private boolean isSnapshotReady;

public SnapshotterIdlingResource(RenderTestActivity activity) {
activity.setOnRenderTestCompletionListener(this);
}

@Override
public String getName() {
return "SnapshotterIdlingResource";
}

@Override
public boolean isIdleNow() {
return isSnapshotReady;
}

@Override
public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
this.resourceCallback = resourceCallback;
}

@Override
public void onFinish() {
isSnapshotReady = true;
if (resourceCallback != null) {
resourceCallback.onTransitionToIdle();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,9 @@
<activity
android:name=".activity.style.FillExtrusionStyleTestActivity"
android:screenOrientation="portrait" />
<activity
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was only the debug setup. Can we remove it?

android:name=".activity.render.RenderTestActivity"
android:screenOrientation="landscape"/>
<!-- Configuration Settings -->
<meta-data
android:name="com.mapbox.TestEventsServer"
Expand Down
Loading