
4 changed files with 437 additions and 0 deletions
@ -0,0 +1,268 @@ |
|||||
|
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.utils.*; |
||||
|
|
||||
|
import java.io.File; |
||||
|
import java.io.FileNotFoundException; |
||||
|
import java.io.IOException; |
||||
|
import java.lang.reflect.Parameter; |
||||
|
import java.nio.charset.Charset; |
||||
|
import java.nio.file.Files; |
||||
|
import java.nio.file.Path; |
||||
|
import java.nio.file.Paths; |
||||
|
import java.util.*; |
||||
|
|
||||
|
import javafx.util.Pair; |
||||
|
|
||||
|
|
||||
|
public class FsMsgQueue implements Queue<String> { |
||||
|
File qDir; |
||||
|
|
||||
|
public FsMsgQueue(String qDirPath) throws RuntimeException { |
||||
|
qDir = new File(qDirPath); |
||||
|
if (!qDir.exists()) { |
||||
|
if (!qDir.mkdirs()) { |
||||
|
throw new RuntimeException("Dir not existing, could not create:" + qDirPath); |
||||
|
} else { |
||||
|
// Dir created
|
||||
|
} |
||||
|
} else { |
||||
|
// Dir already exists
|
||||
|
} |
||||
|
// Dir now definitely exists
|
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int size() { |
||||
|
return qDir.listFiles().length; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean isEmpty() { |
||||
|
return size() <= 0; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean add(String msg) { |
||||
|
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()); |
||||
|
} |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean offer(String msg) { |
||||
|
boolean ret = true; |
||||
|
try { |
||||
|
add(msg); |
||||
|
} catch (Exception e) { |
||||
|
ret = false; |
||||
|
} |
||||
|
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); |
||||
|
} 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); |
||||
|
} |
||||
|
} |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public String remove() throws NoSuchElementException { |
||||
|
String ret = null; |
||||
|
Pair<File, String> pair = null; |
||||
|
File file = null; |
||||
|
try { |
||||
|
pair = get(); |
||||
|
} catch (Exception e) { |
||||
|
throw new NoSuchElementException(e.toString()); |
||||
|
} |
||||
|
// Successful read
|
||||
|
// remove now
|
||||
|
if (pair != null ) { |
||||
|
file = pair.getKey(); |
||||
|
ret = pair.getValue(); |
||||
|
if(file != null && ret != null) { |
||||
|
file.delete(); |
||||
|
if (file.exists()) { |
||||
|
throw new RuntimeException("Cant remove msg from queue: " + file.getAbsolutePath()); |
||||
|
} |
||||
|
} else { |
||||
|
throw new NoSuchElementException("Unknown Error"); |
||||
|
} |
||||
|
} |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public String poll() { |
||||
|
String ret = null; |
||||
|
try { |
||||
|
ret = remove(); |
||||
|
} catch (Exception e) { |
||||
|
} |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public String element() throws NoSuchElementException { |
||||
|
String ret = null; |
||||
|
Pair<File, String> pair = null; |
||||
|
try { |
||||
|
pair = get(); |
||||
|
} catch (Exception e) { |
||||
|
throw new NoSuchElementException(e.toString()); |
||||
|
} |
||||
|
if(pair != null) { |
||||
|
ret = pair.getValue(); |
||||
|
} else { |
||||
|
throw new NoSuchElementException("Unknown Error"); |
||||
|
} |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public String peek() { |
||||
|
String ret = null; |
||||
|
try { |
||||
|
ret = element(); |
||||
|
} catch (Exception e) { |
||||
|
} |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
public boolean addAll(Collection<? extends String> c) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
public void clear() { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// Not implemented
|
||||
|
@Override |
||||
|
public boolean contains(Object o) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
// Not implemented
|
||||
|
@Override |
||||
|
public Iterator<String> iterator() { |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
// Not implemented
|
||||
|
@Override |
||||
|
public Object[] toArray() { |
||||
|
return new Object[0]; |
||||
|
} |
||||
|
|
||||
|
// Not implemented
|
||||
|
@Override |
||||
|
public <T> T[] toArray(T[] a) { |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
// Not implemented
|
||||
|
@Override |
||||
|
public boolean remove(Object o) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
// Not implemented
|
||||
|
@Override |
||||
|
public boolean containsAll(Collection<?> c) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
// Not implemented
|
||||
|
@Override |
||||
|
public boolean removeAll(Collection<?> c) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
// Not implemented
|
||||
|
@Override |
||||
|
public boolean retainAll(Collection<?> c) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
//Math Utils
|
||||
|
private 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) { |
||||
|
return Math.max(min, Math.min(max, val)); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// File Utils
|
||||
|
|
||||
|
// Possibly returns an empty ArrayList
|
||||
|
private ArrayList<File> listFilesByMtime(File dir) { |
||||
|
ArrayList<File> ret = new ArrayList<>(); |
||||
|
File[] listOfFiles = dir.listFiles(); |
||||
|
if (listOfFiles != null) { |
||||
|
Collections.addAll(ret, listOfFiles); |
||||
|
ret = sortFilesByMtime(ret); |
||||
|
} |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
// null in null out
|
||||
|
private ArrayList<File> sortFilesByMtime(ArrayList<File> files) { |
||||
|
ArrayList<File> ret = null; |
||||
|
if (files != null) { |
||||
|
ret = new ArrayList(files); |
||||
|
Collections.sort(ret, (o1, o2) -> { |
||||
|
long ret1 = 0; |
||||
|
ret1 = o1.lastModified() - o2.lastModified(); |
||||
|
return (int) clip(ret1, -1, 1); |
||||
|
}); |
||||
|
} |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
static String readFile(Path path, Charset encoding) throws IOException { |
||||
|
byte[] encoded = Files.readAllBytes(path); |
||||
|
return new String(encoded, encoding); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
@ -0,0 +1,7 @@ |
|||||
|
JAVA_PKG_BASENAME=foundation.pEp.jniadapter.test.utils.fsmsgqueue.test |
||||
|
JAVA_PKG_BASEPATH=foundation/pEp/jniadapter/test/utils/fsmsgqueue/test |
||||
|
JAVA_CWD=../../../../../../../../ |
||||
|
JAVA=java -enableassertions |
||||
|
|
||||
|
JAVA_CLASSES_FSMSGQUEUE= \
|
||||
|
../../FsMsgQueue.class |
@ -0,0 +1,24 @@ |
|||||
|
include ../Makefile.conf |
||||
|
|
||||
|
TEST_UNIT_NAME=readwrite |
||||
|
|
||||
|
JAVA_CLASSES = \
|
||||
|
TestMain.class \
|
||||
|
|
||||
|
JAVA_CLASSES += $(JAVA_CLASSES_FSMSGQUEUE) |
||||
|
|
||||
|
.PHONY: compile run test clean |
||||
|
|
||||
|
all: compile |
||||
|
$(MAKE) run |
||||
|
|
||||
|
run: compile |
||||
|
cd $(JAVA_CWD);$(JAVA) $(JAVA_PKG_BASENAME).$(TEST_UNIT_NAME).TestMain |
||||
|
|
||||
|
compile: $(JAVA_CLASSES) |
||||
|
|
||||
|
%.class: %.java |
||||
|
cd $(JAVA_CWD);pwd;javac $(JAVA_PKG_BASEPATH)/$(TEST_UNIT_NAME)/$< |
||||
|
|
||||
|
clean: |
||||
|
rm -f $(JAVA_CLASSES) |
@ -0,0 +1,138 @@ |
|||||
|
package foundation.pEp.jniadapter.test.utils.fsmsgqueue.test.readwrite; |
||||
|
|
||||
|
import static foundation.pEp.jniadapter.test.framework.TestLogger.*; |
||||
|
|
||||
|
import foundation.pEp.jniadapter.test.framework.*; |
||||
|
import foundation.pEp.jniadapter.test.utils.*; |
||||
|
import foundation.pEp.jniadapter.test.utils.fsmsgqueue.*; |
||||
|
|
||||
|
import java.io.File; |
||||
|
import java.util.ArrayList; |
||||
|
|
||||
|
|
||||
|
class FsMsgQueueTestContext extends AbstractTestContext { |
||||
|
String qDirPath = "../resources/fsmsgqueue-test/q1"; |
||||
|
int msgCount = 4; |
||||
|
ArrayList<String> messages; |
||||
|
|
||||
|
FsMsgQueue queue; |
||||
|
|
||||
|
@Override |
||||
|
public void init() throws Throwable { |
||||
|
deleteQDir(); |
||||
|
messages = createTestMessages(msgCount); |
||||
|
} |
||||
|
|
||||
|
public void deleteQDir() { |
||||
|
File qDir = new File(qDirPath); |
||||
|
if (qDir.exists()) { |
||||
|
log("Deleting Queue Dir: " + qDirPath); |
||||
|
deleteRecursively(qDir); |
||||
|
if (qDir.exists()) throw new RuntimeException("Cant delete Dir:" + qDirPath); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public ArrayList<String> createTestMessages(int count) { |
||||
|
log("Creating Test messages"); |
||||
|
ArrayList<String> messages = new ArrayList<>(); |
||||
|
for (int i = 0; i < count; i++) { |
||||
|
String msg = "TestMessage " + i; |
||||
|
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 { |
||||
|
public static void main(String[] args) throws Exception { |
||||
|
TestSuite.setVerbose(false); |
||||
|
FsMsgQueueTestContext testCtx = new FsMsgQueueTestContext(); |
||||
|
|
||||
|
new TestUnit<FsMsgQueueTestContext>("Constructor", testCtx, ctx -> { |
||||
|
ctx.queue = new FsMsgQueue(ctx.qDirPath); |
||||
|
}).add(); |
||||
|
|
||||
|
new TestUnit<FsMsgQueueTestContext>("Add", 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 -> { |
||||
|
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(); |
||||
|
|
||||
|
new TestUnit<FsMsgQueueTestContext>("remove", testCtx, ctx -> { |
||||
|
while (!ctx.queue.isEmpty()) { |
||||
|
String msg = ctx.queue.remove(); |
||||
|
log("remove: " + msg); |
||||
|
} |
||||
|
}).add(); |
||||
|
|
||||
|
new TestUnit<FsMsgQueueTestContext>("Size 0", testCtx, ctx -> { |
||||
|
int size = ctx.queue.size(); |
||||
|
log("Size: " + size); |
||||
|
assert size == 0; |
||||
|
}).add(); |
||||
|
|
||||
|
new TestUnit<FsMsgQueueTestContext>("isEmpty true", testCtx, ctx -> { |
||||
|
boolean isEmpty = ctx.queue.isEmpty(); |
||||
|
log("isEmpty: " + isEmpty); |
||||
|
assert isEmpty; |
||||
|
}).add(); |
||||
|
|
||||
|
new TestUnit<FsMsgQueueTestContext>("Element on empty", testCtx, ctx -> { |
||||
|
try { |
||||
|
String msg = ctx.queue.element(); |
||||
|
log("Element: " + msg); |
||||
|
} catch (Exception e) { |
||||
|
return; |
||||
|
} |
||||
|
assert false; |
||||
|
}).add(); |
||||
|
|
||||
|
new TestUnit<FsMsgQueueTestContext>("Remove on empty", testCtx, ctx -> { |
||||
|
try { |
||||
|
String msg = ctx.queue.remove(); |
||||
|
log("Element: " + msg); |
||||
|
} catch (Exception e) { |
||||
|
return; |
||||
|
} |
||||
|
assert false; |
||||
|
}).add(); |
||||
|
|
||||
|
|
||||
|
TestSuite.run(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
Loading…
Reference in new issue