Browse Source

FsMsgQueue complete

JNI-96
heck 5 years ago
parent
commit
6537b5b88c
  1. 18
      test/java/foundation/pEp/jniadapter/test/templateAliceBob/TestAlice.java
  2. 22
      test/java/foundation/pEp/jniadapter/test/templateAliceBob/TestBob.java
  3. 224
      test/java/foundation/pEp/jniadapter/test/utils/fsmsgqueue/FsMsgQueue.java
  4. 129
      test/java/foundation/pEp/jniadapter/test/utils/fsmsgqueue/test/readwrite/TestMain.java

18
test/java/foundation/pEp/jniadapter/test/templateAliceBob/TestAlice.java

@ -1,5 +1,7 @@
package foundation.pEp.jniadapter.test.templateAliceBob;
import static foundation.pEp.jniadapter.test.framework.TestLogger.*;
import foundation.pEp.jniadapter.test.framework.*;
import foundation.pEp.jniadapter.test.utils.*;
@ -8,23 +10,25 @@ class TestAlice {
TestSuite.setVerbose(true);
TestSuite.setTestColor(TestUtils.TermColor.GREEN);
new TestUnit<AdapterBaseTestContext>("Test Alice",new AdapterBaseTestContext() , ctx -> {
// do stuff using the context
// Test FAILS on unhandled exception, otherwise SUCCESS
new TestUnit<AdapterBaseTestContext>("Alice tx msg", new AdapterBaseTestContext(), ctx -> {
ctx.alice = ctx.engine.myself(ctx.alice);
if(ctx.alice.fpr == null) {
if (ctx.alice.fpr == null) {
throw new RuntimeException();
}
for(int i=0; i < 1000; i++ ) {
log("Alice is waiting...");
//send message
}).add();
new TestUnit<AdapterBaseTestContext>("Alice rx msg", new AdapterBaseTestContext(), ctx -> {
for (int i = 0; i < 1000; i++) {
log("Alice is waiting for msg...");
TestUtils.sleep(1000);
}
}).add();
TestSuite.run();
}
}

22
test/java/foundation/pEp/jniadapter/test/templateAliceBob/TestBob.java

@ -1,5 +1,7 @@
package foundation.pEp.jniadapter.test.templateAliceBob;
import static foundation.pEp.jniadapter.test.framework.TestLogger.*;
import foundation.pEp.jniadapter.test.framework.*;
import foundation.pEp.jniadapter.test.utils.*;
@ -8,23 +10,25 @@ class TestBob {
TestSuite.setVerbose(true);
TestSuite.setTestColor(TestUtils.TermColor.YELLOW);
new TestUnit<AdapterBaseTestContext>("Test Bob",new AdapterBaseTestContext() , ctx -> {
// do stuff using the context
// Test FAILS on unhandled exception, otherwise SUCCESS
new TestUnit<AdapterBaseTestContext>("Bob rx msg", new AdapterBaseTestContext(), ctx -> {
for (int i = 0; i < 1000; i++) {
log("Bob is waiting for msg...");
TestUtils.sleep(1000);
}
}).add();
new TestUnit<AdapterBaseTestContext>("Bob tx msg", new AdapterBaseTestContext(), ctx -> {
ctx.bob = ctx.engine.myself(ctx.bob);
if(ctx.bob.fpr == null) {
if (ctx.bob.fpr == null) {
throw new RuntimeException();
}
for(int i=0; i < 1000; i++ ) {
log("Bob is waiting...");
TestUtils.sleep(1000);
}
//send message
}).add();
TestSuite.run();
}
}

224
test/java/foundation/pEp/jniadapter/test/utils/fsmsgqueue/FsMsgQueue.java

@ -3,23 +3,29 @@ package foundation.pEp.jniadapter.test.utils.fsmsgqueue;
import static foundation.pEp.jniadapter.test.framework.TestLogger.*;
import foundation.pEp.jniadapter.test.framework.*;
import foundation.pEp.jniadapter.test.framework.TestUtils.*;
import foundation.pEp.jniadapter.test.utils.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Parameter;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import javafx.util.Pair;
public class FsMsgQueue implements Queue<String> {
File qDir;
Charset fileEncoding;
public FsMsgQueue(String qDirPath) throws RuntimeException {
qDir = new File(qDirPath);
@ -33,6 +39,9 @@ public class FsMsgQueue implements Queue<String> {
// Dir already exists
}
// Dir now definitely exists
// log("Available Charsets: " + getAvailableCharsetNames());
fileEncoding = Charset.forName("UTF-8");
log("Using charset: " + fileEncoding.name());
}
@Override
@ -46,18 +55,51 @@ public class FsMsgQueue implements Queue<String> {
}
@Override
public boolean add(String msg) {
public boolean add(String msg) throws NullPointerException, IllegalStateException {
boolean ret = true;
String filename = UUID.randomUUID().toString() + ".msg";
String path = qDir + "/" + filename;
try {
Files.write(Paths.get(path), msg.getBytes());
} catch (IOException e) {
log(e.toString());
String readBack = null;
if (msg != null) {
String filename = getNewFilename();
String path = qDir + "/" + filename;
// check file not existing yet.
log("Adding msg file:" + filename);
File file = new File(path);
if(!file.exists()) {
try {
writeFile(file.toPath(), msg, fileEncoding);
readBack = readFile(Paths.get(path), fileEncoding);
} catch (IOException e) {
log(e.toString());
throw new IllegalStateException();
}
if (!readBack.equals(msg)) {
throw new IllegalStateException("Readback failed:\nwrite:\"" + msg + "\"\nread :\"" + readBack + "\"");
}
} else {
throw new IllegalStateException("Cant create new msg file, already exists:" + path);
}
} else {
throw new NullPointerException();
}
return ret;
}
private String getNewFilename() {
String ret = "";
List<File> msgFiles = dotMsgFilesSorted(qDir, true);
int newNumber = 0;
if(msgFiles.size() > 0) {
File latest = msgFiles.get(msgFiles.size() - 1);
newNumber = Integer.parseInt(latest.getName().replace(".msg", "")) + 1;
}
ret = TestUtils.padOrClipString(String.valueOf(newNumber),"0",12,Alignment.Right,"");
ret += ".msg";
return ret;
}
@Override
public boolean offer(String msg) {
boolean ret = true;
@ -69,29 +111,26 @@ public class FsMsgQueue implements Queue<String> {
return ret;
}
private File getOldestMsgFilename() {
File ret = null;
List<File> msgFiles = dotMsgFilesSorted(qDir, false);
if(msgFiles.size() > 0) {
File oldest = msgFiles.get(msgFiles.size() - 1);
ret = oldest;
}
return ret;
}
private Pair<File, String> get() throws Exception {
Pair<File, String> ret = null;
ArrayList<File> files = listFilesByMtime(qDir);
File oldestFile = null;
if (files == null || (files.size() <= 0)) {
throw new NoSuchElementException("Dir empty: " + qDir);
File oldestFile = getOldestMsgFilename();
log("reading file:" + oldestFile.getName());
if (oldestFile == null) {
throw new NoSuchElementException("MNo .msg file in dir: " + qDir);
} else {
oldestFile = files.get(0);
if(oldestFile != null) {
String fContent = null;
try {
fContent = readFile(oldestFile.toPath(), Charset.defaultCharset());
} catch (Exception e) {
throw new Exception("Error reading file: " + oldestFile.getAbsolutePath());
}
if(fContent != null) {
ret = new Pair<>(oldestFile,fContent);
} else {
throw new Exception("Error reading file: " + oldestFile.getAbsolutePath());
}
} else {
throw new NoSuchElementException("Dir empty: " + qDir);
}
String fContent = null;
fContent = readFile(oldestFile.toPath(), fileEncoding);
ret = new Pair<>(oldestFile, fContent);
}
return ret;
}
@ -108,10 +147,10 @@ public class FsMsgQueue implements Queue<String> {
}
// Successful read
// remove now
if (pair != null ) {
if (pair != null) {
file = pair.getKey();
ret = pair.getValue();
if(file != null && ret != null) {
if (file != null && ret != null) {
file.delete();
if (file.exists()) {
throw new RuntimeException("Cant remove msg from queue: " + file.getAbsolutePath());
@ -138,11 +177,11 @@ public class FsMsgQueue implements Queue<String> {
String ret = null;
Pair<File, String> pair = null;
try {
pair = get();
pair = get();
} catch (Exception e) {
throw new NoSuchElementException(e.toString());
}
if(pair != null) {
if (pair != null) {
ret = pair.getValue();
} else {
throw new NoSuchElementException("Unknown Error");
@ -162,80 +201,111 @@ public class FsMsgQueue implements Queue<String> {
@Override
public boolean addAll(Collection<? extends String> c) {
return false;
public void clear() {
deleteContentsRecursively(qDir);
}
// Not implemented
@Override
public void clear() {
public boolean addAll(Collection<? extends String> c) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
// Not implemented
@Override
public boolean contains(Object o) {
return false;
public boolean contains(Object o) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
// Not implemented
@Override
public Iterator<String> iterator() {
return null;
public Iterator<String> iterator() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
// Not implemented
@Override
public Object[] toArray() {
return new Object[0];
public Object[] toArray() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
// Not implemented
@Override
public <T> T[] toArray(T[] a) {
return null;
public <T> T[] toArray(T[] a) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
// Not implemented
@Override
public boolean remove(Object o) {
return false;
public boolean remove(Object o) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
// Not implemented
@Override
public boolean containsAll(Collection<?> c) {
return false;
public boolean containsAll(Collection<?> c) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
// Not implemented
@Override
public boolean removeAll(Collection<?> c) {
return false;
public boolean removeAll(Collection<?> c) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
// Not implemented
@Override
public boolean retainAll(Collection<?> c) {
return false;
public boolean retainAll(Collection<?> c) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
//Math Utils
private int clip(int val, int min, int max) {
public static int clip(int val, int min, int max) {
return Math.max(min, Math.min(max, val));
}
private long clip(long val, long min, long max) {
public static long clip(long val, long min, long max) {
return Math.max(min, Math.min(max, val));
}
// File Utils
// Possibly returns an empty List
private static List<File> dotMsgFilesSorted(File dir, boolean ascending) {
List<File> ret = new ArrayList<>();
File[] listOfFiles = dir.listFiles();
if (listOfFiles != null) {
Collections.addAll(ret, listOfFiles);
if (ret.size() > 0) {
ret = filterbyFilename(ret, ".*\\.msg$");
Collections.sort(ret, (o1, o2) -> {
long ret1 = 0;
int f1 = Integer.parseInt(o1.getName().replace(".msg", ""));
int f2 = Integer.parseInt(o2.getName().replace(".msg", ""));
ret1 = f1 - f2;
if (!ascending) {
ret1 = ret1 * -1;
}
return (int) clip(ret1, -1, 1);
});
}
}
return ret;
}
// possibly returns an empty list
private static List<File> filterbyFilename(List<File> files, String regex) {
List<File> ret = null;
Predicate<File> dotMsg = file -> file.getName().matches(regex);
ret = files.stream().filter(dotMsg).collect(Collectors.toList());
return ret;
}
// Possibly returns an empty ArrayList
private ArrayList<File> listFilesByMtime(File dir) {
ArrayList<File> ret = new ArrayList<>();
private static List<File> listFilesByMtime(File dir) {
List<File> ret = new ArrayList<>();
File[] listOfFiles = dir.listFiles();
if (listOfFiles != null) {
Collections.addAll(ret, listOfFiles);
@ -245,8 +315,8 @@ public class FsMsgQueue implements Queue<String> {
}
// null in null out
private ArrayList<File> sortFilesByMtime(ArrayList<File> files) {
ArrayList<File> ret = null;
private static List<File> sortFilesByMtime(List<File> files) {
List<File> ret = null;
if (files != null) {
ret = new ArrayList(files);
Collections.sort(ret, (o1, o2) -> {
@ -258,11 +328,45 @@ public class FsMsgQueue implements Queue<String> {
return ret;
}
static String readFile(Path path, Charset encoding) throws IOException {
public static String readFile(Path path, Charset decoding) throws IOException {
String ret = null;
byte[] encoded = Files.readAllBytes(path);
return new String(encoded, encoding);
ret = new String(encoded, decoding);
if (ret == null) {
throw new IOException("Error reading file: " + path);
}
return ret;
}
public static void writeFile(Path path, String msg, Charset encoding) throws IOException {
Files.write(path, msg.getBytes(encoding));
}
public static boolean deleteRecursively(File dir) {
deleteContentsRecursively(dir);
log("deleting: " + dir.getAbsolutePath());
return dir.delete();
}
public static boolean deleteContentsRecursively(File dir) {
boolean ret = false;
File[] allContents = dir.listFiles();
if (allContents != null) {
for (File file : allContents) {
ret = deleteRecursively(file);
}
}
return ret;
}
private static List<String> getAvailableCharsetNames() {
List<String> ret = new ArrayList<>();
for (String key : Charset.availableCharsets().keySet()) {
Charset val = Charset.forName(key);
ret.add(val.name());
}
return ret;
}
}

129
test/java/foundation/pEp/jniadapter/test/utils/fsmsgqueue/test/readwrite/TestMain.java

@ -1,6 +1,7 @@
package foundation.pEp.jniadapter.test.utils.fsmsgqueue.test.readwrite;
import static foundation.pEp.jniadapter.test.framework.TestLogger.*;
import static foundation.pEp.jniadapter.test.utils.fsmsgqueue.FsMsgQueue.*;
import foundation.pEp.jniadapter.test.framework.*;
import foundation.pEp.jniadapter.test.utils.*;
@ -8,11 +9,12 @@ import foundation.pEp.jniadapter.test.utils.fsmsgqueue.*;
import java.io.File;
import java.util.ArrayList;
import java.util.NoSuchElementException;
class FsMsgQueueTestContext extends AbstractTestContext {
String qDirPath = "../resources/fsmsgqueue-test/q1";
int msgCount = 4;
int msgCount = 10;
ArrayList<String> messages;
FsMsgQueue queue;
@ -26,7 +28,7 @@ class FsMsgQueueTestContext extends AbstractTestContext {
public void deleteQDir() {
File qDir = new File(qDirPath);
if (qDir.exists()) {
log("Deleting Queue Dir: " + qDirPath);
log("Deleting queue dir: " + qDirPath);
deleteRecursively(qDir);
if (qDir.exists()) throw new RuntimeException("Cant delete Dir:" + qDirPath);
}
@ -37,24 +39,13 @@ class FsMsgQueueTestContext extends AbstractTestContext {
ArrayList<String> messages = new ArrayList<>();
for (int i = 0; i < count; i++) {
String msg = "TestMessage " + i;
msg += "\nLine 2 of " + msg;
// msg += "\nLine 2 of " + msg;
messages.add(msg);
log("Creating msg: " + msg);
}
return messages;
}
// FileUtils
boolean deleteRecursively(File dir) {
File[] allContents = dir.listFiles();
if (allContents != null) {
for (File file : allContents) {
deleteRecursively(file);
}
}
return dir.delete();
}
}
class TestMain {
@ -63,70 +54,110 @@ class TestMain {
FsMsgQueueTestContext testCtx = new FsMsgQueueTestContext();
new TestUnit<FsMsgQueueTestContext>("Constructor", testCtx, ctx -> {
log("Creating queue obj on dir:" + ctx.qDirPath);
ctx.queue = new FsMsgQueue(ctx.qDirPath);
}).add();
new TestUnit<FsMsgQueueTestContext>("Add", testCtx, ctx -> {
TestUnit isEmpty = new TestUnit<FsMsgQueueTestContext>("isEmpty", testCtx, ctx -> {
log("Checking queue is empty");
assert ctx.queue.isEmpty();
}).add();
TestUnit size0 = new TestUnit<FsMsgQueueTestContext>("Size == 0", testCtx, ctx -> {
log("Checking queue size == 0");
assert ctx.queue.size() == 0;
}).add();
new TestUnit<FsMsgQueueTestContext>("write msg[0]", testCtx, ctx -> {
String msg = ctx.messages.get(0);
log("adding msg[0]:" + msg);
ctx.queue.add(msg);
}).add();
TestUnit notEmpty = new TestUnit<FsMsgQueueTestContext>("Not empty", testCtx, ctx -> {
log("Checking queue not empty");
assert !ctx.queue.isEmpty();
}).add();
new TestUnit<FsMsgQueueTestContext>("Size == 1", testCtx, ctx -> {
log("Checking queue size == 1");
assert ctx.queue.size() == 1;
}).add();
new TestUnit<FsMsgQueueTestContext>("read equals write (element)", testCtx, ctx -> {
String msg = ctx.queue.element();
log("Read:" + msg);
assert msg.equals(ctx.messages.get(0));
}).add();
new TestUnit<FsMsgQueueTestContext>("read equals write (remove)", testCtx, ctx -> {
String msg = ctx.queue.remove();
log("Read:" + msg);
assert msg.equals(ctx.messages.get(0));
}).add();
isEmpty.add();
size0.add();
TestUnit addAllMsgs = new TestUnit<FsMsgQueueTestContext>("Add " + testCtx.msgCount + " msgs", testCtx, ctx -> {
for (String msg : ctx.messages) {
log("Adding msg:" + msg);
ctx.queue.add(msg);
}
}).add();
new TestUnit<FsMsgQueueTestContext>("Element", testCtx, ctx -> {
String msg = ctx.queue.element();
log("Element: " + msg);
}).add();
new TestUnit<FsMsgQueueTestContext>("Size", testCtx, ctx -> {
TestUnit sizeFull = new TestUnit<FsMsgQueueTestContext>("Size == " + testCtx.msgCount, testCtx, ctx -> {
int size = ctx.queue.size();
log("Size: " + size);
assert size == ctx.msgCount;
}).add();
new TestUnit<FsMsgQueueTestContext>("isEmpty", testCtx, ctx -> {
boolean isEmpty = ctx.queue.isEmpty();
log("isEmpty: " + isEmpty);
assert !isEmpty;
}).add();
notEmpty.add();
new TestUnit<FsMsgQueueTestContext>("remove", testCtx, ctx -> {
new TestUnit<FsMsgQueueTestContext>("read all equals write", testCtx, ctx -> {
int msgIndex = 0;
while (!ctx.queue.isEmpty()) {
String msg = ctx.queue.remove();
log("remove: " + msg);
String expected = ctx.messages.get(msgIndex);
log("Expected:" + expected);
log("Returned:" + msg);
assert msg.equals(expected);
msgIndex++;
}
}).add();
new TestUnit<FsMsgQueueTestContext>("Size 0", testCtx, ctx -> {
int size = ctx.queue.size();
log("Size: " + size);
assert size == 0;
}).add();
addAllMsgs.add();
notEmpty.add();
sizeFull.add();
new TestUnit<FsMsgQueueTestContext>("isEmpty true", testCtx, ctx -> {
boolean isEmpty = ctx.queue.isEmpty();
log("isEmpty: " + isEmpty);
assert isEmpty;
TestUnit clear = new TestUnit<FsMsgQueueTestContext>("Clear", testCtx, ctx -> {
ctx.queue.clear();
}).add();
new TestUnit<FsMsgQueueTestContext>("Element on empty", testCtx, ctx -> {
isEmpty.add();
size0.add();
new TestUnit<FsMsgQueueTestContext>("Empty queue: element()", testCtx, ctx -> {
try {
String msg = ctx.queue.element();
log("Element: " + msg);
} catch (Exception e) {
return;
ctx.queue.element();
} catch (NoSuchElementException e) {
}
assert false;
}).add();
new TestUnit<FsMsgQueueTestContext>("Remove on empty", testCtx, ctx -> {
new TestUnit<FsMsgQueueTestContext>("Empty queue: peek()", testCtx, ctx -> {
assert ctx.queue.peek() == null;
}).add();
new TestUnit<FsMsgQueueTestContext>("Empty queue: remove()", testCtx, ctx -> {
try {
String msg = ctx.queue.remove();
log("Element: " + msg);
} catch (Exception e) {
return;
ctx.queue.remove();
} catch (NoSuchElementException e) {
}
assert false;
}).add();
new TestUnit<FsMsgQueueTestContext>("Empty queue: poll()", testCtx, ctx -> {
assert ctx.queue.poll() == null;
}).add();

Loading…
Cancel
Save