From 6d9eaaabb211d538866edfa362c7a4abea05a962 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Fri, 18 Jul 2014 19:05:38 +0200 Subject: [PATCH 1/8] work on test prepare script, make the whole thing optional --- .gitignore | 3 +++ .travis.yml | 2 +- install-custom-gradle-test-plugin.sh | 15 -------------- prepare-tests.sh | 30 ++++++++++++++++++++++++++++ settings.gradle | 1 - 5 files changed, 34 insertions(+), 17 deletions(-) delete mode 100755 install-custom-gradle-test-plugin.sh create mode 100755 prepare-tests.sh diff --git a/.gitignore b/.gitignore index 1dfe84d5a..68f5b5a9e 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,9 @@ ant.properties .gradle build gradle.properties +# this is in here because the prepare-tests thing modifies it, and we DON'T +# want this to be commited. use git add -f to work on this file. +settings.gradle #Maven target diff --git a/.travis.yml b/.travis.yml index fd6e55ea7..ef69eb556 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ before_install: # Install required Android components. #- echo "y" | android update sdk -a --filter build-tools-19.1.0,android-19,platform-tools,extra-android-support,extra-android-m2repository --no-ui --force - ( sleep 5 && while [ 1 ]; do sleep 1; echo y; done ) | android update sdk --no-ui --all --force --filter build-tools-19.1.0,android-19,platform-tools,extra-android-support,extra-android-m2repository - - ./install-custom-gradle-test-plugin.sh + - ./prepare-tests.sh install: echo "Installation done" script: - gradle assemble -S -q diff --git a/install-custom-gradle-test-plugin.sh b/install-custom-gradle-test-plugin.sh deleted file mode 100755 index 85c13d959..000000000 --- a/install-custom-gradle-test-plugin.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -mkdir temp -cd temp - - git clone https://github.com/nenick/gradle-android-test-plugin.git - cd gradle-android-test-plugin - - echo "rootProject.name = 'gradle-android-test-plugin-parent'" > settings.gradle - echo "include ':gradle-android-test-plugin'" >> settings.gradle - - ./gradlew :gradle-android-test-plugin:install - - cd .. -cd .. \ No newline at end of file diff --git a/prepare-tests.sh b/prepare-tests.sh new file mode 100755 index 000000000..027c76f84 --- /dev/null +++ b/prepare-tests.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# This script installs a plugin which is necessary to run OpenKeychain's tests +# into the local maven repository, then puts a line to include the -Test +# subproject into settings.gradle + +echo "checking jdk runtime.." +if ! java -version 2>&1 | grep OpenJDK; then + echo "tests will only run on openjdk, see readme for details!" >&2 + return +fi + +tmpdir="$(mktemp -d)" +( + cd "$tmpdir"; + git clone https://github.com/nenick/gradle-android-test-plugin.git + cd gradle-android-test-plugin + echo "rootProject.name = 'gradle-android-test-plugin-parent'" > settings.gradle + echo "include ':gradle-android-test-plugin'" >> settings.gradle + ./gradlew :gradle-android-test-plugin:install +) +rm -rf "$tmpdir" + +echo -n "ok, adding tests to include list.. " +if grep OpenKeychain-Test settings.gradle >/dev/null ; then + echo " already in." +else + echo "include ':OpenKeychain-Test'" >> settings.gradle + echo "ok" +fi diff --git a/settings.gradle b/settings.gradle index 86088e04a..d8802320c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,4 @@ include ':OpenKeychain' -include ':OpenKeychain-Test' include ':extern:openpgp-api-lib' include ':extern:openkeychain-api-lib' include ':extern:html-textview' From 19dc49153d7942912d2d16664e0118751b560d66 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 19 Jul 2014 01:31:34 +0200 Subject: [PATCH 2/8] use jacoco for test coverage --- OpenKeychain-Test/build.gradle | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/OpenKeychain-Test/build.gradle b/OpenKeychain-Test/build.gradle index d795ace3d..a00268c59 100644 --- a/OpenKeychain-Test/build.gradle +++ b/OpenKeychain-Test/build.gradle @@ -1,5 +1,6 @@ apply plugin: 'java' apply plugin: 'android-test' +apply plugin: 'jacoco' dependencies { testCompile 'junit:junit:4.11' @@ -31,6 +32,29 @@ android { projectUnderTest ':OpenKeychain' } +jacoco { + toolVersion = "0.7.0.201403182114" +} + +coverageSourceDirs = [ + '../OpenKeychain/src/main/java', + '../OpenKeychain/src/gen', + '../OpenKeychain/build/source/apt/debug', + '../OpenKeychain/build/source/generated/buildConfig/debug', + '../OpenKeychain/build/source/generated/r/debug' + ] + +jacocoTestReport { + reports { + xml.enabled = true + html.destination "${buildDir}/jacocoHtml" + } + // class R is used, but usage will not be covered, so ignore this class from report + classDirectories = fileTree(dir: '../OpenKeychain/build/intermediates/classes/debug/org/sufficientlysecure/keychain', exclude: 'R*.class') + additionalSourceDirs = files(coverageSourceDirs) + executionData = files('build/jacoco/testDebug.exec') +} + // new workaround to force add custom output dirs for android studio task addTest { def file = file(project.name + ".iml") From 299570f1b9c550c67375f0f1a0b7ea372cc39e10 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 19 Jul 2014 02:12:04 +0200 Subject: [PATCH 3/8] test: start with UncachedKeyRing.canonicalize tests --- .../support/KeyringTestingHelper.java | 12 ++ .../keychain/tests/UncachedKeyringTest.java | 123 ++++++++++++++++-- 2 files changed, 127 insertions(+), 8 deletions(-) diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/support/KeyringTestingHelper.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/support/KeyringTestingHelper.java index 398b2393e..3fa668e6e 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/support/KeyringTestingHelper.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/support/KeyringTestingHelper.java @@ -21,6 +21,7 @@ import android.content.Context; import org.spongycastle.util.Arrays; import org.sufficientlysecure.keychain.pgp.NullProgressable; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.OperationResults; @@ -68,6 +69,11 @@ public class KeyringTestingHelper { return saveSuccess; } + public static UncachedKeyRing removePacket(UncachedKeyRing ring, int position) + throws IOException, PgpGeneralException { + return UncachedKeyRing.decodeFromData(removePacket(ring.getEncoded(), position)); + } + public static byte[] removePacket(byte[] ring, int position) throws IOException { Iterator it = parseKeyring(ring); ByteArrayOutputStream out = new ByteArrayOutputStream(ring.length); @@ -76,6 +82,7 @@ public class KeyringTestingHelper { while(it.hasNext()) { // at the right position, skip the packet if(i++ == position) { + it.next(); continue; } // write the old one @@ -89,6 +96,11 @@ public class KeyringTestingHelper { return out.toByteArray(); } + public static UncachedKeyRing injectPacket(UncachedKeyRing ring, byte[] inject, int position) + throws IOException, PgpGeneralException { + return UncachedKeyRing.decodeFromData(injectPacket(ring.getEncoded(), inject, position)); + } + public static byte[] injectPacket(byte[] ring, byte[] inject, int position) throws IOException { Iterator it = parseKeyring(ring); diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/tests/UncachedKeyringTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/tests/UncachedKeyringTest.java index 66e31c272..496850eb7 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/tests/UncachedKeyringTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/tests/UncachedKeyringTest.java @@ -31,6 +31,7 @@ import java.util.Iterator; public class UncachedKeyringTest { static UncachedKeyRing staticRing; + static int totalPackets; UncachedKeyRing ring; ArrayList onlyA = new ArrayList(); ArrayList onlyB = new ArrayList(); @@ -59,6 +60,9 @@ public class UncachedKeyringTest { Assert.assertNotNull("initial test key creation must succeed", staticRing); + // just for later reference + totalPackets = 9; + // we sleep here for a second, to make sure all new certificates have different timestamps Thread.sleep(1000); } @@ -76,24 +80,24 @@ public class UncachedKeyringTest { Assert.assertEquals("packet #1 should be secret key", PacketTags.SECRET_KEY, it.next().tag); - Assert.assertEquals("packet #2 should be secret key", + Assert.assertEquals("packet #2 should be user id", PacketTags.USER_ID, it.next().tag); - Assert.assertEquals("packet #3 should be secret key", + Assert.assertEquals("packet #3 should be signature", PacketTags.SIGNATURE, it.next().tag); - Assert.assertEquals("packet #4 should be secret key", + Assert.assertEquals("packet #4 should be user id", PacketTags.USER_ID, it.next().tag); - Assert.assertEquals("packet #5 should be secret key", + Assert.assertEquals("packet #5 should be signature", PacketTags.SIGNATURE, it.next().tag); - Assert.assertEquals("packet #6 should be secret key", + Assert.assertEquals("packet #6 should be secret subkey", PacketTags.SECRET_SUBKEY, it.next().tag); - Assert.assertEquals("packet #7 should be secret key", + Assert.assertEquals("packet #7 should be signature", PacketTags.SIGNATURE, it.next().tag); - Assert.assertEquals("packet #8 should be secret key", + Assert.assertEquals("packet #8 should be secret subkey", PacketTags.SECRET_SUBKEY, it.next().tag); - Assert.assertEquals("packet #9 should be secret key", + Assert.assertEquals("packet #9 should be signature", PacketTags.SIGNATURE, it.next().tag); Assert.assertFalse("exactly 9 packets total", it.hasNext()); @@ -103,4 +107,107 @@ public class UncachedKeyringTest { } + @Test public void testBrokenSignature() throws Exception { + + byte[] brokenSig; + { + UncachedPublicKey masterKey = ring.getPublicKey(); + WrappedSignature sig = masterKey.getSignaturesForId("twi").next(); + brokenSig = sig.getEncoded(); + // break the signature + brokenSig[brokenSig.length - 5] += 1; + } + + byte[] reng = ring.getEncoded(); + for(int i = 0; i < totalPackets; i++) { + + byte[] brokenBytes = KeyringTestingHelper.injectPacket(reng, brokenSig, i); + Assert.assertEquals("broken ring must be original + injected size", + reng.length + brokenSig.length, brokenBytes.length); + + try { + UncachedKeyRing brokenRing = UncachedKeyRing.decodeFromData(brokenBytes); + + brokenRing = brokenRing.canonicalize(log, 0); + if (brokenRing == null) { + System.out.println("ok, canonicalization failed."); + continue; + } + + Assert.assertArrayEquals("injected bad signature must be gone after canonicalization", + ring.getEncoded(), brokenRing.getEncoded()); + + } catch (Exception e) { + System.out.println("ok, rejected with: " + e.getMessage()); + } + } + + } + + @Test public void testUidSignature() throws Exception { + + UncachedPublicKey masterKey = ring.getPublicKey(); + final WrappedSignature sig = masterKey.getSignaturesForId("twi").next(); + + byte[] raw = sig.getEncoded(); + // destroy the signature + raw[raw.length - 5] += 1; + final WrappedSignature brokenSig = WrappedSignature.fromBytes(raw); + + { // bad certificates get stripped + UncachedKeyRing modified = KeyringTestingHelper.injectPacket(ring, brokenSig.getEncoded(), 3); + modified = modified.canonicalize(log, 0); + + Assert.assertTrue("canonicalized keyring with invalid extra sig must be same as original one", + !KeyringTestingHelper.diffKeyrings( + ring.getEncoded(), modified.getEncoded(), onlyA, onlyB)); + } + + // remove user id certificate for one user + final UncachedKeyRing base = KeyringTestingHelper.removePacket(ring, 2); + + { // user id without certificate should be removed + UncachedKeyRing modified = base.canonicalize(log, 0); + Assert.assertTrue("canonicalized keyring must differ", KeyringTestingHelper.diffKeyrings( + ring.getEncoded(), modified.getEncoded(), onlyA, onlyB)); + + Assert.assertEquals("two packets should be stripped after canonicalization", 2, onlyA.size()); + Assert.assertEquals("no new packets after canonicalization", 0, onlyB.size()); + + Packet p; + p = new BCPGInputStream(new ByteArrayInputStream(onlyA.get(0).buf)).readPacket(); + Assert.assertTrue("first stripped packet must be user id", p instanceof UserIDPacket); + Assert.assertEquals("missing user id must be the expected one", + "twi", ((UserIDPacket) p).getID()); + + p = new BCPGInputStream(new ByteArrayInputStream(onlyA.get(1).buf)).readPacket(); + Assert.assertArrayEquals("second stripped packet must be signature we removed", + sig.getEncoded(), onlyA.get(1).buf); + + } + + { // add error to signature + + UncachedKeyRing modified = KeyringTestingHelper.injectPacket(base, brokenSig.getEncoded(), 3); + modified = modified.canonicalize(log, 0); + + Assert.assertTrue("canonicalized keyring must differ", KeyringTestingHelper.diffKeyrings( + ring.getEncoded(), modified.getEncoded(), onlyA, onlyB)); + + Assert.assertEquals("two packets should be missing after canonicalization", 2, onlyA.size()); + Assert.assertEquals("no new packets after canonicalization", 0, onlyB.size()); + + Packet p; + p = new BCPGInputStream(new ByteArrayInputStream(onlyA.get(0).buf)).readPacket(); + Assert.assertTrue("first stripped packet must be user id", p instanceof UserIDPacket); + Assert.assertEquals("missing user id must be the expected one", + "twi", ((UserIDPacket) p).getID()); + + p = new BCPGInputStream(new ByteArrayInputStream(onlyA.get(1).buf)).readPacket(); + Assert.assertArrayEquals("second stripped packet must be signature we removed", + sig.getEncoded(), onlyA.get(1).buf); + } + + } + } From cd1511a4e6d346d177be7d828faa82f99e46685c Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 19 Jul 2014 02:19:15 +0200 Subject: [PATCH 4/8] canonicalize: fix for tests --- .../sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 1 + .../sufficientlysecure/keychain/pgp/UncachedKeyRing.java | 8 ++++++-- .../keychain/pgp/UncachedPublicKey.java | 3 --- .../keychain/service/OperationResultParcel.java | 2 ++ OpenKeychain/src/main/res/values/strings.xml | 2 ++ extern/spongycastle | 2 +- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index bd8a9201e..00f73a5b0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -599,6 +599,7 @@ public class PgpKeyOperation { log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_ENCODE, indent+1); return null; } catch (PGPException e) { + Log.e(Constants.TAG, "encountered pgp error while modifying key", e); log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_PGP, indent+1); return null; } catch (SignatureException e) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java index 9ddfd3405..6020fc084 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -229,7 +229,7 @@ public class UncachedKeyRing { PGPPublicKey modified = masterKey; PGPSignature revocation = null; - for (PGPSignature zert : new IterableIterator(masterKey.getSignatures())) { + for (PGPSignature zert : new IterableIterator(masterKey.getKeySignatures())) { int type = zert.getSignatureType(); // Disregard certifications on user ids, we will deal with those later @@ -238,6 +238,10 @@ public class UncachedKeyRing { || type == PGPSignature.CASUAL_CERTIFICATION || type == PGPSignature.POSITIVE_CERTIFICATION || type == PGPSignature.CERTIFICATION_REVOCATION) { + // These should not be here... + log.add(LogLevel.WARN, LogType.MSG_KC_REVOKE_BAD_TYPE_UID, indent); + modified = PGPPublicKey.removeCertification(modified, zert); + badCerts += 1; continue; } WrappedSignature cert = new WrappedSignature(zert); @@ -429,7 +433,7 @@ public class UncachedKeyRing { // If no valid certificate (if only a revocation) remains, drop it if (selfCert == null && revocation == null) { modified = PGPPublicKey.removeCertification(modified, userId); - log.add(LogLevel.ERROR, LogType.MSG_KC_UID_REVOKE_DUP, + log.add(LogLevel.ERROR, LogType.MSG_KC_UID_REMOVE, indent, userId); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java index ef5aa8e86..358b1c552 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java @@ -1,8 +1,6 @@ package org.sufficientlysecure.keychain.pgp; -import org.spongycastle.bcpg.SignatureSubpacketTags; import org.spongycastle.bcpg.sig.KeyFlags; -import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPSignature; import org.spongycastle.openpgp.PGPSignatureSubpacketVector; @@ -11,7 +9,6 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; -import java.security.SignatureException; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index 705d6afaf..89d534df6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -202,6 +202,7 @@ public class OperationResultParcel implements Parcelable { MSG_KC_REVOKE_BAD_LOCAL (R.string.msg_kc_revoke_bad_local), MSG_KC_REVOKE_BAD_TIME (R.string.msg_kc_revoke_bad_time), MSG_KC_REVOKE_BAD_TYPE (R.string.msg_kc_revoke_bad_type), + MSG_KC_REVOKE_BAD_TYPE_UID (R.string.msg_kc_revoke_bad_type_uid), MSG_KC_REVOKE_BAD (R.string.msg_kc_revoke_bad), MSG_KC_REVOKE_DUP (R.string.msg_kc_revoke_dup), MSG_KC_SUB (R.string.msg_kc_sub), @@ -233,6 +234,7 @@ public class OperationResultParcel implements Parcelable { MSG_KC_UID_NO_CERT (R.string.msg_kc_uid_no_cert), MSG_KC_UID_REVOKE_DUP (R.string.msg_kc_uid_revoke_dup), MSG_KC_UID_REVOKE_OLD (R.string.msg_kc_uid_revoke_old), + MSG_KC_UID_REMOVE (R.string.msg_kc_uid_remove), // keyring consolidation diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index c1c18effe..55ecf3ae0 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -592,6 +592,7 @@ Removing keyring revocation certificate with "local" flag Removing keyring revocation certificate with future timestamp Removing master key certificate of unknown type (%s) + Removing user id certification in bad position Removing bad keyring revocation certificate Removing redundant keyring revocation certificate Processing subkey %s @@ -629,6 +630,7 @@ Removing redundant revocation certificate for user id "%s" Removing outdated revocation certificate for user id "%s" No valid self-certificate found for user id %s, removing from ring + Removing invalid user id %s Merging into public keyring %s diff --git a/extern/spongycastle b/extern/spongycastle index 968405ee5..c142a844b 160000 --- a/extern/spongycastle +++ b/extern/spongycastle @@ -1 +1 @@ -Subproject commit 968405ee5d4272330cffdf75f7eee4cd9f5c8646 +Subproject commit c142a844b680652adb751a193a4e4a926a4c080b From 8385c9c9dda37426f22adf744d203e94ff3c2034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 19 Jul 2014 15:14:20 +0200 Subject: [PATCH 5/8] Update README --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4a2fad2ee..c99020ae0 100644 --- a/README.md +++ b/README.md @@ -37,10 +37,13 @@ Expand the Tools directory and select "Android SDK Build-tools (Version 19.1)". Expand the Extras directory and install "Android Support Repository" Select everything for the newest SDK Platform (API-Level 19) 4. Export ANDROID_HOME pointing to your Android SDK -5. Use OpenJDK 7 instead of Oracle JDK (this is required for OpenKeychain's tests based on Bouncy Castle) -6. Execute ``./install-custom-gradle-test-plugin.sh`` -7. Execute ``./gradlew build`` -8. You can install the app with ``adb install -r OpenKeychain/build/outputs/apk/OpenKeychain-debug-unaligned.apk`` +5. Execute ``./gradlew build`` +6. You can install the app with ``adb install -r OpenKeychain/build/outputs/apk/OpenKeychain-debug-unaligned.apk`` + +### Run Tests +1. Use OpenJDK instead of Oracle JDK +2. Execute ``./prepare-tests.sh`` +3. Execute ``./gradlew build`` ### Build API Demo with Gradle From 207870af1df0597c7832b9eaf7cd0dbda8050ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 19 Jul 2014 15:15:31 +0200 Subject: [PATCH 6/8] Update README.md --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index c99020ae0..4eed54540 100644 --- a/README.md +++ b/README.md @@ -56,10 +56,7 @@ Select everything for the newest SDK Platform (API-Level 19) I am using the newest [Android Studio](http://developer.android.com/sdk/installing/studio.html) for development. Development with Eclipse is currently not possible because I am using the new [project structure](http://developer.android.com/sdk/installing/studio-tips.html). 1. Clone the project from github -2. From Android Studio: File -> Import Project -> ... - * Select the cloned top folder if you want to develop on the main project - * Select the "OpenKeychain-API" folder if you want to develop on the API example -3. Import project from external model -> choose Gradle +2. From Android Studio: File -> Import Project -> Select the cloned top folder ## OpenKeychain's API From 527c3e93f8c570096f52d8ae5bc3ce68bef96269 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 19 Jul 2014 15:16:45 +0200 Subject: [PATCH 7/8] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4eed54540..230fd2d6f 100644 --- a/README.md +++ b/README.md @@ -53,9 +53,9 @@ Select everything for the newest SDK Platform (API-Level 19) ### Development with Android Studio -I am using the newest [Android Studio](http://developer.android.com/sdk/installing/studio.html) for development. Development with Eclipse is currently not possible because I am using the new [project structure](http://developer.android.com/sdk/installing/studio-tips.html). +We are using the newest [Android Studio](http://developer.android.com/sdk/installing/studio.html) for development. Development with Eclipse is currently not possible because we are using the new [project structure](http://developer.android.com/sdk/installing/studio-tips.html). -1. Clone the project from github +1. Clone the project from Github 2. From Android Studio: File -> Import Project -> Select the cloned top folder ## OpenKeychain's API From f560bc9317357a755b5862c1eec142b7c4665c0a Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 21 Jul 2014 03:59:16 +0200 Subject: [PATCH 8/8] forgot to move test classpath out of root project --- OpenKeychain-Test/build.gradle | 14 ++++++++++++++ ...t.java => UncachedKeyringCanonicalizeTest.java} | 2 +- OpenKeychain/build.gradle | 1 - build.gradle | 5 ----- 4 files changed, 15 insertions(+), 7 deletions(-) rename OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/tests/{UncachedKeyringTest.java => UncachedKeyringCanonicalizeTest.java} (99%) diff --git a/OpenKeychain-Test/build.gradle b/OpenKeychain-Test/build.gradle index a00268c59..a98a79dc1 100644 --- a/OpenKeychain-Test/build.gradle +++ b/OpenKeychain-Test/build.gradle @@ -1,3 +1,17 @@ +buildscript { + repositories { + mavenCentral() + // need this for com.novoda:gradle-android-test-plugin:0.9.9-SNAPSHOT below (0.9.3 in repos doesn't work!) + // run ./install-custom-gradle-test-plugin.sh to pull the thing into the local repository + mavenLocal() + } + + 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.novoda:gradle-android-test-plugin:0.9.9-SNAPSHOT' + } +} + apply plugin: 'java' apply plugin: 'android-test' apply plugin: 'jacoco' diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/tests/UncachedKeyringTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/tests/UncachedKeyringCanonicalizeTest.java similarity index 99% rename from OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/tests/UncachedKeyringTest.java rename to OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/tests/UncachedKeyringCanonicalizeTest.java index 496850eb7..6f3cf31b5 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/tests/UncachedKeyringTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/tests/UncachedKeyringCanonicalizeTest.java @@ -28,7 +28,7 @@ import java.util.Iterator; @RunWith(RobolectricTestRunner.class) @org.robolectric.annotation.Config(emulateSdk = 18) // Robolectric doesn't yet support 19 -public class UncachedKeyringTest { +public class UncachedKeyringCanonicalizeTest { static UncachedKeyRing staticRing; static int totalPackets; diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index a6c01543c..11fa54a57 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -1,5 +1,4 @@ apply plugin: 'android' -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 diff --git a/build.gradle b/build.gradle index 698b4cd37..05e90eb17 100644 --- a/build.gradle +++ b/build.gradle @@ -1,16 +1,11 @@ buildscript { repositories { mavenCentral() - // need this for com.novoda:gradle-android-test-plugin:0.9.9-SNAPSHOT below (0.9.3 in repos doesn't work!) - // run ./install-custom-gradle-test-plugin.sh to pull the thing into the local repository - mavenLocal() } 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.12.0' - classpath 'org.robolectric:robolectric-gradle-plugin:0.11.0' - classpath 'com.novoda:gradle-android-test-plugin:0.9.9-SNAPSHOT' } }