From d06ba72edc3136ef2ff8a758e8d53fa13347c778 Mon Sep 17 00:00:00 2001 From: Art O Cathain Date: Sun, 15 Jun 2014 16:08:41 +0100 Subject: [PATCH] Start on Robolectric integration test --- OpenKeychain/build.gradle | 53 +++++------ .../src/androidTest/java/tests/SomeTest.java | 12 --- .../testsupport/PgpVerifyTestingHelper.java | 82 ++++++++++++++++++ .../keychain/testsupport/package-info.java | 7 ++ .../src/test/java/tests/RoboTest.java | 37 ++++++++ .../test/resources/public-key-for-sample.blob | Bin 0 -> 35198 bytes .../src/test/resources/sample-altered.txt | 26 ++++++ OpenKeychain/src/test/resources/sample.txt | 26 ++++++ build.gradle | 2 +- 9 files changed, 202 insertions(+), 43 deletions(-) delete mode 100644 OpenKeychain/src/androidTest/java/tests/SomeTest.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/testsupport/PgpVerifyTestingHelper.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/testsupport/package-info.java create mode 100644 OpenKeychain/src/test/java/tests/RoboTest.java create mode 100644 OpenKeychain/src/test/resources/public-key-for-sample.blob create mode 100644 OpenKeychain/src/test/resources/sample-altered.txt create mode 100644 OpenKeychain/src/test/resources/sample.txt diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index ba527948a..b39c19bfa 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -1,13 +1,5 @@ apply plugin: 'android' -//apply plugin: 'android-test' - -sourceSets { - //androidTest { - //java.srcDir file('src/test/java') - // configure the set of classes for JUnit tests - // include '**/*Test.class' - //} -} +apply plugin: 'robolectric' dependencies { // NOTE: Always use fixed version codes not dynamic ones, e.g. 0.7.3 instead of 0.7.+, see README for more information @@ -29,26 +21,27 @@ dependencies { compile project(':extern:SuperToasts:supertoasts') compile project(':extern:dnsjava') - // Dependencies for the `instrumentTest` task, make sure to list all your global dependencies here as well - androidTestCompile 'junit:junit:4.11' - androidTestCompile 'org.robolectric:robolectric:2.3' - androidTestCompile 'com.squareup:fest-android:1.0.8' - androidTestCompile 'com.google.android:android:4.1.1.4' - androidTestCompile 'com.android.support:support-v4:19.1.0' - androidTestCompile 'com.android.support:appcompat-v7:19.1.0' - androidTestCompile project(':extern:openpgp-api-lib') - androidTestCompile project(':extern:openkeychain-api-lib') - androidTestCompile project(':extern:html-textview') - androidTestCompile project(':extern:StickyListHeaders:library') - androidTestCompile project(':extern:AndroidBootstrap:AndroidBootstrap') - androidTestCompile project(':extern:zxing-qr-code') - androidTestCompile project(':extern:zxing-android-integration') - androidTestCompile project(':extern:spongycastle:core') - androidTestCompile project(':extern:spongycastle:pg') - androidTestCompile project(':extern:spongycastle:pkix') - androidTestCompile project(':extern:spongycastle:prov') - androidTestCompile project(':extern:AppMsg:library') - androidTestCompile project(':extern:SuperToasts:supertoasts') + + // Unit tests are run with Robolectric + testCompile 'junit:junit:4.11' + testCompile 'org.robolectric:robolectric:2.3' + testCompile 'com.squareup:fest-android:1.0.8' + testCompile 'com.google.android:android:4.1.1.4' + testCompile 'com.android.support:support-v4:19.1.0' + testCompile 'com.android.support:appcompat-v7:19.1.0' + testCompile project(':extern:openpgp-api-lib') + testCompile project(':extern:openkeychain-api-lib') + testCompile project(':extern:html-textview') + testCompile project(':extern:StickyListHeaders:library') + testCompile project(':extern:AndroidBootstrap:AndroidBootstrap') + testCompile project(':extern:zxing-qr-code') + testCompile project(':extern:zxing-android-integration') + testCompile project(':extern:spongycastle:core') + testCompile project(':extern:spongycastle:pg') + testCompile project(':extern:spongycastle:pkix') + testCompile project(':extern:spongycastle:prov') + testCompile project(':extern:AppMsg:library') + testCompile project(':extern:SuperToasts:supertoasts') } @@ -57,7 +50,7 @@ android { buildToolsVersion "19.1" defaultConfig { - minSdkVersion 9 + minSdkVersion 15 targetSdkVersion 19 } diff --git a/OpenKeychain/src/androidTest/java/tests/SomeTest.java b/OpenKeychain/src/androidTest/java/tests/SomeTest.java deleted file mode 100644 index edf5f7bcc..000000000 --- a/OpenKeychain/src/androidTest/java/tests/SomeTest.java +++ /dev/null @@ -1,12 +0,0 @@ -package tests; - -import org.junit.Assert; -import org.junit.Test; - -public class SomeTest { - @Test - public void willFail() { - // stub - // Assert.assertThat(); - } -} \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/testsupport/PgpVerifyTestingHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/testsupport/PgpVerifyTestingHelper.java new file mode 100644 index 000000000..d5edae5f0 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/testsupport/PgpVerifyTestingHelper.java @@ -0,0 +1,82 @@ +package org.sufficientlysecure.keychain.testsupport; + +import android.content.Context; +import android.net.Uri; + +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult; +import org.sufficientlysecure.keychain.pgp.WrappedPublicKeyRing; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.util.InputData; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * For functional tests of PgpDecryptVerify + */ +public class PgpVerifyTestingHelper { + + private final Context context; + + public PgpVerifyTestingHelper(Context robolectricContext) { + this.context=robolectricContext; + } + + public int doTestFile(String testFileName) throws Exception { + ProviderHelper providerHelper = new ProviderHelperStub(context); + + PgpDecryptVerify.PassphraseCache passphraseCache = new PgpDecryptVerify.PassphraseCache() { + public String getCachedPassphrase(long masterKeyId) { + return "I am a passphrase"; + } + }; + + InputStream sampleInput = getClass().getResourceAsStream(testFileName); + assert null != sampleInput; + InputData data = new InputData(sampleInput, 705); + OutputStream outStream = new ByteArrayOutputStream(); + + PgpDecryptVerify verify = new PgpDecryptVerify.Builder(providerHelper, passphraseCache, data, outStream).build(); + PgpDecryptVerifyResult result = verify.execute(); + + return result.getSignatureResult().getStatus(); + } + + + static class ProviderHelperStub extends ProviderHelper { + public ProviderHelperStub(Context context) { + super(context); + } + + @Override + public WrappedPublicKeyRing getWrappedPublicKeyRing(Uri id) throws NotFoundException { + try { + byte[] data = readFully(getClass().getResourceAsStream("/public-key-for-sample.blob")); + return new WrappedPublicKeyRing(data, false, 0); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + public static byte[] readFully(InputStream input) throws IOException + { + byte[] buffer = new byte[8192]; + int bytesRead; + ByteArrayOutputStream output = new ByteArrayOutputStream(); + while ((bytesRead = input.read(buffer)) != -1) + { + output.write(buffer, 0, bytesRead); + } + return output.toByteArray(); + } + + + + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/testsupport/package-info.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/testsupport/package-info.java new file mode 100644 index 000000000..1cc0f9a95 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/testsupport/package-info.java @@ -0,0 +1,7 @@ +/** + * Test support classes. + * This is only in main code because of gradle-Android Studio-robolectric issues. Having + * classes in main code means IDE autocomplete, class detection, etc., all works. + * TODO Move into test package when possible + */ +package org.sufficientlysecure.keychain.testsupport; diff --git a/OpenKeychain/src/test/java/tests/RoboTest.java b/OpenKeychain/src/test/java/tests/RoboTest.java new file mode 100644 index 000000000..1a4f6b4aa --- /dev/null +++ b/OpenKeychain/src/test/java/tests/RoboTest.java @@ -0,0 +1,37 @@ +package tests; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.*; +import org.openintents.openpgp.OpenPgpSignatureResult; +import org.sufficientlysecure.keychain.testsupport.PgpVerifyTestingHelper; + +@RunWith(RobolectricTestRunner.class) +@org.robolectric.annotation.Config(emulateSdk = 18) // Robolectric doesn't yet support 19 +public class RoboTest { + + @Test + public void testVerifySuccess() throws Exception { + + String testFileName = "/sample.txt"; + int expectedSignatureResult = OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED; + + int status = new PgpVerifyTestingHelper(Robolectric.application).doTestFile(testFileName); + + Assert.assertEquals(expectedSignatureResult, status); + } + + + @Test + public void testVerifyFailure() throws Exception { + + String testFileName = "/sample-altered.txt"; + int expectedSignatureResult = OpenPgpSignatureResult.SIGNATURE_ERROR; + + int status = new PgpVerifyTestingHelper(Robolectric.application).doTestFile(testFileName); + + Assert.assertEquals(expectedSignatureResult, status); + } + +} diff --git a/OpenKeychain/src/test/resources/public-key-for-sample.blob b/OpenKeychain/src/test/resources/public-key-for-sample.blob new file mode 100644 index 0000000000000000000000000000000000000000..4aa91510bb558e243f773771960c528fac5ac05b GIT binary patch literal 35198 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 + +iQA/AwUBN78ib3S9RCOKzj55EQKqDACg1NV2/iyPKrDlOVJvJwz6ArcQ0UQAnjNC +CDxKAFyaaGa835l1vpbFkAJk +=3r/N +-----END PGP SIGNATURE----- diff --git a/OpenKeychain/src/test/resources/sample.txt b/OpenKeychain/src/test/resources/sample.txt new file mode 100644 index 000000000..c0065f78d --- /dev/null +++ b/OpenKeychain/src/test/resources/sample.txt @@ -0,0 +1,26 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +This is a simple text document, which is used to illustrate +the concept of signing simple text files. There are no +control characters or special formatting commands in this +text, just simple printable ASCII characters. + +To make this a slightly less uninteresting document, there +follows a short shopping list. + + eggs, 1 doz + milk, 1 gal + bacon, 1 lb + olive oil + bread, 1 loaf + +That's all there is to this document. + +-----BEGIN PGP SIGNATURE----- +Version: PGPfreeware 5.5.5 for non-commercial use + +iQA/AwUBN78ib3S9RCOKzj55EQKqDACg1NV2/iyPKrDlOVJvJwz6ArcQ0UQAnjNC +CDxKAFyaaGa835l1vpbFkAJk +=3r/N +-----END PGP SIGNATURE----- diff --git a/build.gradle b/build.gradle index e3cafe3ce..e0da6b52f 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { dependencies { // NOTE: Always use fixed version codes not dynamic ones, e.g. 0.7.3 instead of 0.7.+, see README for more information classpath 'com.android.tools.build:gradle:0.11.1' - //classpath 'org.robolectric.gradle:gradle-android-test-plugin:0.10.0' + classpath 'org.robolectric:robolectric-gradle-plugin:0.11.0' } }