[sdks/android] Part 3: Finish conversion to Robolectric.

This commit is contained in:
Nick Alexander 2018-07-26 17:22:53 -07:00
parent 190e05e360
commit 2978ad91c0
5 changed files with 60 additions and 31 deletions

View file

@ -29,9 +29,13 @@ buildscript {
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
classpath 'gradle.plugin.org.mozilla.rust-android-gradle:plugin:0.0.4' classpath 'gradle.plugin.org.mozilla.rust-android-gradle:plugin:0.1.0'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files
// Yes, this is unusual. We want to access some host-specific
// computation at build time.
classpath 'net.java.dev.jna:jna:4.5.2'
} }
} }

View file

@ -6,6 +6,8 @@ apply plugin: 'com.jfrog.bintray'
// Simply applying this plugin gets bintray to publish a pom file. // Simply applying this plugin gets bintray to publish a pom file.
apply plugin: 'com.github.dcendents.android-maven' apply plugin: 'com.github.dcendents.android-maven'
import com.sun.jna.Platform
android { android {
compileSdkVersion rootProject.ext.build['compileSdkVersion'] compileSdkVersion rootProject.ext.build['compileSdkVersion']
defaultConfig { defaultConfig {
@ -26,6 +28,9 @@ android {
sourceSets { sourceSets {
androidTest.assets.srcDirs += '../../../../fixtures' androidTest.assets.srcDirs += '../../../../fixtures'
test.resources.srcDirs += '../../../../fixtures'
test.resources.srcDirs += "$buildDir/rustResources"
} }
// TODO silences: // TODO silences:
@ -40,27 +45,41 @@ android {
packagingOptions { packagingOptions {
doNotStrip "**/*.so" doNotStrip "**/*.so"
} }
testOptions.unitTests.all {
maxParallelForks = 4
}
} }
cargo { cargo {
module = '../../../../ffi' module = '../../../../ffi'
targetDirectory = '../../../../target' targetDirectory = '../../../../target'
targetInclude = 'libmentat_ffi.so' targetIncludes = ['libmentat_ffi.so', 'libmentat_ffi.dylib', 'libmentat_ffi.dll']
targets = [ targets = [
'x86', 'default', // For unit tests.
'arm', 'arm',
'arm64', 'arm64',
'x86',
] ]
// This puts the output of `cargo build` (the "default" toolchain) into the correct directory
// for JNA to find it.
defaultToolchainBuildPrefixDir = Platform.RESOURCE_PREFIX
} }
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'net.java.dev.jna:jna:4.5.2@aar'
testImplementation 'net.java.dev.jna:jna:4.5.2'
testImplementation 'junit:junit:4.12'
testImplementation 'org.robolectric:robolectric:3.8'
testImplementation 'org.mockito:mockito-core:2.20.0'
androidTestImplementation 'com.android.support:support-annotations:27.1.1' androidTestImplementation 'com.android.support:support-annotations:27.1.1'
androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test:rules:1.0.2' androidTestImplementation 'com.android.support.test:rules:1.0.2'
testImplementation 'junit:junit:4.12'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'net.java.dev.jna:jna:4.5.2@aar'
} }
repositories { repositories {
@ -68,7 +87,7 @@ repositories {
} }
afterEvaluate { afterEvaluate {
// The `cargoBuild` tasks isn't available until after evaluation. // The `cargoBuild` task isn't available until after evaluation.
android.libraryVariants.all { variant -> android.libraryVariants.all { variant ->
def productFlavor = "" def productFlavor = ""
variant.productFlavors.each { variant.productFlavors.each {
@ -76,6 +95,8 @@ afterEvaluate {
} }
def buildType = "${variant.buildType.name.capitalize()}" def buildType = "${variant.buildType.name.capitalize()}"
tasks["generate${productFlavor}${buildType}Assets"].dependsOn(tasks["cargoBuild"]) tasks["generate${productFlavor}${buildType}Assets"].dependsOn(tasks["cargoBuild"])
tasks["process${productFlavor}${buildType}UnitTestJavaRes"].dependsOn(tasks["cargoBuild"])
} }
} }

View file

@ -21,10 +21,6 @@ import com.sun.jna.Pointer;
* The raw pointer it holds is a pointer to a Store. * The raw pointer it holds is a pointer to a Store.
*/ */
public class Mentat extends RustObject<JNA.Store> { public class Mentat extends RustObject<JNA.Store> {
static {
System.loadLibrary("mentat_ffi");
}
/** /**
* Create a new Mentat with the provided pointer to a Mentat Store * Create a new Mentat with the provided pointer to a Mentat Store
* @param rawPointer A pointer to a Mentat Store. * @param rawPointer A pointer to a Mentat Store.

View file

@ -11,15 +11,16 @@
package org.mozilla.mentat; package org.mozilla.mentat;
import android.content.Context; import android.content.Context;
import android.content.res.AssetManager;
import android.util.Log;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.ParseException; import java.text.ParseException;
@ -27,18 +28,20 @@ import java.text.SimpleDateFormat;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Locale; import java.util.TimeZone;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import static org.junit.Assert.*; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/** /**
* Instrumentation test, which will execute on an Android device. * Instrumentation test, which will execute on an Android device.
*/ */
@RunWith(AndroidJUnit4.class) @RunWith(RobolectricTestRunner.class)
public class FFIIntegrationTest { public class FFIIntegrationTest {
class DBSetupResult { class DBSetupResult {
TxReport schemaReport; TxReport schemaReport;
TxReport dataReport; TxReport dataReport;
@ -76,17 +79,19 @@ public class FFIIntegrationTest {
@Test @Test
public void openStoreInLocationSucceeds() throws Exception { public void openStoreInLocationSucceeds() throws Exception {
Context context = InstrumentationRegistry.getTargetContext(); Context context = RuntimeEnvironment.application.getApplicationContext();
String path = context.getDatabasePath("test.db").getAbsolutePath(); String path = context.getDatabasePath("test.db").getAbsolutePath();
assertTrue(new File(path).getParentFile().mkdirs());
Mentat mentat = Mentat.open(path); Mentat mentat = Mentat.open(path);
assertNotNull(mentat); assertNotNull(mentat);
} }
public String readFile(String fileName) { public String readFile(String fileName) {
Context testContext = InstrumentationRegistry.getInstrumentation().getContext(); final File resource = new File(getClass().getClassLoader().getResource(fileName).getFile());
AssetManager assetManager = testContext.getAssets(); assertTrue(resource.exists());
try { try {
InputStream inputStream = assetManager.open(fileName); final FileInputStream inputStream = new FileInputStream(resource);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder out = new StringBuilder(); StringBuilder out = new StringBuilder();
String line; String line;
@ -261,8 +266,8 @@ public class FFIIntegrationTest {
assertNotNull(row); assertNotNull(row);
String name = row.asString(0); String name = row.asString(0);
String category = row.asString(1); String category = row.asString(1);
assert(name == "Community Harvest of Southwest Seattle"); assertEquals("Community Harvest of Southwest Seattle", name);
assert(category == "sustainable food"); assertEquals("sustainable food", category);
expectation.countDown(); expectation.countDown();
} }
}); });
@ -611,10 +616,14 @@ public class FFIIntegrationTest {
TxReport report = this.populateWithTypesSchema(mentat).dataReport; TxReport report = this.populateWithTypesSchema(mentat).dataReport;
final Long aEntid = report.getEntidForTempId("a"); final Long aEntid = report.getEntidForTempId("a");
String query = "[:find ?v . :in ?e :where [?e :foo/instant ?v]]"; String query = "[:find ?v . :in ?e :where [?e :foo/instant ?v]]";
final CountDownLatch expectation = new CountDownLatch(1);
DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZZ", Locale.ENGLISH); final TimeZone tz = TimeZone.getTimeZone("UTC");
format.parse("2017-01-01T11:00:00+00:00"); final DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
format.setTimeZone(tz);
format.parse("2017-01-01T11:00:00.000Z");
final Calendar expectedDate = format.getCalendar(); final Calendar expectedDate = format.getCalendar();
final CountDownLatch expectation = new CountDownLatch(1);
mentat.query(query).bindEntidReference("?e", aEntid).run(new ScalarResultHandler() { mentat.query(query).bindEntidReference("?e", aEntid).run(new ScalarResultHandler() {
@Override @Override
public void handleValue(TypedValue value) { public void handleValue(TypedValue value) {
@ -1205,10 +1214,8 @@ public class FFIIntegrationTest {
expectation2.await(); expectation2.await();
long timingDifference = uncachedTimer.duration() - cachedTimer.duration(); long timingDifference = uncachedTimer.duration() - cachedTimer.duration();
Log.d("testCaching", "Cached query is "+ timingDifference +" nanoseconds faster than the uncached query"); assertTrue("Cached query is "+ timingDifference +" nanoseconds faster than the uncached query",
cachedTimer.duration() < uncachedTimer.duration());
assert cachedTimer.duration() < uncachedTimer.duration();
} }
} }

View file

@ -0,0 +1 @@
manifest=--none