diff --git a/android/build.gradle b/android/build.gradle index da8455a..f058512 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -2,7 +2,8 @@ def pEpEngineSrc = hasProperty('pEpEngineSrc') ? pEpEngineSrc : "../../pEpEngine" def buildAutomatic = hasProperty('buildAutomatic') ? buildAutomatic : "true" -def threadsToUse = hasProperty('threadsToUse') ? threadsToUse : 1 +def threadsToUse = hasProperty('threadsToUse') ? + threadsToUse : Runtime.getRuntime().availableProcessors() def pEpEngineDB = new File(new File(pEpEngineSrc), 'db') @@ -77,7 +78,7 @@ android { jniDebuggable true externalNativeBuild { ndkBuild { - arguments "-j${threadsToUse}", 'NDK_LOG=1' + arguments "-j${threadsToUse}", 'NDK_LOG=1', 'NDK_DEBUG=1', 'NDEBUG=null' // arguments '-B', 'NDK_DEBUG=1', 'NDEBUG=null', 'NDK_LOG=1' } } diff --git a/android/external/Makefile.conf b/android/external/Makefile.conf index 60890e5..561134d 100644 --- a/android/external/Makefile.conf +++ b/android/external/Makefile.conf @@ -20,7 +20,7 @@ NETTLE_VERSION=3.4.1 ### Git deps repos EXTERNAL_GIT_REPOS += libetpan|https://github.com/fdik/libetpan.git?HEAD -EXTERNAL_GIT_REPOS += sequoia|https://gitlab.com/sequoia-pgp/sequoia.git?b5b783f58c9b6fdb26163cb7b236ee71cfef339e +EXTERNAL_GIT_REPOS += sequoia|https://gitlab.com/sequoia-pgp/sequoia.git?de497f59570437d448b293769eb57bf7a9741f30 ### Common variables #### Source code targets diff --git a/src/codegen/gen_cpp_Engine.ysl2 b/src/codegen/gen_cpp_Engine.ysl2 index f1a193c..96b9d93 100644 --- a/src/codegen/gen_cpp_Engine.ysl2 +++ b/src/codegen/gen_cpp_Engine.ysl2 @@ -273,6 +273,7 @@ tstylesheet { const "dir", "name(*[1])"; const "type", "name(*[2])"; const "name", "name(*[3])"; + const "const", "name(*[4])"; choose { when "$type = 'message'" @@ -283,10 +284,18 @@ tstylesheet { | bool _«$name» = (bool) «$name»; when "$type='int'" | int _«$name» = (int) «$name»; + when "$type='uint'" + | auto _«$name» = (unsigned int) «$name»; when "$type='string'" | const char *_«$name» = to_string(env, «$name»); - otherwise - | √$type *_«$name» = to_«$type»(env, «$name»); + otherwise { + choose { + when "$const" + | const √$type *_«$name» = to_«$type»(env, «$name»); + otherwise + | √$type *_«$name» = to_«$type»(env, «$name»); + } + } } } diff --git a/src/codegen/pEp.yml2 b/src/codegen/pEp.yml2 index 8810026..c3022fa 100644 --- a/src/codegen/pEp.yml2 +++ b/src/codegen/pEp.yml2 @@ -119,14 +119,14 @@ namespace pEp { inout int flags ); - method re_evaluate_message_rating( + method cached=true re_evaluate_message_rating( in message src, - Cconst stringlist x_keylist "NULL", + Cconst stringlist x_keylist "static_cast(nullptr)", Cconst Rating x_enc_status "PEP_rating_undefined", returns Rating rating ); - method outgoing_message_rating( + method cached=true outgoing_message_rating( in message msg, returns Rating rating ); @@ -136,18 +136,18 @@ namespace pEp { returns Rating rating ); - method get_identity( + method cached=true get_identity( in string address, in string userid, returns identity ident ); - method identity_rating( + method cached=true identity_rating( in identity ident, returns Rating rating ); - method blacklist_retrieve( + method cached=true blacklist_retrieve( returns stringlist blacklist ); @@ -157,34 +157,36 @@ namespace pEp { returns identity ident ); - method OpenPGP_list_keyinfo( + method cached=true OpenPGP_list_keyinfo( in string pattern, returns stringpairlist keyinfoList ); - method set_identity_flags( + //TODO Move to use IdentityFlag instead of ints + method cached=true set_identity_flags( in identity ident, - in int flags + in uint flags ); - method unset_identity_flags( + method cached=true unset_identity_flags( in identity ident, - in int flags + in uint flags ); - method own_identities_retrieve( + method cached=true own_identities_retrieve( returns identitylist identities ); - method get_trustwords( - in identity id1, - in identity id2, + + method cached=true get_trustwords( + in identity id1 const, + in identity id2 const, in string lang, returns sstring words, in bool full ); - method get_trustwords_for_fprs( + method cached=true get_trustwords_for_fprs( in string fpr1, in string fpr2, in string lang, @@ -201,13 +203,13 @@ namespace pEp { in bool full ); - method get_languagelist( + method cached=true get_languagelist( returns string languagelist ); // this function is not related to key reset - method key_reset_trust( + method cached=true key_reset_trust( in identity ident ); @@ -223,14 +225,14 @@ namespace pEp { method cached=true key_reset_all_own_keys(); - method deliverHandshakeResult( + method cached=true deliverHandshakeResult( in SyncHandshakeResult shr, - in identitylist identities + in identitylist identities const ); - method leave_device_group(); + method cached=true leave_device_group(); - method enable_identity_for_sync( + method cached=true enable_identity_for_sync( in identity ident ); diff --git a/src/codegen/types_c.ysl2 b/src/codegen/types_c.ysl2 index 1ec81ea..0d2497f 100644 --- a/src/codegen/types_c.ysl2 +++ b/src/codegen/types_c.ysl2 @@ -17,6 +17,7 @@ function "toC" { when "$type='Rating'" > PEP_rating when "$type='SyncHandshakeResult'" > sync_handshake_result when "$type='CipherSuite'" > PEP_CIPHER_SUITE + when "$type='uint'" > uint otherwise value "$type"; } @@ -31,6 +32,7 @@ function "jni_type" { when "$type = 'string' or $type = 'sstring'" > jbyteArray when "$type='bool'" > jboolean when "$type='int'" > jint + when "$type='uint'" > jint otherwise > jobject } } diff --git a/src/codegen/types_java.ysl2 b/src/codegen/types_java.ysl2 index a6806e5..6e67660 100644 --- a/src/codegen/types_java.ysl2 +++ b/src/codegen/types_java.ysl2 @@ -4,6 +4,7 @@ function "toJava" { choose { when "$type='bool'" > Boolean when "$type='int'" > int + when "$type='uint'" > int when "$type='string' or $type='sstring'" > String when "$type='timestamp'" > Date when "$type='void'" > void diff --git a/src/cxx/basic_api.cc b/src/cxx/basic_api.cc index 469b822..3d8d14d 100644 --- a/src/cxx/basic_api.cc +++ b/src/cxx/basic_api.cc @@ -9,6 +9,7 @@ #include "throw_pEp_exception.hh" #include "jniutils.hh" +#include "passphrase_callback.hh" extern "C" { using namespace pEp::JNIAdapter; @@ -33,11 +34,18 @@ JNIEXPORT jbyteArray JNICALL Java_foundation_pEp_jniadapter_Engine__1trustwords( char *words; size_t wsize; + PEP_STATUS status = PEP_STATUS_OK; + if (_ident->fpr == NULL || _ident->fpr[0] == 0) { if (_ident->me) - ::myself(session(), _ident); + status = passphraseWrap(::myself, session(), _ident); else - ::update_identity(session(), _ident); + status = passphraseWrap(::update_identity, session(), _ident); + } + + if (status != PEP_STATUS_OK) { + throw_pEp_Exception(env, status); + return NULL; } if (_ident->fpr == NULL || _ident->fpr[0] == 0) { @@ -51,7 +59,9 @@ JNIEXPORT jbyteArray JNICALL Java_foundation_pEp_jniadapter_Engine__1trustwords( else lang = "en"; - PEP_STATUS status = ::trustwords(session(), _ident->fpr, lang, &words, &wsize, 10); + status = passphraseWrap(::trustwords, + session(), (const char *) _ident->fpr, lang, &words, &wsize, 10); + if (status != PEP_STATUS_OK) { throw_pEp_Exception(env, status); return NULL; @@ -76,7 +86,7 @@ JNIEXPORT jobject JNICALL Java_foundation_pEp_jniadapter_Engine__1myself( pEp_identity *_ident = to_identity(env, ident); - PEP_STATUS status = ::myself(session(), _ident); + PEP_STATUS status = passphraseWrap(::myself, session(), _ident); if (status != PEP_STATUS_OK) { LOGD("Failed Myself: 0x%04x\\n", status); @@ -102,7 +112,7 @@ JNIEXPORT jobject JNICALL Java_foundation_pEp_jniadapter_Engine__1updateIdentity pEp_identity *_ident = to_identity(env, ident); - ::update_identity(session(), _ident); + passphraseWrap(::update_identity, session(), _ident); return from_identity(env, _ident); } @@ -123,9 +133,9 @@ JNIEXPORT jobject JNICALL Java_foundation_pEp_jniadapter_Engine__1setOwnKey( std::lock_guard l(*mutex_local); pEp_identity *_ident = to_identity(env, ident); - char *_fpr = to_string(env, fpr); + const char *_fpr = to_string(env, fpr); - PEP_STATUS status = ::set_own_key(session(), _ident, _fpr); + PEP_STATUS status = passphraseWrap(::set_own_key, session(), _ident, _fpr); if (status != PEP_STATUS_OK) { LOGD("Failed setOwnKey: 0x%04x\\n", status); @@ -152,11 +162,18 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1keyMistrusted( pEp_identity *_ident = to_identity(env, ident); + PEP_STATUS status = PEP_STATUS_OK; + if (_ident->fpr == NULL || _ident->fpr[0] == 0) { if (_ident->me) - ::myself(session(), _ident); + status = passphraseWrap(::myself, session(), _ident); else - ::update_identity(session(), _ident); + status = passphraseWrap(::update_identity, session(), _ident); + } + + if (status != PEP_STATUS_OK) { + throw_pEp_Exception(env, status); + return; } if (_ident->fpr == NULL || _ident->fpr[0] == 0) { @@ -164,7 +181,7 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1keyMistrusted( return; } - ::key_mistrusted(session(), _ident); + passphraseWrap(::key_mistrusted, session(), _ident); } JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1keyResetTrust( @@ -183,11 +200,18 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1keyResetTrust( pEp_identity *_ident = to_identity(env, ident); + PEP_STATUS status = PEP_STATUS_OK; + if (_ident->fpr == NULL || _ident->fpr[0] == 0) { if (_ident->me) - ::myself(session(), _ident); + status = passphraseWrap(::myself, session(), _ident); else - ::update_identity(session(), _ident); + status = passphraseWrap(::update_identity, session(), _ident); + } + + if (status != PEP_STATUS_OK) { + throw_pEp_Exception(env, status); + return; } if (_ident->fpr == NULL || _ident->fpr[0] == 0) { @@ -195,7 +219,7 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1keyResetTrust( return; } - ::key_reset_trust(session(), _ident); + passphraseWrap(::key_reset_trust, session(), _ident); } JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1trustPersonalKey( @@ -214,11 +238,18 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1trustPersonalKey( pEp_identity *_ident = to_identity(env, ident); + PEP_STATUS status = PEP_STATUS_OK; + if (_ident->fpr == NULL || _ident->fpr[0] == 0) { if (_ident->me) - ::myself(session(), _ident); + status = passphraseWrap(::myself, session(), _ident); else - ::update_identity(session(), _ident); + status = passphraseWrap(::update_identity, session(), _ident); + } + + if (status != PEP_STATUS_OK) { + throw_pEp_Exception(env, status); + return; } if (_ident->fpr == NULL || _ident->fpr[0] == 0) { @@ -226,7 +257,7 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1trustPersonalKey( return; } - ::trust_personal_key(session(), _ident); + passphraseWrap(::trust_personal_key, session(), _ident); } JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1trustOwnKey( @@ -250,7 +281,7 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1trustOwnKey( return; } - ::trust_own_key(session(), _ident); + passphraseWrap(::trust_own_key, session(), _ident); } JNIEXPORT jobject JNICALL Java_foundation_pEp_jniadapter_Engine__1importKey( @@ -268,7 +299,7 @@ JNIEXPORT jobject JNICALL Java_foundation_pEp_jniadapter_Engine__1importKey( std::lock_guard l(*mutex_local); size_t _size = (size_t) env->GetArrayLength(key); - char *_key = (char *) env->GetByteArrayElements(key, NULL); + const char *_key = (char *) env->GetByteArrayElements(key, NULL); if(_key == NULL){ throw_pEp_Exception(env, PEP_OUT_OF_MEMORY); @@ -277,7 +308,7 @@ JNIEXPORT jobject JNICALL Java_foundation_pEp_jniadapter_Engine__1importKey( identity_list *_identities; - PEP_STATUS status = ::import_key(session(), _key, _size, &_identities); + PEP_STATUS status = passphraseWrap(::import_key, session(), _key, _size, &_identities); if (status != PEP_STATUS_OK && status != PEP_KEY_IMPORTED) { throw_pEp_Exception(env, status); return NULL; @@ -342,14 +373,14 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1blacklist_1add( } std::lock_guard l(*mutex_local); - char *_fpr = to_string(env, fpr); + const char *_fpr = to_string(env, fpr); if(_fpr == NULL){ throw_pEp_Exception(env, PEP_OUT_OF_MEMORY); return; } - PEP_STATUS status = ::blacklist_add(session(), _fpr); + PEP_STATUS status = passphraseWrap(::blacklist_add, session(), _fpr); if (status != PEP_STATUS_OK) { throw_pEp_Exception(env, status); return; @@ -371,14 +402,14 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1blacklist_1delete } std::lock_guard l(*mutex_local); - char *_fpr = to_string(env, fpr); + const char *_fpr = to_string(env, fpr); if(_fpr == NULL){ throw_pEp_Exception(env, PEP_OUT_OF_MEMORY); return; } - PEP_STATUS status = ::blacklist_delete(session(), _fpr); + PEP_STATUS status = passphraseWrap(::blacklist_delete, session(), _fpr); if (status != PEP_STATUS_OK) { throw_pEp_Exception(env, status); return; @@ -400,7 +431,7 @@ JNIEXPORT jboolean JNICALL Java_foundation_pEp_jniadapter_Engine__1blacklist_1is } std::lock_guard l(*mutex_local); - char *_fpr = to_string(env, fpr); + const char *_fpr = to_string(env, fpr); bool _listed = 0; if(_fpr == NULL){ @@ -408,7 +439,7 @@ JNIEXPORT jboolean JNICALL Java_foundation_pEp_jniadapter_Engine__1blacklist_1is return 0; } - PEP_STATUS status = ::blacklist_is_listed(session(), _fpr, &_listed); + PEP_STATUS status = passphraseWrap(::blacklist_is_listed, session(), _fpr, &_listed); if (status != PEP_STATUS_OK) { throw_pEp_Exception(env, status); return 0; @@ -435,7 +466,7 @@ JNIEXPORT jbyteArray JNICALL Java_foundation_pEp_jniadapter_Engine__1getCrashdum int _maxlines = (int) maxlines; char *_logdata; - PEP_STATUS status = ::get_crashdump_log(session(), _maxlines, &_logdata); + PEP_STATUS status = passphraseWrap(::get_crashdump_log, session(), _maxlines, &_logdata); if ((status > PEP_STATUS_OK && status < PEP_UNENCRYPTED) || status < PEP_STATUS_OK || status >= PEP_TRUSTWORD_NOT_FOUND) { @@ -525,6 +556,7 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1config_1passphras return ; } + } } // extern "C" diff --git a/src/passphrase_callback.hh b/src/passphrase_callback.hh new file mode 100644 index 0000000..8482077 --- /dev/null +++ b/src/passphrase_callback.hh @@ -0,0 +1,15 @@ +#pragma once +#include + + +namespace pEp { + namespace JNIAdapter { + + char* passphraseRequiredCallback(); + + template PEP_STATUS passphraseWrap( + PEP_STATUS f(PEP_SESSION, A...), PEP_SESSION session, A... a); + }; +}; + +#include "passphrase_callback.hxx" \ No newline at end of file diff --git a/src/passphrase_callback.hxx b/src/passphrase_callback.hxx new file mode 100644 index 0000000..20bfa36 --- /dev/null +++ b/src/passphrase_callback.hxx @@ -0,0 +1,41 @@ +#pragma once + +#include "passphrase_callback.hh" + +namespace pEp { + namespace JNIAdapter { + + template PEP_STATUS passphraseWrap( + PEP_STATUS f(PEP_SESSION, A...), PEP_SESSION session, A... a) { + pEpLog("cached passphrase mode"); + bool retryAgain = false; + int maxRetries = 3; + int retryCount = 0; + PEP_STATUS status; + do { + // the actual target function + pEpLog("calling passphrase_cache.api from basic_api"); + status = passphrase_cache.api(f, session, a...); + pEpLog("PEP_STATUS:" << status); + if (status == PEP_PASSPHRASE_REQUIRED || status == PEP_WRONG_PASSPHRASE) { + pEpLog("none of the cached passphrases worked"); + if (retryCount < maxRetries) { + // call the app + char *_passphrase = passphraseRequiredCallback(); + pEpLog("callback returned, config_passphrase() with new passphrase"); + PEP_STATUS status = ::config_passphrase(session, + passphrase_cache.add(_passphrase)); + retryAgain = true; + retryCount++; + } else { + pEpLog("max retries reached:" << maxRetries); + retryAgain = false; + } + } else { + retryAgain = false; + } + } while (retryAgain); + return status; + } + } +} \ No newline at end of file diff --git a/test/java/foundation/pEp/jniadapter/test/Makefile b/test/java/foundation/pEp/jniadapter/test/Makefile index bb1aebe..5d18cf1 100644 --- a/test/java/foundation/pEp/jniadapter/test/Makefile +++ b/test/java/foundation/pEp/jniadapter/test/Makefile @@ -11,7 +11,12 @@ run: compile $(MAKE) -C jni91 run $(MAKE) -C jni92 run $(MAKE) -C jni94 run + $(MAKE) -C jni96 run $(MAKE) -C jni98 run + $(MAKE) -C jni100 run + $(MAKE) -C jni111 run + $(MAKE) -C jni114 run + $(MAKE) -C jni115 run compile: $(MAKE) -C templateAlice compile @@ -22,7 +27,12 @@ compile: $(MAKE) -C jni91 compile $(MAKE) -C jni92 compile $(MAKE) -C jni94 compile + $(MAKE) -C jni96 compile $(MAKE) -C jni98 compile + $(MAKE) -C jni100 compile + $(MAKE) -C jni111 compile + $(MAKE) -C jni114 compile + $(MAKE) -C jni115 compile clean: $(MAKE) -C templateAlice clean @@ -33,7 +43,12 @@ clean: $(MAKE) -C jni91 clean $(MAKE) -C jni92 clean $(MAKE) -C jni94 clean + $(MAKE) -C jni96 clean $(MAKE) -C jni98 clean + $(MAKE) -C jni100 clean + $(MAKE) -C jni111 clean + $(MAKE) -C jni114 clean + $(MAKE) -C jni115 clean clean-pep-home: $(MAKE) -C basic clean-pep-home diff --git a/test/java/foundation/pEp/jniadapter/test/jni115/Makefile b/test/java/foundation/pEp/jniadapter/test/jni115/Makefile new file mode 100644 index 0000000..cbf5351 --- /dev/null +++ b/test/java/foundation/pEp/jniadapter/test/jni115/Makefile @@ -0,0 +1,37 @@ +include ../../../../../../../Makefile.conf +include ../Makefile.conf + +TEST_UNIT_NAME=jni115 + +JAVA_CLASSES = \ + TestAlice.class \ + ../utils/AdapterBaseTestContext.class \ + ../utils/AdapterTestUtils.class \ + ../utils/TestCallbacks.class + +.PHONY: pitytest compile alice test clean + +all: alice compile + +pitytest: + $(MAKE) -C $(PITYTEST_DIR) + +alice: compile clean-pep-home-alice + cd $(JAVA_CWD);pwd;HOME=$(JAVA_PEP_HOME_DIR_ALICE) $(JAVA) $(JAVA_PKG_BASENAME).$(TEST_UNIT_NAME).TestAlice + +compile: $(JAVA_CLASSES) pitytest + +%.class: %.java + cd $(JAVA_CWD);javac -cp $(CLASSPATH) $(JAVA_PKG_BASEPATH)/$(TEST_UNIT_NAME)/$< + +clean: + rm -f $(JAVA_CLASSES) + rm -f *.class + rm -f *.log + rm -Rf .gnupg + rm -Rf .lldb + +clean-pep-home: clean-pep-home-alice + +clean-pep-home-alice: + rm -rf $(PEP_HOME_DIR_ALICE)/.pEp diff --git a/test/java/foundation/pEp/jniadapter/test/jni115/TestAlice.java b/test/java/foundation/pEp/jniadapter/test/jni115/TestAlice.java new file mode 100644 index 0000000..fb82385 --- /dev/null +++ b/test/java/foundation/pEp/jniadapter/test/jni115/TestAlice.java @@ -0,0 +1,123 @@ +package foundation.pEp.jniadapter.test.jni115; + +import static foundation.pEp.pitytest.TestLogger.*; + +import foundation.pEp.jniadapter.Message; +import foundation.pEp.pitytest.*; +import foundation.pEp.pitytest.utils.TestUtils; +import foundation.pEp.jniadapter.test.utils.*; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; + +class Jni115TestContext extends AdapterBaseTestContext { + public int messagesToBobCount = 10; + public List messagesToBobSmall; + public List messagesToBobBig; + public List messagesToBobHuge; + public List messagesToBob; + + @Override + public void init() throws Throwable { + super.init(); + messagesToBobSmall = new ArrayList<>(); + messagesToBobBig = new ArrayList<>(); + messagesToBobHuge = new ArrayList<>(); + + log("Preparing " + messagesToBobCount + " messagesToBob small"); + for (int i = 0; i < messagesToBobCount; i++) { + logRaw("."); + Message tmp = AdapterTestUtils.makeNewTestMessage(alice, bob, Message.Direction.Outgoing); + tmp.setLongmsg(tmp.getLongmsg() + " nr: " + String.valueOf(i)); + messagesToBobSmall.add(tmp); + } + logRaw("\n"); + + + log("Preparing " + messagesToBobCount + " messagesToBob big"); + for (int i = 0; i < messagesToBobCount; i++) { + logRaw("."); + Message tmp = AdapterTestUtils.makeNewTestMessage(alice, bob, Message.Direction.Outgoing); + tmp.setLongmsg(TestUtils.repeatString(tmp.getLongmsg() + " nr: " + String.valueOf(i), 100)); + messagesToBobBig.add(tmp); + } + logRaw("\n"); + + log("Preparing " + messagesToBobCount + " messagesToBob huge"); + for (int i = 0; i < messagesToBobCount; i++) { + logRaw("."); + Message tmp = AdapterTestUtils.makeNewTestMessage(alice, bob, Message.Direction.Outgoing); + tmp.setLongmsg(TestUtils.repeatString(tmp.getLongmsg() + " nr: " + String.valueOf(i), 10000)); + messagesToBobHuge.add(tmp); + } + logRaw("\n"); + } + +} + +class TestAlice { + public static void main(String[] args) throws Exception { + TestSuite.getDefault().setVerbose(false); + TestSuite.getDefault().setTestColor(TestUtils.TermColor.GREEN); + + Jni115TestContext ctx1 = new Jni115TestContext(); + + new TestUnit("myself()", ctx1, ctx -> { + ctx.alice = ctx.engine.myself(ctx.alice); + if (ctx.alice.fpr == null) { + throw new RuntimeException(); + } + }).run(); + + + TestUnit perfTest = new TestUnit("EncPerf mini message", ctx1, ctx -> { +// TestUtils.readKey(); + log("encrypting " + ctx.messagesToBobCount + " messages"); + Message encrypted = null; + for (Message msg : ctx.messagesToBob) { + encrypted = ctx.engine.encrypt_message(msg, null, Message.EncFormat.PEP); + logRaw("."); + if (encrypted == null) { +// log(msg.getEncFormat().toString()); + } else { +// log(encrypted.getEncFormat().toString()); + } + } + logRaw("\n"); +// log(AdapterTestUtils.msgToString(encrypted,false)); + + }); + + // Perf test for UNENCRTYPTED (no pubkey) + ctx1.messagesToBob = ctx1.messagesToBobSmall; + perfTest.run(); + + ctx1.messagesToBob = ctx1.messagesToBobBig; + perfTest.run(); + + ctx1.messagesToBob = ctx1.messagesToBobHuge; + perfTest.run(); + + + // Key import + new TestUnit("importKey()", ctx1, ctx -> { + ctx.engine.importKey(ctx.keyBobPub); + }).run(); + + // Perf test for ENCRTYPTED (with pubkey) + ctx1.messagesToBob = ctx1.messagesToBobSmall; + perfTest.run(); + + ctx1.messagesToBob = ctx1.messagesToBobBig; + perfTest.run(); + + ctx1.messagesToBob = ctx1.messagesToBobHuge; + perfTest.run(); + +// TestSuite.getDefault().run(); + } +} + + + diff --git a/test/java/foundation/pEp/jniadapter/test/utils/AdapterTestUtils.java b/test/java/foundation/pEp/jniadapter/test/utils/AdapterTestUtils.java index ccc4821..2ee3992 100644 --- a/test/java/foundation/pEp/jniadapter/test/utils/AdapterTestUtils.java +++ b/test/java/foundation/pEp/jniadapter/test/utils/AdapterTestUtils.java @@ -286,4 +286,21 @@ public class AdapterTestUtils { msg.setLongmsg("Hi i am the longMessage"); return msg; } + + public static Message generateSourceMessage(Identity from, Identity to, long id, long longMsgLen) { + Message msg = new Message(); + Vector vID = new Vector(); + if (to != null) { + vID.add(to); + } + + msg.setFrom(from); + msg.setTo(vID); + msg.setDir(Message.Direction.Outgoing); + msg.setShortmsg(String.valueOf(id)); + +// String + msg.setLongmsg("Hi i am the longMessage"); + return msg; + } } \ No newline at end of file diff --git a/test/java/foundation/pEp/pitytest/Makefile.conf b/test/java/foundation/pEp/pitytest/Makefile.conf index 9805a1c..51eae4a 100644 --- a/test/java/foundation/pEp/pitytest/Makefile.conf +++ b/test/java/foundation/pEp/pitytest/Makefile.conf @@ -13,5 +13,5 @@ JAVA_CLASSES_PITYTEST= \ utils/TestUtils.class \ utils/Pair.class \ TestState.class \ - TestResult.class + StopWatch.class diff --git a/test/java/foundation/pEp/pitytest/StopWatch.java b/test/java/foundation/pEp/pitytest/StopWatch.java new file mode 100644 index 0000000..7dd77f4 --- /dev/null +++ b/test/java/foundation/pEp/pitytest/StopWatch.java @@ -0,0 +1,20 @@ +package foundation.pEp.pitytest; + +import java.time.Duration; + +public class StopWatch { + private long timeStart = 0; + private long timeEnd = 0; + private Duration duration = null; + + public StopWatch(Runnable lambda) { + timeStart = System.nanoTime(); + lambda.run(); + timeEnd = System.nanoTime(); + duration = Duration.ofNanos(timeEnd - timeStart); + } + + public Duration getDuration() { + return duration; + } +} diff --git a/test/java/foundation/pEp/pitytest/TestResult.java b/test/java/foundation/pEp/pitytest/TestResult.java deleted file mode 100644 index 68e4e46..0000000 --- a/test/java/foundation/pEp/pitytest/TestResult.java +++ /dev/null @@ -1,8 +0,0 @@ -package foundation.pEp.pitytest; - -public enum TestResult { - UNEVALUATED, - SKIPPED, - SUCCESS, - FAILED; -} \ No newline at end of file diff --git a/test/java/foundation/pEp/pitytest/TestState.java b/test/java/foundation/pEp/pitytest/TestState.java index 3f5eb4c..53ee416 100644 --- a/test/java/foundation/pEp/pitytest/TestState.java +++ b/test/java/foundation/pEp/pitytest/TestState.java @@ -7,6 +7,6 @@ public enum TestState { FAILED, STARTING, CTX_INIT, - CTX_INIT_FAILED, + CTX_FAIL, RUNNING; } \ No newline at end of file diff --git a/test/java/foundation/pEp/pitytest/TestSuite.java b/test/java/foundation/pEp/pitytest/TestSuite.java index 2bbe926..f44d355 100644 --- a/test/java/foundation/pEp/pitytest/TestSuite.java +++ b/test/java/foundation/pEp/pitytest/TestSuite.java @@ -98,9 +98,9 @@ public class TestSuite { int failedCount = 0; int successCount = 0; for (TestUnit t : tests) { - if (t.getResult() == TestResult.SKIPPED) skippedCount++; - if (t.getResult() == TestResult.FAILED) failedCount++; - if (t.getResult() == TestResult.SUCCESS) successCount++; + if (t.getResult() == TestState.SKIPPED) skippedCount++; + if (t.getResult() == TestState.FAILED) failedCount++; + if (t.getResult() == TestState.SUCCESS) successCount++; } failedCount = failedCount + skippedCount; diff --git a/test/java/foundation/pEp/pitytest/TestUnit.java b/test/java/foundation/pEp/pitytest/TestUnit.java index 6e543ef..a14b4f0 100644 --- a/test/java/foundation/pEp/pitytest/TestUnit.java +++ b/test/java/foundation/pEp/pitytest/TestUnit.java @@ -3,30 +3,38 @@ package foundation.pEp.pitytest; import foundation.pEp.pitytest.utils.TestUtils; import static foundation.pEp.pitytest.TestLogger.*; -import static foundation.pEp.pitytest.utils.TestUtils.TermColor; -import static foundation.pEp.pitytest.utils.TestUtils.colorString; +import static foundation.pEp.pitytest.utils.TestUtils.*; +import java.text.DecimalFormat; +import java.time.Duration; import java.util.function.Consumer; -//Automatically get added to the default TestSuite always -//Can be added to any nr of TestSuites +// Automatically gets added to the default TestSuite always +// Can be added to any nr of TestSuites public class TestUnit implements Runnable { private String testUnitName = "default test unit"; private T ctx; private Consumer lambda; - private TestResult result = TestResult.UNEVALUATED; + private TestState result = TestState.UNEVALUATED; private TestState state = TestState.UNEVALUATED; private Throwable lastException; + private Duration testDuration = null; private boolean verboseMode = true; private TermColor testColor = TermColor.CYAN; // Defaults (line width 80) - private int logFmtTestNameLen = 35; - private int logFmtCtxNameLen = 25; + // fixed width + private int logFmtPadding = 4; private int logFmtMsgLen = 12; + private int logFmtTestDuration = 14; + private int lineWidthMin = logFmtPadding + logFmtMsgLen + logFmtTestDuration + 20; + + // dynamic + private int logFmtTestNameLen = 32; + private int logFmtCtxNameLen = 20; public TestUnit(String name, T context, Consumer lambda) { this.testUnitName = name; @@ -52,7 +60,7 @@ public class TestUnit implements Runnable { this.testColor = testColor; } - public TestResult getResult() { + public TestState getResult() { return result; } @@ -70,96 +78,87 @@ public class TestUnit implements Runnable { return this; } + public T getContext() { + return ctx; + } + public void run() { TestUtils.standardOutErrEnabled(verboseMode); if (ctx.isUninitializable()) { - setTestState(TestState.CTX_INIT_FAILED); + setTestState(TestState.CTX_FAIL); TestUtils.standardOutErrEnabled(true); - return; - } - try { - setTestState(TestState.STARTING); - // Init the Context if not already done - if (!ctx.isInitialized()) { - //Context init problems need to throw to fail - try { - setTestState(TestState.CTX_INIT); - setTermColor(testColor); - ctx.init(); - setTermColor(TermColor.RESET); - } catch (Throwable t) { - lastException = t; - setTermColor(TermColor.RESET); - setTestState(TestState.CTX_INIT_FAILED); - TestUtils.standardOutErrEnabled(true); - return; + } else { + try { + setTestState(TestState.STARTING); + // Init the Context if not already done + if (!ctx.isInitialized()) { + //Context init problems need to throw to fail + try { + setTestState(TestState.CTX_INIT); + setTermColor(testColor); + ctx.init(); + setTermColor(TermColor.RESET); + } catch (Throwable t) { + lastException = t; + setTermColor(TermColor.RESET); + ctx.setUninitializable(true); + setTestState(TestState.CTX_FAIL); + TestUtils.standardOutErrEnabled(true); + return; + } + ctx.setInitialized(true); } - ctx.setInitialized(true); + //tests need to throw to fail + setTestState(TestState.RUNNING); + setTermColor(testColor); + testDuration = new StopWatch(() -> { + lambda.accept(ctx); + }).getDuration(); + setTermColor(TermColor.RESET); + setTestState(TestState.SUCCESS); + } catch (Throwable t) { + lastException = t; + setTermColor(TermColor.RESET); + setTestState(TestState.FAILED); + TestUtils.standardOutErrEnabled(true); + return; } - //tests need to throw to fail - setTestState(TestState.RUNNING); - setTermColor(testColor); - lambda.accept(ctx); - setTermColor(TermColor.RESET); - setTestState(TestState.SUCCESS); - } catch (Throwable t) { - lastException = t; setTermColor(TermColor.RESET); - setTestState(TestState.FAILED); TestUtils.standardOutErrEnabled(true); - return; } - setTermColor(TermColor.RESET); - TestUtils.standardOutErrEnabled(true); } private void setTestState(TestState s) { state = s; switch (state) { - case UNEVALUATED: { - setTestResult(TestResult.UNEVALUATED); - break; - } - case SKIPPED: { - setTestResult(TestResult.SKIPPED); - break; - } - case SUCCESS: { - setTestResult(TestResult.SUCCESS); - break; - } + case UNEVALUATED: + case SKIPPED: + case SUCCESS: case FAILED: { - setTestResult(TestResult.FAILED); + setTestResult(s); break; } - case STARTING: case CTX_INIT: + case STARTING: case RUNNING: { - logH1(makeLogString(state.toString())); + logH1(makeLogString()); break; } - case CTX_INIT_FAILED: { - logH1(makeLogString(state.toString())); - setTestResult(TestResult.SKIPPED); + case CTX_FAIL: { + setTestResult(TestState.SKIPPED); +// logH1(makeLogString()); break; } } } - private void setTestResult(TestResult r) { + private void setTestResult(TestState r) { + assert (r == TestState.SKIPPED || r == TestState.FAILED || r == TestState.SUCCESS || r == TestState.UNEVALUATED ): "PityTest Internal: illegal result value '" + r +"'"; result = r; - String resultStr = r.toString(); - - if(r != TestResult.SUCCESS) { - resultStr = colorString(resultStr, TermColor.RED); - } else { - resultStr = colorString(resultStr, TermColor.GREEN); - } - TestUtils.standardOutErrEnabled(true); - logH1(makeLogString(resultStr)); - if( r != TestResult.SUCCESS) { + logH1(makeLogString()); + if (result == TestState.FAILED || result == TestState.CTX_FAIL) { log("ERROR: " + getLastException().toString()); } if (verboseMode) logRaw("\n\n"); @@ -167,16 +166,39 @@ public class TestUnit implements Runnable { } private void logLayout() { - logFmtTestNameLen = (int) Math.floor(TestLogger.getMsgWidth() * 0.39); - logFmtCtxNameLen = (int) Math.floor(TestLogger.getMsgWidth() * 0.28); - logFmtMsgLen = (int) Math.floor(TestLogger.getMsgWidth() * 0.25); + int lineWidth = TestLogger.getMsgWidth(); + // Fixed sizes + lineWidth -= logFmtPadding; + lineWidth -= logFmtMsgLen; + lineWidth -= logFmtTestDuration; + lineWidth = clip(lineWidth, lineWidthMin, Integer.MAX_VALUE); + + // Proportional (dynamic sizes) + logFmtTestNameLen = (int) Math.floor(lineWidth * 0.45); + logFmtCtxNameLen = (int) Math.floor(lineWidth * 0.45); } - private String makeLogString(String str) { + private String makeLogString() { + String resultStr = state.toString(); + if (state == TestState.FAILED) { + resultStr = colorString(resultStr, TermColor.RED); + } else if (state == TestState.SUCCESS) { + resultStr = colorString(resultStr, TermColor.GREEN); + } + String testUnitNameFmtd = TestUtils.padOrClipString(" TEST: '" + testUnitName + "' ", "=", logFmtTestNameLen, TestUtils.Alignment.Left, ".. "); String testCtxNameFmtd = TestUtils.padOrClipString(" CTX: '" + ctx.getTestContextName() + "' ", "=", logFmtCtxNameLen, TestUtils.Alignment.Center, ".. "); - String strFmtd = TestUtils.padOrClipString(" " + str + " ", "=", logFmtMsgLen, TestUtils.Alignment.Right, ".. "); - return testUnitNameFmtd + testCtxNameFmtd + strFmtd; + String strTestDuration = ""; + if (state == TestState.SUCCESS) { + DecimalFormat f = new DecimalFormat("0.000"); + String durationFmtd = f.format(testDuration.toMillis() / 1000.0); + strTestDuration = TestUtils.padOrClipString(" [" + durationFmtd + " sec] ", "=", logFmtTestDuration, TestUtils.Alignment.Right, ".. "); + } else { + strTestDuration = TestUtils.padOrClipString("", "=", logFmtTestDuration, TestUtils.Alignment.Right, ".. "); + } + + String strFmtd = TestUtils.padOrClipString(" " + resultStr + " ", "=", logFmtMsgLen, TestUtils.Alignment.Right, ".. "); + return testUnitNameFmtd + testCtxNameFmtd + strTestDuration + strFmtd; } } diff --git a/test/java/foundation/pEp/pitytest/examples/Makefile.conf b/test/java/foundation/pEp/pitytest/examples/Makefile.conf index 97fdd45..c0100ad 100644 --- a/test/java/foundation/pEp/pitytest/examples/Makefile.conf +++ b/test/java/foundation/pEp/pitytest/examples/Makefile.conf @@ -10,7 +10,6 @@ JAVA_CLASSES_PITYTEST= \ ../../TestLogger.class \ ../../utils/TestUtils.class \ ../../utils/Pair.class \ - ../../TestState.class \ - ../../TestResult.class + ../../TestState.class PITYTEST_DIR=../../ diff --git a/test/java/foundation/pEp/pitytest/utils/TestUtils.java b/test/java/foundation/pEp/pitytest/utils/TestUtils.java index f6df12c..f18d6b4 100644 --- a/test/java/foundation/pEp/pitytest/utils/TestUtils.java +++ b/test/java/foundation/pEp/pitytest/utils/TestUtils.java @@ -140,7 +140,7 @@ public class TestUtils { public static String padOrClipString(String str, String padChar, int len, Alignment alignment, String clipMsg) { String ret = ""; int strLen = str.length(); - len += (substringOccurencesCount(str, "\u001B") * 4); + len += (substringOccurencesCount(str, "\u001B") * 4.5); if (strLen <= len) { if (alignment == Alignment.Left) { ret = str + repeatString(padChar, len - strLen);