merge in default

JNI-106
heck 3 years ago
commit ce852ad0c5

@ -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'
}
}

@ -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

@ -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»);
}
}
}
}

@ -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<stringlist_t*>(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
);

@ -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
}
}

@ -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

@ -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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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"

@ -0,0 +1,15 @@
#pragma once
#include <pEp/passphrase_cache.hh>
namespace pEp {
namespace JNIAdapter {
char* passphraseRequiredCallback();
template<typename... A> PEP_STATUS passphraseWrap(
PEP_STATUS f(PEP_SESSION, A...), PEP_SESSION session, A... a);
};
};
#include "passphrase_callback.hxx"

@ -0,0 +1,41 @@
#pragma once
#include "passphrase_callback.hh"
namespace pEp {
namespace JNIAdapter {
template<typename... A> 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;
}
}
}

@ -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

@ -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

@ -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<Message> messagesToBobSmall;
public List<Message> messagesToBobBig;
public List<Message> messagesToBobHuge;
public List<Message> 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<Jni115TestContext>("myself()", ctx1, ctx -> {
ctx.alice = ctx.engine.myself(ctx.alice);
if (ctx.alice.fpr == null) {
throw new RuntimeException();
}
}).run();
TestUnit perfTest = new TestUnit<Jni115TestContext>("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<Jni115TestContext>("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();
}
}

@ -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<Identity> vID = new Vector<Identity>();
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;
}
}

@ -13,5 +13,5 @@ JAVA_CLASSES_PITYTEST= \
utils/TestUtils.class \
utils/Pair.class \
TestState.class \
TestResult.class
StopWatch.class

@ -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;
}
}

@ -1,8 +0,0 @@
package foundation.pEp.pitytest;
public enum TestResult {
UNEVALUATED,
SKIPPED,
SUCCESS,
FAILED;
}

@ -7,6 +7,6 @@ public enum TestState {
FAILED,
STARTING,
CTX_INIT,
CTX_INIT_FAILED,
CTX_FAIL,
RUNNING;
}

@ -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;

@ -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<T extends TestContextInterface> implements Runnable {
private String testUnitName = "default test unit";
private T ctx;
private Consumer<T> 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<T> lambda) {
this.testUnitName = name;
@ -52,7 +60,7 @@ public class TestUnit<T extends TestContextInterface> implements Runnable {
this.testColor = testColor;
}
public TestResult getResult() {
public TestState getResult() {
return result;
}
@ -70,96 +78,87 @@ public class TestUnit<T extends TestContextInterface> 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<T extends TestContextInterface> 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;
}
}

@ -10,7 +10,6 @@ JAVA_CLASSES_PITYTEST= \
../../TestLogger.class \
../../utils/TestUtils.class \
../../utils/Pair.class \
../../TestState.class \
../../TestResult.class
../../TestState.class
PITYTEST_DIR=../../

@ -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);

Loading…
Cancel
Save